From f00d02b254d94eeaf52742e0640e9eacd63fafca Mon Sep 17 00:00:00 2001 From: Hyunyoung Song Date: Fri, 5 Jun 2015 13:30:19 -0700 Subject: [PATCH] Improve AyncTask throughput inside WidgetPreviewLoader b/21133230 > Synchronized block was creating a bottleneck for the AsyncTasks. > Remove calls that doesn't need to be synchronized outside synchronized block. > Also removed setAlpha call as after the bottleneck was removed, Inefficient alpha view usage alert started popping up in traceview. Due to less jankness, removing the fadein animation doesn't have any visible effect. Link to lock congestion visualization: https://x20web.corp.google.com/~hyunyoungs/no_crawl/traceview/traceview_lockcontention.html Result: gfx-avg-jank delta = "-1" Change-Id: If12817df0730f346cdba7e2f38f232eb9a4336c0 --- .../launcher3/WidgetPreviewLoader.java | 20 +++++++++---------- .../android/launcher3/widget/WidgetCell.java | 4 +++- .../launcher3/widget/WidgetImageView.java | 8 ++++++++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java index a621771423..cfeced2df5 100644 --- a/src/com/android/launcher3/WidgetPreviewLoader.java +++ b/src/com/android/launcher3/WidgetPreviewLoader.java @@ -586,26 +586,26 @@ public class WidgetPreviewLoader { protected Bitmap doInBackground(Void... params) { Bitmap unusedBitmap = null; + // If already cancelled before this gets to run in the background, then return early + if (isCancelled()) { + return null; + } synchronized (mUnusedBitmaps) { - // If already cancelled before this gets to run in the background, then return early - if (isCancelled()) { - return null; - } - // Check if we can use a bitmap + // Check if we can re-use a bitmap for (Bitmap candidate : mUnusedBitmaps) { if (candidate != null && candidate.isMutable() && candidate.getWidth() == mPreviewWidth && candidate.getHeight() == mPreviewHeight) { unusedBitmap = candidate; + mUnusedBitmaps.remove(unusedBitmap); break; } } + } - if (unusedBitmap == null) { - unusedBitmap = Bitmap.createBitmap(mPreviewWidth, mPreviewHeight, Config.ARGB_8888); - } else { - mUnusedBitmaps.remove(unusedBitmap); - } + // creating a bitmap is expensive. Do not do this inside synchronized block. + if (unusedBitmap == null) { + unusedBitmap = Bitmap.createBitmap(mPreviewWidth, mPreviewHeight, Config.ARGB_8888); } // If cancelled now, don't bother reading the preview from the DB if (isCancelled()) { diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index 2714f51820..7496ea2eff 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -26,6 +26,7 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnLayoutChangeListener; +import android.view.ViewPropertyAnimator; import android.widget.LinearLayout; import android.widget.TextView; @@ -175,7 +176,8 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { if (bitmap != null) { mWidgetImage.setBitmap(bitmap); mWidgetImage.setAlpha(0f); - mWidgetImage.animate().alpha(1.0f).setDuration(FADE_IN_DURATION_MS); + ViewPropertyAnimator anim = mWidgetImage.animate(); + anim.alpha(1.0f).setDuration(FADE_IN_DURATION_MS); } } diff --git a/src/com/android/launcher3/widget/WidgetImageView.java b/src/com/android/launcher3/widget/WidgetImageView.java index 6f8fd897b3..b0fbe1ed9f 100644 --- a/src/com/android/launcher3/widget/WidgetImageView.java +++ b/src/com/android/launcher3/widget/WidgetImageView.java @@ -64,6 +64,14 @@ public class WidgetImageView extends View { } } + /** + * Prevents the inefficient alpha view rendering. + */ + @Override + public boolean hasOverlappingRendering() { + return false; + } + private void updateDstRectF() { if (mBitmap.getWidth() > getWidth()) { float scale = ((float) getWidth()) / mBitmap.getWidth();