summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Romain Guy <romainguy@google.com> 2012-02-23 13:50:37 -0800
committer Romain Guy <romainguy@google.com> 2012-02-23 13:50:37 -0800
commitcfef12374c15b11b3c2a1041582be9728152e15d (patch)
tree2f3479768cc3253194aa3f045c0a2683b85a0e65
parentb442eca2b19bc392a336d6ffdcbf3bdf2449c0dd (diff)
Perform early intersect to avoid unnecessary draws
Change-Id: I48d61c4488e622f93733d8e53a50c93e6a20166d
-rw-r--r--core/java/android/view/HardwareRenderer.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java42
-rw-r--r--graphics/java/android/graphics/Rect.java43
3 files changed, 39 insertions, 48 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 7054851dedbe..ec9586308568 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -910,8 +910,6 @@ public abstract class HardwareRenderer {
if (canDraw()) {
if (!hasDirtyRegions()) {
dirty = null;
- } else if (dirty != null) {
- dirty.intersect(0, 0, mWidth, mHeight);
}
attachInfo.mIgnoreDirtyState = true;
attachInfo.mDrawingTime = SystemClock.uptimeMillis();
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 28737fcaa091..f831d85f70f2 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -771,19 +771,29 @@ public final class ViewRootImpl implements ViewParent,
return mLayoutRequested;
}
+ void invalidate() {
+ mDirty.set(0, 0, mWidth, mHeight);
+ scheduleTraversals();
+ }
+
public void invalidateChild(View child, Rect dirty) {
+ invalidateChildInParent(null, dirty);
+ }
+
+ public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
checkThread();
if (DEBUG_DRAW) Log.v(TAG, "Invalidate child: " + dirty);
+
if (dirty == null) {
- // Fast invalidation for GL-enabled applications; GL must redraw everything
invalidate();
- return;
+ return null;
}
+
if (mCurScrollY != 0 || mTranslator != null) {
mTempRect.set(dirty);
dirty = mTempRect;
if (mCurScrollY != 0) {
- dirty.offset(0, -mCurScrollY);
+ dirty.offset(0, -mCurScrollY);
}
if (mTranslator != null) {
mTranslator.translateRectInAppWindowToScreen(dirty);
@@ -792,19 +802,24 @@ public final class ViewRootImpl implements ViewParent,
dirty.inset(-1, -1);
}
}
- if (!mDirty.isEmpty() && !mDirty.contains(dirty)) {
+
+ final Rect localDirty = mDirty;
+ if (!localDirty.isEmpty() && !localDirty.contains(dirty)) {
mAttachInfo.mSetIgnoreDirtyState = true;
mAttachInfo.mIgnoreDirtyState = true;
}
- mDirty.union(dirty);
+
+ // Add the new dirty rect to the current one
+ localDirty.union(dirty.left, dirty.top, dirty.right, dirty.bottom);
+ // Intersect with the bounds of the window to skip
+ // updates that lie outside of the visible region
+ localDirty.intersect(0, 0, mWidth, mHeight);
+
if (!mWillDrawSoon) {
scheduleTraversals();
}
- }
-
- void invalidate() {
- mDirty.set(0, 0, mWidth, mHeight);
- scheduleTraversals();
+
+ return null;
}
void setStopped(boolean stopped) {
@@ -815,13 +830,8 @@ public final class ViewRootImpl implements ViewParent,
}
}
}
-
- public ViewParent getParent() {
- return null;
- }
- public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) {
- invalidateChild(null, dirty);
+ public ViewParent getParent() {
return null;
}
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 0ada1fbdcd8d..ec911b06be75 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -352,8 +352,7 @@ public final class Rect implements Parcelable {
// check for empty first
return this.left < this.right && this.top < this.bottom
// now check for containment
- && left <= r.left && top <= r.top
- && right >= r.right && bottom >= r.bottom;
+ && left <= r.left && top <= r.top && right >= r.right && bottom >= r.bottom;
}
/**
@@ -375,20 +374,11 @@ public final class Rect implements Parcelable {
* return false and do not change this rectangle.
*/
public boolean intersect(int left, int top, int right, int bottom) {
- if (this.left < right && left < this.right
- && this.top < bottom && top < this.bottom) {
- if (this.left < left) {
- this.left = left;
- }
- if (this.top < top) {
- this.top = top;
- }
- if (this.right > right) {
- this.right = right;
- }
- if (this.bottom > bottom) {
- this.bottom = bottom;
- }
+ if (this.left < right && left < this.right && this.top < bottom && top < this.bottom) {
+ if (this.left < left) this.left = left;
+ if (this.top < top) this.top = top;
+ if (this.right > right) this.right = right;
+ if (this.bottom > bottom) this.bottom = bottom;
return true;
}
return false;
@@ -422,8 +412,7 @@ public final class Rect implements Parcelable {
* false and do not change this rectangle.
*/
public boolean setIntersect(Rect a, Rect b) {
- if (a.left < b.right && b.left < a.right
- && a.top < b.bottom && b.top < a.bottom) {
+ if (a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom) {
left = Math.max(a.left, b.left);
top = Math.max(a.top, b.top);
right = Math.min(a.right, b.right);
@@ -448,8 +437,7 @@ public final class Rect implements Parcelable {
* no event is this rectangle modified.
*/
public boolean intersects(int left, int top, int right, int bottom) {
- return this.left < right && left < this.right
- && this.top < bottom && top < this.bottom;
+ return this.left < right && left < this.right && this.top < bottom && top < this.bottom;
}
/**
@@ -463,8 +451,7 @@ public final class Rect implements Parcelable {
* either of the rectangles modified.
*/
public static boolean intersects(Rect a, Rect b) {
- return a.left < b.right && b.left < a.right
- && a.top < b.bottom && b.top < a.bottom;
+ return a.left < b.right && b.left < a.right && a.top < b.bottom && b.top < a.bottom;
}
/**
@@ -480,14 +467,10 @@ public final class Rect implements Parcelable {
public void union(int left, int top, int right, int bottom) {
if ((left < right) && (top < bottom)) {
if ((this.left < this.right) && (this.top < this.bottom)) {
- if (this.left > left)
- this.left = left;
- if (this.top > top)
- this.top = top;
- if (this.right < right)
- this.right = right;
- if (this.bottom < bottom)
- this.bottom = bottom;
+ if (this.left > left) this.left = left;
+ if (this.top > top) this.top = top;
+ if (this.right < right) this.right = right;
+ if (this.bottom < bottom) this.bottom = bottom;
} else {
this.left = left;
this.top = top;