Merge "Recycle the bitmap as soon as possible" into rvc-dev am: 4c0116ee1a am: e3f11b2675

Change-Id: I4e9e9def90e7ede8dea77af60f92170c79275269
This commit is contained in:
TreeHugger Robot
2020-03-31 17:37:34 +00:00
committed by Automerger Merge Worker
4 changed files with 101 additions and 44 deletions

View File

@@ -16,6 +16,8 @@
package com.android.systemui.glwallpaper; package com.android.systemui.glwallpaper;
import static com.android.systemui.glwallpaper.ImageWallpaperRenderer.WallpaperTexture;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
@@ -66,15 +68,15 @@ class ImageProcessHelper {
private float mThreshold = DEFAULT_THRESHOLD; private float mThreshold = DEFAULT_THRESHOLD;
void start(Bitmap bitmap) { void start(WallpaperTexture texture) {
new ThresholdComputeTask(mHandler).execute(bitmap); new ThresholdComputeTask(mHandler).execute(texture);
} }
float getThreshold() { float getThreshold() {
return Math.min(mThreshold, MAX_THRESHOLD); 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; private Handler mUpdateHandler;
ThresholdComputeTask(Handler handler) { ThresholdComputeTask(Handler handler) {
@@ -83,13 +85,22 @@ class ImageProcessHelper {
} }
@Override @Override
protected Float doInBackground(Bitmap... bitmaps) { protected Float doInBackground(WallpaperTexture... textures) {
Bitmap bitmap = bitmaps[0]; WallpaperTexture texture = textures[0];
if (bitmap != null) { final float[] threshold = new float[] {DEFAULT_THRESHOLD};
return new Threshold().compute(bitmap); if (texture == null) {
Log.e(TAG, "ThresholdComputeTask: WallpaperTexture not initialized");
return threshold[0];
} }
texture.use(bitmap -> {
if (bitmap != null) {
threshold[0] = new Threshold().compute(bitmap);
} else {
Log.e(TAG, "ThresholdComputeTask: Can't get bitmap"); Log.e(TAG, "ThresholdComputeTask: Can't get bitmap");
return DEFAULT_THRESHOLD; }
});
return threshold[0];
} }
@Override @Override

View File

@@ -36,6 +36,8 @@ import com.android.systemui.R;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
/** /**
* A GL renderer for image wallpaper. * A GL renderer for image wallpaper.
@@ -47,7 +49,6 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
private static final float SCALE_VIEWPORT_MAX = 1.1f; private static final float SCALE_VIEWPORT_MAX = 1.1f;
private static final boolean DEBUG = true; private static final boolean DEBUG = true;
private final WallpaperManager mWallpaperManager;
private final ImageGLProgram mProgram; private final ImageGLProgram mProgram;
private final ImageGLWallpaper mWallpaper; private final ImageGLWallpaper mWallpaper;
private final ImageProcessHelper mImageProcessHelper; private final ImageProcessHelper mImageProcessHelper;
@@ -57,18 +58,18 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
private final Rect mScissor; private final Rect mScissor;
private final Rect mSurfaceSize = new Rect(); private final Rect mSurfaceSize = new Rect();
private final Rect mViewport = new Rect(); private final Rect mViewport = new Rect();
private Bitmap mBitmap;
private boolean mScissorMode; private boolean mScissorMode;
private float mXOffset; private float mXOffset;
private float mYOffset; private float mYOffset;
private boolean mWcgContent; private final WallpaperTexture mTexture;
public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) { public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
mWallpaperManager = context.getSystemService(WallpaperManager.class); final WallpaperManager wpm = context.getSystemService(WallpaperManager.class);
if (mWallpaperManager == null) { if (wpm == null) {
Log.w(TAG, "WallpaperManager not available"); Log.w(TAG, "WallpaperManager not available");
} }
mTexture = new WallpaperTexture(wpm);
DisplayInfo displayInfo = new DisplayInfo(); DisplayInfo displayInfo = new DisplayInfo();
context.getDisplay().getDisplayInfo(displayInfo); context.getDisplay().getDisplayInfo(displayInfo);
@@ -90,15 +91,13 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
} }
protected void startProcessingImage() { protected void startProcessingImage() {
if (loadBitmap()) {
// Compute threshold of the image, this is an async work. // Compute threshold of the image, this is an async work.
mImageProcessHelper.start(mBitmap); mImageProcessHelper.start(mTexture);
}
} }
@Override @Override
public boolean isWcgContent() { public boolean isWcgContent() {
return mWcgContent; return mTexture.isWcgContent();
} }
@Override @Override
@@ -107,30 +106,12 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
mProgram.useGLProgram( mProgram.useGLProgram(
R.raw.image_wallpaper_vertex_shader, R.raw.image_wallpaper_fragment_shader); R.raw.image_wallpaper_vertex_shader, R.raw.image_wallpaper_fragment_shader);
if (!loadBitmap()) { mTexture.use(bitmap -> {
Log.w(TAG, "reload bitmap failed!"); if (bitmap == null) {
Log.w(TAG, "reload texture failed!");
} }
mWallpaper.setup(bitmap);
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());
}
}
if (DEBUG) {
Log.d(TAG, "loadBitmap done");
}
return mBitmap != null;
} }
@Override @Override
@@ -174,6 +155,8 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
@Override @Override
public Size reportSurfaceSize() { public Size reportSurfaceSize() {
mTexture.use(null);
mSurfaceSize.set(mTexture.getTextureDimensions());
return new Size(mSurfaceSize.width(), mSurfaceSize.height()); return new Size(mSurfaceSize.width(), mSurfaceSize.height());
} }
@@ -235,7 +218,69 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
out.print(prefix); out.print("mYOffset="); out.print(mYOffset); out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold()); 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("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); 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() + "}";
}
}
} }

View File

@@ -134,7 +134,7 @@ public class ImageWallpaperTest extends SysuiTestCase {
return new ImageWallpaperRenderer(mMockContext, engine) { return new ImageWallpaperRenderer(mMockContext, engine) {
@Override @Override
public void startProcessingImage() { public void startProcessingImage() {
loadBitmap(); // No - Op
} }
}; };
} }

View File

@@ -92,6 +92,7 @@ public class ImageWallpaperRendererTest extends SysuiTestCase {
mWpmSpy.setBitmap(p3Bitmap); mWpmSpy.setBitmap(p3Bitmap);
ImageWallpaperRenderer rendererP3 = new ImageWallpaperRenderer(mContext, mSurfaceProxy); ImageWallpaperRenderer rendererP3 = new ImageWallpaperRenderer(mContext, mSurfaceProxy);
rendererP3.reportSurfaceSize();
assertThat(rendererP3.isWcgContent()).isTrue(); assertThat(rendererP3.isWcgContent()).isTrue();
mWpmSpy.setBitmap(srgbBitmap); mWpmSpy.setBitmap(srgbBitmap);