Merge "Recycle the bitmap as soon as possible" into rvc-dev am: 4c0116ee1a am: e3f11b2675
Change-Id: I4e9e9def90e7ede8dea77af60f92170c79275269
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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() + "}";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user