OSDN Git Service

Expand invalidation rectangle when clipChildren == false
authorChet Haase <chet@google.com>
Mon, 22 Apr 2013 18:11:39 +0000 (11:11 -0700)
committerChet Haase <chet@google.com>
Mon, 22 Apr 2013 18:11:39 +0000 (11:11 -0700)
The current invalidation logic does not take into account the clipChildren
flag. When this flag is set to false on a container (an uncommon but
possible case), it is possible for views in the child hierarchy of
the container to be draw outside of the container's bounds. But invalidations
on that view hiearrchy can be clipped to the container's bounds, causing us to
not redraw views outside of those bounds.

Fix is to expand the dirty rect of an invalidation to encompass the complete
bounds of any container with clipChildren==false.

Issue #680037 Some transform combinations can leave old pixel values on the screen

Change-Id: I426beee15d04145fac2f6b4203748ae309e392b4

core/java/android/view/ViewGroup.java

index 39bff68..c7ce999 100644 (file)
@@ -4279,6 +4279,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                         FLAG_OPTIMIZE_INVALIDATE) {
                 dirty.offset(location[CHILD_LEFT_INDEX] - mScrollX,
                         location[CHILD_TOP_INDEX] - mScrollY);
+                if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) {
+                    dirty.union(0, 0, mRight - mLeft, mBottom - mTop);
+                }
 
                 final int left = mLeft;
                 final int top = mTop;
@@ -4378,6 +4381,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
         if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN ||
                 (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) {
             dirty.offset(left - mScrollX, top - mScrollY);
+            if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0) {
+                dirty.union(0, 0, mRight - mLeft, mBottom - mTop);
+            }
 
             if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0 ||
                     dirty.intersect(0, 0, mRight - mLeft, mBottom - mTop)) {