Skip to content

Commit f186f30

Browse files
committed
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
1 parent 4ee3666 commit f186f30

1 file changed

Lines changed: 4 additions & 0 deletions

File tree

core/java/android/view/View.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8108,6 +8108,7 @@ public void invalidate(Rect dirty) {
81088108
(mPrivateFlags & INVALIDATED) != INVALIDATED) {
81098109
mPrivateFlags &= ~DRAWING_CACHE_VALID;
81108110
mPrivateFlags |= INVALIDATED;
8111+
mPrivateFlags |= DIRTY;
81118112
final ViewParent p = mParent;
81128113
final AttachInfo ai = mAttachInfo;
81138114
//noinspection PointlessBooleanExpression,ConstantConditions
@@ -8154,6 +8155,7 @@ public void invalidate(int l, int t, int r, int b) {
81548155
(mPrivateFlags & INVALIDATED) != INVALIDATED) {
81558156
mPrivateFlags &= ~DRAWING_CACHE_VALID;
81568157
mPrivateFlags |= INVALIDATED;
8158+
mPrivateFlags |= DIRTY;
81578159
final ViewParent p = mParent;
81588160
final AttachInfo ai = mAttachInfo;
81598161
//noinspection PointlessBooleanExpression,ConstantConditions
@@ -8209,6 +8211,7 @@ void invalidate(boolean invalidateCache) {
82098211
(mPrivateFlags & INVALIDATED) != INVALIDATED || isOpaque() != mLastIsOpaque) {
82108212
mLastIsOpaque = isOpaque();
82118213
mPrivateFlags &= ~DRAWN;
8214+
mPrivateFlags |= DIRTY;
82128215
if (invalidateCache) {
82138216
mPrivateFlags |= INVALIDATED;
82148217
mPrivateFlags &= ~DRAWING_CACHE_VALID;
@@ -8249,6 +8252,7 @@ public void fastInvalidate() {
82498252
((View) mParent).mPrivateFlags |= INVALIDATED;
82508253
}
82518254
mPrivateFlags &= ~DRAWN;
8255+
mPrivateFlags |= DIRTY;
82528256
mPrivateFlags |= INVALIDATED;
82538257
mPrivateFlags &= ~DRAWING_CACHE_VALID;
82548258
if (mParent != null && mAttachInfo != null) {

0 commit comments

Comments
 (0)