diff options
author | Riley Andrews <riandrews@google.com> | 2014-09-04 16:20:31 -0700 |
---|---|---|
committer | Riley Andrews <riandrews@google.com> | 2014-09-09 03:51:16 +0000 |
commit | c3ebe66b49cfba035e1fd0e160a13db38eb81b0e (patch) | |
tree | e19c408d47ebbfa8512885dd593c0f1c598c1215 | |
parent | 7eff26a02aeb35d6c48e1af8d9bebcc838ad1fd2 (diff) | |
download | frameworks_native-c3ebe66b49cfba035e1fd0e160a13db38eb81b0e.zip frameworks_native-c3ebe66b49cfba035e1fd0e160a13db38eb81b0e.tar.gz frameworks_native-c3ebe66b49cfba035e1fd0e160a13db38eb81b0e.tar.bz2 |
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
-rw-r--r-- | include/gui/ISurfaceComposer.h | 10 | ||||
-rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 8 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 3 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp | 21 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/GLES11RenderEngine.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp | 23 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/GLES20RenderEngine.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/RenderEngine/RenderEngine.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 43 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 6 |
10 files changed, 102 insertions, 21 deletions
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index 9f1937b..742fc83 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -62,6 +62,13 @@ public: eDisplayIdHdmi = 1 }; + enum Rotation { + eRotateNone = 0, + eRotate90 = 1, + eRotate180 = 2, + eRotate270 = 3 + }; + /* create connection with surface flinger, requires * ACCESS_SURFACE_FLINGER permission */ @@ -130,7 +137,8 @@ public: const sp<IGraphicBufferProducer>& producer, Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, uint32_t maxLayerZ, - bool useIdentityTransform) = 0; + bool useIdentityTransform, + Rotation rotation = eRotateNone) = 0; /* Clears the frame statistics for animations. * diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 4680168..4d65c56 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -106,7 +106,8 @@ public: 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) { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); @@ -118,6 +119,7 @@ public: data.writeInt32(minLayerZ); data.writeInt32(maxLayerZ); data.writeInt32(static_cast<int32_t>(useIdentityTransform)); + data.writeInt32(static_cast<int32_t>(rotation)); remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply); return reply.readInt32(); } @@ -329,10 +331,12 @@ status_t BnSurfaceComposer::onTransact( uint32_t minLayerZ = data.readInt32(); uint32_t maxLayerZ = data.readInt32(); bool useIdentityTransform = static_cast<bool>(data.readInt32()); + uint32_t rotation = data.readInt32(); status_t res = captureScreen(display, producer, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, - useIdentityTransform); + useIdentityTransform, + static_cast<ISurfaceComposer::Rotation>(rotation)); reply->writeInt32(res); return NO_ERROR; } diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index bf42b77..564f974 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -288,7 +288,8 @@ void DisplayDevice::setViewportAndProjection() const { size_t w = mDisplayWidth; size_t h = mDisplayHeight; Rect sourceCrop(0, 0, w, h); - mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, false); + mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, + false, Transform::ROT_0); } // ---------------------------------------------------------------------------- diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp index d1e324c..c2768f3 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp @@ -21,6 +21,7 @@ #include <utils/String8.h> #include <cutils/compiler.h> +#include <gui/ISurfaceComposer.h> #include "GLES11RenderEngine.h" #include "Mesh.h" @@ -74,7 +75,8 @@ size_t GLES11RenderEngine::getMaxViewportDims() const { } void GLES11RenderEngine::setViewportAndProjection( - size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap) { + size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap, + Transform::orientation_flags rotation) { glViewport(0, 0, vpw, vph); glMatrixMode(GL_PROJECTION); glLoadIdentity(); @@ -91,6 +93,23 @@ void GLES11RenderEngine::setViewportAndProjection( } else { glOrthof(l, r, b, t, 0, 1); } + + switch (rotation) { + case Transform::ROT_0: + break; + case Transform::ROT_90: + glRotatef(90, 0, 0, 1); + break; + case Transform::ROT_180: + glRotatef(180, 0, 0, 1); + break; + case Transform::ROT_270: + glRotatef(270, 0, 0, 1); + break; + default: + break; + } + glMatrixMode(GL_MODELVIEW); } diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h index 1a94592..87eb3e4 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h @@ -22,6 +22,7 @@ #include <sys/types.h> #include <GLES/gl.h> +#include <Transform.h> #include "RenderEngine.h" @@ -50,7 +51,7 @@ protected: virtual void dump(String8& result); virtual void setViewportAndProjection(size_t vpw, size_t vph, - Rect sourceCrop, size_t hwh, bool yswap); + Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation); virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha); virtual void setupDimLayerBlending(int alpha); virtual void setupLayerTexturing(const Texture& texture); diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 8c1f04e..8ebafbc 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -25,6 +25,8 @@ #include <utils/Trace.h> #include <cutils/compiler.h> +#include <gui/ISurfaceComposer.h> +#include <math.h> #include "GLES20RenderEngine.h" #include "Program.h" @@ -80,7 +82,8 @@ size_t GLES20RenderEngine::getMaxViewportDims() const { } void GLES20RenderEngine::setViewportAndProjection( - size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap) { + size_t vpw, size_t vph, Rect sourceCrop, size_t hwh, bool yswap, + Transform::orientation_flags rotation) { size_t l = sourceCrop.left; size_t r = sourceCrop.right; @@ -96,6 +99,24 @@ void GLES20RenderEngine::setViewportAndProjection( m = mat4::ortho(l, r, b, t, 0, 1); } + // Apply custom rotation to the projection. + float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f; + switch (rotation) { + case Transform::ROT_0: + break; + case Transform::ROT_90: + m = mat4::rotate(rot90InRadians, vec3(0,0,1)) * m; + break; + case Transform::ROT_180: + m = mat4::rotate(rot90InRadians * 2.0f, vec3(0,0,1)) * m; + break; + case Transform::ROT_270: + m = mat4::rotate(rot90InRadians * 3.0f, vec3(0,0,1)) * m; + break; + default: + break; + } + glViewport(0, 0, vpw, vph); mState.setProjectionMatrix(m); mVpWidth = vpw; diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h index b6d32fc..3d6243e 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -22,6 +22,7 @@ #include <sys/types.h> #include <GLES2/gl2.h> +#include <Transform.h> #include "RenderEngine.h" #include "ProgramCache.h" @@ -65,7 +66,7 @@ protected: virtual void dump(String8& result); virtual void setViewportAndProjection(size_t vpw, size_t vph, - Rect sourceCrop, size_t hwh, bool yswap); + Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation); virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha); virtual void setupDimLayerBlending(int alpha); virtual void setupLayerTexturing(const Texture& texture); diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index a2d8242..acbff9b 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -24,6 +24,7 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <ui/mat4.h> +#include <Transform.h> #define EGL_NO_CONFIG ((EGLConfig)0) @@ -90,7 +91,7 @@ public: // set-up virtual void checkErrors() const; virtual void setViewportAndProjection(size_t vpw, size_t vph, - Rect sourceCrop, size_t hwh, bool yswap) = 0; + Rect sourceCrop, size_t hwh, bool yswap, Transform::orientation_flags rotation) = 0; virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0; virtual void setupDimLayerBlending(int alpha) = 0; virtual void setupLayerTexturing(const Texture& texture) = 0; 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 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 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 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, } } + // 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 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 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 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 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 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 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 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display, 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 @@ void SurfaceFlinger::renderScreenImplLocked( 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 @@ void SurfaceFlinger::renderScreenImplLocked( 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 @@ status_t SurfaceFlinger::captureScreenImplLocked( 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 @@ status_t SurfaceFlinger::captureScreenImplLocked( // 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 diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index d5547b3..26f0acf 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -205,7 +205,7 @@ private: 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); virtual status_t getDisplayConfigs(const sp<IBinder>& display, Vector<DisplayInfo>* configs); virtual int getActiveConfig(const sp<IBinder>& display); @@ -313,14 +313,14 @@ private: 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); status_t captureScreenImplLocked( const sp<const DisplayDevice>& hw, 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); /* ------------------------------------------------------------------------ * EGL |