From e5e59c6da424096da8f57137cdc57d8bd410b079 Mon Sep 17 00:00:00 2001 From: Alan Viverette Date: Mon, 4 Jan 2016 12:36:28 -0500 Subject: [PATCH] Avoid drawable invalidation during draw() Prevents infinite invalidation loop when reusing a drawable asset within a single draw() call. Also reduces unnecessary extra invalidations due to drawable setters (ex. setBounds()) being called during draw(). Bug: 26329675 Change-Id: I31b3c99e8efd4193415cc562a84c8939a2f56c2d (cherry picked from commit 8cda8e915916b3166e4496589b802fd1ed553c77) --- core/java/android/view/View.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index dea004e3ee349..5f8d49d91e3ca 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -3481,6 +3481,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, private int[] mDrawableState = null; + /** Whether draw() is currently being called. */ + private boolean mInDraw = false; + ViewOutlineProvider mOutlineProvider = ViewOutlineProvider.BACKGROUND; /** @@ -16151,6 +16154,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @CallSuper public void draw(Canvas canvas) { + mInDraw = true; + final int privateFlags = mPrivateFlags; final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE && (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState); @@ -16195,6 +16200,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, onDrawForeground(canvas); // we're done... + mInDraw = false; return; } @@ -16342,6 +16348,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // Step 6, draw decorations (foreground, scrollbars) onDrawForeground(canvas); + + mInDraw = false; } /** @@ -16786,7 +16794,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ @Override public void invalidateDrawable(@NonNull Drawable drawable) { - if (verifyDrawable(drawable)) { + // Don't invalidate if a drawable changes during drawing. + if (verifyDrawable(drawable) && !mInDraw) { final Rect dirty = drawable.getDirtyBounds(); final int scrollX = mScrollX; final int scrollY = mScrollY;