1+ package com.mapbox.maps.renderer
2+
3+ import android.util.Log
4+ import com.mapbox.maps.IVulkanManager
5+ import com.mapbox.maps.NativeMapImpl
6+ import com.mapbox.maps.logI
7+ import com.mapbox.maps.logW
8+ import com.mapbox.maps.shadows.ShadowLogThrottler
9+ import com.mapbox.verifyNo
10+ import com.mapbox.verifyOnce
11+ import io.mockk.every
12+ import io.mockk.mockk
13+ import io.mockk.mockkStatic
14+ import io.mockk.unmockkAll
15+ import io.mockk.unmockkStatic
16+ import io.mockk.verify
17+ import io.mockk.verifyOrder
18+ import org.junit.After
19+ import org.junit.Assert.assertFalse
20+ import org.junit.Assert.assertTrue
21+ import org.junit.Test
22+ import org.junit.runner.RunWith
23+ import org.robolectric.RobolectricTestRunner
24+ import org.robolectric.annotation.Config
25+ import org.robolectric.annotation.LooperMode
26+ import org.robolectric.shadows.ShadowLog
27+ import java.util.concurrent.locks.ReentrantLock
28+
29+ @RunWith(RobolectricTestRunner ::class )
30+ @Config(
31+ shadows = [
32+ ShadowLogThrottler ::class ,
33+ ShadowSurfaceWrapper ::class
34+ ]
35+ )
36+ @LooperMode(LooperMode .Mode .PAUSED )
37+ class VulkanMapboxRenderThreadTest {
38+
39+ private lateinit var mapboxRenderer: MapboxRenderer
40+ private lateinit var vulkanManager: IVulkanManager
41+ private lateinit var nativeMap: NativeMapImpl
42+ private lateinit var renderThread: VulkanMapboxRenderThread
43+ private lateinit var renderHandlerThread: RenderHandlerThread
44+ private lateinit var fpsManager: FpsManager
45+
46+ private fun initRenderThread () {
47+ mapboxRenderer = mockk(relaxUnitFun = true )
48+ vulkanManager = mockk(relaxUnitFun = true )
49+ nativeMap = mockk(relaxUnitFun = true )
50+
51+ renderHandlerThread = RenderHandlerThread (mapName = " " )
52+ renderHandlerThread.start()
53+
54+ fpsManager = mockk(relaxUnitFun = true )
55+ every { fpsManager.preRender(any()) } returns true
56+
57+ val surfaceProcessingLock = ReentrantLock ()
58+
59+ renderThread = VulkanMapboxRenderThread (
60+ mapboxRenderer = mapboxRenderer,
61+ antialiasingSampleCount = 1 ,
62+ handlerThread = renderHandlerThread,
63+ fpsManager = fpsManager,
64+ surfaceProcessingLock = surfaceProcessingLock,
65+ createCondition = surfaceProcessingLock.newCondition(),
66+ destroyCondition = surfaceProcessingLock.newCondition(),
67+ )
68+
69+ mockkStatic(" com.mapbox.maps.MapboxLogger" )
70+ ShadowLog .stream = System .out
71+ every { logI(any(), any()) } answers { Log .i(firstArg(), secondArg()) }
72+ every { logI(any(), any(), any()) } answers { Log .i(firstArg(), secondArg()) }
73+ every { logW(any(), any()) } answers { Log .w(firstArg<String >(), secondArg<String >()) }
74+ }
75+
76+ private fun setupVulkanManagerAvailable () {
77+ every { mapboxRenderer.map } returns nativeMap
78+ every { nativeMap.getVulkanManager() } returns vulkanManager
79+ }
80+
81+ private fun setupVulkanManagerUnavailable () {
82+ every { mapboxRenderer.map } returns nativeMap
83+ every { nativeMap.getVulkanManager() } returns null
84+ }
85+
86+ @After
87+ fun cleanup () {
88+ if (::renderHandlerThread.isInitialized) {
89+ renderHandlerThread.stop()
90+ }
91+ unmockkStatic(" com.mapbox.maps.MapboxLogger" )
92+ unmockkAll()
93+ }
94+
95+ @Test
96+ fun resizeForwardsToVulkanManagerWhenAvailable () {
97+ initRenderThread()
98+ setupVulkanManagerAvailable()
99+ assertTrue(renderThread.prepareRendererForTest())
100+
101+ renderThread.resize(800 , 600 )
102+
103+ verifyOnce { vulkanManager.resize(800 , 600 ) }
104+ }
105+
106+ @Test
107+ fun resizeCachesDimensionsWhenVulkanManagerNull () {
108+ initRenderThread()
109+ setupVulkanManagerUnavailable()
110+ assertFalse(renderThread.prepareRendererForTest())
111+
112+ renderThread.resize(800 , 600 )
113+
114+ verifyNo { vulkanManager.resize(any(), any()) }
115+ }
116+
117+ @Test
118+ fun cachedResizeAppliedWhenVulkanManagerBecomesAvailable () {
119+ initRenderThread()
120+ setupVulkanManagerUnavailable()
121+ renderThread.prepareRendererForTest()
122+ renderThread.resize(800 , 600 )
123+
124+ setupVulkanManagerAvailable()
125+ renderThread.prepareRendererForTest()
126+
127+ verifyOnce { vulkanManager.resize(800 , 600 ) }
128+ }
129+
130+ @Test
131+ fun lastResizeWinsWhenMultipleCached () {
132+ initRenderThread()
133+ setupVulkanManagerUnavailable()
134+ renderThread.prepareRendererForTest()
135+
136+ renderThread.resize(800 , 600 )
137+ renderThread.resize(1024 , 768 )
138+ renderThread.resize(1920 , 1080 )
139+
140+ setupVulkanManagerAvailable()
141+ renderThread.prepareRendererForTest()
142+
143+ verifyOnce { vulkanManager.resize(1920 , 1080 ) }
144+ verifyNo { vulkanManager.resize(800 , 600 ) }
145+ verifyNo { vulkanManager.resize(1024 , 768 ) }
146+ }
147+
148+ @Test
149+ fun cachedResizeClearedAfterApplying () {
150+ initRenderThread()
151+ setupVulkanManagerUnavailable()
152+ renderThread.prepareRendererForTest()
153+ renderThread.resize(800 , 600 )
154+
155+ setupVulkanManagerAvailable()
156+ renderThread.prepareRendererForTest()
157+ verifyOnce { vulkanManager.resize(800 , 600 ) }
158+
159+ renderThread.prepareRendererForTest()
160+ verify(exactly = 1 ) { vulkanManager.resize(800 , 600 ) }
161+ }
162+
163+ @Test
164+ fun noCachedResizeWhenNeverResizedBeforeVulkanManager () {
165+ initRenderThread()
166+ setupVulkanManagerAvailable()
167+ renderThread.prepareRendererForTest()
168+
169+ verifyNo { vulkanManager.resize(any(), any()) }
170+ }
171+
172+ @Test
173+ fun resizeAfterVulkanManagerAvailableGoesDirectly () {
174+ initRenderThread()
175+ setupVulkanManagerAvailable()
176+ renderThread.prepareRendererForTest()
177+
178+ renderThread.resize(800 , 600 )
179+ renderThread.resize(1024 , 768 )
180+
181+ verifyOrder {
182+ vulkanManager.resize(800 , 600 )
183+ vulkanManager.resize(1024 , 768 )
184+ }
185+ }
186+ }
0 commit comments