Merge "Allow disabling layer rotation during screenshots"
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 5c3c99c..35dcd4e 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -120,7 +120,8 @@
     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;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index e982bcd..350b987 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -164,7 +164,8 @@
             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 @@
     ~ScreenshotClient();
 
     // frees the previous screenshot and capture a new one
-    status_t update(const sp<IBinder>& display);
-    status_t update(const sp<IBinder>& display,
-            uint32_t reqWidth, uint32_t reqHeight);
+    status_t update(const sp<IBinder>& display, bool useIdentityTransform);
     status_t update(const sp<IBinder>& display,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ);
+            bool useIdentityTransform);
+    status_t update(const sp<IBinder>& display,
+            uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ,
+            bool useIdentityTransform);
 
     sp<CpuConsumer> getCpuConsumer() const;
 
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index aab0604..e96cc54 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -105,7 +105,8 @@
     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 @@
         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 @@
             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;
         }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 2246f5f..5fe99e8 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -628,11 +628,11 @@
         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 @@
 
 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 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 @@
     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() {
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index e5ecf07..d7bbf5c 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -194,6 +194,8 @@
         eglSetSwapRectangleANDROID(dpy, surface,
                 b.left, b.top, b.width(), b.height());
     }
+#else
+    (void) dirty; // Eliminate unused parameter warning
 #endif
 
     mPageFlipCount++;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index fcc9d78..465d376 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -145,7 +145,7 @@
 // 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 @@
     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::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 @@
     } 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 @@
     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 @@
 // 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()) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index ea65ded..9283eaa 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -135,7 +135,8 @@
     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 @@
     /*
      * 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 @@
      * 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 @@
     // 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;
 
 
     // -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 4e82bab..14aa328 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -39,12 +39,13 @@
 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);
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index 6561d7f..4de0ddc 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -34,7 +34,8 @@
         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; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9f687e2..808fa1b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -190,7 +190,7 @@
     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 @@
 }
 
 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 @@
     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 @@
     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::clearStatsLocked(const Vector<String16>& args, size_t& index,
-        String8& result)
+        String8& /* result */)
 {
     String8 name;
     if (index < args.size()) {
@@ -2664,7 +2664,7 @@
      * 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 @@
 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 @@
         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 @@
         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 @@
     // 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 @@
         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 @@
             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 @@
         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 @@
                         // 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(),
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 9db0ce1..9230467 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -203,7 +203,8 @@
     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 @@
             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