diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 625ed380efd54..fdea1ba157f47 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1638,6 +1638,8 @@ public final class ViewRootImpl implements ViewParent, final boolean stableInsetsChanged = !mPendingStableInsets.equals( mAttachInfo.mStableInsets); final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets); + final boolean surfaceSizeChanged = (relayoutResult + & WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0; if (contentInsetsChanged) { mAttachInfo.mContentInsets.set(mPendingContentInsets); if (DEBUG_LAYOUT) Log.v(TAG, "Content insets changing to: " @@ -1723,10 +1725,20 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mHardwareRenderer.isEnabled()) { mAttachInfo.mHardwareRenderer.destroy(); } - } else if (surfaceGenerationId != mSurface.getGenerationId() && - mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) { + } else if ((surfaceGenerationId != mSurface.getGenerationId() + || surfaceSizeChanged) + && mSurfaceHolder == null + && mAttachInfo.mHardwareRenderer != null) { mFullRedrawNeeded = true; try { + // Need to do updateSurface (which leads to CanvasContext::setSurface and + // re-create the EGLSurface) if either the Surface changed (as indicated by + // generation id), or WindowManager changed the surface size. The latter is + // because on some chips, changing the consumer side's BufferQueue size may + // not take effect immediately unless we create a new EGLSurface. + // Note that frame size change doesn't always imply surface size change (eg. + // drag resizing uses fullscreen surface), need to check surfaceSizeChanged + // flag from WindowManager. mAttachInfo.mHardwareRenderer.updateSurface(mSurface); } catch (OutOfResourcesException e) { handleOutOfResourcesException(e); diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java index 43d643e51c32f..c08e1b5803c48 100644 --- a/core/java/android/view/WindowManagerGlobal.java +++ b/core/java/android/view/WindowManagerGlobal.java @@ -76,6 +76,11 @@ public final class WindowManagerGlobal { */ public static final int RELAYOUT_RES_DRAG_RESIZING = 0x8; + /** + * The window manager has changed the size of the surface from the last call. + */ + public static final int RELAYOUT_RES_SURFACE_RESIZED = 0x10; + /** * Flag for relayout: the client will be later giving * internal insets; as a result, the window will not impact other window diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index a22f8213e15d8..490f5d88011c0 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2725,6 +2725,8 @@ public class WindowManagerService extends IWindowManager.Stub WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; } + final int oldSurfaceResizeGeneration = winAnimator.mSurfaceResizeGeneration; + win.setDisplayLayoutNeeded(); win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0; configChanged = updateOrientationFromAppTokensLocked(false); @@ -2737,6 +2739,9 @@ public class WindowManagerService extends IWindowManager.Stub if (win.mAppToken != null) { win.mAppToken.updateReportedVisibilityLocked(); } + if (winAnimator.mSurfaceResizeGeneration != oldSurfaceResizeGeneration) { + result |= WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED; + } outFrame.set(win.mCompatFrame); outOverscanInsets.set(win.mOverscanInsets); outContentInsets.set(win.mContentInsets); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index decfb342acad7..4b2edf64aa518 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -99,6 +99,7 @@ class WindowStateAnimator { * we must tell them application to resize (and thus redraw itself). */ boolean mSurfaceResized; + int mSurfaceResizeGeneration; WindowSurfaceController mSurfaceController; private WindowSurfaceController mPendingDestroySurface; @@ -1183,6 +1184,7 @@ class WindowStateAnimator { recoveringMemory); if (mSurfaceResized) { + mSurfaceResizeGeneration++; mAnimator.setPendingLayoutChanges(w.getDisplayId(), WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); w.applyDimLayerIfNeeded();