diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index bbb90536e8f89..1812d291dd8f0 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -33,6 +33,7 @@ import android.graphics.Region; import android.graphics.RenderNode; import android.os.Build; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.SystemClock; import android.util.AttributeSet; @@ -119,11 +120,10 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb final Rect mScreenRect = new Rect(); SurfaceSession mSurfaceSession; - SurfaceControl mSurfaceControl; + SurfaceControlWithBackground mSurfaceControl; // In the case of format changes we switch out the surface in-place // we need to preserve the old one until the new one has drawn. - SurfaceControl mDeferredDestroySurfaceControl; - SurfaceControl mBackgroundControl; + SurfaceControlWithBackground mDeferredDestroySurfaceControl; final Rect mTmpRect = new Rect(); final Configuration mConfiguration = new Configuration(); @@ -487,29 +487,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb } } - private void updateBackgroundVisibilityInTransaction() { - if (mBackgroundControl == null) { - return; - } - if ((mSubLayer < 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) { - mBackgroundControl.show(); - mBackgroundControl.setLayer(Integer.MIN_VALUE); - } else { - mBackgroundControl.hide(); - } - } - - private void releaseSurfaces() { - if (mSurfaceControl != null) { - mSurfaceControl.remove(); - mSurfaceControl = null; - } - if (mBackgroundControl != null) { - mBackgroundControl.remove(); - mBackgroundControl = null; - } - } - /** @hide */ protected void updateSurface() { if (!mHaveFrame) { @@ -576,21 +553,14 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb updateOpaqueFlag(); final String name = "SurfaceView - " + viewRoot.getTitle().toString(); - mSurfaceControl = new SurfaceControl.Builder(mSurfaceSession) - .setName(name) - .setOpaque((mSurfaceFlags & SurfaceControl.OPAQUE) != 0) - .setBufferSize(mSurfaceWidth, mSurfaceHeight) - .setFormat(mFormat) - .setParent(viewRoot.getSurfaceControl()) - .setFlags(mSurfaceFlags) - .build(); - mBackgroundControl = new SurfaceControl.Builder(mSurfaceSession) - .setName("Background for -" + name) - .setOpaque(true) - .setColorLayer() - .setParent(mSurfaceControl) - .build(); - + mSurfaceControl = new SurfaceControlWithBackground( + name, + (mSurfaceFlags & SurfaceControl.OPAQUE) != 0, + new SurfaceControl.Builder(mSurfaceSession) + .setBufferSize(mSurfaceWidth, mSurfaceHeight) + .setFormat(mFormat) + .setParent(viewRoot.getSurfaceControl()) + .setFlags(mSurfaceFlags)); } else if (mSurfaceControl == null) { return; } @@ -607,13 +577,11 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb SurfaceControl.openTransaction(); try { mSurfaceControl.setLayer(mSubLayer); - if (mViewVisibility) { mSurfaceControl.show(); } else { mSurfaceControl.hide(); } - updateBackgroundVisibilityInTransaction(); // While creating the surface, we will set it's initial // geometry. Outside of that though, we should generally @@ -699,7 +667,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb } if (creating) { - mSurface.copyFrom(mSurfaceControl); + mSurface.copyFrom(mSurfaceControl.mForegroundControl); } if (sizeChanged && getContext().getApplicationInfo().targetSdkVersion @@ -709,7 +677,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb // existing {@link Surface} will be ignored when the size changes. // Therefore, we must explicitly recreate the {@link Surface} in these // cases. - mSurface.createFrom(mSurfaceControl); + mSurface.createFrom(mSurfaceControl.mForegroundControl); } if (visible && mSurface.isValid()) { @@ -756,7 +724,8 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb if (mSurfaceControl != null && !mSurfaceCreated) { mSurface.release(); - releaseSurfaces(); + mSurfaceControl.remove(); + mSurfaceControl = null; } } } catch (Exception ex) { @@ -857,7 +826,8 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb private void setParentSpaceRectangle(Rect position, long frameNumber) { final ViewRootImpl viewRoot = getViewRootImpl(); - applySurfaceTransforms(mSurfaceControl, position, frameNumber); + applySurfaceTransforms(mSurfaceControl.mForegroundControl, position, frameNumber); + applySurfaceTransforms(mSurfaceControl.mBackgroundControl, position, frameNumber); applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface, frameNumber); @@ -922,10 +892,13 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb if (frameNumber > 0) { final ViewRootImpl viewRoot = getViewRootImpl(); - mRtTransaction.deferTransactionUntilSurface(mSurfaceControl, viewRoot.mSurface, + mRtTransaction.deferTransactionUntilSurface(mSurfaceControl.mForegroundControl, viewRoot.mSurface, + frameNumber); + mRtTransaction.deferTransactionUntilSurface(mSurfaceControl.mBackgroundControl, viewRoot.mSurface, frameNumber); } - mRtTransaction.hide(mSurfaceControl); + mRtTransaction.hide(mSurfaceControl.mForegroundControl); + mRtTransaction.hide(mSurfaceControl.mBackgroundControl); mRtTransaction.apply(); } }; @@ -972,19 +945,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb * @hide */ public void setResizeBackgroundColor(int bgColor) { - if (mBackgroundControl == null) { - return; - } - - final float[] colorComponents = new float[] { Color.red(bgColor) / 255.f, - Color.green(bgColor) / 255.f, Color.blue(bgColor) / 255.f }; - - SurfaceControl.openTransaction(); - try { - mBackgroundControl.setColor(colorComponents); - } finally { - SurfaceControl.closeTransaction(); - } + mSurfaceControl.setBackgroundColor(bgColor); } @UnsupportedAppUsage @@ -1168,6 +1129,134 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb * @return The SurfaceControl for this SurfaceView. */ public SurfaceControl getSurfaceControl() { - return mSurfaceControl; + return mSurfaceControl.mForegroundControl; + } + + class SurfaceControlWithBackground { + SurfaceControl mForegroundControl; + SurfaceControl mBackgroundControl; + private boolean mOpaque = true; + public boolean mVisible = false; + + public SurfaceControlWithBackground(String name, boolean opaque, SurfaceControl.Builder b) + throws Exception { + mForegroundControl = b.setName(name).build(); + mBackgroundControl = b.setName("Background for -" + name) + // Unset the buffer size of the background color layer. + .setBufferSize(0, 0) + .setColorLayer() + .build(); + + mOpaque = opaque; + } + + public void setAlpha(float alpha) { + mForegroundControl.setAlpha(alpha); + mBackgroundControl.setAlpha(alpha); + } + + public void setLayer(int zorder) { + mForegroundControl.setLayer(zorder); + // -3 is below all other child layers as SurfaceView never goes below -2 + mBackgroundControl.setLayer(-3); + } + + public void setPosition(float x, float y) { + mForegroundControl.setPosition(x, y); + mBackgroundControl.setPosition(x, y); + } + + public void setBufferSize(int w, int h) { + mForegroundControl.setBufferSize(w, h); + // The background surface is a color layer so we do not set a size. + } + + public void setWindowCrop(Rect crop) { + mForegroundControl.setWindowCrop(crop); + mBackgroundControl.setWindowCrop(crop); + } + + public void setWindowCrop(int width, int height) { + mForegroundControl.setWindowCrop(width, height); + mBackgroundControl.setWindowCrop(width, height); + } + + public void setLayerStack(int layerStack) { + mForegroundControl.setLayerStack(layerStack); + mBackgroundControl.setLayerStack(layerStack); + } + + public void setOpaque(boolean isOpaque) { + mForegroundControl.setOpaque(isOpaque); + mOpaque = isOpaque; + updateBackgroundVisibility(); + } + + public void setSecure(boolean isSecure) { + mForegroundControl.setSecure(isSecure); + } + + public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { + mForegroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy); + mBackgroundControl.setMatrix(dsdx, dtdx, dsdy, dtdy); + } + + public void hide() { + mForegroundControl.hide(); + mVisible = false; + updateBackgroundVisibility(); + } + + public void show() { + mForegroundControl.show(); + mVisible = true; + updateBackgroundVisibility(); + } + + public void remove() { + mForegroundControl.remove(); + mBackgroundControl.remove(); + } + + public void release() { + mForegroundControl.release(); + mBackgroundControl.release(); + } + + public void setTransparentRegionHint(Region region) { + mForegroundControl.setTransparentRegionHint(region); + mBackgroundControl.setTransparentRegionHint(region); + } + + public void deferTransactionUntil(IBinder handle, long frame) { + mForegroundControl.deferTransactionUntil(handle, frame); + mBackgroundControl.deferTransactionUntil(handle, frame); + } + + public void deferTransactionUntil(Surface barrier, long frame) { + mForegroundControl.deferTransactionUntil(barrier, frame); + mBackgroundControl.deferTransactionUntil(barrier, frame); + } + + /** Set the color to fill the background with. */ + private void setBackgroundColor(int bgColor) { + final float[] colorComponents = new float[] { Color.red(bgColor) / 255.f, + Color.green(bgColor) / 255.f, Color.blue(bgColor) / 255.f }; + + SurfaceControl.openTransaction(); + try { + mBackgroundControl.setColor(colorComponents); + } finally { + SurfaceControl.closeTransaction(); + } + } + + void updateBackgroundVisibility() { + if (mOpaque && mVisible) { + mBackgroundControl.show(); + } else { + mBackgroundControl.hide(); + } + } } }