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:
Riley Andrews
2014-09-09 20:05:04 +00:00
committed by Android Git Automerger
3 changed files with 32 additions and 38 deletions

View File

@@ -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,

View File

@@ -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 },

View File

@@ -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;
}
/**