Skip to content

Commit cee733e

Browse files
authored
fix(android): Canvas was getting blank because of unexpected flush calls (#85)
1 parent a541f93 commit cee733e

File tree

5 files changed

+21
-13
lines changed

5 files changed

+21
-13
lines changed

packages/canvas/src-native/canvas-android/canvas/src/main/java/org/nativescript/canvas/CPUView.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,11 @@ class CPUView @JvmOverloads constructor(
6969
canvasView?.get()?.let { canvas ->
7070
if (canvas.nativeContext != 0L) {
7171
canvas.queueEvent {
72+
// We don't want pending flags that were set up to this point
73+
canvas.invalidateState = canvas.invalidateState and TNSCanvas.INVALIDATE_STATE_PENDING.inv()
7274
TNSCanvas.nativeCustomWithBitmapFlush(canvas.nativeContext, it)
7375
handler!!.post {
74-
canvas.invalidateState = TNSCanvas.InvalidateState.NONE
76+
canvas.invalidateState = canvas.invalidateState and TNSCanvas.INVALIDATE_STATE_INVALIDATING.inv()
7577
invalidate()
7678
}
7779
}

packages/canvas/src-native/canvas-android/canvas/src/main/java/org/nativescript/canvas/GLContext.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,23 @@ internal class GLContext {
149149
queueEvent {
150150
if (reference != null) {
151151
val canvasView = reference!!.get()
152-
if (canvasView != null && canvasView.nativeContext != 0L && canvasView.invalidateState == TNSCanvas.InvalidateState.INVALIDATING) {
152+
if (canvasView != null && canvasView.nativeContext != 0L && (canvasView.invalidateState and TNSCanvas.INVALIDATE_STATE_INVALIDATING) == TNSCanvas.INVALIDATE_STATE_INVALIDATING) {
153+
// We don't want pending flags that were set up to this point
154+
canvasView.invalidateState = canvasView.invalidateState and TNSCanvas.INVALIDATE_STATE_PENDING.inv()
155+
153156
TNSCanvas.nativeFlush(canvasView.nativeContext)
154157
if (!mGLThread!!.getPaused() && !swapBuffers(mEGLSurface)) {
155158
Log.e("JS", "GLContext: Cannot swap buffers!")
156159
}
157-
canvasView.invalidateState = TNSCanvas.InvalidateState.NONE
160+
canvasView.invalidateState = canvasView.invalidateState and TNSCanvas.INVALIDATE_STATE_INVALIDATING.inv()
158161
} else {
159162
// WebGL
160163
if (!mGLThread!!.getPaused() && !swapBuffers(mEGLSurface)) {
161164
Log.e("JS", "GLContext: Cannot swap buffers!")
162165
}
163166
if (canvasView != null) {
164-
canvasView.invalidateState = TNSCanvas.InvalidateState.NONE
167+
// If this point is reached, it means something went wrong so set flag to none
168+
canvasView.invalidateState = TNSCanvas.INVALIDATE_STATE_NONE
165169
}
166170
}
167171
}

packages/canvas/src-native/canvas-android/canvas/src/main/java/org/nativescript/canvas/TNSCanvas.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class TNSCanvas : FrameLayout, FrameCallback, ActivityLifecycleCallbacks {
4646
}
4747

4848
@JvmField
49-
internal var invalidateState = InvalidateState.NONE
49+
internal var invalidateState = TNSCanvas.INVALIDATE_STATE_NONE // bitwise flag
5050
internal var contextType = ContextType.NONE
5151
internal var actualContextType = ""
5252
internal var useCpu = false
@@ -122,14 +122,11 @@ class TNSCanvas : FrameLayout, FrameCallback, ActivityLifecycleCallbacks {
122122

123123
private val mainHandler = Handler(Looper.getMainLooper())
124124

125-
enum class InvalidateState {
126-
NONE, PENDING, INVALIDATING
127-
}
128-
129125
override fun doFrame(frameTimeNanos: Long) {
130126
if (!isHandleInvalidationManually) {
131-
if (invalidateState == InvalidateState.PENDING) {
132-
invalidateState = InvalidateState.INVALIDATING
127+
// Only pending state flag is accepted
128+
if (invalidateState == INVALIDATE_STATE_PENDING) {
129+
invalidateState = INVALIDATE_STATE_INVALIDATING
133130
flush()
134131
}
135132
}
@@ -600,6 +597,11 @@ class TNSCanvas : FrameLayout, FrameCallback, ActivityLifecycleCallbacks {
600597
companion object {
601598
var views: ConcurrentHashMap<*, *> = ConcurrentHashMap<Any?, Any?>()
602599

600+
// Invalidate state bitwise flags
601+
internal const val INVALIDATE_STATE_NONE = 0
602+
internal const val INVALIDATE_STATE_PENDING = 1
603+
internal const val INVALIDATE_STATE_INVALIDATING = 2
604+
603605
@JvmStatic
604606
fun layoutView(width: Int, height: Int, tnsCanvas: TNSCanvas) {
605607
var rootParams = tnsCanvas.layoutParams

packages/canvas/src-native/canvas-android/canvas/src/main/java/org/nativescript/canvas/TNSCanvasRenderingContext2D.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ class TNSCanvasRenderingContext2D internal constructor(val canvas: TNSCanvas) :
523523

524524
private fun updateCanvas() {
525525
// synchronized (canvasView.lock) {
526-
canvas.invalidateState = TNSCanvas.InvalidateState.PENDING
526+
canvas.invalidateState = canvas.invalidateState or TNSCanvas.INVALIDATE_STATE_PENDING
527527
//}
528528
}
529529

packages/canvas/src-native/canvas-android/canvas/src/main/java/org/nativescript/canvas/TNSWebGLRenderingContext.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ open class TNSWebGLRenderingContext : TNSCanvasRenderingContext {
3939

4040
fun updateCanvas() {
4141
// synchronized (canvasView.lock) {
42-
canvas.invalidateState = TNSCanvas.InvalidateState.PENDING
42+
canvas.invalidateState = canvas.invalidateState or TNSCanvas.INVALIDATE_STATE_PENDING
4343
//}
4444
}
4545

0 commit comments

Comments
 (0)