am 4b7c14bf: Merge "Use surfaceflinger for recents thumbnail rotations." into lmp-dev
* commit '4b7c14bf1cb62c806223b12fdf3c5ba1d48908e7': Use surfaceflinger for recents thumbnail rotations.
This commit is contained in:
@@ -39,7 +39,7 @@ public class SurfaceControl {
|
||||
|
||||
private static native Bitmap nativeScreenshot(IBinder displayToken,
|
||||
Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
|
||||
boolean allLayers, boolean useIdentityTransform);
|
||||
boolean allLayers, boolean useIdentityTransform, int rotation);
|
||||
private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
|
||||
Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
|
||||
boolean allLayers, boolean useIdentityTransform);
|
||||
@@ -688,17 +688,23 @@ public class SurfaceControl {
|
||||
* @param useIdentityTransform Replace whatever transformation (rotation,
|
||||
* scaling, translation) the surface layers are currently using with the
|
||||
* identity transformation while taking the screenshot.
|
||||
* @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
|
||||
* Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
|
||||
* screenshots in its native portrait orientation by default, so this is
|
||||
* useful for returning screenshots that are independent of device
|
||||
* orientation.
|
||||
* @return Returns a Bitmap containing the screen contents, or null
|
||||
* if an error occurs. Make sure to call Bitmap.recycle() as soon as
|
||||
* possible, once its content is not needed anymore.
|
||||
*/
|
||||
public static Bitmap screenshot(Rect sourceCrop, int width, int height,
|
||||
int minLayer, int maxLayer, boolean useIdentityTransform) {
|
||||
int minLayer, int maxLayer, boolean useIdentityTransform,
|
||||
int rotation) {
|
||||
// TODO: should take the display as a parameter
|
||||
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
|
||||
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
|
||||
return nativeScreenshot(displayToken, sourceCrop, width, height,
|
||||
minLayer, maxLayer, false, useIdentityTransform);
|
||||
minLayer, maxLayer, false, useIdentityTransform, rotation);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -717,7 +723,8 @@ public class SurfaceControl {
|
||||
// TODO: should take the display as a parameter
|
||||
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
|
||||
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
|
||||
return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, false);
|
||||
return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
|
||||
false, Surface.ROTATION_0);
|
||||
}
|
||||
|
||||
private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
|
||||
|
||||
@@ -117,7 +117,8 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {
|
||||
|
||||
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
|
||||
jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
|
||||
jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
|
||||
jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
|
||||
int rotation) {
|
||||
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
|
||||
if (displayToken == NULL) {
|
||||
return NULL;
|
||||
@@ -131,17 +132,13 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
|
||||
|
||||
SkAutoTDelete<ScreenshotClient> screenshot(new ScreenshotClient());
|
||||
status_t res;
|
||||
if (width > 0 && height > 0) {
|
||||
if (allLayers) {
|
||||
res = screenshot->update(displayToken, sourceCrop, width, height,
|
||||
useIdentityTransform);
|
||||
} else {
|
||||
res = screenshot->update(displayToken, sourceCrop, width, height,
|
||||
minLayer, maxLayer, useIdentityTransform);
|
||||
}
|
||||
} else {
|
||||
res = screenshot->update(displayToken, sourceCrop, useIdentityTransform);
|
||||
if (allLayers) {
|
||||
minLayer = 0;
|
||||
maxLayer = -1UL;
|
||||
}
|
||||
|
||||
res = screenshot->update(displayToken, sourceCrop, width, height,
|
||||
minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation));
|
||||
if (res != NO_ERROR) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -588,7 +585,7 @@ static JNINativeMethod sSurfaceControlMethods[] = {
|
||||
(void*)nativeRelease },
|
||||
{"nativeDestroy", "(J)V",
|
||||
(void*)nativeDestroy },
|
||||
{"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZ)Landroid/graphics/Bitmap;",
|
||||
{"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;",
|
||||
(void*)nativeScreenshotBitmap },
|
||||
{"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
|
||||
(void*)nativeScreenshot },
|
||||
|
||||
@@ -5931,7 +5931,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
@Override
|
||||
public Bitmap screenshotApplications(IBinder appToken, int displayId, int width,
|
||||
int height, boolean force565) {
|
||||
if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
|
||||
if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,
|
||||
"screenshotApplications()")) {
|
||||
throw new SecurityException("Requires READ_FRAME_BUFFER permission");
|
||||
}
|
||||
@@ -5951,7 +5951,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return null;
|
||||
}
|
||||
|
||||
Bitmap rawss = null;
|
||||
Bitmap bm = null;
|
||||
|
||||
int maxLayer = 0;
|
||||
final Rect frame = new Rect();
|
||||
@@ -6092,10 +6092,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
|
||||
// The screenshot API does not apply the current screen rotation.
|
||||
rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
|
||||
|
||||
if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
|
||||
final int tmp = width;
|
||||
width = height;
|
||||
height = tmp;
|
||||
rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
|
||||
}
|
||||
|
||||
@@ -6121,9 +6119,9 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG,
|
||||
"Taking screenshot while rotating");
|
||||
|
||||
rawss = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
|
||||
inRotation);
|
||||
if (rawss == null) {
|
||||
bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
|
||||
inRotation, rot);
|
||||
if (bm == null) {
|
||||
Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
|
||||
+ ") to layer " + maxLayer);
|
||||
return null;
|
||||
@@ -6133,17 +6131,6 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
break;
|
||||
}
|
||||
|
||||
Bitmap bm = Bitmap.createBitmap(width, height, force565 ?
|
||||
Config.RGB_565 : rawss.getConfig());
|
||||
if (DEBUG_SCREENSHOT) {
|
||||
bm.eraseColor(0xFF000000);
|
||||
}
|
||||
Matrix matrix = new Matrix();
|
||||
ScreenRotationAnimation.createRotationMatrix(rot, width, height, matrix);
|
||||
Canvas canvas = new Canvas(bm);
|
||||
canvas.drawBitmap(rawss, matrix, null);
|
||||
canvas.setBitmap(null);
|
||||
|
||||
if (DEBUG_SCREENSHOT) {
|
||||
// TEST IF IT's ALL BLACK
|
||||
int[] buffer = new int[bm.getWidth() * bm.getHeight()];
|
||||
@@ -6164,9 +6151,12 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
rawss.recycle();
|
||||
|
||||
return bm;
|
||||
// Copy the screenshot bitmap to another buffer so that the gralloc backed
|
||||
// bitmap will not have a long lifetime. Gralloc memory can be pinned or
|
||||
// duplicated and might have a higher cost than a skia backed buffer.
|
||||
Bitmap ret = bm.copy(bm.getConfig(),true);
|
||||
bm.recycle();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user