Fix resizing when hardware renderer is off.
Dirty rect offsets and canvas offsets were incorrectly set.
Cherry picked from: b02004c5e4ecfc9b1df49200ebcaa24883c35b0e
and 223fee602408fdd62ac23f7d59406ffe7719e6be.
Test: Resize a test app with HW acceleration disabled. Confirm no
regressions with HW enabled - eg. Gmail.
Bug: 63601140, 64402035
Change-Id: I3e1cea4dc354457b794d3cc50456a27073cb96a0
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 1c9d863..b0f489f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -142,10 +142,11 @@
private static final boolean DEBUG_KEEP_SCREEN_ON = false || LOCAL_LOGV;
/**
- * Set to false if we do not want to use the multi threaded renderer. Note that by disabling
+ * Set to false if we do not want to use the multi threaded renderer even though
+ * threaded renderer (aka hardware renderering) is used. Note that by disabling
* this, WindowCallbacks will not fire.
*/
- private static final boolean USE_MT_RENDERER = true;
+ private static final boolean MT_RENDERER_AVAILABLE = true;
/**
* Set this system property to true to force the view hierarchy to render
@@ -302,6 +303,7 @@
Rect mDirty;
public boolean mIsAnimating;
+ private boolean mUseMTRenderer;
private boolean mDragResizing;
private boolean mInvalidateRootRequested;
private int mResizeMode;
@@ -545,18 +547,14 @@
}
public void addWindowCallbacks(WindowCallbacks callback) {
- if (USE_MT_RENDERER) {
- synchronized (mWindowCallbacks) {
- mWindowCallbacks.add(callback);
- }
+ synchronized (mWindowCallbacks) {
+ mWindowCallbacks.add(callback);
}
}
public void removeWindowCallbacks(WindowCallbacks callback) {
- if (USE_MT_RENDERER) {
- synchronized (mWindowCallbacks) {
- mWindowCallbacks.remove(callback);
- }
+ synchronized (mWindowCallbacks) {
+ mWindowCallbacks.remove(callback);
}
}
@@ -682,7 +680,17 @@
// If the application owns the surface, don't enable hardware acceleration
if (mSurfaceHolder == null) {
+ // While this is supposed to enable only, it can effectively disable
+ // the acceleration too.
enableHardwareAcceleration(attrs);
+ final boolean useMTRenderer = MT_RENDERER_AVAILABLE
+ && mAttachInfo.mThreadedRenderer != null;
+ if (mUseMTRenderer != useMTRenderer) {
+ // Shouldn't be resizing, as it's done only in window setup,
+ // but end just in case.
+ endDragResizing();
+ mUseMTRenderer = useMTRenderer;
+ }
}
boolean restore = false;
@@ -2064,7 +2072,7 @@
endDragResizing();
}
}
- if (!USE_MT_RENDERER) {
+ if (!mUseMTRenderer) {
if (dragResizing) {
mCanvasOffsetX = mWinFrame.left;
mCanvasOffsetY = mWinFrame.top;
@@ -2702,8 +2710,10 @@
@Override
public void onPostDraw(DisplayListCanvas canvas) {
drawAccessibilityFocusedDrawableIfNeeded(canvas);
- for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
- mWindowCallbacks.get(i).onPostDraw(canvas);
+ if (mUseMTRenderer) {
+ for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+ mWindowCallbacks.get(i).onPostDraw(canvas);
+ }
}
}
@@ -3034,7 +3044,8 @@
return;
}
- if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty)) {
+ if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset,
+ scalingRequired, dirty, surfaceInsets)) {
return;
}
}
@@ -3050,11 +3061,22 @@
* @return true if drawing was successful, false if an error occurred
*/
private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
- boolean scalingRequired, Rect dirty) {
+ boolean scalingRequired, Rect dirty, Rect surfaceInsets) {
// Draw with software renderer.
final Canvas canvas;
+
+ // We already have the offset of surfaceInsets in xoff, yoff and dirty region,
+ // therefore we need to add it back when moving the dirty region.
+ int dirtyXOffset = xoff;
+ int dirtyYOffset = yoff;
+ if (surfaceInsets != null) {
+ dirtyXOffset += surfaceInsets.left;
+ dirtyYOffset += surfaceInsets.top;
+ }
+
try {
+ dirty.offset(-dirtyXOffset, -dirtyYOffset);
final int left = dirty.left;
final int top = dirty.top;
final int right = dirty.right;
@@ -3081,6 +3103,8 @@
// kill stuff (or ourself) for no reason.
mLayoutRequested = true; // ask wm for a new surface next time.
return false;
+ } finally {
+ dirty.offset(dirtyXOffset, dirtyYOffset); // Reset to the original value.
}
try {
@@ -6550,7 +6574,7 @@
// Tell all listeners that we are resizing the window so that the chrome can get
// updated as fast as possible on a separate thread,
- if (mDragResizing) {
+ if (mDragResizing && mUseMTRenderer) {
boolean fullscreen = frame.equals(backDropFrame);
synchronized (mWindowCallbacks) {
for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
@@ -7798,9 +7822,11 @@
Rect stableInsets, int resizeMode) {
if (!mDragResizing) {
mDragResizing = true;
- for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
- mWindowCallbacks.get(i).onWindowDragResizeStart(initialBounds, fullscreen,
- systemInsets, stableInsets, resizeMode);
+ if (mUseMTRenderer) {
+ for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+ mWindowCallbacks.get(i).onWindowDragResizeStart(
+ initialBounds, fullscreen, systemInsets, stableInsets, resizeMode);
+ }
}
mFullRedrawNeeded = true;
}
@@ -7812,8 +7838,10 @@
private void endDragResizing() {
if (mDragResizing) {
mDragResizing = false;
- for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
- mWindowCallbacks.get(i).onWindowDragResizeEnd();
+ if (mUseMTRenderer) {
+ for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+ mWindowCallbacks.get(i).onWindowDragResizeEnd();
+ }
}
mFullRedrawNeeded = true;
}
@@ -7821,19 +7849,21 @@
private boolean updateContentDrawBounds() {
boolean updated = false;
- for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
- updated |= mWindowCallbacks.get(i).onContentDrawn(
- mWindowAttributes.surfaceInsets.left,
- mWindowAttributes.surfaceInsets.top,
- mWidth, mHeight);
+ if (mUseMTRenderer) {
+ for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
+ updated |=
+ mWindowCallbacks.get(i).onContentDrawn(mWindowAttributes.surfaceInsets.left,
+ mWindowAttributes.surfaceInsets.top, mWidth, mHeight);
+ }
}
return updated | (mDragResizing && mReportNextDraw);
}
private void requestDrawWindow() {
- if (mReportNextDraw) {
- mWindowDrawCountDown = new CountDownLatch(mWindowCallbacks.size());
+ if (!mUseMTRenderer) {
+ return;
}
+ mWindowDrawCountDown = new CountDownLatch(mWindowCallbacks.size());
for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
mWindowCallbacks.get(i).onRequestDraw(mReportNextDraw);
}