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

Commit 5bcdff45 authored by Romain Guy's avatar Romain Guy
Browse files

Fixes #1846038. The dirty region can sometimes be modified by SurfaceFlinger....

Fixes #1846038. The dirty region can sometimes be modified by SurfaceFlinger. When this happens, force the view hierarchy to ignore the dirty flags.
parent 14ad07f6
Loading
Loading
Loading
Loading
+19 −6
Original line number Diff line number Diff line
@@ -1449,7 +1449,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
        @ViewDebug.FlagToString(mask = LAYOUT_REQUIRED, equals = LAYOUT_REQUIRED,
                name = "LAYOUT_REQUIRED"),
        @ViewDebug.FlagToString(mask = DRAWING_CACHE_VALID, equals = DRAWING_CACHE_VALID,
            name = "DRAWING_CACHE_VALID", outputIf = false),
            name = "DRAWING_CACHE_INVALID", outputIf = false),
        @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "DRAWN", outputIf = true),
        @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "NOT_DRAWN", outputIf = false),
        @ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
@@ -5739,13 +5739,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
            final int restoreCount = canvas.save();
            canvas.translate(-mScrollX, -mScrollY);

            mPrivateFlags = (mPrivateFlags & ~DIRTY_MASK) | DRAWN; 
            mPrivateFlags |= DRAWN;

            // Fast path for layouts with no backgrounds
            if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
                if (ViewDebug.TRACE_HIERARCHY) {
                    ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
                }
                mPrivateFlags &= ~DIRTY_MASK;
                dispatchDraw(canvas);
            } else {
                draw(canvas);
@@ -5800,6 +5801,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
        final int restoreCount = canvas.save();
        canvas.translate(-mScrollX, -mScrollY);

        // Temporarily remove the dirty mask
        int flags = mPrivateFlags;
        mPrivateFlags &= ~DIRTY_MASK;

        // Fast path for layouts with no backgrounds
        if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
            dispatchDraw(canvas);
@@ -5807,6 +5812,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
            draw(canvas);
        }

        mPrivateFlags = flags;

        canvas.restoreToCount(restoreCount);

        if (attachInfo != null) {
@@ -5927,8 +5934,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
            ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
        }

        final boolean dirtyOpaque = (mPrivateFlags & DIRTY_MASK) == DIRTY_OPAQUE;
        mPrivateFlags = (mPrivateFlags & ~DIRTY_MASK) | DRAWN;
        final int privateFlags = mPrivateFlags;
        final boolean dirtyOpaque = (privateFlags & DIRTY_MASK) == DIRTY_OPAQUE &&
                (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
        mPrivateFlags = (privateFlags & ~DIRTY_MASK) | DRAWN;

        /*
         * Draw traversal performs several drawing steps which must be executed
@@ -8158,7 +8167,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
     * window.
     */
    static class AttachInfo {

        interface Callbacks {
            void playSoundEffect(int effectId);
            boolean performHapticFeedback(int effectId, boolean always);
@@ -8287,6 +8295,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
         */
        long mDrawingTime;

        /**
         * Indicates whether or not ignoring the DIRTY_MASK flags.
         */
        boolean mIgnoreDirtyState;

        /**
         * Indicates whether the view's window is currently in touch mode.
         */
+3 −2
Original line number Diff line number Diff line
@@ -1235,10 +1235,11 @@ public class ViewDebug {
        for (int j = 0; j < count; j++) {
            final FlagToString flagMapping = mapping[j];
            final boolean ifTrue = flagMapping.outputIf();
            final boolean test = (intValue & flagMapping.mask()) == flagMapping.equals();
            final int maskResult = intValue & flagMapping.mask();
            final boolean test = maskResult == flagMapping.equals();
            if ((test && ifTrue) || (!test && !ifTrue)) {
                final String name = flagMapping.name();
                final String value = ifTrue ? "true" : "false";
                final String value = "0x" + Integer.toHexString(maskResult);
                writeEntry(out, prefix, name, "", value);
            }
        }
+3 −2
Original line number Diff line number Diff line
@@ -1403,9 +1403,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
            }
        }

        // Clear the flag as early as possible to allow draw() implementations
        // Sets the flag as early as possible to allow draw() implementations
        // to call invalidate() successfully when doing animations
        child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK) | DRAWN;
        child.mPrivateFlags |= DRAWN;

        if (!concatMatrix && canvas.quickReject(cl, ct, cr, cb, Canvas.EdgeType.BW) &&
                (child.mPrivateFlags & DRAW_ANIMATION) == 0) {
@@ -1482,6 +1482,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                if (ViewDebug.TRACE_HIERARCHY) {
                    ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
                }
                child.mPrivateFlags &= ~DIRTY_MASK;                
                child.dispatchDraw(canvas);
            } else {
                child.draw(canvas);
+32 −17
Original line number Diff line number Diff line
@@ -537,7 +537,6 @@ public final class ViewRoot extends Handler implements ViewParent,
            }
            dirty = mTempRect;
        }
        // TODO: When doing a union with mDirty != empty, we must cancel all the DIRTY_OPAQUE flags
        mDirty.union(dirty);
        if (!mWillDrawSoon) {
            scheduleTraversals();
@@ -1142,8 +1141,7 @@ public final class ViewRoot extends Handler implements ViewParent,
        }
        
        int yoff;
        final boolean scrolling = mScroller != null
                && mScroller.computeScrollOffset();
        final boolean scrolling = mScroller != null && mScroller.computeScrollOffset();
        if (scrolling) {
            yoff = mScroller.getCurrY();
        } else {
@@ -1165,6 +1163,7 @@ public final class ViewRoot extends Handler implements ViewParent,
                    mGL.glEnable(GL_SCISSOR_TEST);

                    mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
                    mAttachInfo.mIgnoreDirtyState = true;
                    mView.mPrivateFlags |= View.DRAWN;

                    float scale = mAppScale;
@@ -1182,6 +1181,8 @@ public final class ViewRoot extends Handler implements ViewParent,
                        canvas.restoreToCount(saveCount);
                    }

                    mAttachInfo.mIgnoreDirtyState = false;

                    mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
                    checkEglErrors();

@@ -1201,8 +1202,10 @@ public final class ViewRoot extends Handler implements ViewParent,
            return;
        }

        if (fullRedrawNeeded)
        if (fullRedrawNeeded) {
            mAttachInfo.mIgnoreDirtyState = true;            
            dirty.union(0, 0, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale));
        }

        if (DEBUG_ORIENTATION || DEBUG_DRAW) {
            Log.v("ViewRoot", "Draw " + mView + "/"
@@ -1214,7 +1217,18 @@ public final class ViewRoot extends Handler implements ViewParent,

        Canvas canvas;
        try {
            int left = dirty.left;
            int top = dirty.top;
            int right = dirty.right;
            int bottom = dirty.bottom;

            canvas = surface.lockCanvas(dirty);

            if (left != dirty.left || top != dirty.top || right != dirty.right ||
                    bottom != dirty.bottom) {
                mAttachInfo.mIgnoreDirtyState = true;
            }

            // TODO: Do this in native
            canvas.setDensityScale(mDensity);
        } catch (Surface.OutOfResourcesException e) {
@@ -1242,12 +1256,11 @@ public final class ViewRoot extends Handler implements ViewParent,
                // need to clear it before drawing so that the child will
                // properly re-composite its drawing on a transparent
                // background. This automatically respects the clip/dirty region
                if (!canvas.isOpaque()) {
                    canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
                } else if (yoff != 0) {
                // or
                // If we are applying an offset, we need to clear the area
                // where the offset doesn't appear to avoid having garbage
                // left in the blank areas.
                if (!canvas.isOpaque() || yoff != 0) {
                    canvas.drawColor(0, PorterDuff.Mode.CLEAR);
                }

@@ -1257,9 +1270,10 @@ public final class ViewRoot extends Handler implements ViewParent,
                mView.mPrivateFlags |= View.DRAWN;

                float scale = mAppScale;
                Context cxt = mView.getContext();
                if (DEBUG_DRAW) {
                    Log.i(TAG, "Drawing: package:" + cxt.getPackageName() + ", appScale=" + mAppScale);
                    Context cxt = mView.getContext();
                    Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
                            ", appScale=" + mAppScale);
                }
                int saveCount =  canvas.save(Canvas.MATRIX_SAVE_FLAG);
                try {
@@ -1269,13 +1283,14 @@ public final class ViewRoot extends Handler implements ViewParent,
                        canvas.scale(scale, scale);
                    }
                    mView.draw(canvas);
                } finally {
                    mAttachInfo.mIgnoreDirtyState = false;
                    canvas.restoreToCount(saveCount);
                }

                if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
                    mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
                }
                } finally {
                    canvas.restoreToCount(saveCount);
                }

                if (Config.DEBUG && ViewDebug.showFps) {
                    int now = (int)SystemClock.elapsedRealtime();