Fixed ART Surface initialization: do not cancel updates to the surfce, make them pen…

Summary:
My PR was pulled into RN 0.37 (d294e15c43). 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
This commit is contained in:
Dmitry Petukhov 2017-08-07 18:08:42 -07:00 committed by Facebook Github Bot
parent 2161f92aaf
commit be3f1be8df
1 changed files with 12 additions and 13 deletions

View File

@ -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) {}