From 05e91ed5a7ea17f021e1811166942a7d758e1cce Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Tue, 3 Jul 2012 14:17:57 -0700 Subject: [PATCH] Force invalidates on non-visible views to traverse the hierarchy An optimization prunes invalidates on views which are not inside their parent's bounds. This works in most cases, but it is possible to run a situation where a view has been invalidated (and is thus waiting to be redrawn), but the pruning logic ensures that that draw call will not happen. Further, when/if the view comes into the bounds of its parent again, it may still not be redrawn, because now future invalidates on the view are noop'd because it is already in an invalidated state (and thus will not propagate invalidates up the hierarchy). The fix is to remove the optitmization. This will cause some overhead sending the invalidation request up to the view root, but this overhead is minimal (and only extra for cases of out-of-bounds views), and the more expensive part of rendering these views will still not be done since the view root will avoid re-drawing the hierarchy when the dirty rectangle is empty. Issue #6773607 Layered views animating from offscreen sometimes remain invisible Change-Id: Ia2c1a2b9d3e7f267253cb325ccceff1e7fdbe8bd --- core/java/android/view/ViewGroup.java | 28 +++++++++++++----------- core/java/android/view/ViewRootImpl.java | 2 ++ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 102b504ce394a..af5f474150aff 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -4036,21 +4036,23 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager final int left = mLeft; final int top = mTop; - if ((mGroupFlags & FLAG_CLIP_CHILDREN) != FLAG_CLIP_CHILDREN || - dirty.intersect(0, 0, mRight - left, mBottom - top) || - (mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) { - mPrivateFlags &= ~DRAWING_CACHE_VALID; - - location[CHILD_LEFT_INDEX] = left; - location[CHILD_TOP_INDEX] = top; - - if (mLayerType != LAYER_TYPE_NONE) { - mPrivateFlags |= INVALIDATED; - mLocalDirtyRect.union(dirty); + if ((mGroupFlags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) { + if (!dirty.intersect(0, 0, mRight - left, mBottom - top)) { + dirty.setEmpty(); } - - return mParent; } + mPrivateFlags &= ~DRAWING_CACHE_VALID; + + location[CHILD_LEFT_INDEX] = left; + location[CHILD_TOP_INDEX] = top; + + if (mLayerType != LAYER_TYPE_NONE) { + mPrivateFlags |= INVALIDATED; + mLocalDirtyRect.union(dirty); + } + + return mParent; + } else { mPrivateFlags &= ~DRAWN & ~DRAWING_CACHE_VALID; diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index e03c7d3fc59e4..9798877a815db 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -868,6 +868,8 @@ public final class ViewRootImpl implements ViewParent, if (dirty == null) { invalidate(); return null; + } else if (dirty.isEmpty()) { + return null; } if (mCurScrollY != 0 || mTranslator != null) {