Take app screenshots in 565.
- Or to be specific, SurfaceFlinger can’t easily take 565 screenshots,
so convert them when creating the ashmem bitmap.
Bug: 28151300
Change-Id: Ic7586659a41cc19c322136f77a1c52ef68c22707
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 22a81d4..d681246 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -752,17 +752,32 @@
getPremulBitmapCreateFlags(isMutable));
}
-static jobject Bitmap_copyAshmem(JNIEnv* env, jobject, jlong srcHandle) {
- SkBitmap src;
- reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src);
+static Bitmap* Bitmap_copyAshmemImpl(JNIEnv* env, SkBitmap& src, SkColorType& dstCT) {
SkBitmap result;
AshmemPixelAllocator allocator(env);
- if (!src.copyTo(&result, &allocator)) {
+ if (!src.copyTo(&result, dstCT, &allocator)) {
return NULL;
}
Bitmap* bitmap = allocator.getStorageObjAndReset();
bitmap->peekAtPixelRef()->setImmutable();
+ return bitmap;
+}
+
+static jobject Bitmap_copyAshmem(JNIEnv* env, jobject, jlong srcHandle) {
+ SkBitmap src;
+ reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src);
+ SkColorType dstCT = src.colorType();
+ Bitmap* bitmap = Bitmap_copyAshmemImpl(env, src, dstCT);
+ jobject ret = GraphicsJNI::createBitmap(env, bitmap, getPremulBitmapCreateFlags(false));
+ return ret;
+}
+
+static jobject Bitmap_copyAshmemConfig(JNIEnv* env, jobject, jlong srcHandle, jint dstConfigHandle) {
+ SkBitmap src;
+ reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src);
+ SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle);
+ Bitmap* bitmap = Bitmap_copyAshmemImpl(env, src, dstCT);
jobject ret = GraphicsJNI::createBitmap(env, bitmap, getPremulBitmapCreateFlags(false));
return ret;
}
@@ -1355,6 +1370,8 @@
(void*)Bitmap_copy },
{ "nativeCopyAshmem", "(J)Landroid/graphics/Bitmap;",
(void*)Bitmap_copyAshmem },
+ { "nativeCopyAshmemConfig", "(JI)Landroid/graphics/Bitmap;",
+ (void*)Bitmap_copyAshmemConfig },
{ "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer },
{ "nativeRecycle", "(J)Z", (void*)Bitmap_recycle },
{ "nativeReconfigure", "(JIIIIZ)V", (void*)Bitmap_reconfigure },
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 169ef0b..ac2a88a1 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -25,14 +25,14 @@
import android.util.DisplayMetrics;
import android.util.Log;
+import libcore.util.NativeAllocationRegistry;
+
import java.io.OutputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
-import libcore.util.NativeAllocationRegistry;
-
public final class Bitmap implements Parcelable {
private static final String TAG = "Bitmap";
@@ -614,6 +614,22 @@
}
/**
+ * Creates a new immutable bitmap backed by ashmem which can efficiently
+ * be passed between processes.
+ *
+ * @hide
+ */
+ public Bitmap createAshmemBitmap(Config config) {
+ checkRecycled("Can't copy a recycled bitmap");
+ Bitmap b = nativeCopyAshmemConfig(mNativePtr, config.nativeInt);
+ if (b != null) {
+ b.setPremultiplied(mRequestPremultiplied);
+ b.mDensity = mDensity;
+ }
+ return b;
+ }
+
+ /**
* Creates a new bitmap, scaled from an existing bitmap, when possible. If the
* specified width and height are the same as the current width and height of
* the source bitmap, the source bitmap is returned and no new bitmap is
@@ -1675,6 +1691,7 @@
private static native Bitmap nativeCopy(long nativeSrcBitmap, int nativeConfig,
boolean isMutable);
private static native Bitmap nativeCopyAshmem(long nativeSrcBitmap);
+ private static native Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig);
private static native long nativeGetNativeFinalizer();
private static native boolean nativeRecycle(long nativeBitmap);
private static native void nativeReconfigure(long nativeBitmap, int width, int height,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 2d5addb..63bcc2d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -99,6 +99,7 @@
static {
sBitmapOptions = new BitmapFactory.Options();
sBitmapOptions.inMutable = true;
+ sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
}
final static List<String> sRecentsBlacklist;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0a0f0f0..ee94291f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5993,7 +5993,7 @@
@Override
public void run() {
Bitmap bm = screenshotApplicationsInner(null, Display.DEFAULT_DISPLAY, -1, -1,
- true, 1f);
+ true, 1f, Bitmap.Config.ARGB_8888);
try {
receiver.send(bm);
} catch (RemoteException e) {
@@ -6006,8 +6006,7 @@
/**
* Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
- * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
- * of the target image.
+ * In portrait mode, it grabs the full screenshot.
*
* @param displayId the Display to take a screenshot of.
* @param width the width of the target bitmap
@@ -6024,14 +6023,14 @@
try {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "screenshotApplications");
return screenshotApplicationsInner(appToken, displayId, width, height, false,
- frameScale);
+ frameScale, Bitmap.Config.RGB_565);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
}
Bitmap screenshotApplicationsInner(IBinder appToken, int displayId, int width, int height,
- boolean includeFullDisplay, float frameScale) {
+ boolean includeFullDisplay, float frameScale, Bitmap.Config config) {
final DisplayContent displayContent;
synchronized(mWindowMap) {
displayContent = getDisplayContentLocked(displayId);
@@ -6270,7 +6269,7 @@
// Create a copy of the screenshot that is immutable and backed in ashmem.
// This greatly reduces the overhead of passing the bitmap between processes.
- Bitmap ret = bm.createAshmemBitmap();
+ Bitmap ret = bm.createAshmemBitmap(config);
bm.recycle();
return ret;
}