OSDN Git Service

Allow disabling layer rotation during screenshots
authorDan Stoza <stoza@google.com>
Fri, 14 Feb 2014 23:03:43 +0000 (15:03 -0800)
committerDan Stoza <stoza@google.com>
Fri, 14 Feb 2014 23:10:42 +0000 (23:10 +0000)
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: I854d87bc84ca06ef9a054a454af1c080ee66fbb8

include/gui/ISurfaceComposer.h
include/gui/SurfaceComposerClient.h
libs/gui/ISurfaceComposer.cpp
libs/gui/SurfaceComposerClient.cpp
services/surfaceflinger/DisplayDevice.cpp
services/surfaceflinger/Layer.cpp
services/surfaceflinger/Layer.h
services/surfaceflinger/LayerDim.cpp
services/surfaceflinger/LayerDim.h
services/surfaceflinger/SurfaceFlinger.cpp
services/surfaceflinger/SurfaceFlinger.h

index 5c3c99c..35dcd4e 100644 (file)
@@ -120,7 +120,8 @@ public:
     virtual status_t captureScreen(const sp<IBinder>& display,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
+            uint32_t minLayerZ, uint32_t maxLayerZ,
+            bool useIdentityTransform) = 0;
 };
 
 // ----------------------------------------------------------------------------
index e982bcd..350b987 100644 (file)
@@ -164,7 +164,8 @@ public:
             const sp<IBinder>& display,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ);
+            uint32_t minLayerZ, uint32_t maxLayerZ,
+            bool useIdentityTransform);
 
 private:
     mutable sp<CpuConsumer> mCpuConsumer;
@@ -177,12 +178,14 @@ public:
     ~ScreenshotClient();
 
     // frees the previous screenshot and capture a new one
-    status_t update(const sp<IBinder>& display);
+    status_t update(const sp<IBinder>& display, bool useIdentityTransform);
     status_t update(const sp<IBinder>& display,
-            uint32_t reqWidth, uint32_t reqHeight);
+            uint32_t reqWidth, uint32_t reqHeight,
+            bool useIdentityTransform);
     status_t update(const sp<IBinder>& display,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ);
+            uint32_t minLayerZ, uint32_t maxLayerZ,
+            bool useIdentityTransform);
 
     sp<CpuConsumer> getCpuConsumer() const;
 
index aab0604..e96cc54 100644 (file)
@@ -105,7 +105,8 @@ public:
     virtual status_t captureScreen(const sp<IBinder>& display,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ)
+            uint32_t minLayerZ, uint32_t maxLayerZ,
+            bool useIdentityTransform)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -115,6 +116,7 @@ public:
         data.writeInt32(reqHeight);
         data.writeInt32(minLayerZ);
         data.writeInt32(maxLayerZ);
+        data.writeInt32(static_cast<int32_t>(useIdentityTransform));
         remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
         return reply.readInt32();
     }
@@ -285,8 +287,11 @@ status_t BnSurfaceComposer::onTransact(
             uint32_t reqHeight = data.readInt32();
             uint32_t minLayerZ = data.readInt32();
             uint32_t maxLayerZ = data.readInt32();
+            bool useIdentityTransform = static_cast<bool>(data.readInt32());
+
             status_t res = captureScreen(display, producer,
-                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
+                    reqWidth, reqHeight, minLayerZ, maxLayerZ,
+                    useIdentityTransform);
             reply->writeInt32(res);
             return NO_ERROR;
         }
index 2246f5f..5fe99e8 100644 (file)
@@ -628,11 +628,11 @@ status_t ScreenshotClient::capture(
         const sp<IBinder>& display,
         const sp<IGraphicBufferProducer>& producer,
         uint32_t reqWidth, uint32_t reqHeight,
-        uint32_t minLayerZ, uint32_t maxLayerZ) {
+        uint32_t minLayerZ, uint32_t maxLayerZ, bool useIdentityTransform) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == NULL) return NO_INIT;
     return s->captureScreen(display, producer,
-            reqWidth, reqHeight, minLayerZ, maxLayerZ);
+            reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
 }
 
 ScreenshotClient::ScreenshotClient()
@@ -655,7 +655,8 @@ sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const {
 
 status_t ScreenshotClient::update(const sp<IBinder>& display,
         uint32_t reqWidth, uint32_t reqHeight,
-        uint32_t minLayerZ, uint32_t maxLayerZ) {
+        uint32_t minLayerZ, uint32_t maxLayerZ,
+        bool useIdentityTransform) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == NULL) return NO_INIT;
     sp<CpuConsumer> cpuConsumer = getCpuConsumer();
@@ -667,7 +668,7 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
     }
 
     status_t err = s->captureScreen(display, mBufferQueue,
-            reqWidth, reqHeight, minLayerZ, maxLayerZ);
+            reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
 
     if (err == NO_ERROR) {
         err = mCpuConsumer->lockNextBuffer(&mBuffer);
@@ -678,13 +679,16 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
     return err;
 }
 
-status_t ScreenshotClient::update(const sp<IBinder>& display) {
-    return ScreenshotClient::update(display, 0, 0, 0, -1UL);
+status_t ScreenshotClient::update(const sp<IBinder>& display,
+        bool useIdentityTransform) {
+    return ScreenshotClient::update(display, 0, 0, 0, -1UL,
+            useIdentityTransform);
 }
 
 status_t ScreenshotClient::update(const sp<IBinder>& display,
-        uint32_t reqWidth, uint32_t reqHeight) {
-    return ScreenshotClient::update(display, reqWidth, reqHeight, 0, -1UL);
+        uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) {
+    return ScreenshotClient::update(display, reqWidth, reqHeight, 0, -1UL,
+            useIdentityTransform);
 }
 
 void ScreenshotClient::release() {
index e5ecf07..d7bbf5c 100644 (file)
@@ -194,6 +194,8 @@ void DisplayDevice::flip(const Region& dirty) const
         eglSetSwapRectangleANDROID(dpy, surface,
                 b.left, b.top, b.width(), b.height());
     }
+#else
+    (void) dirty; // Eliminate unused parameter warning
 #endif
 
     mPageFlipCount++;
index fcc9d78..465d376 100644 (file)
@@ -145,7 +145,7 @@ Layer::~Layer() {
 // callbacks
 // ---------------------------------------------------------------------------
 
-void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
+void Layer::onLayerDisplayed(const sp<const DisplayDevice>& /* hw */,
         HWComposer::HWCLayerInterface* layer) {
     if (layer) {
         layer->onDisplayed();
@@ -418,7 +418,7 @@ void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
     layer.setBuffer(mActiveBuffer);
 }
 
-void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
+void Layer::setAcquireFence(const sp<const DisplayDevice>& /* hw */,
         HWComposer::HWCLayerInterface& layer) {
     int fenceFd = -1;
 
@@ -442,14 +442,20 @@ void Layer::setAcquireFence(const sp<const DisplayDevice>& hw,
 // ---------------------------------------------------------------------------
 
 void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
-    onDraw(hw, clip);
+    onDraw(hw, clip, false);
 }
 
-void Layer::draw(const sp<const DisplayDevice>& hw) {
-    onDraw( hw, Region(hw->bounds()) );
+void Layer::draw(const sp<const DisplayDevice>& hw,
+        bool useIdentityTransform) const {
+    onDraw(hw, Region(hw->bounds()), useIdentityTransform);
 }
 
-void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
+void Layer::draw(const sp<const DisplayDevice>& hw) const {
+    onDraw(hw, Region(hw->bounds()), false);
+}
+
+void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
+        bool useIdentityTransform) const
 {
     ATRACE_CALL();
 
@@ -540,16 +546,17 @@ void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
     } else {
         engine.setupLayerBlackedOut();
     }
-    drawWithOpenGL(hw, clip);
+    drawWithOpenGL(hw, clip, useIdentityTransform);
     engine.disableTexturing();
 }
 
 
-void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
-        float red, float green, float blue, float alpha) const
+void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw,
+        const Region& /* clip */, float red, float green, float blue,
+        float alpha) const
 {
     RenderEngine& engine(mFlinger->getRenderEngine());
-    computeGeometry(hw, mMesh);
+    computeGeometry(hw, mMesh, false);
     engine.setupFillWithColor(red, green, blue, alpha);
     engine.drawMesh(mMesh);
 }
@@ -559,12 +566,12 @@ void Layer::clearWithOpenGL(
     clearWithOpenGL(hw, clip, 0,0,0,0);
 }
 
-void Layer::drawWithOpenGL(
-        const sp<const DisplayDevice>& hw, const Region& clip) const {
+void Layer::drawWithOpenGL(const sp<const DisplayDevice>& hw,
+        const Region& /* clip */, bool useIdentityTransform) const {
     const uint32_t fbHeight = hw->getHeight();
     const State& s(getDrawingState());
 
-    computeGeometry(hw, mMesh);
+    computeGeometry(hw, mMesh, useIdentityTransform);
 
     /*
      * NOTE: the way we compute the texture coordinates here produces
@@ -634,10 +641,12 @@ bool Layer::getOpacityForFormat(uint32_t format) {
 // local state
 // ----------------------------------------------------------------------------
 
-void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
+void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
+        bool useIdentityTransform) const
 {
     const Layer::State& s(getDrawingState());
-    const Transform tr(hw->getTransform() * s.transform);
+    const Transform tr(useIdentityTransform ?
+            hw->getTransform() : hw->getTransform() * s.transform);
     const uint32_t hw_h = hw->getHeight();
     Rect win(s.active.w, s.active.h);
     if (!s.active.crop.isEmpty()) {
index ea65ded..9283eaa 100644 (file)
@@ -135,7 +135,8 @@ public:
     uint32_t getTransactionFlags(uint32_t flags);
     uint32_t setTransactionFlags(uint32_t flags);
 
-    void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const;
+    void computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh,
+            bool useIdentityTransform) const;
     Rect computeBounds() const;
 
     sp<IBinder> getHandle();
@@ -182,7 +183,8 @@ protected:
     /*
      * onDraw - draws the surface.
      */
-    virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
+    virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
+            bool useIdentityTransform) const;
 
 public:
     // -----------------------------------------------------------------------
@@ -216,7 +218,8 @@ public:
      * and calls onDraw().
      */
     void draw(const sp<const DisplayDevice>& hw, const Region& clip) const;
-    void draw(const sp<const DisplayDevice>& hw);
+    void draw(const sp<const DisplayDevice>& hw, bool useIdentityTransform) const;
+    void draw(const sp<const DisplayDevice>& hw) const;
 
     /*
      * doTransaction - process the transaction. This is a good place to figure
@@ -326,7 +329,8 @@ private:
     // drawing
     void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
             float r, float g, float b, float alpha) const;
-    void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
+    void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
+            bool useIdentityTransform) const;
 
 
     // -----------------------------------------------------------------------
index 4e82bab..14aa328 100644 (file)
@@ -39,12 +39,13 @@ LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client,
 LayerDim::~LayerDim() {
 }
 
-void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
+void LayerDim::onDraw(const sp<const DisplayDevice>& hw,
+        const Region& /* clip */, bool useIdentityTransform) const
 {
     const State& s(getDrawingState());
     if (s.alpha>0) {
         Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2);
-        computeGeometry(hw, mesh);
+        computeGeometry(hw, mesh, useIdentityTransform);
         RenderEngine& engine(mFlinger->getRenderEngine());
         engine.setupDimLayerBlending(s.alpha);
         engine.drawMesh(mesh);
index 6561d7f..4de0ddc 100644 (file)
@@ -34,7 +34,8 @@ public:
         virtual ~LayerDim();
 
     virtual const char* getTypeId() const { return "LayerDim"; }
-    virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
+    virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip,
+            bool useIdentityTransform) const;
     virtual bool isOpaque() const         { return false; }
     virtual bool isSecure() const         { return false; }
     virtual bool isFixedSize() const      { return true; }
index 9f687e2..808fa1b 100644 (file)
@@ -190,7 +190,7 @@ SurfaceFlinger::~SurfaceFlinger()
     eglTerminate(display);
 }
 
-void SurfaceFlinger::binderDied(const wp<IBinder>& who)
+void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
 {
     // the window manager died on us. prepare its eulogy.
 
@@ -593,12 +593,12 @@ void SurfaceFlinger::signalRefresh() {
 }
 
 status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
-        nsecs_t reltime, uint32_t flags) {
+        nsecs_t reltime, uint32_t /* flags */) {
     return mEventQueue.postMessage(msg, reltime);
 }
 
 status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
-        nsecs_t reltime, uint32_t flags) {
+        nsecs_t reltime, uint32_t /* flags */) {
     status_t res = mEventQueue.postMessage(msg, reltime);
     if (res == NO_ERROR) {
         msg->wait();
@@ -1710,7 +1710,7 @@ status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
     return status_t(index);
 }
 
-uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) {
+uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t /* flags */) {
     return android_atomic_release_load(&mTransactionFlags);
 }
 
@@ -2220,8 +2220,8 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
     return NO_ERROR;
 }
 
-void SurfaceFlinger::listLayersLocked(const Vector<String16>& args, size_t& index,
-        String8& result) const
+void SurfaceFlinger::listLayersLocked(const Vector<String16>& /* args */,
+        size_t& /* index */, String8& result) const
 {
     const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
     const size_t count = currentLayers.size();
@@ -2259,7 +2259,7 @@ void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index
 }
 
 void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
-        String8& result)
+        String8& /* result */)
 {
     String8 name;
     if (index < args.size()) {
@@ -2664,7 +2664,7 @@ class GraphicProducerWrapper : public BBinder, public MessageHandler {
      * data and reply Parcel and forward them to the calling thread.
      */
     virtual status_t transact(uint32_t code,
-            const Parcel& data, Parcel* reply, uint32_t flags) {
+            const Parcel& data, Parcel* reply, uint32_t /* flags */) {
         this->code = code;
         this->data = &data;
         this->reply = reply;
@@ -2718,7 +2718,8 @@ public:
 status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
         const sp<IGraphicBufferProducer>& producer,
         uint32_t reqWidth, uint32_t reqHeight,
-        uint32_t minLayerZ, uint32_t maxLayerZ) {
+        uint32_t minLayerZ, uint32_t maxLayerZ,
+        bool useIdentityTransform) {
 
     if (CC_UNLIKELY(display == 0))
         return BAD_VALUE;
@@ -2744,16 +2745,19 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
         sp<IGraphicBufferProducer> producer;
         uint32_t reqWidth, reqHeight;
         uint32_t minLayerZ,maxLayerZ;
+        bool useIdentityTransform;
         status_t result;
     public:
         MessageCaptureScreen(SurfaceFlinger* flinger,
                 const sp<IBinder>& display,
                 const sp<IGraphicBufferProducer>& producer,
                 uint32_t reqWidth, uint32_t reqHeight,
-                uint32_t minLayerZ, uint32_t maxLayerZ)
+                uint32_t minLayerZ, uint32_t maxLayerZ,
+                bool useIdentityTransform)
             : flinger(flinger), display(display), producer(producer),
               reqWidth(reqWidth), reqHeight(reqHeight),
               minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
+              useIdentityTransform(useIdentityTransform),
               result(PERMISSION_DENIED)
         {
         }
@@ -2763,8 +2767,9 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
         virtual bool handler() {
             Mutex::Autolock _l(flinger->mStateLock);
             sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
-            result = flinger->captureScreenImplLocked(hw,
-                    producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
+            result = flinger->captureScreenImplLocked(hw, producer,
+                    reqWidth, reqHeight, minLayerZ, maxLayerZ,
+                    useIdentityTransform);
             static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
             return true;
         }
@@ -2786,7 +2791,7 @@ status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
     // which does the marshaling work forwards to our "fake remote" above.
     sp<MessageBase> msg = new MessageCaptureScreen(this,
             display, IGraphicBufferProducer::asInterface( wrapper ),
-            reqWidth, reqHeight, minLayerZ, maxLayerZ);
+            reqWidth, reqHeight, minLayerZ, maxLayerZ, useIdentityTransform);
 
     status_t res = postMessageAsync(msg);
     if (res == NO_ERROR) {
@@ -2800,7 +2805,7 @@ void SurfaceFlinger::renderScreenImplLocked(
         const sp<const DisplayDevice>& hw,
         uint32_t reqWidth, uint32_t reqHeight,
         uint32_t minLayerZ, uint32_t maxLayerZ,
-        bool yswap)
+        bool yswap, bool useIdentityTransform)
 {
     ATRACE_CALL();
     RenderEngine& engine(getRenderEngine());
@@ -2829,7 +2834,7 @@ void SurfaceFlinger::renderScreenImplLocked(
             if (state.z >= minLayerZ && state.z <= maxLayerZ) {
                 if (layer->isVisible()) {
                     if (filtering) layer->setFiltering(true);
-                    layer->draw(hw);
+                    layer->draw(hw, useIdentityTransform);
                     if (filtering) layer->setFiltering(false);
                 }
             }
@@ -2846,7 +2851,8 @@ status_t SurfaceFlinger::captureScreenImplLocked(
         const sp<const DisplayDevice>& hw,
         const sp<IGraphicBufferProducer>& producer,
         uint32_t reqWidth, uint32_t reqHeight,
-        uint32_t minLayerZ, uint32_t maxLayerZ)
+        uint32_t minLayerZ, uint32_t maxLayerZ,
+        bool useIdentityTransform)
 {
     ATRACE_CALL();
 
@@ -2900,7 +2906,7 @@ status_t SurfaceFlinger::captureScreenImplLocked(
                         // an EGLSurface and therefore we're not
                         // dependent on the context's EGLConfig.
                         renderScreenImplLocked(hw, reqWidth, reqHeight,
-                                minLayerZ, maxLayerZ, true);
+                                minLayerZ, maxLayerZ, true, useIdentityTransform);
 
                         // Create a sync point and wait on it, so we know the buffer is
                         // ready before we pass it along.  We can't trivially call glFlush(),
index 9db0ce1..9230467 100644 (file)
@@ -203,7 +203,8 @@ private:
     virtual status_t captureScreen(const sp<IBinder>& display,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ);
+            uint32_t minLayerZ, uint32_t maxLayerZ,
+            bool useIdentityTransform);
     // called when screen needs to turn off
     virtual void blank(const sp<IBinder>& display);
     // called when screen is turning back on
@@ -307,13 +308,14 @@ private:
             const sp<const DisplayDevice>& hw,
             uint32_t reqWidth, uint32_t reqHeight,
             uint32_t minLayerZ, uint32_t maxLayerZ,
-            bool yswap);
+            bool yswap, bool useIdentityTransform);
 
     status_t captureScreenImplLocked(
             const sp<const DisplayDevice>& hw,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ);
+            uint32_t minLayerZ, uint32_t maxLayerZ,
+            bool useIdentityTransform);
 
     /* ------------------------------------------------------------------------
      * EGL