Merge "Release virtual display buffer immediately after HWC set" into jb-mr2-dev
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 29838e4..d85a1d7 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -176,13 +176,18 @@
 // Truncate a file.
 static bool truncateFile(const char* path)
 {
-    int err = truncate(path, 0);
-    if (err != 0) {
+    // This uses creat rather than truncate because some of the debug kernel
+    // device nodes (e.g. k_ftraceFilterPath) currently aren't changed by
+    // calls to truncate, but they are cleared by calls to creat.
+    int traceFD = creat(path, 0);
+    if (traceFD == -1) {
         fprintf(stderr, "error truncating %s: %s (%d)\n", path,
-                strerror(errno), errno);
+            strerror(errno), errno);
         return false;
     }
 
+    close(traceFD);
+
     return true;
 }
 
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index b3a4cc6..a18c00d 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -101,6 +101,12 @@
 
     run_command("LIST OF OPEN FILES", 10, SU_PATH, "root", "lsof", NULL);
 
+    if (screenshot_path[0]) {
+        ALOGI("taking screenshot\n");
+        run_command(NULL, 10, "/system/bin/screencap", "-p", screenshot_path, NULL);
+        ALOGI("wrote screenshot: %s\n", screenshot_path);
+    }
+
     for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES");
     for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS");
 
@@ -159,12 +165,6 @@
     dump_file("LAST PANIC CONSOLE", "/data/dontpanic/apanic_console");
     dump_file("LAST PANIC THREADS", "/data/dontpanic/apanic_threads");
 
-    if (screenshot_path[0]) {
-        ALOGI("taking screenshot\n");
-        run_command(NULL, 10, "/system/bin/screencap", "-p", screenshot_path, NULL);
-        ALOGI("wrote screenshot: %s\n", screenshot_path);
-    }
-
     run_command("SYSTEM SETTINGS", 20, SU_PATH, "root", "sqlite3",
             "/data/data/com.android.providers.settings/databases/settings.db",
             "pragma user_version; select * from system; select * from secure; select * from global;", NULL);
diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h
index 93dff32..4b956c7 100644
--- a/include/gui/CpuConsumer.h
+++ b/include/gui/CpuConsumer.h
@@ -37,7 +37,7 @@
  * This queue is synchronous by default.
  */
 
-class CpuConsumer: public ConsumerBase
+class CpuConsumer : public ConsumerBase
 {
   public:
     typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
@@ -88,14 +88,25 @@
     // Maximum number of buffers that can be locked at a time
     uint32_t mMaxLockedBuffers;
 
+    status_t releaseAcquiredBufferLocked(int lockedIdx);
+
     virtual void freeBufferLocked(int slotIndex);
 
-    // Array for tracking pointers passed to the consumer, matching the
-    // mSlots indexing
-    struct LockedSlot {
+    // Tracking for buffers acquired by the user
+    struct AcquiredBuffer {
+        // Need to track the original mSlot index and the buffer itself because
+        // the mSlot entry may be freed/reused before the acquired buffer is
+        // released.
+        int mSlot;
         sp<GraphicBuffer> mGraphicBuffer;
         void *mBufferPointer;
-    } mLockedSlots[BufferQueue::NUM_BUFFER_SLOTS];
+
+        AcquiredBuffer() :
+                mSlot(BufferQueue::INVALID_BUFFER_SLOT),
+                mBufferPointer(NULL) {
+        }
+    };
+    Vector<AcquiredBuffer> mAcquiredBuffers;
 
     // Count of currently locked buffers
     uint32_t mCurrentLockedBuffers;
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 47f9552..9018b87 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -95,14 +95,6 @@
     virtual bool authenticateSurfaceTexture(
             const sp<IGraphicBufferProducer>& surface) const = 0;
 
-    /* Capture the specified screen. requires READ_FRAME_BUFFER permission
-     * This function will fail if there is a secure window on screen.
-     */
-    virtual status_t captureScreen(const sp<IBinder>& display, sp<IMemoryHeap>* heap,
-            uint32_t* width, uint32_t* height, PixelFormat* format,
-            uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
-
     /* triggers screen off and waits for it to complete
      * requires ACCESS_SURFACE_FLINGER permission.
      */
@@ -123,7 +115,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 isCpuConsumer) = 0;
 };
 
 // ----------------------------------------------------------------------------
@@ -141,7 +134,6 @@
         GET_BUILT_IN_DISPLAY,
         SET_TRANSACTION_STATE,
         AUTHENTICATE_SURFACE,
-        CAPTURE_SCREEN_DEPRECATED,
         BLANK,
         UNBLANK,
         GET_DISPLAY_INFO,
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 38c931d..23655c7 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -30,6 +30,7 @@
 
 #include <ui/PixelFormat.h>
 
+#include <gui/CpuConsumer.h>
 #include <gui/SurfaceControl.h>
 
 namespace android {
@@ -38,7 +39,6 @@
 
 class DisplayInfo;
 class Composer;
-class IMemoryHeap;
 class ISurfaceComposerClient;
 class IGraphicBufferProducer;
 class Region;
@@ -164,10 +164,9 @@
             uint32_t minLayerZ, uint32_t maxLayerZ);
 
 private:
-    sp<IMemoryHeap> mHeap;
-    uint32_t mWidth;
-    uint32_t mHeight;
-    PixelFormat mFormat;
+    mutable sp<CpuConsumer> mCpuConsumer;
+    CpuConsumer::LockedBuffer mBuffer;
+    bool mHaveBuffer;
 
 public:
     ScreenshotClient();
@@ -180,6 +179,8 @@
             uint32_t reqWidth, uint32_t reqHeight,
             uint32_t minLayerZ, uint32_t maxLayerZ);
 
+    sp<CpuConsumer> getCpuConsumer() const;
+
     // release memory occupied by the screenshot
     void release();
 
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index fe8eb6f..f27754c 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -58,7 +58,7 @@
     
     status_t    setLayerStack(int32_t layerStack);
     status_t    setLayer(int32_t layer);
-    status_t    setPosition(int32_t x, int32_t y);
+    status_t    setPosition(float x, float y);
     status_t    setSize(uint32_t w, uint32_t h);
     status_t    hide();
     status_t    show();
diff --git a/include/media/drm/DrmAPI.h b/include/media/drm/DrmAPI.h
new file mode 100644
index 0000000..77da0bf
--- /dev/null
+++ b/include/media/drm/DrmAPI.h
@@ -0,0 +1,205 @@
+ /*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DRM_API_H_
+#define DRM_API_H_
+
+#include <utils/List.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
+#include <media/stagefright/foundation/ABase.h>
+
+//  Loadable DrmEngine shared libraries should define the entry points
+//  createDrmFactory and createCryptoFactory as shown below:
+//
+//  extern "C" {
+//      extern android::DrmFactory *createDrmFactory();
+//      extern android::CryptoFactory *createCryptoFactory();
+//  }
+
+namespace android {
+
+    struct DrmPlugin;
+
+    // DRMs are implemented in DrmEngine plugins, which are dynamically
+    // loadable shared libraries that implement the entry points
+    // createDrmFactory and createCryptoFactory.  createDrmFactory
+    // constructs and returns an instance of a DrmFactory object.  Similarly,
+    // createCryptoFactory creates an instance of a CryptoFactory object.
+    // When a MediaCrypto or MediaDrm object needs to be constructed, all
+    // available DrmEngines present in the plugins directory on the device
+    // are scanned for a matching DrmEngine that can support the crypto
+    // scheme.  When a match is found, the DrmEngine's createCryptoPlugin and
+    // createDrmPlugin methods are used to create CryptoPlugin or
+    // DrmPlugin instances to support that DRM scheme.
+
+    class DrmFactory {
+    public:
+        DrmFactory() {}
+        virtual ~DrmFactory() {}
+
+        // DrmFactory::isCryptoSchemeSupported can be called to determine
+        // if the plugin factory is able to construct plugins that support a
+        // given crypto scheme, which is specified by a UUID.
+        virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) = 0;
+
+        // Construct a DrmPlugin for the crypto scheme specified by UUID.
+        virtual status_t createDrmPlugin(
+                const uint8_t uuid[16], DrmPlugin **plugin) = 0;
+
+    private:
+        DrmFactory(const DrmFactory &);
+        DrmFactory &operator=(const DrmFactory &);
+    };
+
+    class DrmPlugin {
+    public:
+        enum EventType {
+            kDrmPluginEventProvisionRequired,
+            kDrmPluginEventLicenseNeeded,
+            kDrmPluginEventLicenseExpired,
+            kDrmPluginEventVendorDefined
+        };
+
+        // A license can be for offline content or for online streaming.
+        // Offline licenses are persisted on the device and may be used when the device
+        // is disconnected from the network.
+        enum LicenseType {
+            kLicenseType_Offline,
+            kLicenseType_Streaming
+        };
+
+        DrmPlugin() {}
+        virtual ~DrmPlugin() {}
+
+        // Open a new session with the DrmPlugin object.  A session ID is returned
+        // in the sessionId parameter.
+        virtual status_t openSession(Vector<uint8_t> &sessionId) = 0;
+
+        // Close a session on the DrmPlugin object.
+        virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0;
+
+        // A license request/response exchange occurs between the app and a License
+        // Server to obtain the keys required to decrypt the content.  getLicenseRequest()
+        // is used to obtain an opaque license request blob that is delivered to the
+        // license server.
+        //
+        // The init data passed to getLicenseRequest is container-specific and its
+        // meaning is interpreted based on the mime type provided in the mimeType
+        // parameter to getLicenseRequest.  It could contain, for example, the content
+        // ID, key ID or other data obtained from the content metadata that is required
+        // in generating the license request.
+        //
+        // licenseType specifes if the license is for streaming or offline content
+        //
+        // optionalParameters are included in the license server request message to
+        // allow a client application to provide additional message parameters to the
+        // server.
+        //
+        // If successful, the opaque license request blob is returned to the caller.
+        virtual status_t
+            getLicenseRequest(Vector<uint8_t> const &sessionId,
+                              Vector<uint8_t> const &initData,
+                              String8 const &mimeType, LicenseType licenseType,
+                              KeyedVector<String8, String8> const &optionalParameters,
+                              Vector<uint8_t> &request, String8 &defaultUrl) = 0;
+
+        // After a license response is received by the app, it is provided to the
+        // Drm plugin using provideLicenseResponse.
+        virtual status_t provideLicenseResponse(Vector<uint8_t> const &sessionId,
+                                                Vector<uint8_t> const &response) = 0;
+
+        // Remove the keys associated with a license.
+        virtual status_t removeLicense(Vector<uint8_t> const &sessionId) = 0;
+
+        // Request an informative description of the license for the session.  The status
+        // is in the form of {name, value} pairs.  Since DRM license policies vary by
+        // vendor, the specific status field names are determined by each DRM vendor.
+        // Refer to your DRM provider documentation for definitions of the field names
+        // for a particular DrmEngine.
+        virtual status_t
+            queryLicenseStatus(Vector<uint8_t> const &sessionId,
+                               KeyedVector<String8, String8> &infoMap) const = 0;
+
+        // A provision request/response exchange occurs between the app and a
+        // provisioning server to retrieve a device certificate.  getProvisionRequest
+        // is used to obtain an opaque license request blob that is delivered to the
+        // provisioning server.
+        //
+        // If successful, the opaque provision request blob is returned to the caller.
+        virtual status_t getProvisionRequest(Vector<uint8_t> &request,
+                                             String8 &defaultUrl) = 0;
+
+        // After a provision response is received by the app, it is provided to the
+        // Drm plugin using provideProvisionResponse.
+        virtual status_t provideProvisionResponse(Vector<uint8_t> const &response) = 0;
+
+        // A means of enforcing the contractual requirement for a concurrent stream
+        // limit per subscriber across devices is provided via SecureStop.  SecureStop
+        // is a means of securely monitoring the lifetime of sessions. Since playback
+        // on a device can be interrupted due to reboot, power failure, etc. a means
+        // of persisting the lifetime information on the device is needed.
+        //
+        // A signed version of the sessionID is written to persistent storage on the
+        // device when each MediaCrypto object is created. The sessionID is signed by
+        // the device private key to prevent tampering.
+        //
+        // In the normal case, playback will be completed, the session destroyed and
+        // the Secure Stops will be queried. The App queries secure stops and forwards
+        // the secure stop message to the server which verifies the signature and
+        // notifies the server side database that the session destruction has been
+        // confirmed. The persisted record on the client is only removed after positive
+        // confirmation that the server received the message using releaseSecureStops().
+        virtual status_t getSecureStops(List<Vector<uint8_t> > &secureStops) = 0;
+        virtual status_t releaseSecureStops(Vector<uint8_t> const &ssRelease) = 0;
+
+        // Read a property value given the device property string.  There are a few forms
+        // of property access methods, depending on the data type returned.
+        // Since DRM plugin properties may vary, additional field names may be defined
+        // by each DRM vendor.  Refer to your DRM provider documentation for definitions
+        // of its additional field names.
+        //
+        // Standard values are:
+        //   "vendor" [string] identifies the maker of the plugin
+        //   "version" [string] identifies the version of the plugin
+        //   "description" [string] describes the plugin
+        //   'deviceUniqueId' [byte array] The device unique identifier is established
+        //   during device provisioning and provides a means of uniquely identifying
+        //   each device.
+        virtual status_t getPropertyString(String8 const &name, String8 &value ) const = 0;
+        virtual status_t getPropertyByteArray(String8 const &name,
+                                              Vector<uint8_t> &value ) const = 0;
+
+        // Write  a property value given the device property string.  There are a few forms
+        // of property setting methods, depending on the data type.
+        // Since DRM plugin properties may vary, additional field names may be defined
+        // by each DRM vendor.  Refer to your DRM provider documentation for definitions
+        // of its field names.
+        virtual status_t setPropertyString(String8 const &name,
+                                           String8 const &value ) = 0;
+        virtual status_t setPropertyByteArray(String8 const &name,
+                                              Vector<uint8_t> const &value ) = 0;
+
+        // TODO: provide way to send an event
+    private:
+        DISALLOW_EVIL_CONSTRUCTORS(DrmPlugin);
+    };
+
+}  // namespace android
+
+#endif // DRM_API_H_
diff --git a/include/media/drm/DrmClientAPI.h b/include/media/drm/DrmClientAPI.h
deleted file mode 100644
index 6a08933..0000000
--- a/include/media/drm/DrmClientAPI.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DRM_CLIENT_API_H_
-#define DRM_CLIENT_API_H_
-
-#include <utils/String8.h>
-#include <utils/Vector.h>
-#include <utils/List.h>
-#include <media/stagefright/foundation/ABase.h>
-
-namespace android {
-
-    // A DrmMessageStatus object aggregates a sessionId, which uniquely
-    // identifies a playback context with a status code and opaque message
-    // data.
-    struct DrmMessageStatus {
-        Vector<uint8_t> mSessionId;
-        status_t mStatus;
-        Vector<uint8_t> mData;
-    };
-
-    class DrmClientPlugin {
-    public:
-
-        // A license can be for downloaded, offline content or for online streaming
-        // Offline licenses are persisted on the device and may be used when the device
-        // is disconnected from the network.
-        enum LicenseType {
-            kLicenseType_Offline,
-            kLicenseType_Streaming
-        };
-
-        DrmClientPlugin() {}
-        virtual ~DrmClientPlugin() {}
-
-        // A license request/response exchange occurs between the app and a License
-        // Server to obtain the keys required to decrypt the content.  getLicenseRequest()
-        // is used to obtain an opaque license request blob that is delivered to the
-        // license server.
-        //
-        // The init data passed to getLicenseRequest is container-specific and its
-        // meaning is interpreted based on the mime type provided in the mimeType
-        // parameter to getLicenseRequest.  It could contain, for example, the content
-        // ID, key ID or other data obtained from the content metadata that is required
-        // in generating the license request.
-        //
-        // The DrmMessageStatus returned from getLicenseRequest contains a sessionId for
-        // the new session, a status code indicating whether the operation was successful
-        // and if so, the request blob is placed into the mData field.
-        virtual DrmMessageStatus getLicenseRequest(Vector<uint8_t> const &initData,
-                String8 const &mimeType, LicenseType licenseType) = 0;
-
-        // After a license response is received by the app, it is provided to the
-        // DrmClient plugin using provideLicenseResponse.  The response data is provided
-        // in the mData field of the response parameter.
-        virtual status_t provideLicenseResponse(DrmMessageStatus const &response) = 0;
-
-        // Remove the keys associated with a license and release the session
-        virtual status_t clearLicense(Vector<uint8_t> const &sessionId) = 0;
-
-        // A provision request/response exchange occurs between the app and a
-        // provisioning server to retrieve a device certificate.  getProvisionRequest
-        // is used to obtain an opaque license request blob that is delivered to the
-        // provisioning server.
-        //
-        // The DrmMessageStatus returned from getLicenseRequest contains a status code
-        // indicating whether the operation was successful and if so, the request blob
-        // is placed into the mData field.
-        virtual DrmMessageStatus getProvisionRequest() = 0;
-
-        // After a provision response is received by the app, it is provided to the
-        // DrmClient plugin using provideProvisionResponse.  The response data is
-        // provided in the mData field of the response parameter.
-        virtual status_t provideProvisionResponse(DrmMessageStatus const &response) = 0;
-
-        // A means of enforcing the contractual requirement for a concurrent stream
-        // limit per subscriber across devices is provided via SecureStop.  SecureStop
-        // is a means of securely monitoring the lifetime of sessions. Since playback
-        // on a device can be interrupted due to reboot, power failure, etc. a means
-        // of persisting the lifetime information on the device is needed.
-        //
-        // A signed version of the sessionID is written to persistent storage on the
-        // device when each MediaCrypto object is created. The sessionID is signed by
-        // the device private key to prevent tampering.
-        //
-        // In the normal case, playback will be completed, the session destroyed and
-        // the Secure Stops will be queried. The App queries secure stops and forwards
-        // the secure stop message to the server which verifies the signature and
-        // notifies the server side database that the session destruction has been
-        // confirmed. The persisted record on the client is only removed after positive
-        // confirmation that the server received the message using releaseSecureStops().
-        virtual List<DrmMessageStatus> getSecureStops() = 0;
-        virtual status_t releaseSecureStops(DrmMessageStatus const &ssRelease) = 0;
-
-        // Retrieve the device unique identifier for this device.  The device unique
-        // identifier is established during device provisioning.
-        virtual Vector<uint8_t> getDeviceUniqueId() const = 0;
-
-    private:
-        DISALLOW_EVIL_CONSTRUCTORS(DrmClientPlugin);
-    };
-
-}  // namespace android
-
-#endif // DRM_CLIENT_API_H_
diff --git a/include/media/drm/DrmEngineAPI.h b/include/media/drm/DrmEngineAPI.h
deleted file mode 100644
index 25bd34a..0000000
--- a/include/media/drm/DrmEngineAPI.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DRM_ENGINE_API_H_
-#define DRM_ENGINE_API_H_
-
-#include <utils/Errors.h>
-#include <media/stagefright/foundation/ABase.h>
-
-
-namespace android {
-
-    class CryptoPlugin;
-    class DrmClientPlugin;
-
-     // DRMs are implemented in DrmEngine plugins, which are dynamically
-     // loadable shared libraries that implement the entry point
-     // createDrmPluginFactory.  createDrmPluginFactory constructs and returns
-     // an instance of a DrmPluginFactory object.  When a MediaCrypto or
-     // DrmClient object needs to be constructed, all available
-     // DrmEngines present in the plugins directory on the device are scanned
-     // for a matching DrmEngine that can support the crypto scheme.  When a
-     // match is found, the DrmEngine’s createCryptoPlugin or
-     // createDrmClientPlugin methods are used to create CryptoPlugin or
-     // DrmClientPlugin instances to support that DRM scheme.
-
-    class DrmPluginFactory {
-    public:
-        DrmPluginFactory() {}
-        virtual ~DrmPluginFactory() {}
-
-         // DrmPluginFactory::isCryptoSchemeSupported can be called to determine
-         // if the plugin factory is able to construct plugins that support a
-         // given crypto scheme, which is specified by a UUID.
-        virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const = 0;
-
-        // Construct a CryptoPlugin for the crypto scheme specified by UUID.
-        // {data, size} provide scheme-specific initialization data.
-        virtual status_t createCryptoPlugin(
-                const uint8_t uuid[16], const void *data, size_t size,
-                CryptoPlugin **plugin) = 0;
-
-        // Construct a DrmClientPlugin for the crypto scheme specified by UUID.
-        // {data, size} provide scheme-specific initialization data.
-        virtual status_t createDrmClientPlugin(
-                const uint8_t uuid[16], const void *data, size_t size,
-                DrmClientPlugin **plugin) = 0;
-
-    private:
-        DISALLOW_EVIL_CONSTRUCTORS(DrmPluginFactory);
-    };
-
-}  // namespace android
-
- //  Loadable DrmEngine shared libraries should define the entry point
- //  createDrmPluginFactory as shown below:
- //
- //  extern "C" {
- //      extern android::DrmPluginFactory *createDrmPluginFactory();
- //  }
-
-#endif // DRM_ENGINE_API_H_
diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h
index 079e20c..61dc832 100644
--- a/include/utils/CallStack.h
+++ b/include/utils/CallStack.h
@@ -35,6 +35,8 @@
     };
 
     CallStack();
+    CallStack(const char* logtag, int32_t ignoreDepth=1,
+            int32_t maxDepth=MAX_DEPTH);
     CallStack(const CallStack& rhs);
     ~CallStack();
 
@@ -53,8 +55,8 @@
 
     void update(int32_t ignoreDepth=1, int32_t maxDepth=MAX_DEPTH);
 
-    // Dump a stack trace to the log
-    void dump(const char* prefix = 0) const;
+    // Dump a stack trace to the log using the supplied logtag
+    void dump(const char* logtag, const char* prefix = 0) const;
 
     // Return a string (possibly very long) containing the complete stack trace
     String8 toString(const char* prefix = 0) const;
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
index 0a8e10a..033fe67 100644
--- a/include/utils/RefBase.h
+++ b/include/utils/RefBase.h
@@ -52,12 +52,16 @@
 }
 
 // ---------------------------------------------------------------------------
-class ReferenceMover;
-class ReferenceConverterBase {
+
+class ReferenceRenamer {
+protected:
+    // destructor is purposedly not virtual so we avoid code overhead from
+    // subclasses; we have to make it protected to guarantee that it
+    // cannot be called from this base class (and to make strict compilers
+    // happy).
+    ~ReferenceRenamer() { }
 public:
-    virtual size_t getReferenceTypeSize() const = 0;
-    virtual void* getReferenceBase(void const*) const = 0;
-    inline virtual ~ReferenceConverterBase() { }
+    virtual void operator()(size_t i) const = 0;
 };
 
 // ---------------------------------------------------------------------------
@@ -144,17 +148,23 @@
     virtual void            onLastWeakRef(const void* id);
 
 private:
-    friend class ReferenceMover;
-    static void moveReferences(void* d, void const* s, size_t n,
-            const ReferenceConverterBase& caster);
-
-private:
     friend class weakref_type;
     class weakref_impl;
     
                             RefBase(const RefBase& o);
             RefBase&        operator=(const RefBase& o);
 
+private:
+    friend class ReferenceMover;
+
+    static void renameRefs(size_t n, const ReferenceRenamer& renamer);
+
+    static void renameRefId(weakref_type* ref,
+            const void* old_id, const void* new_id);
+
+    static void renameRefId(RefBase* ref,
+            const void* old_id, const void* new_id);
+
         weakref_impl* const mRefs;
 };
 
@@ -185,8 +195,9 @@
 
 private:
     friend class ReferenceMover;
-    inline static void moveReferences(void* d, void const* s, size_t n,
-            const ReferenceConverterBase& caster) { }
+    inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { }
+    inline static void renameRefId(T* ref,
+            const void* old_id, const void* new_id) { }
 
 private:
     mutable volatile int32_t mCount;
@@ -455,42 +466,48 @@
 
 // this class just serves as a namespace so TYPE::moveReferences can stay
 // private.
-
 class ReferenceMover {
-    // StrongReferenceCast and WeakReferenceCast do the impedance matching
-    // between the generic (void*) implementation in Refbase and the strongly typed
-    // template specializations below.
-
-    template <typename TYPE>
-    struct StrongReferenceCast : public ReferenceConverterBase {
-        virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); }
-        virtual void* getReferenceBase(void const* p) const {
-            sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p));
-            return static_cast<typename TYPE::basetype *>(sptr->get());
-        }
-    };
-
-    template <typename TYPE>
-    struct WeakReferenceCast : public ReferenceConverterBase {
-        virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); }
-        virtual void* getReferenceBase(void const* p) const {
-            wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p));
-            return static_cast<typename TYPE::basetype *>(sptr->unsafe_get());
-        }
-    };
-
 public:
+    // it would be nice if we could make sure no extra code is generated
+    // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase:
+    // Using a sp<RefBase> override doesn't work; it's a bit like we wanted
+    // a template<typename TYPE inherits RefBase> template...
+
     template<typename TYPE> static inline
     void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
+
+        class Renamer : public ReferenceRenamer {
+            sp<TYPE>* d;
+            sp<TYPE> const* s;
+            virtual void operator()(size_t i) const {
+                // The id are known to be the sp<>'s this pointer
+                TYPE::renameRefId(d[i].get(), &s[i], &d[i]);
+            }
+        public:
+            Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { }
+        };
+
         memmove(d, s, n*sizeof(sp<TYPE>));
-        StrongReferenceCast<TYPE> caster;
-        TYPE::moveReferences(d, s, n, caster);
+        TYPE::renameRefs(n, Renamer(d, s));
     }
+
+
     template<typename TYPE> static inline
     void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
+
+        class Renamer : public ReferenceRenamer {
+            wp<TYPE>* d;
+            wp<TYPE> const* s;
+            virtual void operator()(size_t i) const {
+                // The id are known to be the wp<>'s this pointer
+                TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]);
+            }
+        public:
+            Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { }
+        };
+
         memmove(d, s, n*sizeof(wp<TYPE>));
-        WeakReferenceCast<TYPE> caster;
-        TYPE::moveReferences(d, s, n, caster);
+        TYPE::renameRefs(n, Renamer(d, s));
     }
 };
 
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index cd2451a..07cb41a 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -246,9 +246,7 @@
                 if (VERBOSE) {
                     ALOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d",
                             binder.get(), this, mSize, mHeapId);
-                    CallStack stack;
-                    stack.update();
-                    stack.dump("callstack");
+                    CallStack stack(LOG_TAG);
                 }
 
                 munmap(mBase, mSize);
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index 1ee6673..a638cfa 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -17,8 +17,9 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "CpuConsumer"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <utils/Log.h>
 
+#include <cutils/compiler.h>
+#include <utils/Log.h>
 #include <gui/CpuConsumer.h>
 
 #define CC_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
@@ -34,9 +35,8 @@
     mMaxLockedBuffers(maxLockedBuffers),
     mCurrentLockedBuffers(0)
 {
-    for (size_t i=0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
-        mLockedSlots[i].mBufferPointer = NULL;
-    }
+    // Create tracking entries for locked buffers
+    mAcquiredBuffers.insertAt(0, maxLockedBuffers);
 
     mBufferQueue->setSynchronousMode(synchronousMode);
     mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
@@ -44,21 +44,11 @@
 }
 
 CpuConsumer::~CpuConsumer() {
-    status_t err;
-    for (size_t i=0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
-        if (mLockedSlots[i].mBufferPointer != NULL) {
-            mLockedSlots[i].mBufferPointer = NULL;
-            err = mLockedSlots[i].mGraphicBuffer->unlock();
-            mLockedSlots[i].mGraphicBuffer.clear();
-            if (err != OK) {
-                CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__,
-                        i);
-            }
-
-        }
-    }
+    // ConsumerBase destructor does all the work.
 }
 
+
+
 void CpuConsumer::setName(const String8& name) {
     Mutex::Autolock _l(mMutex);
     mName = name;
@@ -109,8 +99,19 @@
                 err);
         return err;
     }
-    mLockedSlots[buf].mBufferPointer = bufferPointer;
-    mLockedSlots[buf].mGraphicBuffer = mSlots[buf].mGraphicBuffer;
+    size_t lockedIdx = 0;
+    for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) {
+        if (mAcquiredBuffers[lockedIdx].mSlot ==
+                BufferQueue::INVALID_BUFFER_SLOT) {
+            break;
+        }
+    }
+    assert(lockedIdx < mMaxLockedBuffers);
+
+    AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx);
+    ab.mSlot = buf;
+    ab.mBufferPointer = bufferPointer;
+    ab.mGraphicBuffer = mSlots[buf].mGraphicBuffer;
 
     nativeBuffer->data   =
             reinterpret_cast<uint8_t*>(bufferPointer);
@@ -132,29 +133,46 @@
 
 status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) {
     Mutex::Autolock _l(mMutex);
-    int slotIndex = 0;
+    size_t lockedIdx = 0;
     status_t err;
 
     void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data);
-    for (; slotIndex < BufferQueue::NUM_BUFFER_SLOTS; slotIndex++) {
-        if (bufPtr == mLockedSlots[slotIndex].mBufferPointer) break;
+    for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) {
+        if (bufPtr == mAcquiredBuffers[lockedIdx].mBufferPointer) break;
     }
-    if (slotIndex == BufferQueue::NUM_BUFFER_SLOTS) {
+    if (lockedIdx == mMaxLockedBuffers) {
         CC_LOGE("%s: Can't find buffer to free", __FUNCTION__);
         return BAD_VALUE;
     }
 
-    mLockedSlots[slotIndex].mBufferPointer = NULL;
-    err = mLockedSlots[slotIndex].mGraphicBuffer->unlock();
-    mLockedSlots[slotIndex].mGraphicBuffer.clear();
+    return releaseAcquiredBufferLocked(lockedIdx);
+}
+
+status_t CpuConsumer::releaseAcquiredBufferLocked(int lockedIdx) {
+    status_t err;
+
+    err = mAcquiredBuffers[lockedIdx].mGraphicBuffer->unlock();
     if (err != OK) {
-        CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__, slotIndex);
+        CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__,
+                lockedIdx);
         return err;
     }
-    releaseBufferLocked(slotIndex, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+    int buf = mAcquiredBuffers[lockedIdx].mSlot;
+
+    // release the buffer if it hasn't already been freed by the BufferQueue.
+    // This can happen, for example, when the producer of this buffer
+    // disconnected after this buffer was acquired.
+    if (CC_LIKELY(mAcquiredBuffers[lockedIdx].mGraphicBuffer ==
+            mSlots[buf].mGraphicBuffer)) {
+        releaseBufferLocked(buf, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
+    }
+
+    AcquiredBuffer &ab = mAcquiredBuffers.editItemAt(lockedIdx);
+    ab.mSlot = BufferQueue::INVALID_BUFFER_SLOT;
+    ab.mBufferPointer = NULL;
+    ab.mGraphicBuffer.clear();
 
     mCurrentLockedBuffers--;
-
     return OK;
 }
 
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 0a79ff7..6442a86 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -102,31 +102,11 @@
         remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
     }
 
-    virtual status_t captureScreen(
-            const sp<IBinder>& display, sp<IMemoryHeap>* heap,
-            uint32_t* width, uint32_t* height, PixelFormat* format,
-            uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        data.writeStrongBinder(display);
-        data.writeInt32(reqWidth);
-        data.writeInt32(reqHeight);
-        data.writeInt32(minLayerZ);
-        data.writeInt32(maxLayerZ);
-        remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN_DEPRECATED, data, &reply);
-        *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
-        *width = reply.readInt32();
-        *height = reply.readInt32();
-        *format = reply.readInt32();
-        return reply.readInt32();
-    }
-
     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 isCpuConsumer)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -136,6 +116,7 @@
         data.writeInt32(reqHeight);
         data.writeInt32(minLayerZ);
         data.writeInt32(maxLayerZ);
+        data.writeInt32(isCpuConsumer);
         remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
         return reply.readInt32();
     }
@@ -285,24 +266,6 @@
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             bootFinished();
         } break;
-        case CAPTURE_SCREEN_DEPRECATED: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            sp<IBinder> display = data.readStrongBinder();
-            uint32_t reqWidth = data.readInt32();
-            uint32_t reqHeight = data.readInt32();
-            uint32_t minLayerZ = data.readInt32();
-            uint32_t maxLayerZ = data.readInt32();
-            sp<IMemoryHeap> heap;
-            uint32_t w, h;
-            PixelFormat f;
-            status_t res = captureScreen(display, &heap, &w, &h, &f,
-                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
-            reply->writeStrongBinder(heap->asBinder());
-            reply->writeInt32(w);
-            reply->writeInt32(h);
-            reply->writeInt32(f);
-            reply->writeInt32(res);
-        } break;
         case CAPTURE_SCREEN: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> display = data.readStrongBinder();
@@ -312,8 +275,10 @@
             uint32_t reqHeight = data.readInt32();
             uint32_t minLayerZ = data.readInt32();
             uint32_t maxLayerZ = data.readInt32();
+            bool isCpuConsumer = data.readInt32();
             status_t res = captureScreen(display, producer,
-                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
+                    reqWidth, reqHeight, minLayerZ, maxLayerZ,
+                    isCpuConsumer);
             reply->writeInt32(res);
         } break;
         case AUTHENTICATE_SURFACE: {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 4a4c0c8..ec46fce 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -31,6 +31,7 @@
 
 #include <ui/DisplayInfo.h>
 
+#include <gui/CpuConsumer.h>
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/ISurfaceComposerClient.h>
@@ -617,30 +618,21 @@
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == NULL) return NO_INIT;
     return s->captureScreen(display, producer,
-            reqWidth, reqHeight, minLayerZ, maxLayerZ);
+            reqWidth, reqHeight, minLayerZ, maxLayerZ,
+            false);
 }
 
 ScreenshotClient::ScreenshotClient()
-    : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
+    : mHaveBuffer(false) {
+    memset(&mBuffer, 0, sizeof(mBuffer));
 }
 
-status_t ScreenshotClient::update(const sp<IBinder>& display) {
-    sp<ISurfaceComposer> s(ComposerService::getComposerService());
-    if (s == NULL) return NO_INIT;
-    mHeap = 0;
-    return s->captureScreen(display, &mHeap,
-            &mWidth, &mHeight, &mFormat, 0, 0,
-            0, -1UL);
-}
-
-status_t ScreenshotClient::update(const sp<IBinder>& display,
-        uint32_t reqWidth, uint32_t reqHeight) {
-    sp<ISurfaceComposer> s(ComposerService::getComposerService());
-    if (s == NULL) return NO_INIT;
-    mHeap = 0;
-    return s->captureScreen(display, &mHeap,
-            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
-            0, -1UL);
+sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const {
+    if (mCpuConsumer == NULL) {
+        mCpuConsumer = new CpuConsumer(1);
+        mCpuConsumer->setName(String8("ScreenshotClient"));
+    }
+    return mCpuConsumer;
 }
 
 status_t ScreenshotClient::update(const sp<IBinder>& display,
@@ -648,38 +640,66 @@
         uint32_t minLayerZ, uint32_t maxLayerZ) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == NULL) return NO_INIT;
-    mHeap = 0;
-    return s->captureScreen(display, &mHeap,
-            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight,
-            minLayerZ, maxLayerZ);
+    sp<CpuConsumer> cpuConsumer = getCpuConsumer();
+
+    if (mHaveBuffer) {
+        mCpuConsumer->unlockBuffer(mBuffer);
+        memset(&mBuffer, 0, sizeof(mBuffer));
+        mHaveBuffer = false;
+    }
+
+    status_t err = s->captureScreen(display,cpuConsumer->getBufferQueue(),
+            reqWidth, reqHeight, minLayerZ, maxLayerZ, true);
+
+    if (err == NO_ERROR) {
+        err = mCpuConsumer->lockNextBuffer(&mBuffer);
+        if (err == NO_ERROR) {
+            mHaveBuffer = true;
+        }
+    }
+    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,
+        uint32_t reqWidth, uint32_t reqHeight) {
+    return ScreenshotClient::update(display, reqWidth, reqHeight, 0, -1UL);
 }
 
 void ScreenshotClient::release() {
-    mHeap = 0;
+    if (mHaveBuffer) {
+        mCpuConsumer->unlockBuffer(mBuffer);
+        memset(&mBuffer, 0, sizeof(mBuffer));
+        mHaveBuffer = false;
+    }
+    mCpuConsumer.clear();
 }
 
 void const* ScreenshotClient::getPixels() const {
-    return mHeap->getBase();
+    return mBuffer.data;
 }
 
 uint32_t ScreenshotClient::getWidth() const {
-    return mWidth;
+    return mBuffer.width;
 }
 
 uint32_t ScreenshotClient::getHeight() const {
-    return mHeight;
+    return mBuffer.height;
 }
 
 PixelFormat ScreenshotClient::getFormat() const {
-    return mFormat;
+    return mBuffer.format;
 }
 
 uint32_t ScreenshotClient::getStride() const {
-    return mWidth;
+    return mBuffer.stride;
 }
 
 size_t ScreenshotClient::getSize() const {
-    return mHeap->getSize();
+    return mBuffer.stride * mBuffer.height * bytesPerPixel(mBuffer.format);
 }
 
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index bb57948..f4e88f5 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -102,7 +102,7 @@
     const sp<SurfaceComposerClient>& client(mClient);
     return client->setLayer(mHandle, layer);
 }
-status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
+status_t SurfaceControl::setPosition(float x, float y) {
     status_t err = validate();
     if (err < 0) return err;
     const sp<SurfaceComposerClient>& client(mClient);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 545b547..429becf 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -23,11 +23,17 @@
 #include <utils/String8.h>
 
 #include <private/gui/ComposerService.h>
+#include <binder/ProcessState.h>
 
 namespace android {
 
 class SurfaceTest : public ::testing::Test {
 protected:
+
+    SurfaceTest() {
+        ProcessState::self()->startThreadPool();
+    }
+
     virtual void SetUp() {
         mComposerClient = new SurfaceComposerClient;
         ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
@@ -81,14 +87,11 @@
     sp<ANativeWindow> anw(mSurface);
 
     // Verify the screenshot works with no protected buffers.
-    sp<IMemoryHeap> heap;
-    uint32_t w=0, h=0;
-    PixelFormat fmt=0;
+    sp<CpuConsumer> consumer = new CpuConsumer(1);
     sp<ISurfaceComposer> sf(ComposerService::getComposerService());
     sp<IBinder> display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &heap, &w, &h, &fmt, 64, 64, 0,
-            0x7fffffff));
-    ASSERT_TRUE(heap != NULL);
+    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, consumer->getBufferQueue(),
+            64, 64, 0, 0x7fffffff, true));
 
     // Set the PROTECTED usage bit and verify that the screenshot fails.  Note
     // that we need to dequeue a buffer in order for it to actually get
@@ -116,11 +119,8 @@
                 &buf));
         ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
     }
-    heap = 0;
-    w = h = fmt = 0;
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &heap, &w, &h, &fmt,
-            64, 64, 0, 0x7fffffff));
-    ASSERT_TRUE(heap != NULL);
+    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, consumer->getBufferQueue(),
+            64, 64, 0, 0x7fffffff, true));
 }
 
 TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 1a613f8..488fba3 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -530,9 +530,7 @@
     }
     if (result == false && !silent) {
         reg.dump(name);
-        CallStack stack;
-        stack.update();
-        stack.dump("");
+        CallStack stack(LOG_TAG);
     }
     return result;
 }
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
index 66fabeb..e60f5d8 100644
--- a/libs/utils/CallStack.cpp
+++ b/libs/utils/CallStack.cpp
@@ -30,6 +30,11 @@
         mCount(0) {
 }
 
+CallStack::CallStack(const char* logtag, int32_t ignoreDepth, int32_t maxDepth) {
+    this->update(ignoreDepth+1, maxDepth);
+    this->dump(logtag);
+}
+
 CallStack::CallStack(const CallStack& rhs) :
         mCount(rhs.mCount) {
     if (mCount) {
@@ -96,7 +101,7 @@
     mCount = count > 0 ? count : 0;
 }
 
-void CallStack::dump(const char* prefix) const {
+void CallStack::dump(const char* logtag, const char* prefix) const {
     backtrace_symbol_t symbols[mCount];
 
     get_backtrace_symbols(mStack, mCount, symbols);
@@ -104,7 +109,9 @@
         char line[MAX_BACKTRACE_LINE_LENGTH];
         format_backtrace_line(i, &mStack[i], &symbols[i],
                 line, MAX_BACKTRACE_LINE_LENGTH);
-        ALOGD("%s%s", prefix, line);
+        ALOG(LOG_DEBUG, logtag, "%s%s",
+                prefix ? prefix : "",
+                line);
     }
     free_backtrace_symbols(symbols, mCount);
 }
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index 0623f46..e538f68 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -15,7 +15,7 @@
  */
 
 #define LOG_TAG "RefBase"
-#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
 
 #include <utils/RefBase.h>
 
@@ -35,10 +35,18 @@
 
 // compile with refcounting debugging enabled
 #define DEBUG_REFS                      0
-#define DEBUG_REFS_FATAL_SANITY_CHECKS  0
-#define DEBUG_REFS_ENABLED_BY_DEFAULT   1
+
+// whether ref-tracking is enabled by default, if not, trackMe(true, false)
+// needs to be called explicitly
+#define DEBUG_REFS_ENABLED_BY_DEFAULT   0
+
+// whether callstack are collected (significantly slows things down)
 #define DEBUG_REFS_CALLSTACK_ENABLED    1
 
+// folder where stack traces are saved when DEBUG_REFS is enabled
+// this folder needs to exist and be writable
+#define DEBUG_REFS_CALLSTACK_PATH       "/data/debug"
+
 // log all reference counting operations
 #define PRINT_REFS                      0
 
@@ -96,17 +104,13 @@
         bool dumpStack = false;
         if (!mRetain && mStrongRefs != NULL) {
             dumpStack = true;
-#if DEBUG_REFS_FATAL_SANITY_CHECKS
-            LOG_ALWAYS_FATAL("Strong references remain!");
-#else
             ALOGE("Strong references remain:");
-#endif
             ref_entry* refs = mStrongRefs;
             while (refs) {
                 char inc = refs->ref >= 0 ? '+' : '-';
                 ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
 #if DEBUG_REFS_CALLSTACK_ENABLED
-                refs->stack.dump();
+                refs->stack.dump(LOG_TAG);
 #endif
                 refs = refs->next;
             }
@@ -114,26 +118,20 @@
 
         if (!mRetain && mWeakRefs != NULL) {
             dumpStack = true;
-#if DEBUG_REFS_FATAL_SANITY_CHECKS
-            LOG_ALWAYS_FATAL("Weak references remain:");
-#else
             ALOGE("Weak references remain!");
-#endif
             ref_entry* refs = mWeakRefs;
             while (refs) {
                 char inc = refs->ref >= 0 ? '+' : '-';
                 ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
 #if DEBUG_REFS_CALLSTACK_ENABLED
-                refs->stack.dump();
+                refs->stack.dump(LOG_TAG);
 #endif
                 refs = refs->next;
             }
         }
         if (dumpStack) {
             ALOGE("above errors at:");
-            CallStack stack;
-            stack.update();
-            stack.dump();
+            CallStack stack(LOG_TAG);
         }
     }
 
@@ -199,7 +197,7 @@
 
         {
             char name[100];
-            snprintf(name, 100, "/data/%p.stack", this);
+            snprintf(name, 100, DEBUG_REFS_CALLSTACK_PATH "/%p.stack", this);
             int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644);
             if (rc >= 0) {
                 write(rc, text.string(), text.length());
@@ -258,12 +256,6 @@
                 ref = *refs;
             }
 
-#if DEBUG_REFS_FATAL_SANITY_CHECKS
-            LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p"
-                    "(weakref_type %p) that doesn't exist!",
-                    id, mBase, this);
-#endif
-
             ALOGE("RefBase: removing id %p on RefBase %p"
                     "(weakref_type %p) that doesn't exist!",
                     id, mBase, this);
@@ -275,9 +267,7 @@
                 ref = ref->next;
             }
 
-            CallStack stack;
-            stack.update();
-            stack.dump();
+            CallStack stack(LOG_TAG);
         }
     }
 
@@ -637,21 +627,27 @@
 
 // ---------------------------------------------------------------------------
 
-void RefBase::moveReferences(void* dst, void const* src, size_t n,
-        const ReferenceConverterBase& caster)
-{
+void RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) {
 #if DEBUG_REFS
-    const size_t itemSize = caster.getReferenceTypeSize();
     for (size_t i=0 ; i<n ; i++) {
-        void*       d = reinterpret_cast<void      *>(intptr_t(dst) + i*itemSize);
-        void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize);
-        RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d)));
-        ref->mRefs->renameStrongRefId(s, d);
-        ref->mRefs->renameWeakRefId(s, d);
+        renamer(i);
     }
 #endif
 }
 
+void RefBase::renameRefId(weakref_type* ref,
+        const void* old_id, const void* new_id) {
+    weakref_impl* const impl = static_cast<weakref_impl*>(ref);
+    impl->renameStrongRefId(old_id, new_id);
+    impl->renameWeakRefId(old_id, new_id);
+}
+
+void RefBase::renameRefId(RefBase* ref,
+        const void* old_id, const void* new_id) {
+    ref->mRefs->renameStrongRefId(old_id, new_id);
+    ref->mRefs->renameWeakRefId(old_id, new_id);
+}
+
 // ---------------------------------------------------------------------------
 
 TextOutput& printStrongPointer(TextOutput& to, const void* val)
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index a8691b5..a6e91e0 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -222,9 +222,7 @@
         char value[PROPERTY_VALUE_MAX];
         property_get("debug.egl.callstack", value, "0");
         if (atoi(value)) {
-            CallStack stack;
-            stack.update();
-            stack.dump();
+            CallStack stack(LOG_TAG);
         }
     }
     return 0;
diff --git a/opengl/libs/EGL/egl_tls.cpp b/opengl/libs/EGL/egl_tls.cpp
index 41cfae1..52312a2 100644
--- a/opengl/libs/EGL/egl_tls.cpp
+++ b/opengl/libs/EGL/egl_tls.cpp
@@ -78,9 +78,7 @@
             char value[PROPERTY_VALUE_MAX];
             property_get("debug.egl.callstack", value, "0");
             if (atoi(value)) {
-                CallStack stack;
-                stack.update();
-                stack.dump();
+                CallStack stack(LOG_TAG);
             }
         }
         tls->error = error;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index eeb1fef..8599a29 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -99,7 +99,7 @@
     bool needVSyncThread = true;
 
     // Note: some devices may insist that the FB HAL be opened before HWC.
-    loadFbHalModule();
+    int fberr = loadFbHalModule();
     loadHwcModule();
 
     if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
@@ -113,7 +113,8 @@
     // If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory.
     if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
             && !mFbDev) {
-        ALOGE("ERROR: failed to open framebuffer, aborting");
+        ALOGE("ERROR: failed to open framebuffer (%s), aborting",
+                strerror(-fberr));
         abort();
     }
 
@@ -234,20 +235,17 @@
 }
 
 // Load and prepare the FB HAL, which uses the gralloc module.  Sets mFbDev.
-void HWComposer::loadFbHalModule()
+int HWComposer::loadFbHalModule()
 {
     hw_module_t const* module;
 
-    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) != 0) {
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    if (err != 0) {
         ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
-        return;
+        return err;
     }
 
-    int err = framebuffer_open(module, &mFbDev);
-    if (err) {
-        ALOGE("framebuffer_open failed (%s)", strerror(-err));
-        return;
-    }
+    return framebuffer_open(module, &mFbDev);
 }
 
 status_t HWComposer::initCheck() const {
@@ -514,6 +512,7 @@
                 &disp.framebufferTarget->displayFrame;
             disp.framebufferTarget->acquireFenceFd = -1;
             disp.framebufferTarget->releaseFenceFd = -1;
+            disp.framebufferTarget->planeAlpha = 0xFF;
         }
         disp.list->retireFenceFd = -1;
         disp.list->flags = HWC_GEOMETRY_CHANGED;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 92e4cbf..fdbd2d9 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -265,7 +265,7 @@
 
 private:
     void loadHwcModule();
-    void loadFbHalModule();
+    int loadFbHalModule();
 
     LayerListIterator getLayerIterator(int32_t id, size_t index);
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7fcbd2e..0e5d602 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -109,6 +109,9 @@
     // debugging stuff...
     char value[PROPERTY_VALUE_MAX];
 
+    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
+    mGpuToCpuSupported = !atoi(value);
+
     property_get("debug.sf.showupdates", value, "0");
     mDebugRegion = atoi(value);
 
@@ -489,6 +492,10 @@
     mEGLConfig  = selectEGLConfig(mEGLDisplay, format);
     mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
 
+    // figure out which format we got
+    eglGetConfigAttrib(mEGLDisplay, mEGLConfig,
+            EGL_NATIVE_VISUAL_ID, &mEGLNativeVisualId);
+
     LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
             "couldn't create EGLContext");
 
@@ -2328,13 +2335,18 @@
             "  transaction-flags         : %08x\n"
             "  refresh-rate              : %f fps\n"
             "  x-dpi                     : %f\n"
-            "  y-dpi                     : %f\n",
+            "  y-dpi                     : %f\n"
+            "  EGL_NATIVE_VISUAL_ID      : %d\n"
+            "  gpu_to_cpu_unsupported    : %d\n"
+            ,
             mLastSwapBufferTime/1000.0,
             mLastTransactionTime/1000.0,
             mTransactionFlags,
             1e9 / hwc.getRefreshPeriod(HWC_DISPLAY_PRIMARY),
             hwc.getDpiX(HWC_DISPLAY_PRIMARY),
-            hwc.getDpiY(HWC_DISPLAY_PRIMARY));
+            hwc.getDpiY(HWC_DISPLAY_PRIMARY),
+            mEGLNativeVisualId,
+            !mGpuToCpuSupported);
     result.append(buffer);
 
     snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
@@ -2416,7 +2428,6 @@
             break;
         }
         case CAPTURE_SCREEN:
-        case CAPTURE_SCREEN_DEPRECATED:
         {
             // codes that require permission check
             IPCThreadState* ipc = IPCThreadState::self();
@@ -2511,7 +2522,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 isCpuConsumer) {
 
     if (CC_UNLIKELY(display == 0))
         return BAD_VALUE;
@@ -2525,16 +2537,18 @@
         sp<IGraphicBufferProducer> producer;
         uint32_t reqWidth, reqHeight;
         uint32_t minLayerZ,maxLayerZ;
+        bool isCpuConsumer;
         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 isCpuConsumer)
             : flinger(flinger), display(display), producer(producer),
               reqWidth(reqWidth), reqHeight(reqHeight),
               minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
+              isCpuConsumer(isCpuConsumer),
               result(PERMISSION_DENIED)
         {
         }
@@ -2544,14 +2558,40 @@
         virtual bool handler() {
             Mutex::Autolock _l(flinger->mStateLock);
             sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
-            result = flinger->captureScreenImplLocked(hw, producer,
-                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
+
+            bool useReadPixels = false;
+            if (isCpuConsumer) {
+                bool formatSupportedBytBitmap =
+                        (flinger->mEGLNativeVisualId == HAL_PIXEL_FORMAT_RGBA_8888) ||
+                        (flinger->mEGLNativeVisualId == HAL_PIXEL_FORMAT_RGBX_8888);
+                if (formatSupportedBytBitmap == false) {
+                    // the pixel format we have is not compatible with
+                    // Bitmap.java, which is the likely client of this API,
+                    // so we just revert to glReadPixels() in that case.
+                    useReadPixels = true;
+                }
+                if (flinger->mGpuToCpuSupported == false) {
+                    // When we know the GL->CPU path works, we can call
+                    // captureScreenImplLocked() directly, instead of using the
+                    // glReadPixels() workaround.
+                    useReadPixels = true;
+                }
+            }
+
+            if (!useReadPixels) {
+                result = flinger->captureScreenImplLocked(hw,
+                        producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
+            } else {
+                result = flinger->captureScreenImplCpuConsumerLocked(hw,
+                        producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
+            }
             return true;
         }
     };
 
     sp<MessageBase> msg = new MessageCaptureScreen(this,
-            display, producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
+            display, producer, reqWidth, reqHeight, minLayerZ, maxLayerZ,
+            isCpuConsumer);
     status_t res = postMessageSync(msg);
     if (res == NO_ERROR) {
         res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
@@ -2655,18 +2695,15 @@
     }
 
     eglDestroySurface(mEGLDisplay, eglSurface);
+
     return NO_ERROR;
 }
 
-// ---------------------------------------------------------------------------
-// Capture screen into an IMemoryHeap (legacy)
-// ---------------------------------------------------------------------------
 
-status_t SurfaceFlinger::captureScreenImplLocked(
+status_t SurfaceFlinger::captureScreenImplCpuConsumerLocked(
         const sp<const DisplayDevice>& hw,
-        sp<IMemoryHeap>* heap,
-        uint32_t* w, uint32_t* h, PixelFormat* f,
-        uint32_t sw, uint32_t sh,
+        const sp<IGraphicBufferProducer>& producer,
+        uint32_t reqWidth, uint32_t reqHeight,
         uint32_t minLayerZ, uint32_t maxLayerZ)
 {
     ATRACE_CALL();
@@ -2689,7 +2726,7 @@
 
     // call the new screenshot taking code, passing a BufferQueue to it
     status_t result = captureScreenImplLocked(hw,
-            consumer->getBufferQueue(), sw, sh, minLayerZ, maxLayerZ);
+            consumer->getBufferQueue(), reqWidth, reqHeight, minLayerZ, maxLayerZ);
 
     if (result == NO_ERROR) {
         result = consumer->updateTexImage();
@@ -2701,31 +2738,64 @@
             glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
                     GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
 
-            sp<GraphicBuffer> buf(consumer->getCurrentBuffer());
-            sw = buf->getWidth();
-            sh = buf->getHeight();
-            size_t size = sw * sh * 4;
+            reqWidth = consumer->getCurrentBuffer()->getWidth();
+            reqHeight = consumer->getCurrentBuffer()->getHeight();
 
-            // allocate shared memory large enough to hold the
-            // screen capture
-            sp<MemoryHeapBase> base(
-                    new MemoryHeapBase(size, 0, "screen-capture") );
-            void* const ptr = base->getBase();
-            if (ptr != MAP_FAILED) {
-                // capture the screen with glReadPixels()
-                ScopedTrace _t(ATRACE_TAG, "glReadPixels");
-                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
-                if (glGetError() == GL_NO_ERROR) {
-                    *heap = base;
-                    *w = sw;
-                    *h = sh;
-                    *f = PIXEL_FORMAT_RGBA_8888;
-                    result = NO_ERROR;
-                } else {
-                    result = NO_MEMORY;
+            {
+                // in this block we render the screenshot into the
+                // CpuConsumer using glReadPixels from our GLConsumer,
+                // Some older drivers don't support the GL->CPU path so
+                // have to wrap it with a CPU->CPU path, which is what
+                // glReadPixels essentially is
+
+                sp<Surface> sur = new Surface(producer);
+                ANativeWindow* window = sur.get();
+                ANativeWindowBuffer* buffer;
+                void* vaddr;
+
+                if (native_window_api_connect(window,
+                        NATIVE_WINDOW_API_CPU) == NO_ERROR) {
+                    int err = 0;
+                    err = native_window_set_buffers_dimensions(window,
+                            reqWidth, reqHeight);
+                    err |= native_window_set_buffers_format(window,
+                            HAL_PIXEL_FORMAT_RGBA_8888);
+                    err |= native_window_set_usage(window,
+                            GRALLOC_USAGE_SW_READ_OFTEN |
+                            GRALLOC_USAGE_SW_WRITE_OFTEN);
+
+                    if (err == NO_ERROR) {
+                        if (native_window_dequeue_buffer_and_wait(window,
+                                &buffer) == NO_ERROR) {
+                            sp<GraphicBuffer> buf =
+                                    static_cast<GraphicBuffer*>(buffer);
+                            if (buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN,
+                                    &vaddr) == NO_ERROR) {
+                                if (buffer->stride != int(reqWidth)) {
+                                    // we're unlucky here, glReadPixels is
+                                    // not able to deal with a stride not
+                                    // equal to the width.
+                                    uint32_t* tmp = new uint32_t[reqWidth*reqHeight];
+                                    if (tmp != NULL) {
+                                        glReadPixels(0, 0, reqWidth, reqHeight,
+                                                GL_RGBA, GL_UNSIGNED_BYTE, tmp);
+                                        for (size_t y=0 ; y<reqHeight ; y++) {
+                                            memcpy((uint32_t*)vaddr + y*buffer->stride,
+                                                    tmp + y*reqWidth, reqWidth*4);
+                                        }
+                                        delete [] tmp;
+                                    }
+                                } else {
+                                    glReadPixels(0, 0, reqWidth, reqHeight,
+                                            GL_RGBA, GL_UNSIGNED_BYTE, vaddr);
+                                }
+                                buf->unlock();
+                            }
+                            window->queueBuffer(window, buffer, -1);
+                        }
+                    }
+                    native_window_api_disconnect(window, NATIVE_WINDOW_API_CPU);
                 }
-            } else {
-                result = NO_MEMORY;
             }
 
             // back to main framebuffer
@@ -2742,63 +2812,6 @@
     return result;
 }
 
-status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
-        sp<IMemoryHeap>* heap,
-        uint32_t* outWidth, uint32_t* outHeight, PixelFormat* outFormat,
-        uint32_t reqWidth, uint32_t reqHeight,
-        uint32_t minLayerZ, uint32_t maxLayerZ)
-{
-    if (CC_UNLIKELY(display == 0))
-        return BAD_VALUE;
-
-    class MessageCaptureScreen : public MessageBase {
-        SurfaceFlinger* flinger;
-        sp<IBinder> display;
-        sp<IMemoryHeap>* heap;
-        uint32_t* outWidth;
-        uint32_t* outHeight;
-        PixelFormat* outFormat;
-        uint32_t reqWidth;
-        uint32_t reqHeight;
-        uint32_t minLayerZ;
-        uint32_t maxLayerZ;
-        status_t result;
-    public:
-        MessageCaptureScreen(SurfaceFlinger* flinger,
-                const sp<IBinder>& display, sp<IMemoryHeap>* heap,
-                uint32_t* outWidth, uint32_t* outHeight, PixelFormat* outFormat,
-                uint32_t reqWidth, uint32_t reqHeight,
-                uint32_t minLayerZ, uint32_t maxLayerZ)
-            : flinger(flinger), display(display), heap(heap),
-              outWidth(outWidth), outHeight(outHeight), outFormat(outFormat),
-              reqWidth(reqWidth), reqHeight(reqHeight),
-              minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
-              result(PERMISSION_DENIED)
-        {
-        }
-        status_t getResult() const {
-            return result;
-        }
-        virtual bool handler() {
-            Mutex::Autolock _l(flinger->mStateLock);
-            sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
-            result = flinger->captureScreenImplLocked(hw, heap,
-                    outWidth, outHeight, outFormat,
-                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
-            return true;
-        }
-    };
-
-    sp<MessageBase> msg = new MessageCaptureScreen(this, display, heap,
-            outWidth, outHeight, outFormat,
-            reqWidth, reqHeight, minLayerZ, maxLayerZ);
-    status_t res = postMessageSync(msg);
-    if (res == NO_ERROR) {
-        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
-    }
-    return res;
-}
-
 // ---------------------------------------------------------------------------
 
 SurfaceFlinger::LayerVector::LayerVector() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e6734d2..1017560 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -185,14 +185,10 @@
     virtual bool authenticateSurfaceTexture(
         const sp<IGraphicBufferProducer>& bufferProducer) const;
     virtual sp<IDisplayEventConnection> createDisplayEventConnection();
-    virtual status_t captureScreen(const sp<IBinder>& display, sp<IMemoryHeap>* heap,
-        uint32_t* width, uint32_t* height, PixelFormat* format,
-        uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
-        uint32_t maxLayerZ);
     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 isCpuConsumer);
     // called when screen needs to turn off
     virtual void blank(const sp<IBinder>& display);
     // called when screen is turning back on
@@ -297,17 +293,17 @@
 
     status_t captureScreenImplLocked(
             const sp<const DisplayDevice>& hw,
-            sp<IMemoryHeap>* heap,
-            uint32_t* width, uint32_t* height, PixelFormat* format,
-            uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
-            uint32_t maxLayerZ);
+            const sp<IGraphicBufferProducer>& producer,
+            uint32_t reqWidth, uint32_t reqHeight,
+            uint32_t minLayerZ, uint32_t maxLayerZ);
 
-    status_t captureScreenImplLocked(
+    status_t captureScreenImplCpuConsumerLocked(
             const sp<const DisplayDevice>& hw,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
             uint32_t minLayerZ, uint32_t maxLayerZ);
 
+
     /* ------------------------------------------------------------------------
      * EGL
      */
@@ -416,12 +412,14 @@
     HWComposer* mHwc;
     GLuint mProtectedTexName;
     nsecs_t mBootTime;
+    bool mGpuToCpuSupported;
     sp<EventThread> mEventThread;
     GLint mMaxViewportDims[2];
     GLint mMaxTextureSize;
     EGLContext mEGLContext;
     EGLConfig mEGLConfig;
     EGLDisplay mEGLDisplay;
+    EGLint mEGLNativeVisualId;
     sp<IBinder> mBuiltinDisplays[DisplayDevice::NUM_DISPLAY_TYPES];
 
     // Can only accessed from the main thread, these members