diff options
author | Sunny Goyal <sunnygoyal@google.com> | 2018-04-30 09:20:58 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2018-04-30 09:23:29 -0700 |
commit | 2e4596a448fe8c8aef3b9eaaebd2d73a0880d708 (patch) | |
tree | 9d64a91b4eec44b9621083974e2a2dbd0f9e6770 /src | |
parent | c2c907edec37b3946aa0488956cfe22aafb0401a (diff) | |
download | android_packages_apps_Trebuchet-2e4596a448fe8c8aef3b9eaaebd2d73a0880d708.tar.gz android_packages_apps_Trebuchet-2e4596a448fe8c8aef3b9eaaebd2d73a0880d708.tar.bz2 android_packages_apps_Trebuchet-2e4596a448fe8c8aef3b9eaaebd2d73a0880d708.zip |
Reusing the same bitmap and pixel array for shape detection
Bug: 76162466
Change-Id: I785d9b8673b2b8b0a56a146143b375c412e9322a
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher3/IconCache.java | 2 | ||||
-rw-r--r-- | src/com/android/launcher3/graphics/IconNormalizer.java | 54 |
2 files changed, 26 insertions, 30 deletions
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java index ab730741f..168bd0839 100644 --- a/src/com/android/launcher3/IconCache.java +++ b/src/com/android/launcher3/IconCache.java @@ -780,7 +780,7 @@ public class IconCache { } private static final class IconDB extends SQLiteCacheHelper { - private final static int RELEASE_VERSION = 21; + private final static int RELEASE_VERSION = 22; private final static String TABLE_NAME = "icons"; private final static String COLUMN_ROWID = "rowid"; diff --git a/src/com/android/launcher3/graphics/IconNormalizer.java b/src/com/android/launcher3/graphics/IconNormalizer.java index 81f3f90ea..a2a08015e 100644 --- a/src/com/android/launcher3/graphics/IconNormalizer.java +++ b/src/com/android/launcher3/graphics/IconNormalizer.java @@ -24,6 +24,7 @@ import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PorterDuff; +import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; @@ -66,12 +67,10 @@ public class IconNormalizer { private final int mMaxSize; private final Bitmap mBitmap; - private final Bitmap mBitmapARGB; private final Canvas mCanvas; private final Paint mPaintMaskShape; private final Paint mPaintMaskShapeOutline; private final byte[] mPixels; - private final int[] mPixelsARGB; private final Rect mAdaptiveIconBounds; private float mAdaptiveIconScale; @@ -83,9 +82,6 @@ public class IconNormalizer { private final Path mShapePath; private final Matrix mMatrix; - private final Paint mPaintIcon; - private final Canvas mCanvasARGB; - /** package private **/ IconNormalizer(Context context) { // Use twice the icon size as maximum size to avoid scaling down twice. @@ -93,19 +89,11 @@ public class IconNormalizer { mBitmap = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ALPHA_8); mCanvas = new Canvas(mBitmap); mPixels = new byte[mMaxSize * mMaxSize]; - mPixelsARGB = new int[mMaxSize * mMaxSize]; mLeftBorder = new float[mMaxSize]; mRightBorder = new float[mMaxSize]; mBounds = new Rect(); mAdaptiveIconBounds = new Rect(); - // Needed for isShape() method - mBitmapARGB = Bitmap.createBitmap(mMaxSize, mMaxSize, Bitmap.Config.ARGB_8888); - mCanvasARGB = new Canvas(mBitmapARGB); - - mPaintIcon = new Paint(); - mPaintIcon.setColor(Color.WHITE); - mPaintMaskShape = new Paint(); mPaintMaskShape.setColor(Color.RED); mPaintMaskShape.setStyle(Paint.Style.FILL); @@ -115,7 +103,7 @@ public class IconNormalizer { mPaintMaskShapeOutline.setStrokeWidth(2 * context.getResources().getDisplayMetrics().density); mPaintMaskShapeOutline.setStyle(Paint.Style.STROKE); mPaintMaskShapeOutline.setColor(Color.BLACK); - mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); + mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); mShapePath = new Path(); mMatrix = new Matrix(); @@ -141,8 +129,6 @@ public class IconNormalizer { // Condition 2: // Actual icon (white) and the fitted shape (e.g., circle)(red) XOR operation // should generate transparent image, if the actual icon is equivalent to the shape. - mBitmapARGB.eraseColor(Color.TRANSPARENT); - mCanvasARGB.drawBitmap(mBitmap, 0, 0, mPaintIcon); // Fit the shape within the icon's bounding box mMatrix.reset(); @@ -151,31 +137,41 @@ public class IconNormalizer { maskPath.transform(mMatrix, mShapePath); // XOR operation - mCanvasARGB.drawPath(mShapePath, mPaintMaskShape); + mCanvas.drawPath(mShapePath, mPaintMaskShape); // DST_OUT operation around the mask path outline - mCanvasARGB.drawPath(mShapePath, mPaintMaskShapeOutline); + mCanvas.drawPath(mShapePath, mPaintMaskShapeOutline); // Check if the result is almost transparent - return isTransparentBitmap(mBitmapARGB); + return isTransparentBitmap(); } /** * Used to determine if certain the bitmap is transparent. */ - private boolean isTransparentBitmap(Bitmap bitmap) { - int w = mBounds.width(); - int h = mBounds.height(); - bitmap.getPixels(mPixelsARGB, 0 /* the first index to write into the array */, - w /* stride */, - mBounds.left, mBounds.top, - w, h); + private boolean isTransparentBitmap() { + ByteBuffer buffer = ByteBuffer.wrap(mPixels); + buffer.rewind(); + mBitmap.copyPixelsToBuffer(buffer); + + int y = mBounds.top; + // buffer position + int index = y * mMaxSize; + // buffer shift after every row, width of buffer = mMaxSize + int rowSizeDiff = mMaxSize - mBounds.right; + int sum = 0; - for (int i = w * h - 1; i >= 0; i--) { - if(Color.alpha(mPixelsARGB[i]) > MIN_VISIBLE_ALPHA) { + for (; y < mBounds.bottom; y++) { + index += mBounds.left; + for (int x = mBounds.left; x < mBounds.right; x++) { + if ((mPixels[index] & 0xFF) > MIN_VISIBLE_ALPHA) { sum++; + } + index++; } + index += rowSizeDiff; } + float percentageDiffPixels = ((float) sum) / (mBounds.width() * mBounds.height()); return percentageDiffPixels < PIXEL_DIFF_PERCENTAGE_THRESHOLD; } @@ -306,7 +302,7 @@ public class IconNormalizer { mBounds.bottom = bottomY; if (outBounds != null) { - outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top), + outBounds.set(((float) mBounds.left) / width, ((float) mBounds.top) / height, 1 - ((float) mBounds.right) / width, 1 - ((float) mBounds.bottom) / height); } |