From be3f1be8df8a4313997ba3f49ed1926870e339ff Mon Sep 17 00:00:00 2001 From: Dmitry Petukhov Date: Mon, 7 Aug 2017 18:08:42 -0700 Subject: [PATCH] =?UTF-8?q?Fixed=20ART=20Surface=20initialization:=20do=20?= =?UTF-8?q?not=20cancel=20updates=20to=20the=20surfce,=20make=20them=20pen?= =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: My PR was pulled into RN 0.37 (https://github.com/facebook/react-native/commit/d294e15c43a6222f25953dae8189d0e220dbdf7e). Since then an issue was discovered: ARTSurface skipped drawing the first render cycle if native TextureView takes too long. In case a static graphic is rendered in a single render cycle, it may be skipped resulting in an empty canvas being displayed. A solution proposed in this PR: instead of skipping updates, make them pending and flush once the TextureView is ready. This solution is released within our production app. It fixed ArtSurface initialisation issues cased by original PR to RN 0.37. Closes https://github.com/facebook/react-native/pull/11539 Differential Revision: D4449255 Pulled By: shergin fbshipit-source-id: a517909ca5c78c09a3ac8d9052664b92841b4e08 --- .../views/art/ARTSurfaceViewShadowNode.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java index e3c78600b..7ababfafc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java @@ -34,6 +34,7 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode implements TextureView.SurfaceTextureListener { private @Nullable Surface mSurface; + private @Nullable boolean mHasPendingUpdates; private @Nullable Integer mBackgroundColor; @@ -62,7 +63,7 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode private void drawOutput() { if (mSurface == null || !mSurface.isValid()) { - markChildrenUpdatesSeen(this); + mHasPendingUpdates = true; return; } @@ -77,7 +78,6 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode for (int i = 0; i < getChildCount(); i++) { ARTVirtualNode child = (ARTVirtualNode) getChildAt(i); child.draw(canvas, paint, 1f); - child.markUpdateSeen(); } if (mSurface == null) { @@ -85,23 +85,20 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode } mSurface.unlockCanvasAndPost(canvas); + mHasPendingUpdates = false; } catch (IllegalArgumentException | IllegalStateException e) { - FLog.e(ReactConstants.TAG, e.getClass().getSimpleName() + " in Surface.unlockCanvasAndPost"); - } - } - - private void markChildrenUpdatesSeen(ReactShadowNode shadowNode) { - for (int i = 0; i < shadowNode.getChildCount(); i++) { - ReactShadowNode child = shadowNode.getChildAt(i); - child.markUpdateSeen(); - markChildrenUpdatesSeen(child); + FLog.e(ReactConstants.TAG, e.getClass().getSimpleName() + " in SurfaceView.drawOutput"); + } catch (RuntimeException e) { + FLog.e(ReactConstants.TAG, e.getClass().getSimpleName() + " in SurfaceView.drawOutput"); } } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { mSurface = new Surface(surface); - drawOutput(); + if (mHasPendingUpdates) { + drawOutput(); + } } @Override @@ -112,7 +109,9 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode } @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {} + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + drawOutput(); + } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) {}