summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Stoza <stoza@google.com>2014-02-14 15:06:55 -0800
committerDan Stoza <stoza@google.com>2014-02-14 23:10:29 +0000
commit16ec12ae77fdd2b09ea0ea0885ac52f11bd32c59 (patch)
treea489ab33cd1706382c24a4f71b4ab45990793c39
parentd5c8044e7e1f1402fdd4a035690329294ab07b33 (diff)
Allow disabling layer rotation during screenshots
Add the ability to ignore layers' transformation matrices during screenshot capture, which will allow the window manager to capture unrotated images for recents during the device rotation animation. Bug: 11805195 Change-Id: I96e65506b198d34724eb3aa84815aae6f6de4935
-rw-r--r--cmds/screencap/screencap.cpp2
-rw-r--r--core/java/android/view/SurfaceControl.java36
-rw-r--r--core/jni/android_view_SurfaceControl.cpp26
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java6
4 files changed, 47 insertions, 23 deletions
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index a57de0179d51..2efe4d30cd37 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -141,7 +141,7 @@ int main(int argc, char** argv)
ScreenshotClient screenshot;
sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId);
- if (display != NULL && screenshot.update(display) == NO_ERROR) {
+ if (display != NULL && screenshot.update(display, false) == NO_ERROR) {
base = screenshot.getPixels();
w = screenshot.getWidth();
h = screenshot.getHeight();
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 97a1f2155297..5a8d2c8381c5 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -39,9 +39,11 @@ public class SurfaceControl {
private static native void nativeDestroy(long nativeObject);
private static native Bitmap nativeScreenshot(IBinder displayToken,
- int width, int height, int minLayer, int maxLayer, boolean allLayers);
+ int width, int height, int minLayer, int maxLayer, boolean allLayers,
+ boolean useIdentityTransform);
private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
- int width, int height, int minLayer, int maxLayer, boolean allLayers);
+ int width, int height, int minLayer, int maxLayer, boolean allLayers,
+ boolean useIdentityTransform);
private static native void nativeOpenTransaction();
private static native void nativeCloseTransaction();
@@ -554,10 +556,15 @@ public class SurfaceControl {
* include in the screenshot.
* @param maxLayer The highest (top-most Z order) surface layer to
* include in the screenshot.
+ * @param useIdentityTransform Replace whatever transformation (rotation,
+ * scaling, translation) the surface layers are currently using with the
+ * identity transformation while taking the screenshot.
*/
public static void screenshot(IBinder display, Surface consumer,
- int width, int height, int minLayer, int maxLayer) {
- screenshot(display, consumer, width, height, minLayer, maxLayer, false);
+ int width, int height, int minLayer, int maxLayer,
+ boolean useIdentityTransform) {
+ screenshot(display, consumer, width, height, minLayer, maxLayer, false,
+ useIdentityTransform);
}
/**
@@ -572,7 +579,7 @@ public class SurfaceControl {
*/
public static void screenshot(IBinder display, Surface consumer,
int width, int height) {
- screenshot(display, consumer, width, height, 0, 0, true);
+ screenshot(display, consumer, width, height, 0, 0, true, false);
}
/**
@@ -582,7 +589,7 @@ public class SurfaceControl {
* @param consumer The {@link Surface} to take the screenshot into.
*/
public static void screenshot(IBinder display, Surface consumer) {
- screenshot(display, consumer, 0, 0, 0, 0, true);
+ screenshot(display, consumer, 0, 0, 0, 0, true, false);
}
@@ -602,15 +609,20 @@ public class SurfaceControl {
* include in the screenshot.
* @param maxLayer The highest (top-most Z order) surface layer to
* include in the screenshot.
+ * @param useIdentityTransform Replace whatever transformation (rotation,
+ * scaling, translation) the surface layers are currently using with the
+ * identity transformation while taking the screenshot.
* @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(int width, int height, int minLayer, int maxLayer) {
+ public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer,
+ boolean useIdentityTransform) {
// TODO: should take the display as a parameter
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
- return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false);
+ return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false,
+ useIdentityTransform);
}
/**
@@ -629,17 +641,19 @@ public class SurfaceControl {
// TODO: should take the display as a parameter
IBinder displayToken = SurfaceControl.getBuiltInDisplay(
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
- return nativeScreenshot(displayToken, width, height, 0, 0, true);
+ return nativeScreenshot(displayToken, width, height, 0, 0, true, false);
}
private static void screenshot(IBinder display, Surface consumer,
- int width, int height, int minLayer, int maxLayer, boolean allLayers) {
+ int width, int height, int minLayer, int maxLayer, boolean allLayers,
+ boolean useIdentityTransform) {
if (display == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
if (consumer == null) {
throw new IllegalArgumentException("consumer must not be null");
}
- nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers);
+ nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers,
+ useIdentityTransform);
}
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 88ec0d7ece37..480d0acfb0c2 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -72,12 +72,15 @@ public:
}
status_t update(const sp<IBinder>& display, int width, int height,
- int minLayer, int maxLayer, bool allLayers) {
+ int minLayer, int maxLayer, bool allLayers,
+ bool useIdentityTransform) {
status_t res = (width > 0 && height > 0)
? (allLayers
- ? mScreenshot.update(display, width, height)
- : mScreenshot.update(display, width, height, minLayer, maxLayer))
- : mScreenshot.update(display);
+ ? mScreenshot.update(display, width, height,
+ useIdentityTransform)
+ : mScreenshot.update(display, width, height,
+ minLayer, maxLayer, useIdentityTransform))
+ : mScreenshot.update(display, useIdentityTransform);
if (res != NO_ERROR) {
return res;
}
@@ -162,7 +165,8 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
}
static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj,
- jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
+ jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
+ bool useIdentityTransform) {
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
if (displayToken == NULL) {
return NULL;
@@ -170,7 +174,7 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display
ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
if (pixels->update(displayToken, width, height,
- minLayer, maxLayer, allLayers) != NO_ERROR) {
+ minLayer, maxLayer, allLayers, useIdentityTransform) != NO_ERROR) {
delete pixels;
return NULL;
}
@@ -202,7 +206,8 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display
static void nativeScreenshot(JNIEnv* env, jclass clazz,
jobject displayTokenObj, jobject surfaceObj,
- jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
+ jint width, jint height, jint minLayer, jint maxLayer, bool allLayers,
+ bool useIdentityTransform) {
sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
if (displayToken != NULL) {
sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj);
@@ -213,7 +218,8 @@ static void nativeScreenshot(JNIEnv* env, jclass clazz,
}
ScreenshotClient::capture(
displayToken, consumer->getIGraphicBufferProducer(),
- width, height, uint32_t(minLayer), uint32_t(maxLayer));
+ width, height, uint32_t(minLayer), uint32_t(maxLayer),
+ useIdentityTransform);
}
}
}
@@ -417,9 +423,9 @@ static JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeRelease },
{"nativeDestroy", "(J)V",
(void*)nativeDestroy },
- {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;",
+ {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZZ)Landroid/graphics/Bitmap;",
(void*)nativeScreenshotBitmap },
- {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZ)V",
+ {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZZ)V",
(void*)nativeScreenshot },
{"nativeOpenTransaction", "()V",
(void*)nativeOpenTransaction },
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8f07e27ce78b..e664050e25be 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -5757,7 +5757,11 @@ public class WindowManagerService extends IWindowManager.Stub
+ " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer);
}
}
- rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer);
+ // TODO: Replace 'false' in the following line with a variable that indicates
+ // whether the screenshot should use the identity transformation matrix
+ // (e.g., enable it when taking a screenshot for recents, since we might be in
+ // the middle of the rotation animation, but don't want a rotated recent image).
+ rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer, false);
}
} while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES);
if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " +