Add rotation to surfaceflingers screen cap.
+ This is needed so that activity manager does not
have to do cpu side rotations when capturing recents
thumbnails.
Change-Id: If998008e675ad01305db8399fd643cf4608b7025
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4070f03..043b075 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2938,7 +2938,7 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform) {
+ bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
if (CC_UNLIKELY(display == 0))
return BAD_VALUE;
@@ -2958,6 +2958,27 @@
}
}
+ // Convert to surfaceflinger's internal rotation type.
+ Transform::orientation_flags rotationFlags;
+ switch (rotation) {
+ case ISurfaceComposer::eRotateNone:
+ rotationFlags = Transform::ROT_0;
+ break;
+ case ISurfaceComposer::eRotate90:
+ rotationFlags = Transform::ROT_90;
+ break;
+ case ISurfaceComposer::eRotate180:
+ rotationFlags = Transform::ROT_180;
+ break;
+ case ISurfaceComposer::eRotate270:
+ rotationFlags = Transform::ROT_270;
+ break;
+ default:
+ rotationFlags = Transform::ROT_0;
+ ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
+ break;
+ }
+
class MessageCaptureScreen : public MessageBase {
SurfaceFlinger* flinger;
sp<IBinder> display;
@@ -2966,6 +2987,7 @@
uint32_t reqWidth, reqHeight;
uint32_t minLayerZ,maxLayerZ;
bool useIdentityTransform;
+ Transform::orientation_flags rotation;
status_t result;
public:
MessageCaptureScreen(SurfaceFlinger* flinger,
@@ -2973,11 +2995,12 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform)
+ bool useIdentityTransform, Transform::orientation_flags rotation)
: flinger(flinger), display(display), producer(producer),
sourceCrop(sourceCrop), reqWidth(reqWidth), reqHeight(reqHeight),
minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
useIdentityTransform(useIdentityTransform),
+ rotation(rotation),
result(PERMISSION_DENIED)
{
}
@@ -2989,7 +3012,7 @@
sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
result = flinger->captureScreenImplLocked(hw, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform);
+ useIdentityTransform, rotation);
static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
return true;
}
@@ -3012,7 +3035,7 @@
sp<MessageBase> msg = new MessageCaptureScreen(this,
display, IGraphicBufferProducer::asInterface( wrapper ),
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
- useIdentityTransform);
+ useIdentityTransform, rotationFlags);
status_t res = postMessageAsync(msg);
if (res == NO_ERROR) {
@@ -3026,7 +3049,7 @@
const sp<const DisplayDevice>& hw,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool yswap, bool useIdentityTransform)
+ bool yswap, bool useIdentityTransform, Transform::orientation_flags rotation)
{
ATRACE_CALL();
RenderEngine& engine(getRenderEngine());
@@ -3061,7 +3084,8 @@
engine.checkErrors();
// set-up our viewport
- engine.setViewportAndProjection(reqWidth, reqHeight, sourceCrop, hw_h, yswap);
+ engine.setViewportAndProjection(
+ reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
engine.disableTexturing();
// redraw the screen entirely...
@@ -3094,7 +3118,7 @@
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
- bool useIdentityTransform)
+ bool useIdentityTransform, Transform::orientation_flags rotation)
{
ATRACE_CALL();
@@ -3148,8 +3172,9 @@
// via an FBO, which means we didn't have to create
// an EGLSurface and therefore we're not
// dependent on the context's EGLConfig.
- renderScreenImplLocked(hw, sourceCrop, reqWidth, reqHeight,
- minLayerZ, maxLayerZ, true, useIdentityTransform);
+ renderScreenImplLocked(
+ hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
+ useIdentityTransform, rotation);
// Attempt to create a sync khr object that can produce a sync point. If that
// isn't available, create a non-dupable sync object in the fallback path and