Merge "Recycle the bitmap as soon as possible" into rvc-dev
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
index 54eca0e..703d591 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
@@ -16,6 +16,8 @@
package com.android.systemui.glwallpaper;
+import static com.android.systemui.glwallpaper.ImageWallpaperRenderer.WallpaperTexture;
+
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -66,15 +68,15 @@
private float mThreshold = DEFAULT_THRESHOLD;
- void start(Bitmap bitmap) {
- new ThresholdComputeTask(mHandler).execute(bitmap);
+ void start(WallpaperTexture texture) {
+ new ThresholdComputeTask(mHandler).execute(texture);
}
float getThreshold() {
return Math.min(mThreshold, MAX_THRESHOLD);
}
- private static class ThresholdComputeTask extends AsyncTask<Bitmap, Void, Float> {
+ private static class ThresholdComputeTask extends AsyncTask<WallpaperTexture, Void, Float> {
private Handler mUpdateHandler;
ThresholdComputeTask(Handler handler) {
@@ -83,13 +85,22 @@
}
@Override
- protected Float doInBackground(Bitmap... bitmaps) {
- Bitmap bitmap = bitmaps[0];
- if (bitmap != null) {
- return new Threshold().compute(bitmap);
+ protected Float doInBackground(WallpaperTexture... textures) {
+ WallpaperTexture texture = textures[0];
+ final float[] threshold = new float[] {DEFAULT_THRESHOLD};
+ if (texture == null) {
+ Log.e(TAG, "ThresholdComputeTask: WallpaperTexture not initialized");
+ return threshold[0];
}
- Log.e(TAG, "ThresholdComputeTask: Can't get bitmap");
- return DEFAULT_THRESHOLD;
+
+ texture.use(bitmap -> {
+ if (bitmap != null) {
+ threshold[0] = new Threshold().compute(bitmap);
+ } else {
+ Log.e(TAG, "ThresholdComputeTask: Can't get bitmap");
+ }
+ });
+ return threshold[0];
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index ed6675dc..e9ddb38 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -36,6 +36,8 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
/**
* A GL renderer for image wallpaper.
@@ -47,7 +49,6 @@
private static final float SCALE_VIEWPORT_MAX = 1.1f;
private static final boolean DEBUG = true;
- private final WallpaperManager mWallpaperManager;
private final ImageGLProgram mProgram;
private final ImageGLWallpaper mWallpaper;
private final ImageProcessHelper mImageProcessHelper;
@@ -57,18 +58,18 @@
private final Rect mScissor;
private final Rect mSurfaceSize = new Rect();
private final Rect mViewport = new Rect();
- private Bitmap mBitmap;
private boolean mScissorMode;
private float mXOffset;
private float mYOffset;
- private boolean mWcgContent;
+ private final WallpaperTexture mTexture;
public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
- mWallpaperManager = context.getSystemService(WallpaperManager.class);
- if (mWallpaperManager == null) {
+ final WallpaperManager wpm = context.getSystemService(WallpaperManager.class);
+ if (wpm == null) {
Log.w(TAG, "WallpaperManager not available");
}
+ mTexture = new WallpaperTexture(wpm);
DisplayInfo displayInfo = new DisplayInfo();
context.getDisplay().getDisplayInfo(displayInfo);
@@ -90,15 +91,13 @@
}
protected void startProcessingImage() {
- if (loadBitmap()) {
- // Compute threshold of the image, this is an async work.
- mImageProcessHelper.start(mBitmap);
- }
+ // Compute threshold of the image, this is an async work.
+ mImageProcessHelper.start(mTexture);
}
@Override
public boolean isWcgContent() {
- return mWcgContent;
+ return mTexture.isWcgContent();
}
@Override
@@ -107,30 +106,12 @@
mProgram.useGLProgram(
R.raw.image_wallpaper_vertex_shader, R.raw.image_wallpaper_fragment_shader);
- if (!loadBitmap()) {
- Log.w(TAG, "reload bitmap failed!");
- }
-
- mWallpaper.setup(mBitmap);
- mBitmap = null;
- }
-
- protected boolean loadBitmap() {
- if (DEBUG) {
- Log.d(TAG, "loadBitmap: mBitmap=" + mBitmap);
- }
- if (mWallpaperManager != null && mBitmap == null) {
- mBitmap = mWallpaperManager.getBitmap(false /* hardware */);
- mWcgContent = mWallpaperManager.wallpaperSupportsWcg(WallpaperManager.FLAG_SYSTEM);
- mWallpaperManager.forgetLoadedWallpaper();
- if (mBitmap != null) {
- mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+ mTexture.use(bitmap -> {
+ if (bitmap == null) {
+ Log.w(TAG, "reload texture failed!");
}
- }
- if (DEBUG) {
- Log.d(TAG, "loadBitmap done");
- }
- return mBitmap != null;
+ mWallpaper.setup(bitmap);
+ });
}
@Override
@@ -174,6 +155,8 @@
@Override
public Size reportSurfaceSize() {
+ mTexture.use(null);
+ mSurfaceSize.set(mTexture.getTextureDimensions());
return new Size(mSurfaceSize.width(), mSurfaceSize.height());
}
@@ -235,7 +218,69 @@
out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
out.print(prefix); out.print("mReveal="); out.print(mImageRevealHelper.getReveal());
- out.print(prefix); out.print("mWcgContent="); out.print(mWcgContent);
+ out.print(prefix); out.print("mWcgContent="); out.print(isWcgContent());
mWallpaper.dump(prefix, fd, out, args);
}
+
+ static class WallpaperTexture {
+ private final AtomicInteger mRefCount;
+ private final Rect mDimensions;
+ private final WallpaperManager mWallpaperManager;
+ private Bitmap mBitmap;
+ private boolean mWcgContent;
+
+ private WallpaperTexture(WallpaperManager wallpaperManager) {
+ mWallpaperManager = wallpaperManager;
+ mRefCount = new AtomicInteger();
+ mDimensions = new Rect();
+ }
+
+ public void use(Consumer<Bitmap> consumer) {
+ mRefCount.incrementAndGet();
+ synchronized (mRefCount) {
+ if (mBitmap == null) {
+ mBitmap = mWallpaperManager.getBitmap(false /* hardware */);
+ mWcgContent = mWallpaperManager.wallpaperSupportsWcg(
+ WallpaperManager.FLAG_SYSTEM);
+ mWallpaperManager.forgetLoadedWallpaper();
+ if (mBitmap != null) {
+ mDimensions.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+ } else {
+ Log.w(TAG, "Can't get bitmap");
+ }
+ }
+ }
+ if (consumer != null) {
+ consumer.accept(mBitmap);
+ }
+ synchronized (mRefCount) {
+ final int count = mRefCount.decrementAndGet();
+ if (count == 0 && mBitmap != null) {
+ if (DEBUG) {
+ Log.v(TAG, "WallpaperTexture: release 0x" + getHash()
+ + ", refCount=" + count);
+ }
+ mBitmap.recycle();
+ mBitmap = null;
+ }
+ }
+ }
+
+ private boolean isWcgContent() {
+ return mWcgContent;
+ }
+
+ private String getHash() {
+ return mBitmap != null ? Integer.toHexString(mBitmap.hashCode()) : "null";
+ }
+
+ private Rect getTextureDimensions() {
+ return mDimensions;
+ }
+
+ @Override
+ public String toString() {
+ return "{" + getHash() + ", " + mRefCount.get() + "}";
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
index 678cfd2..475023e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java
@@ -134,7 +134,7 @@
return new ImageWallpaperRenderer(mMockContext, engine) {
@Override
public void startProcessingImage() {
- loadBitmap();
+ // No - Op
}
};
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/ImageWallpaperRendererTest.java b/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/ImageWallpaperRendererTest.java
index d881fd5..d61be37 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/ImageWallpaperRendererTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/glwallpaper/ImageWallpaperRendererTest.java
@@ -92,6 +92,7 @@
mWpmSpy.setBitmap(p3Bitmap);
ImageWallpaperRenderer rendererP3 = new ImageWallpaperRenderer(mContext, mSurfaceProxy);
+ rendererP3.reportSurfaceSize();
assertThat(rendererP3.isWcgContent()).isTrue();
mWpmSpy.setBitmap(srgbBitmap);