diff --git a/core/assets-sources/materials/sceneform_view_material.mat b/core/assets-sources/materials/sceneform_view_material.mat index eae3d460..356aa8c3 100644 --- a/core/assets-sources/materials/sceneform_view_material.mat +++ b/core/assets-sources/materials/sceneform_view_material.mat @@ -8,6 +8,10 @@ material { "type" : "samplerExternal", "name" : "viewTexture" }, + { + "type" : "bool", + "name" : "viewTextureReady" + }, { "type" : "float2", "name" : "offsetUv" @@ -37,7 +41,11 @@ fragment { uv.x = uv.x + materialParams.offsetUv.x * (1.0 - 2.0 * uv.x); uv.y = uv.y + materialParams.offsetUv.y * (1.0 - 2.0 * uv.y); - material.baseColor = texture(materialParams_viewTexture, uv); - material.baseColor.rgb = inverseTonemapSRGB(material.baseColor.rgb); + if (materialParams.viewTextureReady) { + material.baseColor = texture(materialParams_viewTexture, uv); + material.baseColor.rgb = inverseTonemapSRGB(material.baseColor.rgb); + } else { + material.baseColor = vec4(0.0); + } } } diff --git a/core/src/main/java/com/google/ar/sceneform/rendering/RenderViewToExternalTexture.java b/core/src/main/java/com/google/ar/sceneform/rendering/RenderViewToExternalTexture.java index 86c9a396..6cb1d450 100644 --- a/core/src/main/java/com/google/ar/sceneform/rendering/RenderViewToExternalTexture.java +++ b/core/src/main/java/com/google/ar/sceneform/rendering/RenderViewToExternalTexture.java @@ -53,26 +53,10 @@ public interface OnViewSizeChangedListener { externalTexture = new ExternalTexture(); - initializeWithTransparentTexture(); - this.view = view; addView(view); } - private void initializeWithTransparentTexture() { - externalTexture.getSurfaceTexture().setDefaultBufferSize(1, 1); - - // Sanity that the surface is valid. - Surface targetSurface = externalTexture.getSurface(); - if (!targetSurface.isValid()) { - return; - } - - Canvas surfaceCanvas = targetSurface.lockCanvas(null); - surfaceCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); - targetSurface.unlockCanvasAndPost(surfaceCanvas); - } - /** * Register a callback to be invoked when the size of the view changes. * @@ -97,6 +81,10 @@ ExternalTexture getExternalTexture() { return externalTexture; } + public boolean isViewTextureReady() { + return externalTexture.getFilamentStream().getTimestamp() > 0; + } + boolean hasDrawnToSurfaceTexture() { return hasDrawnToSurfaceTexture; } diff --git a/core/src/main/java/com/google/ar/sceneform/rendering/ViewRenderable.java b/core/src/main/java/com/google/ar/sceneform/rendering/ViewRenderable.java index 0286e1d3..a3136b68 100644 --- a/core/src/main/java/com/google/ar/sceneform/rendering/ViewRenderable.java +++ b/core/src/main/java/com/google/ar/sceneform/rendering/ViewRenderable.java @@ -233,7 +233,7 @@ void prepareForDraw() { ViewRenderableInternalData data = Preconditions.checkNotNull(viewRenderableData); RenderViewToExternalTexture renderViewToExternalTexture = data.getRenderView(); - getMaterial().setExternalTexture("viewTexture", renderViewToExternalTexture.getExternalTexture()); + getMaterial().setBoolean("viewTextureReady", renderViewToExternalTexture.isViewTextureReady()); if (!renderViewToExternalTexture.isAttachedToWindow() || !renderViewToExternalTexture.isLaidOut()) { @@ -241,7 +241,16 @@ void prepareForDraw() { return; } + // Wait until one frame after the surface texture has been drawn to for the first time. + // Fixes an issue where the ViewRenderable would render black for a frame before displaying. + boolean hasDrawnToSurfaceTexture = renderViewToExternalTexture.hasDrawnToSurfaceTexture(); + if (!hasDrawnToSurfaceTexture) { + return; + } + if (!isInitialized) { + getMaterial() + .setExternalTexture("viewTexture", renderViewToExternalTexture.getExternalTexture()); updateSuggestedCollisionShape(); isInitialized = true; diff --git a/core/src/main/res/raw/sceneform_view_material.filamat b/core/src/main/res/raw/sceneform_view_material.filamat index 0edec046..9c2bac88 100644 Binary files a/core/src/main/res/raw/sceneform_view_material.filamat and b/core/src/main/res/raw/sceneform_view_material.filamat differ