Merge "Add EGL_KHR_get_all_proc_addresses to extension string"
diff --git a/include/gui/BufferItemConsumer.h b/include/gui/BufferItemConsumer.h
index 9370e81..52edf17 100644
--- a/include/gui/BufferItemConsumer.h
+++ b/include/gui/BufferItemConsumer.h
@@ -87,8 +87,6 @@
     status_t releaseBuffer(const BufferItem &item,
             const sp<Fence>& releaseFence = Fence::NO_FENCE);
 
-    sp<IGraphicBufferProducer> getProducerInterface() const { return getBufferQueue(); }
-
     // setDefaultBufferSize is used to set the size of buffers returned by
     // requestBuffers when a with and height of zero is requested.
     status_t setDefaultBufferSize(uint32_t w, uint32_t h);
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 1fbfc2b..7e404fe 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -78,10 +78,6 @@
     BufferQueue(const sp<IGraphicBufferAlloc>& allocator = NULL);
     virtual ~BufferQueue();
 
-    // dump our state in a String
-    virtual void dump(String8& result) const;
-    virtual void dump(String8& result, const char* prefix) const;
-
     /*
      * IGraphicBufferProducer interface
      */
@@ -302,6 +298,9 @@
     // NATIVE_WINDOW_TRANSFORM_ROT_90.  The default is 0 (no transform).
     virtual status_t setTransformHint(uint32_t hint);
 
+    // dump our state in a String
+    virtual void dump(String8& result, const char* prefix) const;
+
 
 private:
     // freeBufferLocked frees the GraphicBuffer and sync resources for the
diff --git a/include/gui/ConsumerBase.h b/include/gui/ConsumerBase.h
index daad757..fb21185 100644
--- a/include/gui/ConsumerBase.h
+++ b/include/gui/ConsumerBase.h
@@ -66,10 +66,6 @@
     // log messages.
     void setName(const String8& name);
 
-    // getBufferQueue returns the BufferQueue object to which this
-    // ConsumerBase is connected.
-    sp<BufferQueue> getBufferQueue() const;
-
     // dump writes the current state to a string. Child classes should add
     // their state to the dump by overriding the dumpLocked method, which is
     // called by these methods after locking the mutex.
@@ -85,12 +81,11 @@
     void operator=(const ConsumerBase&);
 
 protected:
-
     // ConsumerBase constructs a new ConsumerBase object to consume image
-    // buffers from the given BufferQueue.
+    // buffers from the given IGraphicBufferConsumer.
     // The controlledByApp flag indicates that this consumer is under the application's
     // control.
-    ConsumerBase(const sp<BufferQueue> &bufferQueue, bool controlledByApp = false);
+    ConsumerBase(const sp<IGraphicBufferConsumer>& consumer, bool controlledByApp = false);
 
     // onLastStrongRef gets called by RefBase just before the dtor of the most
     // derived class.  It is used to clean up the buffers so that ConsumerBase
@@ -104,7 +99,7 @@
     // from the derived class.
     virtual void onLastStrongRef(const void* id);
 
-    // Implementation of the BufferQueue::ConsumerListener interface.  These
+    // Implementation of the IConsumerListener interface.  These
     // calls are used to notify the ConsumerBase of asynchronous events in the
     // BufferQueue.  These methods should not need to be overridden by derived
     // classes, but if they are overridden the ConsumerBase implementation
@@ -155,7 +150,7 @@
     // initialization that must take place the first time a buffer is assigned
     // to a slot.  If it is overridden the derived class's implementation must
     // call ConsumerBase::acquireBufferLocked.
-    virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item,
+    virtual status_t acquireBufferLocked(IGraphicBufferConsumer::BufferItem *item,
         nsecs_t presentWhen);
 
     // releaseBufferLocked relinquishes control over a buffer, returning that
@@ -226,7 +221,7 @@
 
     // The ConsumerBase has-a BufferQueue and is responsible for creating this object
     // if none is supplied
-    sp<BufferQueue> mBufferQueue;
+    sp<IGraphicBufferConsumer> mConsumer;
 
     // mMutex is the mutex used to prevent concurrent access to the member
     // variables of ConsumerBase objects. It must be locked whenever the
diff --git a/include/gui/CpuConsumer.h b/include/gui/CpuConsumer.h
index 2890350..9290676 100644
--- a/include/gui/CpuConsumer.h
+++ b/include/gui/CpuConsumer.h
@@ -66,7 +66,7 @@
 
     // Create a new CPU consumer. The maxLockedBuffers parameter specifies
     // how many buffers can be locked for user access at the same time.
-    CpuConsumer(const sp<BufferQueue>& bq,
+    CpuConsumer(const sp<IGraphicBufferConsumer>& bq,
             uint32_t maxLockedBuffers, bool controlledByApp = false);
 
     virtual ~CpuConsumer();
@@ -104,8 +104,6 @@
     // lockNextBuffer.
     status_t unlockBuffer(const LockedBuffer &nativeBuffer);
 
-    sp<IGraphicBufferProducer> getProducerInterface() const { return getBufferQueue(); }
-
   private:
     // Maximum number of buffers that can be locked at a time
     uint32_t mMaxLockedBuffers;
diff --git a/include/gui/GLConsumer.h b/include/gui/GLConsumer.h
index ac4a832..4c9aa87 100644
--- a/include/gui/GLConsumer.h
+++ b/include/gui/GLConsumer.h
@@ -32,10 +32,6 @@
 #include <utils/Vector.h>
 #include <utils/threads.h>
 
-#define ANDROID_GRAPHICS_SURFACETEXTURE_JNI_ID "mSurfaceTexture"
-#define ANDROID_GRAPHICS_FRAMEAVAILABLELISTENER_JNI_ID \
-                                         "mFrameAvailableListener"
-
 namespace android {
 // ----------------------------------------------------------------------------
 
@@ -85,7 +81,7 @@
     // purely to allow a GLConsumer to be transferred from one consumer
     // context to another. If such a transfer is not needed there is no
     // requirement that either of these methods be called.
-    GLConsumer(const sp<BufferQueue>& bq,
+    GLConsumer(const sp<IGraphicBufferConsumer>& bq,
             GLuint tex, GLenum texTarget = GL_TEXTURE_EXTERNAL_OES,
             bool useFenceSync = true, bool isControlledByApp = false);
 
@@ -194,12 +190,6 @@
     status_t setConsumerUsageBits(uint32_t usage);
     status_t setTransformHint(uint32_t hint);
 
-    // getBufferQueue returns the BufferQueue object to which this
-    // GLConsumer is connected.
-    sp<BufferQueue> getBufferQueue() const {
-        return mBufferQueue;
-    }
-
     // detachFromContext detaches the GLConsumer from the calling thread's
     // current OpenGL ES context.  This context must be the same as the context
     // that was current for previous calls to updateTexImage.
diff --git a/include/gui/IGraphicBufferConsumer.h b/include/gui/IGraphicBufferConsumer.h
index 82b50c8..2ad302f 100644
--- a/include/gui/IGraphicBufferConsumer.h
+++ b/include/gui/IGraphicBufferConsumer.h
@@ -188,6 +188,9 @@
     // NATIVE_WINDOW_TRANSFORM_ROT_90.  The default is 0 (no transform).
     virtual status_t setTransformHint(uint32_t hint) = 0;
 
+    // dump state into a string
+    virtual void dump(String8& result, const char* prefix) const = 0;
+
 public:
     DECLARE_META_INTERFACE(GraphicBufferConsumer);
 };
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 9018b87..0606aff 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -115,8 +115,7 @@
     virtual status_t captureScreen(const sp<IBinder>& display,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ,
-            bool isCpuConsumer) = 0;
+            uint32_t minLayerZ, uint32_t maxLayerZ) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 6bf5b47..643d7cf 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -165,6 +165,7 @@
 
 private:
     mutable sp<CpuConsumer> mCpuConsumer;
+    mutable sp<BufferQueue> mBufferQueue;
     CpuConsumer::LockedBuffer mBuffer;
     bool mHaveBuffer;
 
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index 0f818b7..350887a 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -33,8 +33,8 @@
         uint32_t consumerUsage, int bufferCount, bool controlledByApp) :
     ConsumerBase(bq, controlledByApp)
 {
-    mBufferQueue->setConsumerUsageBits(consumerUsage);
-    mBufferQueue->setMaxAcquiredBufferCount(bufferCount);
+    mConsumer->setConsumerUsageBits(consumerUsage);
+    mConsumer->setMaxAcquiredBufferCount(bufferCount);
 }
 
 BufferItemConsumer::~BufferItemConsumer() {
@@ -43,7 +43,7 @@
 void BufferItemConsumer::setName(const String8& name) {
     Mutex::Autolock _l(mMutex);
     mName = name;
-    mBufferQueue->setConsumerName(name);
+    mConsumer->setConsumerName(name);
 }
 
 status_t BufferItemConsumer::acquireBuffer(BufferItem *item,
@@ -95,12 +95,12 @@
 
 status_t BufferItemConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) {
     Mutex::Autolock _l(mMutex);
-    return mBufferQueue->setDefaultBufferSize(w, h);
+    return mConsumer->setDefaultBufferSize(w, h);
 }
 
 status_t BufferItemConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
     Mutex::Autolock _l(mMutex);
-    return mBufferQueue->setDefaultBufferFormat(defaultFormat);
+    return mConsumer->setDefaultBufferFormat(defaultFormat);
 }
 
 } // namespace android
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 07c2d94..033c2a6 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -720,10 +720,6 @@
     return err;
 }
 
-void BufferQueue::dump(String8& result) const {
-    BufferQueue::dump(result, "");
-}
-
 void BufferQueue::dump(String8& result, const char* prefix) const {
     Mutex::Autolock _l(mMutex);
 
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index d748786..c4ec857 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -51,9 +51,9 @@
     return android_atomic_inc(&globalCounter);
 }
 
-ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue, bool controlledByApp) :
+ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
         mAbandoned(false),
-        mBufferQueue(bufferQueue) {
+        mConsumer(bufferQueue) {
     // Choose a name using the PID and a process-unique ID.
     mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
 
@@ -64,12 +64,12 @@
     wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
     sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
 
-    status_t err = mBufferQueue->consumerConnect(proxy, controlledByApp);
+    status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
     if (err != NO_ERROR) {
         CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
                 strerror(-err), err);
     } else {
-        mBufferQueue->setConsumerName(mName);
+        mConsumer->setConsumerName(mName);
     }
 }
 
@@ -96,12 +96,6 @@
     mSlots[slotIndex].mFrameNumber = 0;
 }
 
-// Used for refactoring, should not be in final interface
-sp<BufferQueue> ConsumerBase::getBufferQueue() const {
-    Mutex::Autolock lock(mMutex);
-    return mBufferQueue;
-}
-
 void ConsumerBase::onFrameAvailable() {
     CB_LOGV("onFrameAvailable");
 
@@ -128,7 +122,7 @@
     }
 
     uint32_t mask = 0;
-    mBufferQueue->getReleasedBuffers(&mask);
+    mConsumer->getReleasedBuffers(&mask);
     for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
         if (mask & (1 << i)) {
             freeBufferLocked(i);
@@ -152,8 +146,8 @@
         freeBufferLocked(i);
     }
     // disconnect from the BufferQueue
-    mBufferQueue->consumerDisconnect();
-    mBufferQueue.clear();
+    mConsumer->consumerDisconnect();
+    mConsumer.clear();
 }
 
 void ConsumerBase::setFrameAvailableListener(
@@ -176,13 +170,13 @@
     result.appendFormat("%smAbandoned=%d\n", prefix, int(mAbandoned));
 
     if (!mAbandoned) {
-        mBufferQueue->dump(result, prefix);
+        mConsumer->dump(result, prefix);
     }
 }
 
 status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item,
         nsecs_t presentWhen) {
-    status_t err = mBufferQueue->acquireBuffer(item, presentWhen);
+    status_t err = mConsumer->acquireBuffer(item, presentWhen);
     if (err != NO_ERROR) {
         return err;
     }
@@ -247,7 +241,7 @@
 
     CB_LOGV("releaseBufferLocked: slot=%d/%llu",
             slot, mSlots[slot].mFrameNumber);
-    status_t err = mBufferQueue->releaseBuffer(slot, mSlots[slot].mFrameNumber,
+    status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber,
             display, eglFence, mSlots[slot].mFence);
     if (err == BufferQueue::STALE_BUFFER_SLOT) {
         freeBufferLocked(slot);
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index b8c00af..3db46bc 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -30,7 +30,7 @@
 
 namespace android {
 
-CpuConsumer::CpuConsumer(const sp<BufferQueue>& bq,
+CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq,
         uint32_t maxLockedBuffers, bool controlledByApp) :
     ConsumerBase(bq, controlledByApp),
     mMaxLockedBuffers(maxLockedBuffers),
@@ -39,8 +39,8 @@
     // Create tracking entries for locked buffers
     mAcquiredBuffers.insertAt(0, maxLockedBuffers);
 
-    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
-    mBufferQueue->setMaxAcquiredBufferCount(maxLockedBuffers);
+    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
+    mConsumer->setMaxAcquiredBufferCount(maxLockedBuffers);
 }
 
 CpuConsumer::~CpuConsumer() {
@@ -52,19 +52,19 @@
 void CpuConsumer::setName(const String8& name) {
     Mutex::Autolock _l(mMutex);
     mName = name;
-    mBufferQueue->setConsumerName(name);
+    mConsumer->setConsumerName(name);
 }
 
 status_t CpuConsumer::setDefaultBufferSize(uint32_t width, uint32_t height)
 {
     Mutex::Autolock _l(mMutex);
-    return mBufferQueue->setDefaultBufferSize(width, height);
+    return mConsumer->setDefaultBufferSize(width, height);
 }
 
 status_t CpuConsumer::setDefaultBufferFormat(uint32_t defaultFormat)
 {
     Mutex::Autolock _l(mMutex);
-    return mBufferQueue->setDefaultBufferFormat(defaultFormat);
+    return mConsumer->setDefaultBufferFormat(defaultFormat);
 }
 
 status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index b8a3d28..363e25a 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -85,7 +85,7 @@
 static void mtxMul(float out[16], const float a[16], const float b[16]);
 
 
-GLConsumer::GLConsumer(const sp<BufferQueue>& bq, GLuint tex,
+GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, GLuint tex,
         GLenum texTarget, bool useFenceSync, bool isControlledByApp) :
     ConsumerBase(bq, isControlledByApp),
     mCurrentTransform(0),
@@ -108,12 +108,12 @@
     memcpy(mCurrentTransformMatrix, mtxIdentity,
             sizeof(mCurrentTransformMatrix));
 
-    mBufferQueue->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
+    mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
 }
 
 status_t GLConsumer::setDefaultMaxBufferCount(int bufferCount) {
     Mutex::Autolock lock(mMutex);
-    return mBufferQueue->setDefaultMaxBufferCount(bufferCount);
+    return mConsumer->setDefaultMaxBufferCount(bufferCount);
 }
 
 
@@ -122,7 +122,7 @@
     Mutex::Autolock lock(mMutex);
     mDefaultWidth = w;
     mDefaultHeight = h;
-    return mBufferQueue->setDefaultBufferSize(w, h);
+    return mConsumer->setDefaultBufferSize(w, h);
 }
 
 status_t GLConsumer::updateTexImage() {
@@ -946,23 +946,23 @@
 void GLConsumer::setName(const String8& name) {
     Mutex::Autolock _l(mMutex);
     mName = name;
-    mBufferQueue->setConsumerName(name);
+    mConsumer->setConsumerName(name);
 }
 
 status_t GLConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
     Mutex::Autolock lock(mMutex);
-    return mBufferQueue->setDefaultBufferFormat(defaultFormat);
+    return mConsumer->setDefaultBufferFormat(defaultFormat);
 }
 
 status_t GLConsumer::setConsumerUsageBits(uint32_t usage) {
     Mutex::Autolock lock(mMutex);
     usage |= DEFAULT_USAGE_FLAGS;
-    return mBufferQueue->setConsumerUsageBits(usage);
+    return mConsumer->setConsumerUsageBits(usage);
 }
 
 status_t GLConsumer::setTransformHint(uint32_t hint) {
     Mutex::Autolock lock(mMutex);
-    return mBufferQueue->setTransformHint(hint);
+    return mConsumer->setTransformHint(hint);
 }
 
 void GLConsumer::dumpLocked(String8& result, const char* prefix) const
diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp
index 5263281..6d65016 100644
--- a/libs/gui/IGraphicBufferConsumer.cpp
+++ b/libs/gui/IGraphicBufferConsumer.cpp
@@ -186,7 +186,8 @@
     SET_CONSUMER_NAME,
     SET_DEFAULT_BUFFER_FORMAT,
     SET_CONSUMER_USAGE_BITS,
-    SET_TRANSFORM_HINT
+    SET_TRANSFORM_HINT,
+    DUMP,
 };
 
 
@@ -344,6 +345,15 @@
         }
         return reply.readInt32();
     }
+
+    virtual void dump(String8& result, const char* prefix) const {
+        Parcel data, reply;
+        data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
+        data.writeString8(result);
+        data.writeString8(String8(prefix ? prefix : ""));
+        remote()->transact(DUMP, data, &reply);
+        reply.readString8();
+    }
 };
 
 IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
@@ -452,6 +462,14 @@
             reply->writeInt32(result);
             return NO_ERROR;
         } break;
+        case DUMP: {
+            CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
+            String8 result = data.readString8();
+            String8 prefix = data.readString8();
+            static_cast<IGraphicBufferConsumer*>(this)->dump(result, prefix);
+            reply->writeString8(result);
+            return NO_ERROR;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 6442a86..a9217ca 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -105,8 +105,7 @@
     virtual status_t captureScreen(const sp<IBinder>& display,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ,
-            bool isCpuConsumer)
+            uint32_t minLayerZ, uint32_t maxLayerZ)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -116,7 +115,6 @@
         data.writeInt32(reqHeight);
         data.writeInt32(minLayerZ);
         data.writeInt32(maxLayerZ);
-        data.writeInt32(isCpuConsumer);
         remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
         return reply.readInt32();
     }
@@ -275,10 +273,8 @@
             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,
-                    isCpuConsumer);
+                    reqWidth, reqHeight, minLayerZ, maxLayerZ);
             reply->writeInt32(res);
         } break;
         case AUTHENTICATE_SURFACE: {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index bad4138..e067479 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -618,8 +618,7 @@
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == NULL) return NO_INIT;
     return s->captureScreen(display, producer,
-            reqWidth, reqHeight, minLayerZ, maxLayerZ,
-            false);
+            reqWidth, reqHeight, minLayerZ, maxLayerZ);
 }
 
 ScreenshotClient::ScreenshotClient()
@@ -633,8 +632,8 @@
 
 sp<CpuConsumer> ScreenshotClient::getCpuConsumer() const {
     if (mCpuConsumer == NULL) {
-        sp<BufferQueue> bq = new BufferQueue();
-        mCpuConsumer = new CpuConsumer(bq, 1);
+        mBufferQueue = new BufferQueue();
+        mCpuConsumer = new CpuConsumer(mBufferQueue, 1);
         mCpuConsumer->setName(String8("ScreenshotClient"));
     }
     return mCpuConsumer;
@@ -653,8 +652,8 @@
         mHaveBuffer = false;
     }
 
-    status_t err = s->captureScreen(display, cpuConsumer->getBufferQueue(),
-            reqWidth, reqHeight, minLayerZ, maxLayerZ, true);
+    status_t err = s->captureScreen(display, mBufferQueue,
+            reqWidth, reqHeight, minLayerZ, maxLayerZ);
 
     if (err == NO_ERROR) {
         err = mCpuConsumer->lockNextBuffer(&mBuffer);
diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp
index f8a35b4..afbc026 100644
--- a/libs/gui/tests/CpuConsumer_test.cpp
+++ b/libs/gui/tests/CpuConsumer_test.cpp
@@ -70,7 +70,7 @@
         mCC = new CpuConsumer(bq, params.maxLockedBuffers);
         String8 name("CpuConsumer_Under_Test");
         mCC->setName(name);
-        mSTC = new Surface(mCC->getProducerInterface());
+        mSTC = new Surface(bq);
         mANW = mSTC;
     }
 
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 1de9c27..459b001 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -42,7 +42,7 @@
 
         sp<BufferQueue> bq = new BufferQueue();
         mST = new GLConsumer(bq, 123);
-        mSTC = new Surface(mST->getBufferQueue());
+        mSTC = new Surface(bq);
         mANW = mSTC;
 
         // We need a valid GL context so we can test updateTexImage()
@@ -710,7 +710,7 @@
         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
             sp<BufferQueue> bq = new BufferQueue();
             sp<GLConsumer> st(new GLConsumer(bq, i));
-            sp<Surface> stc(new Surface(st->getBufferQueue()));
+            sp<Surface> stc(new Surface(bq));
             mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
                     static_cast<ANativeWindow*>(stc.get()), NULL);
             ASSERT_EQ(EGL_SUCCESS, eglGetError());
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index ae223c6..05b0b67 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -387,7 +387,7 @@
         GLTest::SetUp();
         sp<BufferQueue> bq = new BufferQueue();
         mGlConsumer = new GLConsumer(bq, TEX_ID);
-        mSurface = new Surface(mGlConsumer->getBufferQueue());
+        mSurface = new Surface(bq);
         mANW = mSurface.get();
 
     }
@@ -481,8 +481,9 @@
     virtual void SetUp() {
         GLTest::SetUp();
         sp<BufferQueue> bq = new BufferQueue();
+        mBQ = bq;
         mST = new GLConsumer(bq, TEX_ID);
-        mSTC = new Surface(mST->getBufferQueue());
+        mSTC = new Surface(bq);
         mANW = mSTC;
         mTextureRenderer = new TextureRenderer(TEX_ID, mST);
         ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp());
@@ -672,6 +673,7 @@
         Condition mFrameCondition;
     };
 
+    sp<BufferQueue> mBQ;
     sp<GLConsumer> mST;
     sp<Surface> mSTC;
     sp<ANativeWindow> mANW;
@@ -1211,7 +1213,7 @@
     };
 
     sp<DisconnectWaiter> dw(new DisconnectWaiter());
-    mST->getBufferQueue()->consumerConnect(dw, false);
+    mBQ->consumerConnect(dw, false);
 
 
     sp<Thread> pt(new ProducerThread(mANW));
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index bcdbedb..e0272ba 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -92,8 +92,8 @@
     sp<CpuConsumer> consumer = new CpuConsumer(bq, 1);
     sp<ISurfaceComposer> sf(ComposerService::getComposerService());
     sp<IBinder> display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, consumer->getBufferQueue(),
-            64, 64, 0, 0x7fffffff, true));
+    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, bq,
+            64, 64, 0, 0x7fffffff));
 
     // 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
@@ -121,8 +121,8 @@
                 &buf));
         ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
     }
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, consumer->getBufferQueue(),
-            64, 64, 0, 0x7fffffff, true));
+    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, bq,
+            64, 64, 0, 0x7fffffff));
 }
 
 TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
@@ -139,7 +139,7 @@
     sp<BufferQueue> bq = new BufferQueue();
     sp<BufferItemConsumer> c = new BufferItemConsumer(bq,
             TEST_USAGE_FLAGS);
-    sp<Surface> s = new Surface(c->getProducerInterface());
+    sp<Surface> s = new Surface(bq);
 
     sp<ANativeWindow> anw(s);
 
diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp
index 906cd80..0cfd886 100644
--- a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp
+++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp
@@ -90,7 +90,7 @@
     jint _remaining;
     EGLint *attrib_list = (EGLint *) 0;
     android::sp<ANativeWindow> window;
-    android::sp<android::GLConsumer> glConsumer;
+    android::sp<android::IGraphicBufferProducer> producer;
 
     if (!attrib_list_ref) {
         _exception = 1;
@@ -111,12 +111,12 @@
         _exceptionMessage = "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface";
         goto exit;
     }
-    glConsumer = android::SurfaceTexture_getSurfaceTexture(_env, win);
+    producer = android::SurfaceTexture_getProducer(_env, win);
 
-    if (glConsumer == NULL)
+    if (producer == NULL)
         goto not_valid_surface;
 
-    window = new android::Surface(glConsumer->getBufferQueue());
+    window = new android::Surface(producer);
 
     if (window == NULL)
         goto not_valid_surface;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index c67f4d8..8143227 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -56,6 +56,7 @@
         bool isSecure,
         const wp<IBinder>& displayToken,
         const sp<DisplaySurface>& displaySurface,
+        const sp<IGraphicBufferProducer>& producer,
         EGLConfig config)
     : mFlinger(flinger),
       mType(type), mHwcDisplayId(hwcId),
@@ -63,7 +64,6 @@
       mDisplaySurface(displaySurface),
       mDisplay(EGL_NO_DISPLAY),
       mSurface(EGL_NO_SURFACE),
-      mContext(EGL_NO_CONTEXT),
       mDisplayWidth(), mDisplayHeight(), mFormat(),
       mFlags(),
       mPageFlipCount(),
@@ -73,12 +73,22 @@
       mLayerStack(NO_LAYER_STACK),
       mOrientation()
 {
-    mNativeWindow = new Surface(mDisplaySurface->getIGraphicBufferProducer());
+    mNativeWindow = new Surface(producer);
     ANativeWindow* const window = mNativeWindow.get();
 
     int format;
     window->query(window, NATIVE_WINDOW_FORMAT, &format);
 
+    // Make sure that composition can never be stalled by a virtual display
+    // consumer that isn't processing buffers fast enough. We have to do this
+    // in two places:
+    // * Here, in case the display is composed entirely by HWC.
+    // * In makeCurrent(), using eglSwapInterval. Some EGL drivers set the
+    //   window's swap interval in eglMakeCurrent, so they'll override the
+    //   interval we set here.
+    if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
+        window->setSwapInterval(window, 0);
+
     /*
      * Create our display's surface
      */
@@ -253,6 +263,8 @@
     if (sur != mSurface) {
         result = eglMakeCurrent(dpy, mSurface, mSurface, ctx);
         if (result == EGL_TRUE) {
+            if (mType >= DisplayDevice::DISPLAY_VIRTUAL)
+                eglSwapInterval(dpy, 0);
             setViewportAndProjection();
         }
     }
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 748be1a..6f0ce88 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -76,6 +76,7 @@
             bool isSecure,
             const wp<IBinder>& displayToken,
             const sp<DisplaySurface>& displaySurface,
+            const sp<IGraphicBufferProducer>& producer,
             EGLConfig config);
 
     ~DisplayDevice();
@@ -170,7 +171,6 @@
 
     EGLDisplay      mDisplay;
     EGLSurface      mSurface;
-    EGLContext      mContext;
     int             mDisplayWidth;
     int             mDisplayHeight;
     PixelFormat     mFormat;
diff --git a/services/surfaceflinger/DisplayHardware/DisplaySurface.h b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
index b0f460d..9192db5 100644
--- a/services/surfaceflinger/DisplayHardware/DisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/DisplaySurface.h
@@ -30,8 +30,6 @@
 
 class DisplaySurface : public virtual RefBase {
 public:
-    virtual sp<IGraphicBufferProducer> getIGraphicBufferProducer() const = 0;
-
     // prepareFrame is called after the composition configuration is known but
     // before composition takes place. The DisplaySurface can use the
     // composition type to decide how to manage the flow of buffers between
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 419b81c..807d4e1 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -50,25 +50,22 @@
  *
  */
 
-FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp) :
-    ConsumerBase(new BufferQueue(new GraphicBufferAlloc())),
+FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp,
+        const sp<IGraphicBufferConsumer>& consumer) :
+    ConsumerBase(consumer),
     mDisplayType(disp),
     mCurrentBufferSlot(-1),
     mCurrentBuffer(0),
     mHwc(hwc)
 {
     mName = "FramebufferSurface";
-    mBufferQueue->setConsumerName(mName);
-    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
+    mConsumer->setConsumerName(mName);
+    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
                                        GRALLOC_USAGE_HW_RENDER |
                                        GRALLOC_USAGE_HW_COMPOSER);
-    mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(disp));
-    mBufferQueue->setDefaultBufferSize(mHwc.getWidth(disp),  mHwc.getHeight(disp));
-    mBufferQueue->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
-}
-
-sp<IGraphicBufferProducer> FramebufferSurface::getIGraphicBufferProducer() const {
-    return getBufferQueue();
+    mConsumer->setDefaultBufferFormat(mHwc.getFormat(disp));
+    mConsumer->setDefaultBufferSize(mHwc.getWidth(disp),  mHwc.getHeight(disp));
+    mConsumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
 }
 
 status_t FramebufferSurface::prepareFrame(CompositionType compositionType) {
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 92a7f9b..fcda287 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -37,9 +37,7 @@
 class FramebufferSurface : public ConsumerBase,
                            public DisplaySurface {
 public:
-    FramebufferSurface(HWComposer& hwc, int disp);
-
-    virtual sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;
+    FramebufferSurface(HWComposer& hwc, int disp, const sp<IGraphicBufferConsumer>& consumer);
 
     virtual status_t prepareFrame(CompositionType compositionType);
     virtual status_t compositionComplete();
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 57cb361..30b0084 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -40,8 +40,10 @@
 }
 
 VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
-        const sp<IGraphicBufferProducer>& sink, const String8& name)
-:   ConsumerBase(new BufferQueue()),
+        const sp<IGraphicBufferProducer>& sink,
+        const sp<BufferQueue>& bq,
+        const String8& name)
+:   ConsumerBase(bq),
     mHwc(hwc),
     mDisplayId(dispId),
     mDisplayName(name),
@@ -51,7 +53,7 @@
     mDbgLastCompositionType(COMPOSITION_UNKNOWN)
 {
     mSource[SOURCE_SINK] = sink;
-    mSource[SOURCE_SCRATCH] = mBufferQueue;
+    mSource[SOURCE_SCRATCH] = bq;
 
     resetPerFrameState();
 
@@ -60,26 +62,15 @@
     mSource[SOURCE_SINK]->query(NATIVE_WINDOW_HEIGHT, &sinkHeight);
 
     ConsumerBase::mName = String8::format("VDS: %s", mDisplayName.string());
-    mBufferQueue->setConsumerName(ConsumerBase::mName);
-    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
-    mBufferQueue->setDefaultBufferSize(sinkWidth, sinkHeight);
-    mBufferQueue->setDefaultMaxBufferCount(2);
+    mConsumer->setConsumerName(ConsumerBase::mName);
+    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER);
+    mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight);
+    mConsumer->setDefaultMaxBufferCount(2);
 }
 
 VirtualDisplaySurface::~VirtualDisplaySurface() {
 }
 
-sp<IGraphicBufferProducer> VirtualDisplaySurface::getIGraphicBufferProducer() const {
-    if (mDisplayId >= 0) {
-        return static_cast<IGraphicBufferProducer*>(
-                const_cast<VirtualDisplaySurface*>(this));
-    } else {
-        // There won't be any interaction with HWC for this virtual display,
-        // so the GLES driver can pass buffers directly to the sink.
-        return mSource[SOURCE_SINK];
-    }
-}
-
 status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
     if (mDisplayId < 0)
         return NO_ERROR;
@@ -294,7 +285,7 @@
         // Queue the buffer back into the scratch pool
         QueueBufferOutput scratchQBO;
         int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, pslot);
-        result = mBufferQueue->queueBuffer(sslot, input, &scratchQBO);
+        result = mSource[SOURCE_SCRATCH]->queueBuffer(sslot, input, &scratchQBO);
         if (result != NO_ERROR)
             return result;
 
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index dc9655b..64a8dce 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -68,17 +68,17 @@
  * is released and the output buffer is queued to the sink.
  */
 class VirtualDisplaySurface : public DisplaySurface,
-                              private BnGraphicBufferProducer,
+                              public BnGraphicBufferProducer,
                               private ConsumerBase {
 public:
     VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
             const sp<IGraphicBufferProducer>& sink,
+            const sp<BufferQueue>& bq,
             const String8& name);
 
     //
     // DisplaySurface interface
     //
-    virtual sp<IGraphicBufferProducer> getIGraphicBufferProducer() const;
     virtual status_t prepareFrame(CompositionType compositionType);
     virtual status_t compositionComplete();
     virtual status_t advanceFrame();
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 401b0f3..2defe34 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -113,8 +113,8 @@
 void Layer::onFirstRef()
 {
     // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
-    sp<BufferQueue> bq = new SurfaceTextureLayer(mFlinger);
-    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(bq, mTextureName,
+    mBufferQueue = new SurfaceTextureLayer(mFlinger);
+    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName,
             GL_TEXTURE_EXTERNAL_OES, false);
 
     mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
@@ -228,8 +228,8 @@
     return new Handle(mFlinger, this);
 }
 
-sp<BufferQueue> Layer::getBufferQueue() const {
-    return mSurfaceFlingerConsumer->getBufferQueue();
+sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
+    return mBufferQueue;
 }
 
 // ---------------------------------------------------------------------------
@@ -926,7 +926,7 @@
             }
 
             virtual bool reject(const sp<GraphicBuffer>& buf,
-                    const BufferQueue::BufferItem& item) {
+                    const IGraphicBufferConsumer::BufferItem& item) {
                 if (buf == NULL) {
                     return false;
                 }
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9093116..8332a5a 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -154,7 +154,7 @@
     Rect computeBounds() const;
 
     sp<IBinder> getHandle();
-    sp<BufferQueue> getBufferQueue() const;
+    sp<IGraphicBufferProducer> getBufferQueue() const;
     const String8& getName() const;
 
     // -----------------------------------------------------------------------
@@ -344,6 +344,7 @@
 
     // constants
     sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer;
+    sp<BufferQueue> mBufferQueue;
     GLuint mTextureName;
     bool mPremultipliedAlpha;
     String8 mName;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b0e4002..b38ad10 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -451,9 +451,11 @@
             createBuiltinDisplayLocked(type);
             wp<IBinder> token = mBuiltinDisplays[i];
 
+            sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
+            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
             sp<DisplayDevice> hw = new DisplayDevice(this,
                     type, allocateHwcDisplayId(type), isSecure, token,
-                    new FramebufferSurface(*mHwc, i),
+                    fbs, bq,
                     mEGLConfig);
             if (i > DisplayDevice::DISPLAY_PRIMARY) {
                 // FIXME: currently we don't get blank/unblank requests
@@ -1101,16 +1103,29 @@
                     const DisplayDeviceState& state(curr[i]);
 
                     sp<DisplaySurface> dispSurface;
+                    sp<IGraphicBufferProducer> producer;
+                    sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
+
                     int32_t hwcDisplayId = -1;
                     if (state.isVirtualDisplay()) {
                         // Virtual displays without a surface are dormant:
                         // they have external state (layer stack, projection,
                         // etc.) but no internal state (i.e. a DisplayDevice).
                         if (state.surface != NULL) {
+
                             hwcDisplayId = allocateHwcDisplayId(state.type);
-                            dispSurface = new VirtualDisplaySurface(
-                                    *mHwc, hwcDisplayId, state.surface,
+                            sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
+                                    *mHwc, hwcDisplayId, state.surface, bq,
                                     state.displayName);
+
+                            dispSurface = vds;
+                            if (hwcDisplayId >= 0) {
+                                producer = vds;
+                            } else {
+                                // There won't be any interaction with HWC for this virtual display,
+                                // so the GLES driver can pass buffers directly to the sink.
+                                producer = state.surface;
+                            }
                         }
                     } else {
                         ALOGE_IF(state.surface!=NULL,
@@ -1120,14 +1135,15 @@
                         hwcDisplayId = allocateHwcDisplayId(state.type);
                         // for supported (by hwc) displays we provide our
                         // own rendering surface
-                        dispSurface = new FramebufferSurface(*mHwc, state.type);
+                        dispSurface = new FramebufferSurface(*mHwc, state.type, bq);
+                        producer = bq;
                     }
 
                     const wp<IBinder>& display(curr.keyAt(i));
                     if (dispSurface != NULL) {
                         sp<DisplayDevice> hw = new DisplayDevice(this,
                                 state.type, hwcDisplayId, state.isSecure,
-                                display, dispSurface, mEGLConfig);
+                                display, dispSurface, producer, mEGLConfig);
                         hw->setLayerStack(state.layerStack);
                         hw->setProjection(state.orientation,
                                 state.viewport, state.frame);
@@ -2615,8 +2631,7 @@
 status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
         const sp<IGraphicBufferProducer>& producer,
         uint32_t reqWidth, uint32_t reqHeight,
-        uint32_t minLayerZ, uint32_t maxLayerZ,
-        bool useReadPixels) {
+        uint32_t minLayerZ, uint32_t maxLayerZ) {
 
     if (CC_UNLIKELY(display == 0))
         return BAD_VALUE;
@@ -2630,18 +2645,16 @@
         sp<IGraphicBufferProducer> producer;
         uint32_t reqWidth, reqHeight;
         uint32_t minLayerZ,maxLayerZ;
-        bool useReadPixels;
         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, bool useReadPixels)
+                uint32_t minLayerZ, uint32_t maxLayerZ)
             : flinger(flinger), display(display), producer(producer),
               reqWidth(reqWidth), reqHeight(reqHeight),
               minLayerZ(minLayerZ), maxLayerZ(maxLayerZ),
-              useReadPixels(useReadPixels),
               result(PERMISSION_DENIED)
         {
         }
@@ -2651,10 +2664,8 @@
         virtual bool handler() {
             Mutex::Autolock _l(flinger->mStateLock);
             sp<const DisplayDevice> hw(flinger->getDisplayDevice(display));
-            bool useReadPixels = this->useReadPixels && !flinger->mGpuToCpuSupported;
             result = flinger->captureScreenImplLocked(hw,
-                    producer, reqWidth, reqHeight, minLayerZ, maxLayerZ,
-                    useReadPixels);
+                    producer, reqWidth, reqHeight, minLayerZ, maxLayerZ);
             static_cast<GraphicProducerWrapper*>(producer->asBinder().get())->exit(result);
             return true;
         }
@@ -2676,8 +2687,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,
-            useReadPixels);
+            reqWidth, reqHeight, minLayerZ, maxLayerZ);
 
     status_t res = postMessageAsync(msg);
     if (res == NO_ERROR) {
@@ -2745,8 +2755,7 @@
         const sp<const DisplayDevice>& hw,
         const sp<IGraphicBufferProducer>& producer,
         uint32_t reqWidth, uint32_t reqHeight,
-        uint32_t minLayerZ, uint32_t maxLayerZ,
-        bool useReadPixels)
+        uint32_t minLayerZ, uint32_t maxLayerZ)
 {
     ATRACE_CALL();
 
@@ -2776,10 +2785,8 @@
 
     status_t result = NO_ERROR;
     if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) == NO_ERROR) {
-        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
-        if (!useReadPixels) {
-            usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
-        }
+        uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
+                        GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
 
         int err = 0;
         err = native_window_set_buffers_dimensions(window, reqWidth, reqHeight);
@@ -2799,28 +2806,16 @@
                         EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
                 if (image != EGL_NO_IMAGE_KHR) {
                     GLuint tname, name;
-                    if (!useReadPixels) {
-                        // turn our EGLImage into a texture
-                        glGenTextures(1, &tname);
-                        glBindTexture(GL_TEXTURE_2D, tname);
-                        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
-                        // create a Framebuffer Object to render into
-                        glGenFramebuffersOES(1, &name);
-                        glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
-                        glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
-                                GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
-                    } else {
-                        // since we're going to use glReadPixels() anyways,
-                        // use an intermediate renderbuffer instead
-                        glGenRenderbuffersOES(1, &tname);
-                        glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
-                        glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, reqWidth, reqHeight);
-                        // create a FBO to render into
-                        glGenFramebuffersOES(1, &name);
-                        glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
-                        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
-                                GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
-                    }
+
+                    // turn our EGLImage into a texture
+                    glGenTextures(1, &tname);
+                    glBindTexture(GL_TEXTURE_2D, tname);
+                    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+                    // create a Framebuffer Object to render into
+                    glGenFramebuffersOES(1, &name);
+                    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+                    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
+                            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
 
                     GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
                     if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
@@ -2830,17 +2825,6 @@
                         // dependent on the context's EGLConfig.
                         renderScreenImplLocked(hw, reqWidth, reqHeight,
                                 minLayerZ, maxLayerZ, true);
-
-                        if (useReadPixels) {
-                            sp<GraphicBuffer> buf = static_cast<GraphicBuffer*>(buffer);
-                            void* vaddr;
-                            if (buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, &vaddr) == NO_ERROR) {
-                                glReadPixels(0, 0, buffer->stride, reqHeight,
-                                        GL_RGBA, GL_UNSIGNED_BYTE, vaddr);
-                                checkScreenshot(buf, vaddr, hw, minLayerZ, maxLayerZ);
-                                buf->unlock();
-                            }
-                        }
                     } else {
                         ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
                         result = INVALID_OPERATION;
@@ -2849,11 +2833,8 @@
                     // back to main framebuffer
                     glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
                     glDeleteFramebuffersOES(1, &name);
-                    if (!useReadPixels) {
-                        glDeleteTextures(1, &tname);
-                    } else {
-                        glDeleteRenderbuffersOES(1, &tname);
-                    }
+                    glDeleteTextures(1, &tname);
+
                     // destroy our image
                     eglDestroyImageKHR(mEGLDisplay, image);
                 } else {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 7099b35..acc8fab 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -194,7 +194,7 @@
     virtual status_t captureScreen(const sp<IBinder>& display,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ, bool isCpuConsumer);
+            uint32_t minLayerZ, uint32_t maxLayerZ);
     // called when screen needs to turn off
     virtual void blank(const sp<IBinder>& display);
     // called when screen is turning back on
@@ -307,8 +307,7 @@
             const sp<const DisplayDevice>& hw,
             const sp<IGraphicBufferProducer>& producer,
             uint32_t reqWidth, uint32_t reqHeight,
-            uint32_t minLayerZ, uint32_t maxLayerZ,
-            bool useReadPixels);
+            uint32_t minLayerZ, uint32_t maxLayerZ);
 
     /* ------------------------------------------------------------------------
      * EGL
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 5de6d12..aa2b37f 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -36,7 +36,7 @@
     class BufferRejecter {
         friend class SurfaceFlingerConsumer;
         virtual bool reject(const sp<GraphicBuffer>& buf,
-                const BufferQueue::BufferItem& item) = 0;
+                const IGraphicBufferConsumer::BufferItem& item) = 0;
 
     protected:
         virtual ~BufferRejecter() { }