Skip to content

Commit

Permalink
Fixed ART Surface initialization: do not cancel updates to the surfce…
Browse files Browse the repository at this point in the history
…, make them pen…

Summary:
My PR was pulled into RN 0.37 (d294e15). 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 #11539

Differential Revision: D4449255

Pulled By: shergin

fbshipit-source-id: a517909ca5c78c09a3ac8d9052664b92841b4e08
  • Loading branch information
tepamid authored and facebook-github-bot committed Aug 8, 2017
1 parent 2161f92 commit be3f1be
Showing 1 changed file with 12 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public class ARTSurfaceViewShadowNode extends LayoutShadowNode
implements TextureView.SurfaceTextureListener {

private @Nullable Surface mSurface;
private @Nullable boolean mHasPendingUpdates;

private @Nullable Integer mBackgroundColor;

Expand Down Expand Up @@ -62,7 +63,7 @@ public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) {

private void drawOutput() {
if (mSurface == null || !mSurface.isValid()) {
markChildrenUpdatesSeen(this);
mHasPendingUpdates = true;
return;
}

Expand All @@ -77,31 +78,27 @@ private void drawOutput() {
for (int i = 0; i < getChildCount(); i++) {
ARTVirtualNode child = (ARTVirtualNode) getChildAt(i);
child.draw(canvas, paint, 1f);
child.markUpdateSeen();
}

if (mSurface == null) {
return;
}

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
Expand All @@ -112,7 +109,9 @@ public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
}

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

0 comments on commit be3f1be

Please sign in to comment.