From f186f30a7cbbf84e9b7ef52403d77f252b5229ed Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Sun, 11 Sep 2011 11:06:06 -0700 Subject: Fix 5266335: bad DIRTY/invalidation logic The DIRTY flag is used to track which elements of the view hierarchy need to be redrawn on the next drawing operation. This flag is set on the parent hierarchy of a view when that view is invalidated. There is an optimization for opaque views that tells the parent that it is dirty, but that it need not redraw its own content because the view will cover it (since it is opaque). This dirty-opaque logic breaks down in the current code because we only set these dirty flags on the parent hierarchy, not on the view itself. In the situation raised by this bug, we would invalidate the parent container directly (which does not case the dirty flag to be set), then we would invalidate a child of that view. Because the child is opaque, the DIRTY_OPAQUE flag would be set on the parent container. This would cause us, in the later rendering process, to skip the drawing on that parent container, assuming that it was only asked to be redrawn because of its opaque child's invalidation. The fix is to now set the DIRTY flag on an invalidated view, not just on its parent hierarchy. The DIRTY_OPAQUE logic will avoid setting the opaque flag on views/parents that are already marked DIRTY, thus an invalidated parent will be correctly drawn during the drawing process. Change-Id: Ib5e014a125a4f5168f6a5a3166e941474659aca5 --- core/java/android/view/View.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index fd60813f923e..ad9271cff241 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -8108,6 +8108,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal (mPrivateFlags & INVALIDATED) != INVALIDATED) { mPrivateFlags &= ~DRAWING_CACHE_VALID; mPrivateFlags |= INVALIDATED; + mPrivateFlags |= DIRTY; final ViewParent p = mParent; final AttachInfo ai = mAttachInfo; //noinspection PointlessBooleanExpression,ConstantConditions @@ -8154,6 +8155,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal (mPrivateFlags & INVALIDATED) != INVALIDATED) { mPrivateFlags &= ~DRAWING_CACHE_VALID; mPrivateFlags |= INVALIDATED; + mPrivateFlags |= DIRTY; final ViewParent p = mParent; final AttachInfo ai = mAttachInfo; //noinspection PointlessBooleanExpression,ConstantConditions @@ -8209,6 +8211,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal (mPrivateFlags & INVALIDATED) != INVALIDATED || isOpaque() != mLastIsOpaque) { mLastIsOpaque = isOpaque(); mPrivateFlags &= ~DRAWN; + mPrivateFlags |= DIRTY; if (invalidateCache) { mPrivateFlags |= INVALIDATED; mPrivateFlags &= ~DRAWING_CACHE_VALID; @@ -8249,6 +8252,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal ((View) mParent).mPrivateFlags |= INVALIDATED; } mPrivateFlags &= ~DRAWN; + mPrivateFlags |= DIRTY; mPrivateFlags |= INVALIDATED; mPrivateFlags &= ~DRAWING_CACHE_VALID; if (mParent != null && mAttachInfo != null) { -- cgit v1.2.3-59-g8ed1b