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:
parent
2161f92aaf
commit
be3f1be8df
|
@ -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) {}
|
||||
|
|
Loading…
Reference in New Issue