Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80181b99 authored by John Reck's avatar John Reck
Browse files

Don't recreate the surface unnecessarily

Bug: 19896200

The flicker is caused because ViewRootImpl is
requesting a change from OPAQUE to TRANSLUCENT due
to the presence of a GLSurfaceView. However, WindowManager
will use this as a signal to recreate the SurfaceControl.

This is not actually correct, as the underlying format
of the SurfaceControl was *already* TRANSLUCENT due to being
hardware accelerated. Add a fast-path for this step
where the format didn't actually change such that all that is
necessary is for the OPAQUE flag to be flushed through
to SurfaceFlinger.

This doesn't address the larger, more complex issue of a surface
flickering if the pixel format really did need to change, but
this should address the common case.

Change-Id: Ia5275705733123a3d7929bf5951829415753e2b2
parent 95ba62f8
Loading
Loading
Loading
Loading
+7 −4
Original line number Original line Diff line number Diff line
@@ -3209,11 +3209,14 @@ public class WindowManagerService extends IWindowManager.Stub
                    }
                    }
                }
                }
                if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
                if ((attrChanges&WindowManager.LayoutParams.FORMAT_CHANGED) != 0) {
                    // To change the format, we need to re-build the surface.
                    // If the format can be changed in place yaay!
                    // If not, fall back to a surface re-build
                    if (!winAnimator.tryChangeFormatInPlaceLocked()) {
                        winAnimator.destroySurfaceLocked();
                        winAnimator.destroySurfaceLocked();
                        toBeDisplayed = true;
                        toBeDisplayed = true;
                        surfaceChanged = true;
                        surfaceChanged = true;
                    }
                    }
                }
                try {
                try {
                    if (!win.mHasSurface) {
                    if (!win.mHasSurface) {
                        surfaceChanged = true;
                        surfaceChanged = true;
+26 −0
Original line number Original line Diff line number Diff line
@@ -146,6 +146,9 @@ class WindowStateAnimator {


    boolean mKeyguardGoingAwayAnimation;
    boolean mKeyguardGoingAwayAnimation;


    /** The pixel format of the underlying SurfaceControl */
    int mSurfaceFormat;

    /** This is set when there is no Surface */
    /** This is set when there is no Surface */
    static final int NO_SURFACE = 0;
    static final int NO_SURFACE = 0;
    /** This is set after the Surface has been created but before the window has been drawn. During
    /** This is set after the Surface has been created but before the window has been drawn. During
@@ -845,6 +848,7 @@ class WindowStateAnimator {
                    flags |= SurfaceControl.OPAQUE;
                    flags |= SurfaceControl.OPAQUE;
                }
                }


                mSurfaceFormat = format;
                if (DEBUG_SURFACE_TRACE) {
                if (DEBUG_SURFACE_TRACE) {
                    mSurfaceControl = new SurfaceTrace(
                    mSurfaceControl = new SurfaceTrace(
                            mSession.mSurfaceSession,
                            mSession.mSurfaceSession,
@@ -1610,6 +1614,28 @@ class WindowStateAnimator {
        }
        }
    }
    }


    /**
     * Try to change the pixel format without recreating the surface. This
     * will be common in the case of changing from PixelFormat.OPAQUE to
     * PixelFormat.TRANSLUCENT in the hardware-accelerated case as both
     * requested formats resolve to the same underlying SurfaceControl format
     * @return True if format was succesfully changed, false otherwise
     */
    boolean tryChangeFormatInPlaceLocked() {
        if (mSurfaceControl == null) {
            return false;
        }
        final LayoutParams attrs = mWin.getAttrs();
        final boolean isHwAccelerated = (attrs.flags &
                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
        final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
        if (format == mSurfaceFormat) {
            setOpaqueLocked(!PixelFormat.formatHasAlpha(attrs.format));
            return true;
        }
        return false;
    }

    void setOpaqueLocked(boolean isOpaque) {
    void setOpaqueLocked(boolean isOpaque) {
        if (mSurfaceControl == null) {
        if (mSurfaceControl == null) {
            return;
            return;