unify SurfaceTexture and Surface

Add the concept of synchronous dequeueBuffer in SurfaceTexture
Implement {Surface|SurfaceTextureClient}::setSwapInterval()
Add SurfaceTexture logging
fix onFrameAvailable
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 717f837..0da03d1 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -20,355 +20,12 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <cutils/compiler.h>
-
 #include <utils/Debug.h>
-#include <utils/threads.h>
-#include <utils/String8.h>
-
-#include <ui/Rect.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
 
-/*
- * These classes manage a stack of buffers in shared memory.
- * 
- * SharedClient: represents a client with several stacks
- * SharedBufferStack: represents a stack of buffers
- * SharedBufferClient: manipulates the SharedBufferStack from the client side 
- * SharedBufferServer: manipulates the SharedBufferStack from the server side 
- *
- * Buffers can be dequeued until there are none available, they can be locked
- * unless they are in use by the server, which is only the case for the last 
- * dequeue-able buffer. When these various conditions are not met, the caller
- * waits until the condition is met.
- * 
- */
-
-// ----------------------------------------------------------------------------
-
-class Region;
-class SharedBufferStack;
-class SharedClient;
-
-// ----------------------------------------------------------------------------
-
-class SharedBufferStack
-{
-    friend class SharedClient;
-    friend class SharedBufferBase;
-    friend class SharedBufferClient;
-    friend class SharedBufferServer;
-
-public:
-    // When changing these values, the COMPILE_TIME_ASSERT at the end of this
-    // file need to be updated.
-    static const unsigned int NUM_LAYERS_MAX  = 31;
-    static const unsigned int NUM_BUFFER_MAX  = 32;
-    static const unsigned int NUM_BUFFER_MIN  = 2;
-    static const unsigned int NUM_DISPLAY_MAX = 4;
-
-    struct Statistics { // 4 longs
-        typedef int32_t usecs_t;
-        usecs_t  totalTime;
-        usecs_t  reserved[3];
-    };
-
-    struct SmallRect {
-        uint16_t l, t, r, b;
-    };
-
-    struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
-        static const unsigned int NUM_RECT_MAX = 5;
-        uint32_t    count;
-        SmallRect   rects[NUM_RECT_MAX];
-    };
-    
-    struct BufferData {
-        FlatRegion dirtyRegion;
-        SmallRect  crop;
-        uint8_t transform;
-        uint8_t reserved[3];
-    };
-    
-    SharedBufferStack();
-    void init(int32_t identity);
-    status_t setDirtyRegion(int buffer, const Region& reg);
-    status_t setCrop(int buffer, const Rect& reg);
-    status_t setTransform(int buffer, uint8_t transform);
-    Region getDirtyRegion(int buffer) const;
-    Rect getCrop(int buffer) const;
-    uint32_t getTransform(int buffer) const;
-
-    // these attributes are part of the conditions/updates
-    volatile int32_t head;      // server's current front buffer
-    volatile int32_t available; // number of dequeue-able buffers
-    volatile int32_t queued;    // number of buffers waiting for post
-    volatile int32_t reserved1;
-    volatile status_t status;   // surface's status code
-
-    // not part of the conditions
-    volatile int32_t reallocMask;
-    volatile int8_t index[NUM_BUFFER_MAX];
-
-    int32_t     identity;       // surface's identity (const)
-    int32_t     token;          // surface's token (for debugging)
-    Statistics  stats;
-    int8_t      headBuf;        // last retired buffer
-    uint8_t     reservedBytes[3];
-    int32_t     reserved;
-    BufferData  buffers[NUM_BUFFER_MAX];     // 1024 bytes
-};
-
-// ----------------------------------------------------------------------------
-
-// 64 KB max
-class SharedClient
-{
-public:
-    SharedClient();
-    ~SharedClient();
-    status_t validate(size_t token) const;
-
-private:
-    friend class SharedBufferBase;
-    friend class SharedBufferClient;
-    friend class SharedBufferServer;
-
-    // FIXME: this should be replaced by a lock-less primitive
-    Mutex lock;
-    Condition cv;
-    SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];
-};
-
-// ============================================================================
-
-class SharedBufferBase
-{
-public:
-    SharedBufferBase(SharedClient* sharedClient, int surface,
-            int32_t identity);
-    ~SharedBufferBase();
-    status_t getStatus() const;
-    int32_t getIdentity() const;
-    String8 dump(char const* prefix) const;
-
-protected:
-    SharedClient* const mSharedClient;
-    SharedBufferStack* const mSharedStack;
-    const int mIdentity;
-
-    friend struct Update;
-    friend struct QueueUpdate;
-
-    struct ConditionBase {
-        SharedBufferStack& stack;
-        inline ConditionBase(SharedBufferBase* sbc) 
-            : stack(*sbc->mSharedStack) { }
-        virtual ~ConditionBase() { };
-        virtual bool operator()() const = 0;
-        virtual const char* name() const = 0;
-    };
-    status_t waitForCondition(const ConditionBase& condition);
-
-    struct UpdateBase {
-        SharedBufferStack& stack;
-        inline UpdateBase(SharedBufferBase* sbb) 
-            : stack(*sbb->mSharedStack) { }
-    };
-    template <typename T>
-    status_t updateCondition(T update);
-};
-
-template <typename T>
-status_t SharedBufferBase::updateCondition(T update) {
-    SharedClient& client( *mSharedClient );
-    Mutex::Autolock _l(client.lock);
-    ssize_t result = update();
-    client.cv.broadcast();    
-    return result;
-}
-
-// ----------------------------------------------------------------------------
-
-class SharedBufferClient : public SharedBufferBase
-{
-public:
-    SharedBufferClient(SharedClient* sharedClient, int surface, int num,
-            int32_t identity);
-
-    ssize_t dequeue();
-    status_t undoDequeue(int buf);
-    
-    status_t lock(int buf);
-    status_t cancel(int buf);
-    status_t queue(int buf);
-    bool needNewBuffer(int buffer) const;
-    status_t setDirtyRegion(int buffer, const Region& reg);
-    status_t setCrop(int buffer, const Rect& reg);
-    status_t setTransform(int buffer, uint32_t transform);
-
-    class SetBufferCountCallback {
-        friend class SharedBufferClient;
-        virtual status_t operator()(int bufferCount) const = 0;
-    protected:
-        virtual ~SetBufferCountCallback() { }
-    };
-    status_t setBufferCount(int bufferCount, const SetBufferCountCallback& ipc);
-
-private:
-    friend struct Condition;
-    friend struct DequeueCondition;
-    friend struct LockCondition;
-
-    struct QueueUpdate : public UpdateBase {
-        inline QueueUpdate(SharedBufferBase* sbb);
-        inline ssize_t operator()();
-    };
-
-    struct DequeueUpdate : public UpdateBase {
-        inline DequeueUpdate(SharedBufferBase* sbb);
-        inline ssize_t operator()();
-    };
-
-    struct CancelUpdate : public UpdateBase {
-        int tail, buf;
-        inline CancelUpdate(SharedBufferBase* sbb, int tail, int buf);
-        inline ssize_t operator()();
-    };
-
-    // --
-
-    struct DequeueCondition : public ConditionBase {
-        inline DequeueCondition(SharedBufferClient* sbc);
-        inline bool operator()() const;
-        inline const char* name() const { return "DequeueCondition"; }
-    };
-
-    struct LockCondition : public ConditionBase {
-        int buf;
-        inline LockCondition(SharedBufferClient* sbc, int buf);
-        inline bool operator()() const;
-        inline const char* name() const { return "LockCondition"; }
-    };
-
-    int32_t computeTail() const;
-
-    mutable RWLock mLock;
-    int mNumBuffers;
-
-    int32_t tail;
-    int32_t queued_head;
-    // statistics...
-    nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX];
-};
-
-// ----------------------------------------------------------------------------
-
-class SharedBufferServer
-    : public SharedBufferBase,
-      public LightRefBase<SharedBufferServer>
-{
-public:
-    SharedBufferServer(SharedClient* sharedClient, int surface, int num,
-            int32_t identity);
-
-    ssize_t retireAndLock();
-    void setStatus(status_t status);
-    status_t reallocateAll();
-    status_t reallocateAllExcept(int buffer);
-    int32_t getQueuedCount() const;
-    Region getDirtyRegion(int buffer) const;
-    Rect getCrop(int buffer) const;
-    uint32_t getTransform(int buffer) const;
-
-    status_t resize(int newNumBuffers);
-    status_t grow(int newNumBuffers);
-    status_t shrink(int newNumBuffers);
-
-    SharedBufferStack::Statistics getStats() const;
-    
-
-private:
-    friend class LightRefBase<SharedBufferServer>;
-    ~SharedBufferServer();
-
-    /*
-     * BufferList is basically a fixed-capacity sorted-vector of
-     * unsigned 5-bits ints using a 32-bits int as storage.
-     * it has efficient iterators to find items in the list and not in the list.
-     */
-    class BufferList {
-        size_t mCapacity;
-        uint32_t mList;
-    public:
-        BufferList(size_t c = SharedBufferStack::NUM_BUFFER_MAX)
-            : mCapacity(c), mList(0) { }
-        status_t add(int value);
-        status_t remove(int value);
-        uint32_t getMask() const { return mList; }
-
-        class const_iterator {
-            friend class BufferList;
-            uint32_t mask, curr;
-            const_iterator(uint32_t mask) :
-                mask(mask), curr(__builtin_clz(mask)) {
-            }
-        public:
-            inline bool operator == (const const_iterator& rhs) const {
-                return mask == rhs.mask;
-            }
-            inline bool operator != (const const_iterator& rhs) const {
-                return mask != rhs.mask;
-            }
-            inline int operator *() const { return curr; }
-            inline const const_iterator& operator ++() {
-                mask &= ~(1<<(31-curr));
-                curr = __builtin_clz(mask);
-                return *this;
-            }
-        };
-
-        inline const_iterator begin() const {
-            return const_iterator(mList);
-        }
-        inline const_iterator end() const   {
-            return const_iterator(0);
-        }
-        inline const_iterator free_begin() const {
-            uint32_t mask = (1 << (32-mCapacity)) - 1;
-            return const_iterator( ~(mList | mask) );
-        }
-    };
-
-    // this protects mNumBuffers and mBufferList
-    mutable RWLock mLock;
-    int mNumBuffers;
-    BufferList mBufferList;
-
-    struct BuffersAvailableCondition : public ConditionBase {
-        int mNumBuffers;
-        inline BuffersAvailableCondition(SharedBufferServer* sbs,
-                int numBuffers);
-        inline bool operator()() const;
-        inline const char* name() const { return "BuffersAvailableCondition"; }
-    };
-
-    struct RetireUpdate : public UpdateBase {
-        const int numBuffers;
-        inline RetireUpdate(SharedBufferBase* sbb, int numBuffers);
-        inline ssize_t operator()();
-    };
-
-    struct StatusUpdate : public UpdateBase {
-        const status_t status;
-        inline StatusUpdate(SharedBufferBase* sbb, status_t status);
-        inline ssize_t operator()();
-    };
-};
-
-// ===========================================================================
+#define NUM_DISPLAY_MAX 4
 
 struct display_cblk_t
 {
@@ -389,12 +46,11 @@
     uint8_t         connected;
     uint8_t         reserved[3];
     uint32_t        pad[7];
-    display_cblk_t  displays[SharedBufferStack::NUM_DISPLAY_MAX];
+    display_cblk_t  displays[NUM_DISPLAY_MAX];
 };
 
 // ---------------------------------------------------------------------------
 
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 65536)
 COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
 
 // ---------------------------------------------------------------------------
diff --git a/include/surfaceflinger/IGraphicBufferAlloc.h b/include/surfaceflinger/IGraphicBufferAlloc.h
index 01e4bd9..e1b6b57 100644
--- a/include/surfaceflinger/IGraphicBufferAlloc.h
+++ b/include/surfaceflinger/IGraphicBufferAlloc.h
@@ -27,6 +27,8 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
+class GraphicBuffer;
+
 class IGraphicBufferAlloc : public IInterface
 {
 public:
diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h
index cd0ee40..5fdf234 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -27,42 +27,23 @@
 
 #include <ui/PixelFormat.h>
 
-#include <hardware/hardware.h>
-#include <hardware/gralloc.h>
-
 namespace android {
 
 typedef int32_t    SurfaceID;
 
-class GraphicBuffer;
+class ISurfaceTexture;
 
 class ISurface : public IInterface
 {
 protected:
     enum {
-        RESERVED0 = IBinder::FIRST_CALL_TRANSACTION,
-        RESERVED1,
-        RESERVED2,
-        REQUEST_BUFFER,
-        SET_BUFFER_COUNT,
+        GET_SURFACE_TEXTURE = IBinder::FIRST_CALL_TRANSACTION,
     };
 
 public: 
     DECLARE_META_INTERFACE(Surface);
 
-    /*
-     * requests a new buffer for the given index. If w, h, or format are
-     * null the buffer is created with the parameters assigned to the
-     * surface it is bound to. Otherwise the buffer's parameters are
-     * set to those specified.
-     */
-    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
-            uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0;
-
-    /*
-     * sets the number of buffers dequeuable for this surface.
-     */
-    virtual status_t setBufferCount(int bufferCount) = 0;
+    virtual sp<ISurfaceTexture> getSurfaceTexture() const = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index dea1b10..03fd01b 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -33,6 +33,8 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
+class IMemoryHeap;
+
 class ISurfaceComposer : public IInterface
 {
 public:
@@ -95,10 +97,6 @@
      */
     virtual sp<ISurfaceComposerClient> createConnection() = 0;
 
-    /* create a client connection with surface flinger
-     */
-    virtual sp<ISurfaceComposerClient> createClientConnection() = 0;
-
     /* create a graphic buffer allocator
      */
     virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc() = 0;
@@ -134,11 +132,6 @@
     virtual status_t turnElectronBeamOff(int32_t mode) = 0;
     virtual status_t turnElectronBeamOn(int32_t mode) = 0;
 
-    /* Signal surfaceflinger that there might be some work to do
-     * This is an ASYNCHRONOUS call.
-     */
-    virtual void signal() const = 0;
-
     /* verify that an ISurface was created by SurfaceFlinger.
      */
     virtual bool authenticateSurface(const sp<ISurface>& surface) const = 0;
@@ -154,7 +147,6 @@
         // Java by ActivityManagerService.
         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
         CREATE_CONNECTION,
-        CREATE_CLIENT_CONNECTION,
         CREATE_GRAPHIC_BUFFER_ALLOC,
         GET_CBLK,
         OPEN_GLOBAL_TRANSACTION,
@@ -162,7 +154,6 @@
         SET_ORIENTATION,
         FREEZE_DISPLAY,
         UNFREEZE_DISPLAY,
-        SIGNAL,
         CAPTURE_SCREEN,
         TURN_ELECTRON_BEAM_OFF,
         TURN_ELECTRON_BEAM_ON,
diff --git a/include/surfaceflinger/ISurfaceComposerClient.h b/include/surfaceflinger/ISurfaceComposerClient.h
index 46b1bb7..2e75a0e 100644
--- a/include/surfaceflinger/ISurfaceComposerClient.h
+++ b/include/surfaceflinger/ISurfaceComposerClient.h
@@ -33,9 +33,6 @@
 
 // ----------------------------------------------------------------------------
 
-class IMemoryHeap;
-
-typedef int32_t    ClientID;
 typedef int32_t    DisplayID;
 
 // ----------------------------------------------------------------------------
@@ -57,9 +54,6 @@
         status_t writeToParcel(Parcel* parcel) const;
     };
 
-    virtual sp<IMemoryHeap> getControlBlock() const = 0;
-    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const = 0;
-
     /*
      * Requires ACCESS_SURFACE_FLINGER permission
      */
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index ab30f45..8845dc9 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -43,9 +43,7 @@
 class Rect;
 class Surface;
 class SurfaceComposerClient;
-class SharedClient;
-class SharedBufferClient;
-class SurfaceClient;
+class SurfaceTextureClient;
 
 // ---------------------------------------------------------------------------
 
@@ -162,9 +160,6 @@
     status_t    lock(SurfaceInfo* info, Region* dirty, bool blocking = true);
     status_t    unlockAndPost();
 
-    // setSwapRectangle() is intended to be used by GL ES clients
-    void        setSwapRectangle(const Rect& r);
-
     sp<IBinder> asBinder() const;
 
 private:
@@ -209,6 +204,7 @@
     static int query(const ANativeWindow* window, int what, int* value);
     static int perform(ANativeWindow* window, int operation, ...);
 
+    int setSwapInterval(int interval);
     int dequeueBuffer(ANativeWindowBuffer** buffer);
     int lockBuffer(ANativeWindowBuffer* buffer);
     int queueBuffer(ANativeWindowBuffer* buffer);
@@ -216,83 +212,23 @@
     int query(int what, int* value) const;
     int perform(int operation, va_list args);
 
-    void dispatch_setUsage(va_list args);
-    int  dispatch_connect(va_list args);
-    int  dispatch_disconnect(va_list args);
-    int  dispatch_crop(va_list args);
-    int  dispatch_set_buffer_count(va_list args);
-    int  dispatch_set_buffers_geometry(va_list args);
-    int  dispatch_set_buffers_transform(va_list args);
-    int  dispatch_set_buffers_timestamp(va_list args);
-
-    void setUsage(uint32_t reqUsage);
-    int  connect(int api);
-    int  disconnect(int api);
-    int  crop(Rect const* rect);
-    int  setBufferCount(int bufferCount);
-    int  setBuffersGeometry(int w, int h, int format);
-    int  setBuffersTransform(int transform);
-    int  setBuffersTimestamp(int64_t timestamp);
-
     /*
      *  private stuff...
      */
     void init();
     status_t validate(bool inCancelBuffer = false) const;
 
-    // When the buffer pool is a fixed size we want to make sure SurfaceFlinger
-    // won't stall clients, so we require an extra buffer.
-    enum { MIN_UNDEQUEUED_BUFFERS = 2 };
-
-    inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
-    inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
-
-    status_t getBufferLocked(int index,
-            uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
-    int getBufferIndex(const sp<GraphicBuffer>& buffer) const;
-
     int getConnectedApi() const;
     
-    bool needNewBuffer(int bufIdx,
-            uint32_t *pWidth, uint32_t *pHeight,
-            uint32_t *pFormat, uint32_t *pUsage) const;
-
     static void cleanCachedSurfacesLocked();
 
-    class BufferInfo {
-        uint32_t mWidth;
-        uint32_t mHeight;
-        uint32_t mFormat;
-        uint32_t mUsage;
-        mutable uint32_t mDirty;
-        enum {
-            GEOMETRY = 0x01
-        };
-    public:
-        BufferInfo();
-        void set(uint32_t w, uint32_t h, uint32_t format);
-        void set(uint32_t usage);
-        void get(uint32_t *pWidth, uint32_t *pHeight,
-                uint32_t *pFormat, uint32_t *pUsage) const;
-        bool validateBuffer(const sp<GraphicBuffer>& buffer) const;
-    };
-
     // constants
-    GraphicBufferMapper&        mBufferMapper;
-    SurfaceClient&              mClient;
-    SharedBufferClient*         mSharedBufferClient;
     status_t                    mInitCheck;
     sp<ISurface>                mSurface;
+    sp<SurfaceTextureClient>    mSurfaceTextureClient;
     uint32_t                    mIdentity;
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
-
-    // protected by mSurfaceLock
-    Rect                        mSwapRectangle;
-    int                         mConnected;
-    Rect                        mNextBufferCrop;
-    uint32_t                    mNextBufferTransform;
-    BufferInfo                  mBufferInfo;
     
     // protected by mSurfaceLock. These are also used from lock/unlock
     // but in that case, they must be called form the same thread.
@@ -304,9 +240,6 @@
     mutable Region              mOldDirtyRegion;
     bool                        mReserved;
 
-    // only used from dequeueBuffer()
-    Vector< sp<GraphicBuffer> > mBuffers;
-
     // query() must be called from dequeueBuffer() thread
     uint32_t                    mWidth;
     uint32_t                    mHeight;
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index c61a5bf..140b9f8 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -36,10 +36,10 @@
 
 // ---------------------------------------------------------------------------
 
-class Region;
-class SharedClient;
-class ISurfaceComposer;
 class DisplayInfo;
+class IMemoryHeap;
+class ISurfaceComposer;
+class Region;
 class surface_flinger_cblk_t;
 
 // ---------------------------------------------------------------------------
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index b5737ff..4070eba 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -16,7 +16,6 @@
 	ISurfaceComposerClient.cpp \
 	IGraphicBufferAlloc.cpp \
 	LayerState.cpp \
-	SharedBufferStack.cpp \
 	Surface.cpp \
 	SurfaceComposerClient.cpp \
 
diff --git a/libs/gui/ISurface.cpp b/libs/gui/ISurface.cpp
index 23b90af..96155d7 100644
--- a/libs/gui/ISurface.cpp
+++ b/libs/gui/ISurface.cpp
@@ -22,9 +22,7 @@
 
 #include <binder/Parcel.h>
 
-#include <ui/GraphicBuffer.h>
-
-#include <surfaceflinger/Surface.h>
+#include <gui/ISurfaceTexture.h>
 #include <surfaceflinger/ISurface.h>
 
 namespace android {
@@ -39,30 +37,11 @@
     {
     }
 
-    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
-            uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
-    {
+    virtual sp<ISurfaceTexture> getSurfaceTexture() const {
         Parcel data, reply;
         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(bufferIdx);
-        data.writeInt32(w);
-        data.writeInt32(h);
-        data.writeInt32(format);
-        data.writeInt32(usage);
-        remote()->transact(REQUEST_BUFFER, data, &reply);
-        sp<GraphicBuffer> buffer = new GraphicBuffer();
-        reply.read(*buffer);
-        return buffer;
-    }
-
-    virtual status_t setBufferCount(int bufferCount)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
-        data.writeInt32(bufferCount);
-        remote()->transact(SET_BUFFER_COUNT, data, &reply);
-        status_t err = reply.readInt32();
-        return err;
+        remote()->transact(GET_SURFACE_TEXTURE, data, &reply);
+        return interface_cast<ISurfaceTexture>(reply.readStrongBinder());
     }
 };
 
@@ -74,23 +53,9 @@
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
     switch(code) {
-        case REQUEST_BUFFER: {
+        case GET_SURFACE_TEXTURE: {
             CHECK_INTERFACE(ISurface, data, reply);
-            int bufferIdx = data.readInt32();
-            uint32_t w = data.readInt32();
-            uint32_t h = data.readInt32();
-            uint32_t format = data.readInt32();
-            uint32_t usage = data.readInt32();
-            sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, w, h, format, usage));
-            if (buffer == NULL)
-                return BAD_VALUE;
-            return reply->write(*buffer);
-        }
-        case SET_BUFFER_COUNT: {
-            CHECK_INTERFACE(ISurface, data, reply);
-            int bufferCount = data.readInt32();
-            status_t err = setBufferCount(bufferCount);
-            reply->writeInt32(err);
+            reply->writeStrongBinder( getSurfaceTexture()->asBinder() );
             return NO_ERROR;
         }
         default:
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 8951c3f..40450a3 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -57,15 +57,6 @@
         return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
     }
 
-    virtual sp<ISurfaceComposerClient> createClientConnection()
-    {
-        uint32_t n;
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::CREATE_CLIENT_CONNECTION, data, &reply);
-        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
-    }
-
     virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc()
     {
         uint32_t n;
@@ -174,13 +165,6 @@
         return reply.readInt32();
     }
 
-    virtual void signal() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::SIGNAL, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
     virtual bool authenticateSurface(const sp<ISurface>& surface) const
     {
         Parcel data, reply;
@@ -229,11 +213,6 @@
             sp<IBinder> b = createConnection()->asBinder();
             reply->writeStrongBinder(b);
         } break;
-        case CREATE_CLIENT_CONNECTION: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            sp<IBinder> b = createClientConnection()->asBinder();
-            reply->writeStrongBinder(b);
-        } break;
         case CREATE_GRAPHIC_BUFFER_ALLOC: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> b = createGraphicBufferAlloc()->asBinder();
@@ -270,10 +249,6 @@
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             bootFinished();
         } break;
-        case SIGNAL: {
-            CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            signal();
-        } break;
         case GET_CBLK: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> b = getCblk()->asBinder();
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index ea38e08..8d83392 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -50,9 +50,7 @@
 namespace android {
 
 enum {
-    GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
-    GET_TOKEN,
-    CREATE_SURFACE,
+    CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
     DESTROY_SURFACE,
     SET_STATE
 };
@@ -65,23 +63,6 @@
     {
     }
 
-    virtual sp<IMemoryHeap> getControlBlock() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
-        remote()->transact(GET_CBLK, data, &reply);
-        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
-    }
-
-    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
-        data.writeStrongBinder(sur->asBinder());
-        remote()->transact(GET_TOKEN, data, &reply);
-        return reply.readInt32();
-    }
-
     virtual sp<ISurface> createSurface( surface_data_t* params,
                                         const String8& name,
                                         DisplayID display,
@@ -131,41 +112,6 @@
 status_t BnSurfaceComposerClient::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
-    // codes that don't require permission check
-
-    switch(code) {
-        case GET_CBLK: {
-            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
-            sp<IMemoryHeap> ctl(getControlBlock());
-            reply->writeStrongBinder(ctl->asBinder());
-            return NO_ERROR;
-        } break;
-        case GET_TOKEN: {
-            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
-            sp<ISurface> sur = interface_cast<ISurface>(data.readStrongBinder());
-            ssize_t token = getTokenForSurface(sur);
-            reply->writeInt32(token);
-            return NO_ERROR;
-        } break;
-    }
-
-    // these must be checked
-
-     IPCThreadState* ipc = IPCThreadState::self();
-     const int pid = ipc->getCallingPid();
-     const int uid = ipc->getCallingUid();
-     const int self_pid = getpid();
-     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
-         // we're called from a different process, do the real check
-         if (!checkCallingPermission(
-                 String16("android.permission.ACCESS_SURFACE_FLINGER")))
-         {
-             LOGE("Permission Denial: "
-                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
-             return PERMISSION_DENIED;
-         }
-     }
-
      switch(code) {
         case CREATE_SURFACE: {
             CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
diff --git a/libs/gui/SharedBufferStack.cpp b/libs/gui/SharedBufferStack.cpp
deleted file mode 100644
index 7505d53..0000000
--- a/libs/gui/SharedBufferStack.cpp
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-#define LOG_TAG "SharedBufferStack"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Debug.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-
-#include <private/surfaceflinger/SharedBufferStack.h>
-
-#include <ui/Rect.h>
-#include <ui/Region.h>
-
-#define DEBUG_ATOMICS 0
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-SharedClient::SharedClient()
-    : lock(Mutex::SHARED), cv(Condition::SHARED)
-{
-}
-
-SharedClient::~SharedClient() {
-}
-
-
-// these functions are used by the clients
-status_t SharedClient::validate(size_t i) const {
-    if (uint32_t(i) >= uint32_t(SharedBufferStack::NUM_LAYERS_MAX))
-        return BAD_INDEX;
-    return surfaces[i].status;
-}
-
-// ----------------------------------------------------------------------------
-
-
-SharedBufferStack::SharedBufferStack()
-{
-}
-
-void SharedBufferStack::init(int32_t i)
-{
-    status = NO_ERROR;
-    identity = i;
-}
-
-status_t SharedBufferStack::setCrop(int buffer, const Rect& crop)
-{
-    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
-        return BAD_INDEX;
-
-    buffers[buffer].crop.l = uint16_t(crop.left);
-    buffers[buffer].crop.t = uint16_t(crop.top);
-    buffers[buffer].crop.r = uint16_t(crop.right);
-    buffers[buffer].crop.b = uint16_t(crop.bottom);
-    return NO_ERROR;
-}
-
-status_t SharedBufferStack::setTransform(int buffer, uint8_t transform)
-{
-    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
-        return BAD_INDEX;
-    buffers[buffer].transform = transform;
-    return NO_ERROR;
-}
-
-status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
-{
-    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
-        return BAD_INDEX;
-
-    FlatRegion& reg(buffers[buffer].dirtyRegion);
-    if (dirty.isEmpty()) {
-        reg.count = 0;
-        return NO_ERROR;
-    }
-
-    size_t count;
-    Rect const* r = dirty.getArray(&count);
-    if (count > FlatRegion::NUM_RECT_MAX) {
-        const Rect bounds(dirty.getBounds());
-        reg.count = 1;
-        reg.rects[0].l = uint16_t(bounds.left);
-        reg.rects[0].t = uint16_t(bounds.top);
-        reg.rects[0].r = uint16_t(bounds.right);
-        reg.rects[0].b = uint16_t(bounds.bottom);
-    } else {
-        reg.count = count;
-        for (size_t i=0 ; i<count ; i++) {
-            reg.rects[i].l = uint16_t(r[i].left);
-            reg.rects[i].t = uint16_t(r[i].top);
-            reg.rects[i].r = uint16_t(r[i].right);
-            reg.rects[i].b = uint16_t(r[i].bottom);
-        }
-    }
-    return NO_ERROR;
-}
-
-Region SharedBufferStack::getDirtyRegion(int buffer) const
-{
-    Region res;
-    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
-        return res;
-
-    const FlatRegion& reg(buffers[buffer].dirtyRegion);
-    if (reg.count > FlatRegion::NUM_RECT_MAX)
-        return res;
-
-    if (reg.count == 1) {
-        const Rect r(
-                reg.rects[0].l,
-                reg.rects[0].t,
-                reg.rects[0].r,
-                reg.rects[0].b);
-        res.set(r);
-    } else {
-        for (size_t i=0 ; i<reg.count ; i++) {
-            const Rect r(
-                    reg.rects[i].l,
-                    reg.rects[i].t,
-                    reg.rects[i].r,
-                    reg.rects[i].b);
-            res.orSelf(r);
-        }
-    }
-    return res;
-}
-
-Rect SharedBufferStack::getCrop(int buffer) const
-{
-    Rect res(-1, -1);
-    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
-        return res;
-    res.left = buffers[buffer].crop.l;
-    res.top = buffers[buffer].crop.t;
-    res.right = buffers[buffer].crop.r;
-    res.bottom = buffers[buffer].crop.b;
-    return res;
-}
-
-uint32_t SharedBufferStack::getTransform(int buffer) const
-{
-    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
-        return 0;
-    return buffers[buffer].transform;
-}
-
-
-// ----------------------------------------------------------------------------
-
-SharedBufferBase::SharedBufferBase(SharedClient* sharedClient,
-        int surface, int32_t identity)
-    : mSharedClient(sharedClient), 
-      mSharedStack(sharedClient->surfaces + surface),
-      mIdentity(identity)
-{
-}
-
-SharedBufferBase::~SharedBufferBase()
-{
-}
-
-status_t SharedBufferBase::getStatus() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.status;
-}
-
-int32_t SharedBufferBase::getIdentity() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.identity;
-}
-
-String8 SharedBufferBase::dump(char const* prefix) const
-{
-    const size_t SIZE = 1024;
-    char buffer[SIZE];
-    String8 result;
-    SharedBufferStack& stack( *mSharedStack );
-    snprintf(buffer, SIZE, 
-            "%s[ head=%2d, available=%2d, queued=%2d ] "
-            "reallocMask=%08x, identity=%d, status=%d",
-            prefix, stack.head, stack.available, stack.queued,
-            stack.reallocMask, stack.identity, stack.status);
-    result.append(buffer);
-    result.append("\n");
-    return result;
-}
-
-status_t SharedBufferBase::waitForCondition(const ConditionBase& condition)
-{
-    const SharedBufferStack& stack( *mSharedStack );
-    SharedClient& client( *mSharedClient );
-    const nsecs_t TIMEOUT = s2ns(1);
-    const int identity = mIdentity;
-
-    Mutex::Autolock _l(client.lock);
-    while ((condition()==false) &&
-            (stack.identity == identity) &&
-            (stack.status == NO_ERROR))
-    {
-        status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
-        // handle errors and timeouts
-        if (CC_UNLIKELY(err != NO_ERROR)) {
-            if (err == TIMED_OUT) {
-                if (condition()) {
-                    LOGE("waitForCondition(%s) timed out (identity=%d), "
-                        "but condition is true! We recovered but it "
-                        "shouldn't happen." , condition.name(), stack.identity);
-                    break;
-                } else {
-                    LOGW("waitForCondition(%s) timed out "
-                        "(identity=%d, status=%d). "
-                        "CPU may be pegged. trying again.", condition.name(),
-                        stack.identity, stack.status);
-                }
-            } else {
-                LOGE("waitForCondition(%s) error (%s) ",
-                        condition.name(), strerror(-err));
-                return err;
-            }
-        }
-    }
-    return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
-}
-// ============================================================================
-// conditions and updates
-// ============================================================================
-
-SharedBufferClient::DequeueCondition::DequeueCondition(
-        SharedBufferClient* sbc) : ConditionBase(sbc)  { 
-}
-bool SharedBufferClient::DequeueCondition::operator()() const {
-    return stack.available > 0;
-}
-
-SharedBufferClient::LockCondition::LockCondition(
-        SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) { 
-}
-bool SharedBufferClient::LockCondition::operator()() const {
-    // NOTE: if stack.head is messed up, we could crash the client
-    // or cause some drawing artifacts. This is okay, as long as it is
-    // limited to the client.
-    return (buf != stack.index[stack.head]);
-}
-
-SharedBufferServer::BuffersAvailableCondition::BuffersAvailableCondition(
-        SharedBufferServer* sbs, int numBuffers) : ConditionBase(sbs),
-        mNumBuffers(numBuffers) {
-}
-bool SharedBufferServer::BuffersAvailableCondition::operator()() const {
-    return stack.available == mNumBuffers;
-}
-
-// ----------------------------------------------------------------------------
-
-SharedBufferClient::QueueUpdate::QueueUpdate(SharedBufferBase* sbb)
-    : UpdateBase(sbb) {    
-}
-ssize_t SharedBufferClient::QueueUpdate::operator()() {
-    android_atomic_inc(&stack.queued);
-    return NO_ERROR;
-}
-
-SharedBufferClient::DequeueUpdate::DequeueUpdate(SharedBufferBase* sbb)
-    : UpdateBase(sbb) {
-}
-ssize_t SharedBufferClient::DequeueUpdate::operator()() {
-    if (android_atomic_dec(&stack.available) == 0) {
-        LOGW("dequeue probably called from multiple threads!");
-    }
-    return NO_ERROR;
-}
-
-SharedBufferClient::CancelUpdate::CancelUpdate(SharedBufferBase* sbb,
-        int tail, int buf)
-    : UpdateBase(sbb), tail(tail), buf(buf) {
-}
-ssize_t SharedBufferClient::CancelUpdate::operator()() {
-    stack.index[tail] = buf;
-    android_atomic_inc(&stack.available);
-    return NO_ERROR;
-}
-
-SharedBufferServer::RetireUpdate::RetireUpdate(
-        SharedBufferBase* sbb, int numBuffers)
-    : UpdateBase(sbb), numBuffers(numBuffers) {
-}
-ssize_t SharedBufferServer::RetireUpdate::operator()() {
-    int32_t head = stack.head;
-    if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
-        return BAD_VALUE;
-
-    // Decrement the number of queued buffers 
-    int32_t queued;
-    do {
-        queued = stack.queued;
-        if (queued == 0) {
-            return NOT_ENOUGH_DATA;
-        }
-    } while (android_atomic_cmpxchg(queued, queued-1, &stack.queued));
-    
-    // lock the buffer before advancing head, which automatically unlocks
-    // the buffer we preventively locked upon entering this function
-
-    head = (head + 1) % numBuffers;
-    const int8_t headBuf = stack.index[head];
-    stack.headBuf = headBuf;
-
-    // head is only modified here, so we don't need to use cmpxchg
-    android_atomic_write(head, &stack.head);
-
-    // now that head has moved, we can increment the number of available buffers
-    android_atomic_inc(&stack.available);
-    return head;
-}
-
-SharedBufferServer::StatusUpdate::StatusUpdate(
-        SharedBufferBase* sbb, status_t status)
-    : UpdateBase(sbb), status(status) {
-}
-
-ssize_t SharedBufferServer::StatusUpdate::operator()() {
-    android_atomic_write(status, &stack.status);
-    return NO_ERROR;
-}
-
-// ============================================================================
-
-SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
-        int surface, int num, int32_t identity)
-    : SharedBufferBase(sharedClient, surface, identity),
-      mNumBuffers(num), tail(0)
-{
-    SharedBufferStack& stack( *mSharedStack );
-    tail = computeTail();
-    queued_head = stack.head;
-}
-
-int32_t SharedBufferClient::computeTail() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
-}
-
-ssize_t SharedBufferClient::dequeue()
-{
-    SharedBufferStack& stack( *mSharedStack );
-
-    RWLock::AutoRLock _rd(mLock);
-
-    const nsecs_t dequeueTime = systemTime(SYSTEM_TIME_THREAD);
-
-    //LOGD("[%d] about to dequeue a buffer",
-    //        mSharedStack->identity);
-    DequeueCondition condition(this);
-    status_t err = waitForCondition(condition);
-    if (err != NO_ERROR)
-        return ssize_t(err);
-
-    DequeueUpdate update(this);
-    updateCondition( update );
-
-    int dequeued = stack.index[tail];
-    tail = ((tail+1 >= mNumBuffers) ? 0 : tail+1);
-    LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail++=%d, %s",
-            dequeued, tail, dump("").string());
-
-    mDequeueTime[dequeued] = dequeueTime; 
-
-    return dequeued;
-}
-
-status_t SharedBufferClient::undoDequeue(int buf)
-{
-    return cancel(buf);
-}
-
-status_t SharedBufferClient::cancel(int buf)
-{
-    RWLock::AutoRLock _rd(mLock);
-
-    // calculate the new position of the tail index (essentially tail--)
-    int localTail = (tail + mNumBuffers - 1) % mNumBuffers;
-    CancelUpdate update(this, localTail, buf);
-    status_t err = updateCondition( update );
-    if (err == NO_ERROR) {
-        tail = localTail;
-    }
-    return err;
-}
-
-status_t SharedBufferClient::lock(int buf)
-{
-    RWLock::AutoRLock _rd(mLock);
-
-    SharedBufferStack& stack( *mSharedStack );
-    LockCondition condition(this, buf);
-    status_t err = waitForCondition(condition);
-    return err;
-}
-
-status_t SharedBufferClient::queue(int buf)
-{
-    RWLock::AutoRLock _rd(mLock);
-
-    SharedBufferStack& stack( *mSharedStack );
-
-    queued_head = (queued_head + 1) % mNumBuffers;
-    stack.index[queued_head] = buf;
-
-    QueueUpdate update(this);
-    status_t err = updateCondition( update );
-    LOGD_IF(DEBUG_ATOMICS, "queued=%d, %s", buf, dump("").string());
-
-    const nsecs_t now = systemTime(SYSTEM_TIME_THREAD);
-    stack.stats.totalTime = ns2us(now - mDequeueTime[buf]);
-
-    return err;
-}
-
-bool SharedBufferClient::needNewBuffer(int buf) const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    const uint32_t mask = 1<<(31-buf);
-    return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0;
-}
-
-status_t SharedBufferClient::setCrop(int buf, const Rect& crop)
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.setCrop(buf, crop);
-}
-
-status_t SharedBufferClient::setTransform(int buf, uint32_t transform)
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.setTransform(buf, uint8_t(transform));
-}
-
-status_t SharedBufferClient::setDirtyRegion(int buf, const Region& reg)
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.setDirtyRegion(buf, reg);
-}
-
-status_t SharedBufferClient::setBufferCount(
-        int bufferCount, const SetBufferCountCallback& ipc)
-{
-    SharedBufferStack& stack( *mSharedStack );
-    if (uint32_t(bufferCount) >= SharedBufferStack::NUM_BUFFER_MAX)
-        return BAD_VALUE;
-
-    if (uint32_t(bufferCount) < SharedBufferStack::NUM_BUFFER_MIN)
-        return BAD_VALUE;
-
-    RWLock::AutoWLock _wr(mLock);
-
-    status_t err = ipc(bufferCount);
-    if (err == NO_ERROR) {
-        mNumBuffers = bufferCount;
-        queued_head = (stack.head + stack.queued) % mNumBuffers;
-        tail = computeTail();
-    }
-    return err;
-}
-
-// ----------------------------------------------------------------------------
-
-SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
-        int surface, int num, int32_t identity)
-    : SharedBufferBase(sharedClient, surface, identity),
-      mNumBuffers(num)
-{
-    mSharedStack->init(identity);
-    mSharedStack->token = surface;
-    mSharedStack->head = num-1;
-    mSharedStack->available = num;
-    mSharedStack->queued = 0;
-    mSharedStack->reallocMask = 0;
-    memset(mSharedStack->buffers, 0, sizeof(mSharedStack->buffers));
-    for (int i=0 ; i<num ; i++) {
-        mBufferList.add(i);
-        mSharedStack->index[i] = i;
-    }
-}
-
-SharedBufferServer::~SharedBufferServer()
-{
-}
-
-ssize_t SharedBufferServer::retireAndLock()
-{
-    RWLock::AutoRLock _l(mLock);
-
-    RetireUpdate update(this, mNumBuffers);
-    ssize_t buf = updateCondition( update );
-    if (buf >= 0) {
-        if (uint32_t(buf) >= SharedBufferStack::NUM_BUFFER_MAX)
-            return BAD_VALUE;
-        SharedBufferStack& stack( *mSharedStack );
-        buf = stack.index[buf];
-        LOGD_IF(DEBUG_ATOMICS && buf>=0, "retire=%d, %s",
-                int(buf), dump("").string());
-    }
-    return buf;
-}
-
-void SharedBufferServer::setStatus(status_t status)
-{
-    if (status < NO_ERROR) {
-        StatusUpdate update(this, status);
-        updateCondition( update );
-    }
-}
-
-status_t SharedBufferServer::reallocateAll()
-{
-    RWLock::AutoRLock _l(mLock);
-
-    SharedBufferStack& stack( *mSharedStack );
-    uint32_t mask = mBufferList.getMask();
-    android_atomic_or(mask, &stack.reallocMask);
-    return NO_ERROR;
-}
-
-status_t SharedBufferServer::reallocateAllExcept(int buffer)
-{
-    RWLock::AutoRLock _l(mLock);
-
-    SharedBufferStack& stack( *mSharedStack );
-    BufferList temp(mBufferList);
-    temp.remove(buffer);
-    uint32_t mask = temp.getMask();
-    android_atomic_or(mask, &stack.reallocMask);
-    return NO_ERROR;
-}
-
-int32_t SharedBufferServer::getQueuedCount() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.queued;
-}
-
-Region SharedBufferServer::getDirtyRegion(int buf) const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.getDirtyRegion(buf);
-}
-
-Rect SharedBufferServer::getCrop(int buf) const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.getCrop(buf);
-}
-
-uint32_t SharedBufferServer::getTransform(int buf) const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.getTransform(buf);
-}
-
-/*
- * NOTE: this is not thread-safe on the server-side, meaning
- * 'head' cannot move during this operation. The client-side
- * can safely operate an usual.
- *
- */
-status_t SharedBufferServer::resize(int newNumBuffers)
-{
-    if ((unsigned int)(newNumBuffers) < SharedBufferStack::NUM_BUFFER_MIN ||
-        (unsigned int)(newNumBuffers) > SharedBufferStack::NUM_BUFFER_MAX) {
-        return BAD_VALUE;
-    }
-
-    RWLock::AutoWLock _l(mLock);
-
-    if (newNumBuffers < mNumBuffers) {
-        return shrink(newNumBuffers);
-    } else {
-        return grow(newNumBuffers);
-    }
-}
-
-status_t SharedBufferServer::grow(int newNumBuffers)
-{
-    SharedBufferStack& stack( *mSharedStack );
-    const int numBuffers = mNumBuffers;
-    const int extra = newNumBuffers - numBuffers;
-
-    // read the head, make sure it's valid
-    int32_t head = stack.head;
-    if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
-        return BAD_VALUE;
-
-    int base = numBuffers;
-    int32_t avail = stack.available;
-    int tail = head - avail + 1;
-
-    if (tail >= 0) {
-        int8_t* const index = const_cast<int8_t*>(stack.index);
-        const int nb = numBuffers - head;
-        memmove(&index[head + extra], &index[head], nb);
-        base = head;
-        // move head 'extra' ahead, this doesn't impact stack.index[head];
-        stack.head = head + extra;
-    }
-    stack.available += extra;
-
-    // fill the new free space with unused buffers
-    BufferList::const_iterator curr(mBufferList.free_begin());
-    for (int i=0 ; i<extra ; i++) {
-        stack.index[base+i] = *curr;
-        mBufferList.add(*curr);
-        ++curr;
-    }
-
-    mNumBuffers = newNumBuffers;
-    return NO_ERROR;
-}
-
-status_t SharedBufferServer::shrink(int newNumBuffers)
-{
-    SharedBufferStack& stack( *mSharedStack );
-
-    // Shrinking is only supported if there are no buffers currently dequeued.
-    int32_t avail = stack.available;
-    int32_t queued = stack.queued;
-    if (avail + queued != mNumBuffers) {
-        return INVALID_OPERATION;
-    }
-
-    // Wait for any queued buffers to be displayed.
-    BuffersAvailableCondition condition(this, mNumBuffers);
-    status_t err = waitForCondition(condition);
-    if (err < 0) {
-        return err;
-    }
-
-    // Reset head to index 0 and make it refer to buffer 0.  The same renaming
-    // (head -> 0) is done in the BufferManager.
-    int32_t head = stack.head;
-    int8_t* index = const_cast<int8_t*>(stack.index);
-    for (int8_t i = 0; i < newNumBuffers; i++) {
-        index[i] = i;
-    }
-    stack.head = 0;
-    stack.headBuf = 0;
-
-    // Free the buffers from the end of the list that are no longer needed.
-    for (int i = newNumBuffers; i < mNumBuffers; i++) {
-        mBufferList.remove(i);
-    }
-
-    // Tell the client to reallocate all the buffers.
-    reallocateAll();
-
-    mNumBuffers = newNumBuffers;
-    stack.available = newNumBuffers;
-
-    return NO_ERROR;
-}
-
-SharedBufferStack::Statistics SharedBufferServer::getStats() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.stats;
-}
-
-// ---------------------------------------------------------------------------
-status_t SharedBufferServer::BufferList::add(int value)
-{
-    if (uint32_t(value) >= mCapacity)
-        return BAD_VALUE;
-    uint32_t mask = 1<<(31-value);
-    if (mList & mask)
-        return ALREADY_EXISTS;
-    mList |= mask;
-    return NO_ERROR;
-}
-
-status_t SharedBufferServer::BufferList::remove(int value)
-{
-    if (uint32_t(value) >= mCapacity)
-        return BAD_VALUE;
-    uint32_t mask = 1<<(31-value);
-    if (!(mList & mask))
-        return NAME_NOT_FOUND;
-    mList &= ~mask;
-    return NO_ERROR;
-}
-
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 0c5767b..4d1d923 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -21,13 +21,15 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#include <utils/Errors.h>
-#include <utils/threads.h>
 #include <utils/CallStack.h>
+#include <utils/Errors.h>
 #include <utils/Log.h>
+#include <utils/threads.h>
 
-#include <binder/IPCThreadState.h>
 #include <binder/IMemory.h>
+#include <binder/IPCThreadState.h>
+
+#include <gui/SurfaceTextureClient.h>
 
 #include <ui/DisplayInfo.h>
 #include <ui/GraphicBuffer.h>
@@ -35,12 +37,11 @@
 #include <ui/GraphicLog.h>
 #include <ui/Rect.h>
 
-#include <surfaceflinger/Surface.h>
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/Surface.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
-#include <private/surfaceflinger/SharedBufferStack.h>
 #include <private/surfaceflinger/LayerState.h>
 
 namespace android {
@@ -273,58 +274,10 @@
 //  Surface
 // ============================================================================
 
-class SurfaceClient : public Singleton<SurfaceClient>
-{
-    // all these attributes are constants
-    sp<ISurfaceComposer> mComposerService;
-    sp<ISurfaceComposerClient> mClient;
-    status_t mStatus;
-    SharedClient* mControl;
-    sp<IMemoryHeap> mControlMemory;
-
-    SurfaceClient()
-        : Singleton<SurfaceClient>(), mStatus(NO_INIT)
-    {
-        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
-        mComposerService = sf;
-        mClient = sf->createClientConnection();
-        if (mClient != NULL) {
-            mControlMemory = mClient->getControlBlock();
-            if (mControlMemory != NULL) {
-                mControl = static_cast<SharedClient *>(
-                        mControlMemory->getBase());
-                if (mControl) {
-                    mStatus = NO_ERROR;
-                }
-            }
-        }
-    }
-    friend class Singleton<SurfaceClient>;
-public:
-    status_t initCheck() const {
-        return mStatus;
-    }
-    SharedClient* getSharedClient() const {
-        return mControl;
-    }
-    ssize_t getTokenForSurface(const sp<ISurface>& sur) const {
-        // TODO: we could cache a few tokens here to avoid an IPC
-        return mClient->getTokenForSurface(sur);
-    }
-    void signalServer() const {
-        mComposerService->signal();
-    }
-};
-
-ANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient);
-
 // ---------------------------------------------------------------------------
 
 Surface::Surface(const sp<SurfaceControl>& surface)
-    : mBufferMapper(GraphicBufferMapper::get()),
-      mClient(SurfaceClient::getInstance()),
-      mSharedBufferClient(NULL),
-      mInitCheck(NO_INIT),
+    : mInitCheck(NO_INIT),
       mSurface(surface->mSurface),
       mIdentity(surface->mIdentity),
       mFormat(surface->mFormat), mFlags(surface->mFlags),
@@ -334,10 +287,7 @@
 }
 
 Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
-    : mBufferMapper(GraphicBufferMapper::get()),
-      mClient(SurfaceClient::getInstance()),
-      mSharedBufferClient(NULL),
-      mInitCheck(NO_INIT)
+    : mInitCheck(NO_INIT)
 {
     mSurface    = interface_cast<ISurface>(ref);
     mIdentity   = parcel.readInt32();
@@ -382,7 +332,6 @@
 
 }
 
-
 Mutex Surface::sCachedSurfacesLock;
 DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces;
 
@@ -422,32 +371,29 @@
     ANativeWindow::query            = query;
     ANativeWindow::perform          = perform;
 
-    DisplayInfo dinfo;
-    SurfaceComposerClient::getDisplayInfo(0, &dinfo);
-    const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
-    const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
-    // FIXME: set real values here
-    const_cast<int&>(ANativeWindow::minSwapInterval) = 1;
-    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
-    const_cast<uint32_t&>(ANativeWindow::flags) = 0;
+    if (mSurface != NULL) {
+        sp<ISurfaceTexture> surfaceTexture(mSurface->getSurfaceTexture());
+        LOGE_IF(surfaceTexture==0, "got a NULL ISurfaceTexture from ISurface");
+        if (surfaceTexture != NULL) {
+            mSurfaceTextureClient = new SurfaceTextureClient(surfaceTexture);
+            mSurfaceTextureClient->setUsage(GraphicBuffer::USAGE_HW_RENDER);
+        }
 
-    mNextBufferTransform = 0;
-    mConnected = 0;
-    mSwapRectangle.makeInvalid();
-    mNextBufferCrop = Rect(0,0);
-    // two buffers by default
-    mBuffers.setCapacity(2);
-    mBuffers.insertAt(0, 2);
+        DisplayInfo dinfo;
+        SurfaceComposerClient::getDisplayInfo(0, &dinfo);
+        const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
+        const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
 
-    if (mSurface != 0 && mClient.initCheck() == NO_ERROR) {
-        int32_t token = mClient.getTokenForSurface(mSurface);
-        if (token >= 0) {
-            mSharedBufferClient = new SharedBufferClient(
-                    mClient.getSharedClient(), token, 2, mIdentity);
-            mInitCheck = mClient.getSharedClient()->validate(token);
-        } else {
-            LOGW("Not initializing the shared buffer client because token = %d",
-                    token);
+        const_cast<int&>(ANativeWindow::minSwapInterval) =
+                mSurfaceTextureClient->minSwapInterval;
+
+        const_cast<int&>(ANativeWindow::maxSwapInterval) =
+                mSurfaceTextureClient->maxSwapInterval;
+
+        const_cast<uint32_t&>(ANativeWindow::flags) = 0;
+
+        if (mSurfaceTextureClient != 0) {
+            mInitCheck = NO_ERROR;
         }
     }
 }
@@ -456,9 +402,8 @@
 {
     // clear all references and trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
-    mBuffers.clear();
+    mSurfaceTextureClient.clear();
     mSurface.clear();
-    delete mSharedBufferClient;
     IPCThreadState::self()->flushCommands();
 }
 
@@ -473,32 +418,6 @@
         LOGE("invalid token (identity=%u)", mIdentity);
         return mInitCheck;
     }
-
-    // verify the identity of this surface
-    uint32_t identity = mSharedBufferClient->getIdentity();
-    if (mIdentity != identity) {
-        LOGE("[Surface] using an invalid surface, "
-                "identity=%u should be %d",
-                mIdentity, identity);
-        CallStack stack;
-        stack.update();
-        stack.dump("Surface");
-        return BAD_INDEX;
-    }
-
-    // check the surface didn't become invalid
-    status_t err = mSharedBufferClient->getStatus();
-    if (err != NO_ERROR) {
-        if (!inCancelBuffer) {
-            LOGE("surface (identity=%u) is invalid, err=%d (%s)",
-                    mIdentity, err, strerror(-err));
-            CallStack stack;
-            stack.update();
-            stack.dump("Surface");
-        }
-        return err;
-    }
-
     return NO_ERROR;
 }
 
@@ -509,7 +428,8 @@
 // ----------------------------------------------------------------------------
 
 int Surface::setSwapInterval(ANativeWindow* window, int interval) {
-    return 0;
+    Surface* self = getSelf(window);
+    return self->setSwapInterval(interval);
 }
 
 int Surface::dequeueBuffer(ANativeWindow* window, 
@@ -554,383 +474,52 @@
 
 // ----------------------------------------------------------------------------
 
-bool Surface::needNewBuffer(int bufIdx,
-        uint32_t *pWidth, uint32_t *pHeight,
-        uint32_t *pFormat, uint32_t *pUsage) const
-{
-    Mutex::Autolock _l(mSurfaceLock);
-
-    // Always call needNewBuffer(), since it clears the needed buffers flags
-    bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx);
-    bool validBuffer = mBufferInfo.validateBuffer(mBuffers[bufIdx]);
-    bool newNeewBuffer = needNewBuffer || !validBuffer;
-    if (newNeewBuffer) {
-        mBufferInfo.get(pWidth, pHeight, pFormat, pUsage);
-    }
-    return newNeewBuffer;
+int Surface::setSwapInterval(int interval) {
+    return mSurfaceTextureClient->setSwapInterval(interval);
 }
 
-int Surface::dequeueBuffer(ANativeWindowBuffer** buffer)
-{
-    status_t err = validate();
-    if (err != NO_ERROR)
-        return err;
-
-    GraphicLog& logger(GraphicLog::getInstance());
-    logger.log(GraphicLog::SF_APP_DEQUEUE_BEFORE, mIdentity, -1);
-
-    ssize_t bufIdx = mSharedBufferClient->dequeue();
-
-    logger.log(GraphicLog::SF_APP_DEQUEUE_AFTER, mIdentity, bufIdx);
-
-    if (bufIdx < 0) {
-        LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
-        return bufIdx;
-    }
-
-    // grow the buffer array if needed
-    const size_t size = mBuffers.size();
-    const size_t needed = bufIdx+1;
-    if (size < needed) {
-        mBuffers.insertAt(size, needed-size);
-    }
-
-    uint32_t w, h, format, usage;
-    if (needNewBuffer(bufIdx, &w, &h, &format, &usage)) {
-        err = getBufferLocked(bufIdx, w, h, format, usage);
-        LOGE_IF(err, "getBufferLocked(%ld, %u, %u, %u, %08x) failed (%s)",
-                bufIdx, w, h, format, usage, strerror(-err));
-        if (err == NO_ERROR) {
-            // reset the width/height with the what we get from the buffer
-            const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
-            mWidth  = uint32_t(backBuffer->width);
-            mHeight = uint32_t(backBuffer->height);
-        }
-    }
-
-    // if we still don't have a buffer here, we probably ran out of memory
-    const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
-    if (!err && backBuffer==0) {
-        err = NO_MEMORY;
-    }
-
+int Surface::dequeueBuffer(ANativeWindowBuffer** buffer) {
+    status_t err = mSurfaceTextureClient->dequeueBuffer(buffer);
     if (err == NO_ERROR) {
-        mDirtyRegion.set(backBuffer->width, backBuffer->height);
-        *buffer = backBuffer.get();
-    } else {
-        mSharedBufferClient->undoDequeue(bufIdx);
-    }
-
-    return err;
-}
-
-int Surface::cancelBuffer(ANativeWindowBuffer* buffer)
-{
-    status_t err = validate(true);
-    switch (err) {
-    case NO_ERROR:
-        // no error, common case
-        break;
-    case BAD_INDEX:
-        // legitimate errors here
-        return err;
-    default:
-        // other errors happen because the surface is now invalid,
-        // for instance because it has been destroyed. In this case,
-        // we just fail silently (canceling a buffer is not technically
-        // an error at this point)
-        return NO_ERROR;
-    }
-
-    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
-
-    err = mSharedBufferClient->cancel(bufIdx);
-
-    LOGE_IF(err, "error canceling buffer %d (%s)", bufIdx, strerror(-err));
-    return err;
-}
-
-
-int Surface::lockBuffer(ANativeWindowBuffer* buffer)
-{
-    status_t err = validate();
-    if (err != NO_ERROR)
-        return err;
-
-    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
-
-    GraphicLog& logger(GraphicLog::getInstance());
-    logger.log(GraphicLog::SF_APP_LOCK_BEFORE, mIdentity, bufIdx);
-
-    err = mSharedBufferClient->lock(bufIdx);
-
-    logger.log(GraphicLog::SF_APP_LOCK_AFTER, mIdentity, bufIdx);
-
-    LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
-    return err;
-}
-
-int Surface::queueBuffer(ANativeWindowBuffer* buffer)
-{
-    status_t err = validate();
-    if (err != NO_ERROR)
-        return err;
-
-    if (mSwapRectangle.isValid()) {
-        mDirtyRegion.set(mSwapRectangle);
-    }
-    
-    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
-
-    GraphicLog::getInstance().log(GraphicLog::SF_APP_QUEUE, mIdentity, bufIdx);
-
-    mSharedBufferClient->setTransform(bufIdx, mNextBufferTransform);
-    mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
-    mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
-    err = mSharedBufferClient->queue(bufIdx);
-    LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
-
-    if (err == NO_ERROR) {
-        // TODO: can we avoid this IPC if we know there is one pending?
-        mClient.signalServer();
+        mDirtyRegion.set(buffer[0]->width, buffer[0]->height);
     }
     return err;
 }
 
-int Surface::query(int what, int* value) const
-{
+int Surface::cancelBuffer(ANativeWindowBuffer* buffer) {
+    return mSurfaceTextureClient->cancelBuffer(buffer);
+}
+
+int Surface::lockBuffer(ANativeWindowBuffer* buffer) {
+    return mSurfaceTextureClient->lockBuffer(buffer);
+}
+
+int Surface::queueBuffer(ANativeWindowBuffer* buffer) {
+    return mSurfaceTextureClient->queueBuffer(buffer);
+}
+
+int Surface::query(int what, int* value) const {
     switch (what) {
-    case NATIVE_WINDOW_WIDTH:
-        *value = int(mWidth);
+    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
+        // TODO: this is not needed anymore
+        *value = 1;
         return NO_ERROR;
-    case NATIVE_WINDOW_HEIGHT:
-        *value = int(mHeight);
-        return NO_ERROR;
-    case NATIVE_WINDOW_FORMAT:
-        *value = int(mFormat);
-        return NO_ERROR;
-    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
-        *value = MIN_UNDEQUEUED_BUFFERS;
-        return NO_ERROR;
-    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
-        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
-        *value = sf->authenticateSurface(mSurface) ? 1 : 0;
-        return NO_ERROR;
-    }
     case NATIVE_WINDOW_CONCRETE_TYPE:
+        // TODO: this is not needed anymore
         *value = NATIVE_WINDOW_SURFACE;
         return NO_ERROR;
     }
-    return BAD_VALUE;
+    return mSurfaceTextureClient->query(what, value);
 }
 
-int Surface::perform(int operation, va_list args)
-{
-    status_t err = validate();
-    if (err != NO_ERROR)
-        return err;
-
-    int res = NO_ERROR;
-    switch (operation) {
-    case NATIVE_WINDOW_SET_USAGE:
-        dispatch_setUsage( args );
-        break;
-    case NATIVE_WINDOW_CONNECT:
-        res = dispatch_connect( args );
-        break;
-    case NATIVE_WINDOW_DISCONNECT:
-        res = dispatch_disconnect( args );
-        break;
-    case NATIVE_WINDOW_SET_CROP:
-        res = dispatch_crop( args );
-        break;
-    case NATIVE_WINDOW_SET_BUFFER_COUNT:
-        res = dispatch_set_buffer_count( args );
-        break;
-    case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
-        res = dispatch_set_buffers_geometry( args );
-        break;
-    case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
-        res = dispatch_set_buffers_transform( args );
-        break;
-    case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
-        res = dispatch_set_buffers_timestamp( args );
-        break;
-    default:
-        res = NAME_NOT_FOUND;
-        break;
-    }
-    return res;
-}
-
-void Surface::dispatch_setUsage(va_list args) {
-    int usage = va_arg(args, int);
-    setUsage( usage );
-}
-int Surface::dispatch_connect(va_list args) {
-    int api = va_arg(args, int);
-    return connect( api );
-}
-int Surface::dispatch_disconnect(va_list args) {
-    int api = va_arg(args, int);
-    return disconnect( api );
-}
-int Surface::dispatch_crop(va_list args) {
-    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
-    return crop( reinterpret_cast<Rect const*>(rect) );
-}
-int Surface::dispatch_set_buffer_count(va_list args) {
-    size_t bufferCount = va_arg(args, size_t);
-    return setBufferCount(bufferCount);
-}
-int Surface::dispatch_set_buffers_geometry(va_list args) {
-    int w = va_arg(args, int);
-    int h = va_arg(args, int);
-    int f = va_arg(args, int);
-    return setBuffersGeometry(w, h, f);
-}
-
-int Surface::dispatch_set_buffers_transform(va_list args) {
-    int transform = va_arg(args, int);
-    return setBuffersTransform(transform);
-}
-
-int Surface::dispatch_set_buffers_timestamp(va_list args) {
-    int64_t timestamp = va_arg(args, int64_t);
-    return setBuffersTimestamp(timestamp);
-}
-
-void Surface::setUsage(uint32_t reqUsage)
-{
-    Mutex::Autolock _l(mSurfaceLock);
-    mBufferInfo.set(reqUsage);
-}
-
-int Surface::connect(int api)
-{
-    Mutex::Autolock _l(mSurfaceLock);
-    int err = NO_ERROR;
-    switch (api) {
-        case NATIVE_WINDOW_API_EGL:
-            if (mConnected) {
-                err = -EINVAL;
-            } else {
-                mConnected = api;
-            }
-            break;
-        default:
-            err = -EINVAL;
-            break;
-    }
-    return err;
-}
-
-int Surface::disconnect(int api)
-{
-    Mutex::Autolock _l(mSurfaceLock);
-    int err = NO_ERROR;
-    switch (api) {
-        case NATIVE_WINDOW_API_EGL:
-            if (mConnected == api) {
-                mConnected = 0;
-            } else {
-                err = -EINVAL;
-            }
-            break;
-        default:
-            err = -EINVAL;
-            break;
-    }
-    return err;
-}
-
-int Surface::crop(Rect const* rect)
-{
-    Mutex::Autolock _l(mSurfaceLock);
-    // TODO: validate rect size
-
-    if (rect == NULL || rect->isEmpty()) {
-        mNextBufferCrop = Rect(0,0);
-    } else {
-        mNextBufferCrop = *rect;
-    }
-
-    return NO_ERROR;
-}
-
-int Surface::setBufferCount(int bufferCount)
-{
-    sp<ISurface> s(mSurface);
-    if (s == 0) return NO_INIT;
-
-    class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
-        sp<ISurface> surface;
-        virtual status_t operator()(int bufferCount) const {
-            return surface->setBufferCount(bufferCount);
-        }
-    public:
-        SetBufferCountIPC(const sp<ISurface>& surface) : surface(surface) { }
-    } ipc(s);
-
-    status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
-    LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
-            bufferCount, strerror(-err));
-
-    if (err == NO_ERROR) {
-        // Clear out any references to the old buffers.
-        mBuffers.clear();
-    }
-
-    return err;
-}
-
-int Surface::setBuffersGeometry(int w, int h, int format)
-{
-    if (w<0 || h<0 || format<0)
-        return BAD_VALUE;
-
-    if ((w && !h) || (!w && h))
-        return BAD_VALUE;
-
-    Mutex::Autolock _l(mSurfaceLock);
-    if (mConnected == NATIVE_WINDOW_API_EGL) {
-        return INVALID_OPERATION;
-    }
-
-    mBufferInfo.set(w, h, format);
-    if (format != 0) {
-        // we update the format of the surface as reported by query().
-        // this is to allow applications to change the format of a surface's
-        // buffer, and have it reflected in EGL; which is needed for
-        // EGLConfig validation.
-        mFormat = format;
-    }
-
-    mNextBufferCrop = Rect(0,0);
-
-    return NO_ERROR;
-}
-
-int Surface::setBuffersTransform(int transform)
-{
-    Mutex::Autolock _l(mSurfaceLock);
-    mNextBufferTransform = transform;
-    return NO_ERROR;
-}
-
-int Surface::setBuffersTimestamp(int64_t timestamp)
-{
-    // Surface doesn't really have anything meaningful to do with timestamps
-    // so they'll just be dropped here.
-    return NO_ERROR;
+int Surface::perform(int operation, va_list args) {
+    return mSurfaceTextureClient->perform(operation, args);
 }
 
 // ----------------------------------------------------------------------------
 
-int Surface::getConnectedApi() const
-{
-    Mutex::Autolock _l(mSurfaceLock);
-    return mConnected;
+int Surface::getConnectedApi() const {
+    return mSurfaceTextureClient->getConnectedApi();
 }
 
 // ----------------------------------------------------------------------------
@@ -967,16 +556,17 @@
     }
 
     // we're intending to do software rendering from this point
-    setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+    mSurfaceTextureClient->setUsage(
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
 
     ANativeWindowBuffer* out;
-    status_t err = dequeueBuffer(&out);
+    status_t err = mSurfaceTextureClient->dequeueBuffer(&out);
     LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
     if (err == NO_ERROR) {
         sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
-        err = lockBuffer(backBuffer.get());
-        LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
-                getBufferIndex(backBuffer), strerror(-err));
+        err = mSurfaceTextureClient->lockBuffer(backBuffer.get());
+        LOGE_IF(err, "lockBuffer (handle=%p) failed (%s)",
+                backBuffer->handle, strerror(-err));
         if (err == NO_ERROR) {
             const Rect bounds(backBuffer->width, backBuffer->height);
             const Region boundsRegion(bounds);
@@ -1043,110 +633,14 @@
     status_t err = mLockedBuffer->unlock();
     LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
     
-    err = queueBuffer(mLockedBuffer.get());
-    LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
-            getBufferIndex(mLockedBuffer), strerror(-err));
+    err = mSurfaceTextureClient->queueBuffer(mLockedBuffer.get());
+    LOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
+            mLockedBuffer->handle, strerror(-err));
 
     mPostedBuffer = mLockedBuffer;
     mLockedBuffer = 0;
     return err;
 }
 
-void Surface::setSwapRectangle(const Rect& r) {
-    Mutex::Autolock _l(mSurfaceLock);
-    mSwapRectangle = r;
-}
-
-int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
-{
-    int idx = buffer->getIndex();
-    if (idx < 0) {
-        // The buffer doesn't have an index set.  See if the handle the same as
-        // one of the buffers for which we do know the index.  This can happen
-        // e.g. if GraphicBuffer is used to wrap an ANativeWindowBuffer that
-        // was dequeued from an ANativeWindow.
-        for (size_t i = 0; i < mBuffers.size(); i++) {
-            if (mBuffers[i] != 0 && buffer->handle == mBuffers[i]->handle) {
-                idx = mBuffers[i]->getIndex();
-                break;
-            }
-        }
-    }
-    return idx;
-}
-
-status_t Surface::getBufferLocked(int index,
-        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
-{
-    sp<ISurface> s(mSurface);
-    if (s == 0) return NO_INIT;
-
-    status_t err = NO_MEMORY;
-
-    // free the current buffer
-    sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
-    if (currentBuffer != 0) {
-        currentBuffer.clear();
-    }
-
-    sp<GraphicBuffer> buffer = s->requestBuffer(index, w, h, format, usage);
-    LOGE_IF(buffer==0,
-            "ISurface::getBuffer(%d, %08x) returned NULL",
-            index, usage);
-    if (buffer != 0) { // this should always happen by construction
-        LOGE_IF(buffer->handle == NULL, 
-                "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) "
-                "returned a buffer with a null handle",
-                mIdentity, index, w, h, format, usage);
-        err = mSharedBufferClient->getStatus();
-        LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
-        if (!err && buffer->handle != NULL) {
-            currentBuffer = buffer;
-            currentBuffer->setIndex(index);
-        } else {
-            err = err<0 ? err : status_t(NO_MEMORY);
-        }
-    }
-    return err; 
-}
-
-// ----------------------------------------------------------------------------
-Surface::BufferInfo::BufferInfo()
-    : mWidth(0), mHeight(0), mFormat(0),
-      mUsage(GRALLOC_USAGE_HW_RENDER), mDirty(0)
-{
-}
-
-void Surface::BufferInfo::set(uint32_t w, uint32_t h, uint32_t format) {
-    if ((mWidth != w) || (mHeight != h) || (mFormat != format)) {
-        mWidth = w;
-        mHeight = h;
-        mFormat = format;
-        mDirty |= GEOMETRY;
-    }
-}
-
-void Surface::BufferInfo::set(uint32_t usage) {
-    mUsage = usage;
-}
-
-void Surface::BufferInfo::get(uint32_t *pWidth, uint32_t *pHeight,
-        uint32_t *pFormat, uint32_t *pUsage) const {
-    *pWidth  = mWidth;
-    *pHeight = mHeight;
-    *pFormat = mFormat;
-    *pUsage  = mUsage;
-}
-
-bool Surface::BufferInfo::validateBuffer(const sp<GraphicBuffer>& buffer) const {
-    // make sure we AT LEAST have the usage flags we want
-    if (mDirty || buffer==0 ||
-            ((buffer->usage & mUsage) != mUsage)) {
-        mDirty = 0;
-        return false;
-    }
-    return true;
-}
-
 // ----------------------------------------------------------------------------
 }; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index a1ff2c1..1678711 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -20,19 +20,20 @@
 #include <sys/types.h>
 
 #include <utils/Errors.h>
-#include <utils/threads.h>
-#include <utils/SortedVector.h>
 #include <utils/Log.h>
 #include <utils/Singleton.h>
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
 
-#include <binder/IServiceManager.h>
 #include <binder/IMemory.h>
+#include <binder/IServiceManager.h>
 
 #include <ui/DisplayInfo.h>
 
+#include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/ISurfaceComposer.h>
 #include <surfaceflinger/ISurfaceComposerClient.h>
-#include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
 #include <private/surfaceflinger/LayerState.h>
@@ -217,7 +218,7 @@
 status_t SurfaceComposerClient::getDisplayInfo(
         DisplayID dpy, DisplayInfo* info)
 {
-    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
         return BAD_VALUE;
 
     volatile surface_flinger_cblk_t const * cblk = get_cblk();
@@ -235,7 +236,7 @@
 
 ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
 {
-    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
         return BAD_VALUE;
     volatile surface_flinger_cblk_t const * cblk = get_cblk();
     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
@@ -244,7 +245,7 @@
 
 ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
 {
-    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
         return BAD_VALUE;
     volatile surface_flinger_cblk_t const * cblk = get_cblk();
     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
@@ -253,7 +254,7 @@
 
 ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
 {
-    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
+    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
         return BAD_VALUE;
     volatile surface_flinger_cblk_t const * cblk = get_cblk();
     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index c20fcf2..22b0852 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -181,6 +181,12 @@
 int SurfaceTextureClient::query(int what, int* value) const {
     LOGV("SurfaceTextureClient::query");
     switch (what) {
+    case NATIVE_WINDOW_FORMAT:
+        if (mReqFormat) {
+            *value = mReqFormat;
+            return NO_ERROR;
+        }
+        break;
     case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
         // TODO: this is not needed anymore
         *value = 0;
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 9daaad8..c618263 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -2,18 +2,18 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    clz.cpp.arm \
-    DisplayHardware/DisplayHardware.cpp \
+    Layer.cpp 								\
+    LayerBase.cpp 							\
+    LayerDim.cpp 							\
+    DisplayHardware/DisplayHardware.cpp 	\
     DisplayHardware/DisplayHardwareBase.cpp \
-    DisplayHardware/HWComposer.cpp \
-    GLExtensions.cpp \
-    Layer.cpp \
-    LayerBase.cpp \
-    LayerDim.cpp \
-    MessageQueue.cpp \
-    SurfaceFlinger.cpp \
-    TextureManager.cpp \
-    Transform.cpp
+    DisplayHardware/HWComposer.cpp 			\
+    GLExtensions.cpp 						\
+    MessageQueue.cpp 						\
+    SurfaceFlinger.cpp 						\
+    SurfaceTextureLayer.cpp 				\
+    Transform.cpp 							\
+    
 
 LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
 LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 8df2b92..0137120 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -18,8 +18,9 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <cutils/properties.h>
+#include <cutils/compiler.h>
 #include <cutils/native_handle.h>
+#include <cutils/properties.h>
 
 #include <utils/Errors.h>
 #include <utils/Log.h>
@@ -31,12 +32,12 @@
 #include <surfaceflinger/Surface.h>
 
 #include "clz.h"
+#include "DisplayHardware/DisplayHardware.h"
+#include "DisplayHardware/HWComposer.h"
 #include "GLExtensions.h"
 #include "Layer.h"
 #include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-#include "DisplayHardware/HWComposer.h"
-
+#include "SurfaceTextureLayer.h"
 
 #define DEBUG_RESIZE    0
 
@@ -52,102 +53,81 @@
 Layer::Layer(SurfaceFlinger* flinger,
         DisplayID display, const sp<Client>& client)
     :   LayerBaseClient(flinger, display, client),
+        mTextureName(-1U),
+        mQueuedFrames(0),
+        mCurrentTransform(0),
+        mCurrentOpacity(true),
         mFormat(PIXEL_FORMAT_NONE),
         mGLExtensions(GLExtensions::getInstance()),
-        mNeedsBlending(true),
+        mOpaqueLayer(true),
         mNeedsDithering(false),
         mSecure(false),
         mProtectedByApp(false),
-        mTextureManager(),
-        mBufferManager(mTextureManager),
-        mWidth(0), mHeight(0),
-        mNeedsScaling(false), mFixedSize(false)
+        mFixedSize(false)
 {
-}
-
-Layer::~Layer()
-{
-    // FIXME: must be called from the main UI thread
-    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
-    mBufferManager.destroy(dpy);
-
-    // we can use getUserClientUnsafe here because we know we're
-    // single-threaded at that point.
-    sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe());
-    if (ourClient != 0) {
-        ourClient->detachLayer(this);
-    }
+    mCurrentCrop.makeInvalid();
+    glGenTextures(1, &mTextureName);
 }
 
 void Layer::destroy() const {
     mFlinger->destroyLayer(this);
 }
 
-status_t Layer::setToken(const sp<UserClient>& userClient,
-        SharedClient* sharedClient, int32_t token)
+void Layer::onFirstRef()
 {
-    sp<SharedBufferServer> lcblk = new SharedBufferServer(
-            sharedClient, token, mBufferManager.getDefaultBufferCount(),
-            getIdentity());
-
-
-    sp<UserClient> ourClient(mUserClientRef.getClient());
-
-    /*
-     *  Here it is guaranteed that userClient != ourClient
-     *  (see UserClient::getTokenForSurface()).
-     *
-     *  We release the token used by this surface in ourClient below.
-     *  This should be safe to do so now, since this layer won't be attached
-     *  to this client, it should be okay to reuse that id.
-     *
-     *  If this causes problems, an other solution would be to keep a list
-     *  of all the {UserClient, token} ever used and release them when the
-     *  Layer is destroyed.
-     *
-     */
-
-    if (ourClient != 0) {
-        ourClient->detachLayer(this);
-    }
-
-    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
-    LOGE_IF(err != NO_ERROR,
-            "ClientRef::setToken(%p, %p, %u) failed",
-            userClient.get(), lcblk.get(), token);
-
-    if (err == NO_ERROR) {
-        // we need to free the buffers associated with this surface
-    }
-
-    return err;
+    LayerBaseClient::onFirstRef();
+    struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {
+        FrameQueuedListener(Layer* layer) : mLayer(layer) { }
+    private:
+        wp<Layer> mLayer;
+        virtual void onFrameAvailable() {
+            sp<Layer> that(mLayer.promote());
+            if (that != 0) {
+                that->onFrameQueued();
+            }
+        }
+    };
+    mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);
+    mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
+    mSurfaceTexture->setSynchronousMode(true);
+    mSurfaceTexture->setBufferCountServer(2);
 }
 
-int32_t Layer::getToken() const
+Layer::~Layer()
 {
-    return mUserClientRef.getToken();
+    glDeleteTextures(1, &mTextureName);
 }
 
-sp<UserClient> Layer::getClient() const
-{
-    return mUserClientRef.getClient();
+void Layer::onFrameQueued() {
+    if (android_atomic_or(1, &mQueuedFrames) == 0) {
+        mFlinger->signalEvent();
+    }
 }
 
 // called with SurfaceFlinger::mStateLock as soon as the layer is entered
 // in the purgatory list
 void Layer::onRemoved()
 {
-    ClientRef::Access sharedClient(mUserClientRef);
-    SharedBufferServer* lcblk(sharedClient.get());
-    if (lcblk) {
-        // wake up the condition
-        lcblk->setStatus(NO_INIT);
-    }
 }
 
-sp<LayerBaseClient::Surface> Layer::createSurface() const
+sp<ISurface> Layer::createSurface()
 {
-    sp<Surface> sur(new SurfaceLayer(mFlinger, const_cast<Layer *>(this)));
+    class BSurface : public BnSurface, public LayerCleaner {
+        wp<const Layer> mOwner;
+        virtual sp<ISurfaceTexture> getSurfaceTexture() const {
+            sp<ISurfaceTexture> res;
+            sp<const Layer> that( mOwner.promote() );
+            if (that != NULL) {
+                res = that->mSurfaceTexture;
+            }
+            return res;
+        }
+    public:
+        BSurface(const sp<SurfaceFlinger>& flinger,
+                const sp<Layer>& layer)
+            : LayerCleaner(flinger, layer), mOwner(layer) { }
+    };
+    sp<ISurface> sur(new BSurface(mFlinger, this));
     return sur;
 }
 
@@ -175,17 +155,14 @@
     const uint32_t hwFlags = hw.getFlags();
     
     mFormat = format;
-    mWidth  = w;
-    mHeight = h;
-
-    mReqFormat = format;
-    mReqWidth = w;
-    mReqHeight = h;
 
     mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
     mProtectedByApp = (flags & ISurfaceComposer::eProtectedByApp) ? true : false;
-    mNeedsBlending = (info.h_alpha - info.l_alpha) > 0 &&
-            (flags & ISurfaceComposer::eOpaque) == 0;
+    mOpaqueLayer = (flags & ISurfaceComposer::eOpaque);
+    mCurrentOpacity = getOpacityForFormat(format);
+
+    mSurfaceTexture->setDefaultBufferSize(w, h);
+    mSurfaceTexture->setDefaultBufferFormat(format);
 
     // we use the red index
     int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
@@ -216,10 +193,12 @@
         return;
     }
 
-    Transform tr(Transform(mOrientation) * Transform(mBufferTransform));
+    // FIXME: shouldn't we take the state's transform into account here?
+
+    Transform tr(Transform(mOrientation) * Transform(mCurrentTransform));
     hwcl->transform = tr.getOrientation();
 
-    if (needsBlending()) {
+    if (!isOpaque()) {
         hwcl->blending = mPremultipliedAlpha ?
                 HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
     }
@@ -236,7 +215,7 @@
 }
 
 void Layer::setPerFrameData(hwc_layer_t* hwcl) {
-    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
+    const sp<GraphicBuffer>& buffer(mActiveBuffer);
     if (buffer == NULL) {
         // this can happen if the client never drew into this layer yet,
         // or if we ran out of memory. In that case, don't let
@@ -247,11 +226,11 @@
     }
     hwcl->handle = buffer->handle;
 
-    if (!mBufferCrop.isEmpty()) {
-        hwcl->sourceCrop.left   = mBufferCrop.left;
-        hwcl->sourceCrop.top    = mBufferCrop.top;
-        hwcl->sourceCrop.right  = mBufferCrop.right;
-        hwcl->sourceCrop.bottom = mBufferCrop.bottom;
+    if (isCropped()) {
+        hwcl->sourceCrop.left   = mCurrentCrop.left;
+        hwcl->sourceCrop.top    = mCurrentCrop.top;
+        hwcl->sourceCrop.right  = mCurrentCrop.right;
+        hwcl->sourceCrop.bottom = mCurrentCrop.bottom;
     } else {
         hwcl->sourceCrop.left   = 0;
         hwcl->sourceCrop.top    = 0;
@@ -260,51 +239,12 @@
     }
 }
 
-void Layer::reloadTexture(const Region& dirty)
-{
-    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
-    if (buffer == NULL) {
-        // this situation can happen if we ran out of memory for instance.
-        // not much we can do. continue to use whatever texture was bound
-        // to this context.
-        return;
-    }
-
-    if (mGLExtensions.haveDirectTexture()) {
-        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
-        if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
-            // not sure what we can do here...
-            goto slowpath;
-        }
-    } else {
-slowpath:
-        GGLSurface t;
-        if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) {
-            status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
-            LOGE_IF(res, "error %d (%s) locking buffer %p",
-                    res, strerror(res), buffer.get());
-            if (res == NO_ERROR) {
-                mBufferManager.loadTexture(dirty, t);
-                buffer->unlock();
-            }
-        } else {
-            // we can't do anything
-        }
-    }
+static inline uint16_t pack565(int r, int g, int b) {
+    return (r<<11)|(g<<5)|b;
 }
-
-void Layer::drawForSreenShot() const
-{
-    const bool currentFiltering = mNeedsFiltering;
-    const_cast<Layer*>(this)->mNeedsFiltering = true;
-    LayerBase::drawForSreenShot();
-    const_cast<Layer*>(this)->mNeedsFiltering = currentFiltering;
-}
-
 void Layer::onDraw(const Region& clip) const
 {
-    Texture tex(mBufferManager.getActiveTexture());
-    if (tex.name == -1LU) {
+    if (CC_UNLIKELY(mActiveBuffer == 0)) {
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. This happens frequently with
         // SurfaceView because the WindowManager can't know when the client
@@ -330,7 +270,25 @@
         }
         return;
     }
-    drawWithOpenGL(clip, tex);
+
+    GLenum target = mSurfaceTexture->getCurrentTextureTarget();
+    glBindTexture(target, mTextureName);
+    if (getFiltering() || needsFiltering() || isFixedSize() || isCropped()) {
+        // TODO: we could be more subtle with isFixedSize()
+        glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    } else {
+        glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    }
+    glEnable(target);
+    glMatrixMode(GL_TEXTURE);
+    glLoadMatrixf(mTextureMatrix);
+    glMatrixMode(GL_MODELVIEW);
+
+    drawWithOpenGL(clip);
+
+    glDisable(target);
 }
 
 // As documented in libhardware header, formats in the range
@@ -340,186 +298,37 @@
 // hardware.h, instead of using hard-coded values here.
 #define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
 
-bool Layer::needsBlending(const sp<GraphicBuffer>& buffer) const
+bool Layer::getOpacityForFormat(uint32_t format)
 {
-    // If buffers where set with eOpaque flag, all buffers are known to
-    // be opaque without having to check their actual format
-    if (mNeedsBlending && buffer != NULL) {
-        PixelFormat format = buffer->getPixelFormat();
-
-        if (HARDWARE_IS_DEVICE_FORMAT(format)) {
-            return false;
-        }
-
-        PixelFormatInfo info;
-        status_t err = getPixelFormatInfo(format, &info);
-        if (!err && info.h_alpha <= info.l_alpha) {
-            return false;
-        }
+    if (HARDWARE_IS_DEVICE_FORMAT(format)) {
+        return true;
     }
-
-    // Return opacity as determined from flags and format options
-    // passed to setBuffers()
-    return mNeedsBlending;
+    PixelFormatInfo info;
+    status_t err = getPixelFormatInfo(PixelFormat(format), &info);
+    // in case of error (unknown format), we assume no blending
+    return (err || info.h_alpha <= info.l_alpha);
 }
 
-bool Layer::needsBlending() const
-{
-    if (mBufferManager.hasActiveBuffer()) {
-        return needsBlending(mBufferManager.getActiveBuffer());
-    }
 
-    return mNeedsBlending;
-}
-
-bool Layer::needsFiltering() const
+bool Layer::isOpaque() const
 {
-    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
-        // if our buffer is not the same size than ourselves,
-        // we need filtering.
-        Mutex::Autolock _l(mLock);
-        if (mNeedsScaling)
-            return true;
-    }
-    return LayerBase::needsFiltering();
+    // if we don't have a buffer yet, we're translucent regardless of the
+    // layer's opaque flag.
+    if (mActiveBuffer == 0)
+        return false;
+
+    // if the layer has the opaque flag, then we're always opaque,
+    // otherwise we use the current buffer's format.
+    return mOpaqueLayer || mCurrentOpacity;
 }
 
 bool Layer::isProtected() const
 {
-    sp<GraphicBuffer> activeBuffer(mBufferManager.getActiveBuffer());
+    const sp<GraphicBuffer>& activeBuffer(mActiveBuffer);
     return (activeBuffer != 0) &&
             (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
 }
 
-status_t Layer::setBufferCount(int bufferCount)
-{
-    ClientRef::Access sharedClient(mUserClientRef);
-    SharedBufferServer* lcblk(sharedClient.get());
-    if (!lcblk) {
-        // oops, the client is already gone
-        return DEAD_OBJECT;
-    }
-
-    // NOTE: lcblk->resize() is protected by an internal lock
-    status_t err = lcblk->resize(bufferCount);
-    if (err == NO_ERROR) {
-        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
-        mBufferManager.resize(bufferCount, mFlinger, dpy);
-    }
-
-    return err;
-}
-
-sp<GraphicBuffer> Layer::requestBuffer(int index,
-        uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat,
-        uint32_t usage)
-{
-    sp<GraphicBuffer> buffer;
-
-    if (int32_t(reqWidth | reqHeight | reqFormat) < 0)
-        return buffer;
-
-    if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
-        return buffer;
-
-    // this ensures our client doesn't go away while we're accessing
-    // the shared area.
-    ClientRef::Access sharedClient(mUserClientRef);
-    SharedBufferServer* lcblk(sharedClient.get());
-    if (!lcblk) {
-        // oops, the client is already gone
-        return buffer;
-    }
-
-    /*
-     * This is called from the client's Surface::dequeue(). This can happen
-     * at any time, especially while we're in the middle of using the
-     * buffer 'index' as our front buffer.
-     */
-
-    status_t err = NO_ERROR;
-    uint32_t w, h, f;
-    { // scope for the lock
-        Mutex::Autolock _l(mLock);
-
-        // zero means default
-        const bool fixedSize = reqWidth && reqHeight;
-        if (!reqFormat) reqFormat = mFormat;
-        if (!reqWidth)  reqWidth = mWidth;
-        if (!reqHeight) reqHeight = mHeight;
-
-        w = reqWidth;
-        h = reqHeight;
-        f = reqFormat;
-
-        if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) ||
-                (reqFormat != mReqFormat)) {
-            mReqWidth  = reqWidth;
-            mReqHeight = reqHeight;
-            mReqFormat = reqFormat;
-            mFixedSize = fixedSize;
-            mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
-
-            lcblk->reallocateAllExcept(index);
-        }
-    }
-
-    // here we have to reallocate a new buffer because the buffer could be
-    // used as the front buffer, or by a client in our process
-    // (eg: status bar), and we can't release the handle under its feet.
-    const uint32_t effectiveUsage = getEffectiveUsage(usage);
-    buffer = new GraphicBuffer(w, h, f, effectiveUsage);
-    err = buffer->initCheck();
-
-    if (err || buffer->handle == 0) {
-        GraphicBuffer::dumpAllocationsToSystemLog();
-        LOGE_IF(err || buffer->handle == 0,
-                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
-                this, index, w, h, strerror(-err));
-    } else {
-        LOGD_IF(DEBUG_RESIZE,
-                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
-                this, index, w, h, buffer->handle);
-    }
-
-    if (err == NO_ERROR && buffer->handle != 0) {
-        Mutex::Autolock _l(mLock);
-        mBufferManager.attachBuffer(index, buffer);
-    }
-    return buffer;
-}
-
-uint32_t Layer::getEffectiveUsage(uint32_t usage) const
-{
-    /*
-     *  buffers used for software rendering, but h/w composition
-     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
-     *
-     *  buffers used for h/w rendering and h/w composition
-     *  are allocated with  HW_RENDER | HW_TEXTURE
-     *
-     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
-     *  are allocated with SW_READ_RARELY | HW_RENDER
-     *
-     */
-
-    if (mSecure) {
-        // secure buffer, don't store it into the GPU
-        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
-                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
-    } else {
-        // it's allowed to modify the usage flags here, but generally
-        // the requested flags should be honored.
-        // request EGLImage for all buffers
-        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
-    }
-    if (mProtectedByApp) {
-        // need a hardware-protected path to external video sink
-        usage |= GraphicBuffer::USAGE_PROTECTED;
-    }
-    return usage;
-}
-
 uint32_t Layer::doTransaction(uint32_t flags)
 {
     const Layer::State& front(drawingState());
@@ -531,10 +340,12 @@
     if (sizeChanged) {
         // the size changed, we need to ask our client to request a new buffer
         LOGD_IF(DEBUG_RESIZE,
-                "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
+                "resize (layer=%p), requested (%dx%d), drawing (%d,%d), "
+                "fixedSize=%d",
                 this,
                 int(temp.requested_w), int(temp.requested_h),
-                int(front.requested_w), int(front.requested_h));
+                int(front.requested_w), int(front.requested_h),
+                isFixedSize());
 
         if (!isFixedSize()) {
             // we're being resized and there is a freeze display request,
@@ -557,17 +368,7 @@
 
             // record the new size, form this point on, when the client request
             // a buffer, it'll get the new size.
-            setBufferSize(temp.requested_w, temp.requested_h);
-
-            ClientRef::Access sharedClient(mUserClientRef);
-            SharedBufferServer* lcblk(sharedClient.get());
-            if (lcblk) {
-                // all buffers need reallocation
-                lcblk->reallocateAll();
-            }
-        } else {
-            // record the new size
-            setBufferSize(temp.requested_w, temp.requested_h);
+            mSurfaceTexture->setDefaultBufferSize(temp.requested_w, temp.requested_h);
         }
     }
 
@@ -582,79 +383,69 @@
     return LayerBase::doTransaction(flags);
 }
 
-void Layer::setBufferSize(uint32_t w, uint32_t h) {
-    Mutex::Autolock _l(mLock);
-    mWidth = w;
-    mHeight = h;
-    mNeedsScaling = mWidth != mReqWidth || mHeight != mReqHeight;
-}
-
 bool Layer::isFixedSize() const {
     Mutex::Autolock _l(mLock);
     return mFixedSize;
 }
 
+void Layer::setFixedSize(bool fixedSize)
+{
+    Mutex::Autolock _l(mLock);
+    mFixedSize = fixedSize;
+}
+
+bool Layer::isCropped() const {
+    return !mCurrentCrop.isEmpty();
+}
+
 // ----------------------------------------------------------------------------
 // pageflip handling...
 // ----------------------------------------------------------------------------
 
 void Layer::lockPageFlip(bool& recomputeVisibleRegions)
 {
-    ClientRef::Access sharedClient(mUserClientRef);
-    SharedBufferServer* lcblk(sharedClient.get());
-    if (!lcblk) {
-        // client died
-        recomputeVisibleRegions = true;
-        return;
-    }
+    if (android_atomic_and(0, &mQueuedFrames)) {
+        if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
+            // something happened!
+            recomputeVisibleRegions = true;
+            return;
+        }
 
-    ssize_t buf = lcblk->retireAndLock();
-    if (buf == NOT_ENOUGH_DATA) {
-        // NOTE: This is not an error, it simply means there is nothing to
-        // retire. The buffer is locked because we will use it
-        // for composition later in the loop
-        return;
-    }
+        // signal another event if we have more frames waiting
+        if (mSurfaceTexture->getQueuedCount()) {
+            if (android_atomic_or(1, &mQueuedFrames) == 0) {
+                mFlinger->signalEvent();
+            }
+        }
 
-    if (buf < NO_ERROR) {
-        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
-        mPostedDirtyRegion.clear();
-        return;
-    }
+        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
+        mSurfaceTexture->getTransformMatrix(mTextureMatrix);
 
-    // we retired a buffer, which becomes the new front buffer
+        const Rect crop(mSurfaceTexture->getCurrentCrop());
+        const uint32_t transform(mSurfaceTexture->getCurrentTransform());
+        if ((crop != mCurrentCrop) || (transform != mCurrentTransform)) {
+            mCurrentCrop = crop;
+            mCurrentTransform = transform;
+            mFlinger->invalidateHwcGeometry();
+        }
 
-    const bool noActiveBuffer = !mBufferManager.hasActiveBuffer();
-    const bool activeBlending =
-            noActiveBuffer ? true : needsBlending(mBufferManager.getActiveBuffer());
-
-    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
-        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
-        mPostedDirtyRegion.clear();
-        return;
-    }
-
-    if (noActiveBuffer) {
-        // we didn't have an active buffer, we need to recompute
-        // our visible region
-        recomputeVisibleRegions = true;
-    }
-
-    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
-    if (newFrontBuffer != NULL) {
-        if (!noActiveBuffer && activeBlending != needsBlending(newFrontBuffer)) {
-            // new buffer has different opacity than previous active buffer, need
-            // to recompute visible regions accordingly
+        const bool opacity(getOpacityForFormat(mActiveBuffer->format));
+        if (opacity != mCurrentOpacity) {
+            mCurrentOpacity = opacity;
             recomputeVisibleRegions = true;
         }
 
-        // get the dirty region
-        // compute the posted region
-        const Region dirty(lcblk->getDirtyRegion(buf));
-        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
+        const GLenum target(mSurfaceTexture->getCurrentTextureTarget());
+        glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+        glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
         // update the layer size and release freeze-lock
         const Layer::State& front(drawingState());
+
+        // FIXME: mPostedDirtyRegion = dirty & bounds
+        mPostedDirtyRegion.set(front.w, front.h);
+
+        sp<GraphicBuffer> newFrontBuffer(mActiveBuffer);
         if ((newFrontBuffer->getWidth()  == front.requested_w &&
             newFrontBuffer->getHeight() == front.requested_h) ||
             isFixedSize())
@@ -685,35 +476,7 @@
             // we now have the correct size, unfreeze the screen
             mFreezeLock.clear();
         }
-
-        // get the crop region
-        setBufferCrop( lcblk->getCrop(buf) );
-
-        // get the transformation
-        setBufferTransform( lcblk->getTransform(buf) );
-
-    } else {
-        // this should not happen unless we ran out of memory while
-        // allocating the buffer. we're hoping that things will get back
-        // to normal the next time the app tries to draw into this buffer.
-        // meanwhile, pretend the screen didn't update.
-        mPostedDirtyRegion.clear();
     }
-
-    if (lcblk->getQueuedCount()) {
-        // signal an event if we have more buffers waiting
-        mFlinger->signalEvent();
-    }
-
-    /* a buffer was posted, so we need to call reloadTexture(), which
-     * will update our internal data structures (eg: EGLImageKHR or
-     * texture names). we need to do this even if mPostedDirtyRegion is
-     * empty -- it's orthogonal to the fact that a new buffer was posted,
-     * for instance, a degenerate case could be that the user did an empty
-     * update but repainted the buffer with appropriate content (after a
-     * resize for instance).
-     */
-    reloadTexture( mPostedDirtyRegion );
 }
 
 void Layer::unlockPageFlip(
@@ -746,329 +509,36 @@
 {
     LayerBaseClient::dump(result, buffer, SIZE);
 
-    ClientRef::Access sharedClient(mUserClientRef);
-    SharedBufferServer* lcblk(sharedClient.get());
-    uint32_t totalTime = 0;
-    if (lcblk) {
-        SharedBufferStack::Statistics stats = lcblk->getStats();
-        totalTime= stats.totalTime;
-        result.append( lcblk->dump("      ") );
-    }
-
-    sp<const GraphicBuffer> buf0(getBuffer(0));
-    sp<const GraphicBuffer> buf1(getBuffer(1));
-    uint32_t w0=0, h0=0, s0=0;
-    uint32_t w1=0, h1=0, s1=0;
+    sp<const GraphicBuffer> buf0(mActiveBuffer);
+    uint32_t w0=0, h0=0, s0=0, f0=0;
     if (buf0 != 0) {
         w0 = buf0->getWidth();
         h0 = buf0->getHeight();
         s0 = buf0->getStride();
-    }
-    if (buf1 != 0) {
-        w1 = buf1->getWidth();
-        h1 = buf1->getHeight();
-        s1 = buf1->getStride();
+        f0 = buf0->format;
     }
     snprintf(buffer, SIZE,
             "      "
-            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
-            " freezeLock=%p, dq-q-time=%u us\n",
-            mFormat, w0, h0, s0, w1, h1, s1,
-            getFreezeLock().get(), totalTime);
+            "format=%2d, activeBuffer=[%3ux%3u:%3u,%3u],"
+            " freezeLock=%p, queued-frames=%d\n",
+            mFormat, w0, h0, s0,f0,
+            getFreezeLock().get(), mQueuedFrames);
 
     result.append(buffer);
-}
 
-// ---------------------------------------------------------------------------
-
-Layer::ClientRef::ClientRef()
-    : mControlBlock(0), mToken(-1) {
-}
-
-Layer::ClientRef::~ClientRef() {
-}
-
-int32_t Layer::ClientRef::getToken() const {
-    Mutex::Autolock _l(mLock);
-    return mToken;
-}
-
-sp<UserClient> Layer::ClientRef::getClient() const {
-    Mutex::Autolock _l(mLock);
-    return mUserClient.promote();
-}
-
-status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
-        const sp<SharedBufferServer>& sharedClient, int32_t token) {
-    Mutex::Autolock _l(mLock);
-
-    { // scope for strong mUserClient reference
-        sp<UserClient> userClient(mUserClient.promote());
-        if (userClient != 0 && mControlBlock != 0) {
-            mControlBlock->setStatus(NO_INIT);
-        }
+    if (mSurfaceTexture != 0) {
+        mSurfaceTexture->dump(result, "            ", buffer, SIZE);
     }
-
-    mUserClient = uc;
-    mToken = token;
-    mControlBlock = sharedClient;
-    return NO_ERROR;
 }
 
-sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
-    return mUserClient.promote();
-}
-
-// this class gives us access to SharedBufferServer safely
-// it makes sure the UserClient (and its associated shared memory)
-// won't go away while we're accessing it.
-Layer::ClientRef::Access::Access(const ClientRef& ref)
-    : mControlBlock(0)
+uint32_t Layer::getEffectiveUsage(uint32_t usage) const
 {
-    Mutex::Autolock _l(ref.mLock);
-    mUserClientStrongRef = ref.mUserClient.promote();
-    if (mUserClientStrongRef != 0)
-        mControlBlock = ref.mControlBlock;
-}
-
-Layer::ClientRef::Access::~Access()
-{
-}
-
-// ---------------------------------------------------------------------------
-
-Layer::BufferManager::BufferManager(TextureManager& tm)
-    : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
-      mActiveBufferIndex(-1), mFailover(false)
-{
-}
-
-Layer::BufferManager::~BufferManager()
-{
-}
-
-status_t Layer::BufferManager::resize(size_t size,
-        const sp<SurfaceFlinger>& flinger, EGLDisplay dpy)
-{
-    Mutex::Autolock _l(mLock);
-
-    if (size < mNumBuffers) {
-        // If there is an active texture, move it into slot 0 if needed
-        if (mActiveBufferIndex > 0) {
-            BufferData activeBufferData = mBufferData[mActiveBufferIndex];
-            mBufferData[mActiveBufferIndex] = mBufferData[0];
-            mBufferData[0] = activeBufferData;
-            mActiveBufferIndex = 0;
-        }
-
-        // Free the buffers that are no longer needed.
-        for (size_t i = size; i < mNumBuffers; i++) {
-            mBufferData[i].buffer = 0;
-
-            // Create a message to destroy the textures on SurfaceFlinger's GL
-            // thread.
-            class MessageDestroyTexture : public MessageBase {
-                Image mTexture;
-                EGLDisplay mDpy;
-             public:
-                MessageDestroyTexture(const Image& texture, EGLDisplay dpy)
-                    : mTexture(texture), mDpy(dpy) { }
-                virtual bool handler() {
-                    status_t err = Layer::BufferManager::destroyTexture(
-                            &mTexture, mDpy);
-                    LOGE_IF(err<0, "error destroying texture: %d (%s)",
-                            mTexture.name, strerror(-err));
-                    return true; // XXX: err == 0;  ????
-                }
-            };
-
-            MessageDestroyTexture *msg = new MessageDestroyTexture(
-                    mBufferData[i].texture, dpy);
-
-            // Don't allow this texture to be cleaned up by
-            // BufferManager::destroy.
-            mBufferData[i].texture.name = -1U;
-            mBufferData[i].texture.image = EGL_NO_IMAGE_KHR;
-
-            // Post the message to the SurfaceFlinger object.
-            flinger->postMessageAsync(msg);
-        }
+    // TODO: should we do something special if mSecure is set?
+    if (mProtectedByApp) {
+        // need a hardware-protected path to external video sink
+        usage |= GraphicBuffer::USAGE_PROTECTED;
     }
-
-    mNumBuffers = size;
-    return NO_ERROR;
-}
-
-// only for debugging
-sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
-    return mBufferData[index].buffer;
-}
-
-status_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
-    BufferData const * const buffers = mBufferData;
-    Mutex::Autolock _l(mLock);
-    mActiveBuffer = buffers[index].buffer;
-    mActiveBufferIndex = index;
-    return NO_ERROR;
-}
-
-size_t Layer::BufferManager::getActiveBufferIndex() const {
-    return mActiveBufferIndex;
-}
-
-Texture Layer::BufferManager::getActiveTexture() const {
-    Texture res;
-    if (mFailover || mActiveBufferIndex<0) {
-        res = mFailoverTexture;
-    } else {
-        static_cast<Image&>(res) = mBufferData[mActiveBufferIndex].texture;
-    }
-    return res;
-}
-
-sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
-    return mActiveBuffer;
-}
-
-bool Layer::BufferManager::hasActiveBuffer() const {
-    return mActiveBufferIndex >= 0;
-}
-
-sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
-{
-    BufferData* const buffers = mBufferData;
-    sp<GraphicBuffer> buffer;
-    Mutex::Autolock _l(mLock);
-    buffer = buffers[index].buffer;
-    buffers[index].buffer = 0;
-    return buffer;
-}
-
-status_t Layer::BufferManager::attachBuffer(size_t index,
-        const sp<GraphicBuffer>& buffer)
-{
-    BufferData* const buffers = mBufferData;
-    Mutex::Autolock _l(mLock);
-    buffers[index].buffer = buffer;
-    buffers[index].texture.dirty = true;
-    return NO_ERROR;
-}
-
-status_t Layer::BufferManager::destroy(EGLDisplay dpy)
-{
-    BufferData* const buffers = mBufferData;
-    size_t num;
-    { // scope for the lock
-        Mutex::Autolock _l(mLock);
-        num = mNumBuffers;
-        for (size_t i=0 ; i<num ; i++) {
-            buffers[i].buffer = 0;
-        }
-    }
-    for (size_t i=0 ; i<num ; i++) {
-        destroyTexture(&buffers[i].texture, dpy);
-    }
-    destroyTexture(&mFailoverTexture, dpy);
-    return NO_ERROR;
-}
-
-status_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
-        const sp<GraphicBuffer>& buffer)
-{
-    status_t err = NO_INIT;
-    ssize_t index = mActiveBufferIndex;
-    if (index >= 0) {
-        if (!mFailover) {
-            {
-               // Without that lock, there is a chance of race condition
-               // where while composing a specific index, requestBuf
-               // with the same index can be executed and touch the same data
-               // that is being used in initEglImage.
-               // (e.g. dirty flag in texture)
-               Mutex::Autolock _l(mLock);
-               Image& texture(mBufferData[index].texture);
-               err = mTextureManager.initEglImage(&texture, dpy, buffer);
-            }
-            // if EGLImage fails, we switch to regular texture mode, and we
-            // free all resources associated with using EGLImages.
-            if (err == NO_ERROR) {
-                mFailover = false;
-                destroyTexture(&mFailoverTexture, dpy);
-            } else {
-                mFailover = true;
-                const size_t num = mNumBuffers;
-                for (size_t i=0 ; i<num ; i++) {
-                    destroyTexture(&mBufferData[i].texture, dpy);
-                }
-            }
-        } else {
-            // we failed once, don't try again
-            err = BAD_VALUE;
-        }
-    }
-    return err;
-}
-
-status_t Layer::BufferManager::loadTexture(
-        const Region& dirty, const GGLSurface& t)
-{
-    return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
-}
-
-status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
-{
-    if (tex->name != -1U) {
-        glDeleteTextures(1, &tex->name);
-        tex->name = -1U;
-    }
-    if (tex->image != EGL_NO_IMAGE_KHR) {
-        eglDestroyImageKHR(dpy, tex->image);
-        tex->image = EGL_NO_IMAGE_KHR;
-    }
-    return NO_ERROR;
-}
-
-// ---------------------------------------------------------------------------
-
-Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
-        const sp<Layer>& owner)
-    : Surface(flinger, owner->getIdentity(), owner)
-{
-}
-
-Layer::SurfaceLayer::~SurfaceLayer()
-{
-}
-
-sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index,
-        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
-{
-    sp<GraphicBuffer> buffer;
-    sp<Layer> owner(getOwner());
-    if (owner != 0) {
-        /*
-         * requestBuffer() cannot be called from the main thread
-         * as it could cause a dead-lock, since it may have to wait
-         * on conditions updated my the main thread.
-         */
-        buffer = owner->requestBuffer(index, w, h, format, usage);
-    }
-    return buffer;
-}
-
-status_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
-{
-    status_t err = DEAD_OBJECT;
-    sp<Layer> owner(getOwner());
-    if (owner != 0) {
-        /*
-         * setBufferCount() cannot be called from the main thread
-         * as it could cause a dead-lock, since it may have to wait
-         * on conditions updated my the main thread.
-         */
-        err = owner->setBufferCount(bufferCount);
-    }
-    return err;
+    return usage;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 278d64e..72e290c 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -20,9 +20,11 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <gui/SurfaceTexture.h>
+
+#include <pixelflinger/pixelflinger.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
-#include <pixelflinger/pixelflinger.h>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
@@ -30,8 +32,8 @@
 #include <GLES/glext.h>
 
 #include "LayerBase.h"
+#include "SurfaceTextureLayer.h"
 #include "Transform.h"
-#include "TextureManager.h"
 
 namespace android {
 
@@ -40,7 +42,6 @@
 class FreezeLock;
 class Client;
 class GLExtensions;
-class UserClient;
 
 // ---------------------------------------------------------------------------
 
@@ -58,164 +59,59 @@
     status_t setBuffers(uint32_t w, uint32_t h, 
             PixelFormat format, uint32_t flags=0);
 
-    // associate a UserClient to this Layer
-    status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx);
-    int32_t getToken() const;
-    sp<UserClient> getClient() const;
-
     // Set this Layer's buffers size
-    void setBufferSize(uint32_t w, uint32_t h);
     bool isFixedSize() const;
 
     // LayerBase interface
     virtual void setGeometry(hwc_layer_t* hwcl);
     virtual void setPerFrameData(hwc_layer_t* hwcl);
-    virtual void drawForSreenShot() const;
     virtual void onDraw(const Region& clip) const;
     virtual uint32_t doTransaction(uint32_t transactionFlags);
     virtual void lockPageFlip(bool& recomputeVisibleRegions);
     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-    virtual bool needsBlending(const sp<GraphicBuffer>& buffer) const;
-    virtual bool needsBlending() const;
+    virtual bool isOpaque() const;
     virtual bool needsDithering() const     { return mNeedsDithering; }
-    virtual bool needsFiltering() const;
     virtual bool isSecure() const           { return mSecure; }
     virtual bool isProtected() const;
-    virtual sp<Surface> createSurface() const;
     virtual void onRemoved();
 
     // only for debugging
-    inline sp<GraphicBuffer> getBuffer(int i) const {
-        return mBufferManager.getBuffer(i); }
-    // only for debugging
-    inline const sp<FreezeLock>&  getFreezeLock() const {
-        return mFreezeLock; }
+    inline const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
 
 protected:
     virtual void destroy() const;
+    virtual void onFirstRef();
     virtual void dump(String8& result, char* scratch, size_t size) const;
 
 private:
-    void reloadTexture(const Region& dirty);
+    friend class SurfaceTextureLayer;
+    void onFrameQueued();
+    virtual sp<ISurface> createSurface();
     uint32_t getEffectiveUsage(uint32_t usage) const;
-    sp<GraphicBuffer> requestBuffer(int bufferIdx,
-            uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
-    status_t setBufferCount(int bufferCount);
+    void setFixedSize(bool fixedSize);
+    bool isCropped() const;
+    static bool getOpacityForFormat(uint32_t format);
 
     // -----------------------------------------------------------------------
 
-    class SurfaceLayer : public LayerBaseClient::Surface {
-    public:
-        SurfaceLayer(const sp<SurfaceFlinger>& flinger, const sp<Layer>& owner);
-        ~SurfaceLayer();
-    private:
-        virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
-                uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
-        virtual status_t setBufferCount(int bufferCount);
-        sp<Layer> getOwner() const {
-            return static_cast<Layer*>(Surface::getOwner().get());
-        }
-    };
-    friend class SurfaceLayer;
-
-    // -----------------------------------------------------------------------
-
-    class ClientRef {
-        ClientRef(const ClientRef& rhs);
-        ClientRef& operator = (const ClientRef& rhs);
-        mutable Mutex mLock;
-        // binder thread, page-flip thread
-        sp<SharedBufferServer> mControlBlock;
-        wp<UserClient> mUserClient;
-        int32_t mToken;
-    public:
-        ClientRef();
-        ~ClientRef();
-        int32_t getToken() const;
-        sp<UserClient> getClient() const;
-        status_t setToken(const sp<UserClient>& uc,
-                const sp<SharedBufferServer>& sharedClient, int32_t token);
-        sp<UserClient> getUserClientUnsafe() const;
-        class Access {
-            Access(const Access& rhs);
-            Access& operator = (const Access& rhs);
-            sp<UserClient> mUserClientStrongRef;
-            sp<SharedBufferServer> mControlBlock;
-        public:
-            Access(const ClientRef& ref);
-            ~Access();
-            inline SharedBufferServer* get() const { return mControlBlock.get(); }
-        };
-        friend class Access;
-    };
-
-    // -----------------------------------------------------------------------
-
-    class BufferManager {
-        static const size_t NUM_BUFFERS = 2;
-        struct BufferData {
-            sp<GraphicBuffer>   buffer;
-            Image               texture;
-        };
-        // this lock protect mBufferData[].buffer but since there
-        // is very little contention, we have only one like for
-        // the whole array, we also use it to protect mNumBuffers.
-        mutable Mutex mLock;
-        BufferData          mBufferData[SharedBufferStack::NUM_BUFFER_MAX];
-        size_t              mNumBuffers;
-        Texture             mFailoverTexture;
-        TextureManager&     mTextureManager;
-        ssize_t             mActiveBufferIndex;
-        sp<GraphicBuffer>   mActiveBuffer;
-        bool                mFailover;
-        static status_t destroyTexture(Image* tex, EGLDisplay dpy);
-
-    public:
-        static size_t getDefaultBufferCount() { return NUM_BUFFERS; }
-        BufferManager(TextureManager& tm);
-        ~BufferManager();
-
-        // detach/attach buffer from/to given index
-        sp<GraphicBuffer> detachBuffer(size_t index);
-        status_t attachBuffer(size_t index, const sp<GraphicBuffer>& buffer);
-        // resize the number of active buffers
-        status_t resize(size_t size, const sp<SurfaceFlinger>& flinger,
-                EGLDisplay dpy);
-
-        // ----------------------------------------------
-        // must be called from GL thread
-
-        // set/get active buffer index
-        status_t setActiveBufferIndex(size_t index);
-        size_t getActiveBufferIndex() const;
-        // return the active buffer
-        sp<GraphicBuffer> getActiveBuffer() const;
-        // return wether we have an active buffer
-        bool hasActiveBuffer() const;
-        // return the active texture (or fail-over)
-        Texture getActiveTexture() const;
-        // frees resources associated with all buffers
-        status_t destroy(EGLDisplay dpy);
-        // load bitmap data into the active buffer
-        status_t loadTexture(const Region& dirty, const GGLSurface& t);
-        // make active buffer an EGLImage if needed
-        status_t initEglImage(EGLDisplay dpy,
-                const sp<GraphicBuffer>& buffer);
-
-        // ----------------------------------------------
-        // only for debugging
-        sp<GraphicBuffer> getBuffer(size_t index) const;
-    };
-
-    // -----------------------------------------------------------------------
+    // constants
+    sp<SurfaceTextureLayer> mSurfaceTexture;
+    GLuint mTextureName;
 
     // thread-safe
-    ClientRef mUserClientRef;
+    volatile int32_t mQueuedFrames;
+
+    // main thread
+    sp<GraphicBuffer> mActiveBuffer;
+    GLfloat mTextureMatrix[16];
+    Rect mCurrentCrop;
+    uint32_t mCurrentTransform;
+    bool mCurrentOpacity;
 
     // constants
     PixelFormat mFormat;
     const GLExtensions& mGLExtensions;
-    bool mNeedsBlending;
+    bool mOpaqueLayer;
     bool mNeedsDithering;
 
     // page-flip thread (currently main thread)
@@ -226,18 +122,8 @@
     // page-flip thread and transaction thread (currently main thread)
     sp<FreezeLock>  mFreezeLock;
 
-    // see threading usage in declaration
-    TextureManager mTextureManager;
-    BufferManager mBufferManager;
-
     // binder thread, transaction thread
     mutable Mutex mLock;
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mReqWidth;
-    uint32_t mReqHeight;
-    uint32_t mReqFormat;
-    bool mNeedsScaling;
     bool mFixedSize;
 };
 
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 022f251..bcd8c83 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -32,8 +32,6 @@
 #include "LayerBase.h"
 #include "SurfaceFlinger.h"
 #include "DisplayHardware/DisplayHardware.h"
-#include "TextureManager.h"
-
 
 namespace android {
 
@@ -44,7 +42,7 @@
 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
     : dpy(display), contentDirty(false),
       sequence(uint32_t(android_atomic_inc(&sSequence))),
-      mFlinger(flinger),
+      mFlinger(flinger), mFiltering(false),
       mNeedsFiltering(false),
       mOrientation(0),
       mLeft(0), mTop(0),
@@ -54,8 +52,6 @@
 {
     const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
     mFlags = hw.getFlags();
-    mBufferCrop.makeInvalid();
-    mBufferTransform = 0;
 }
 
 LayerBase::~LayerBase()
@@ -310,6 +306,16 @@
     hwcl->handle = NULL;
 }
 
+void LayerBase::setFiltering(bool filtering)
+{
+    mFiltering = filtering;
+}
+
+bool LayerBase::getFiltering() const
+{
+    return mFiltering;
+}
+
 void LayerBase::draw(const Region& clip) const
 {
     // reset GL state
@@ -318,10 +324,12 @@
     onDraw(clip);
 }
 
-void LayerBase::drawForSreenShot() const
+void LayerBase::drawForSreenShot()
 {
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    setFiltering(true);
     onDraw( Region(hw.bounds()) );
+    setFiltering(false);
 }
 
 void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red,
@@ -332,8 +340,12 @@
     const uint32_t fbHeight = hw.getHeight();
     glColor4f(red,green,blue,alpha);
 
-    TextureManager::deactivateTextures();
-
+#if defined(GL_OES_EGL_image_external)
+        if (GLExtensions::getInstance().haveTextureExternal()) {
+            glDisable(GL_TEXTURE_EXTERNAL_OES);
+        }
+#endif
+    glDisable(GL_TEXTURE_2D);
     glDisable(GL_BLEND);
     glDisable(GL_DITHER);
 
@@ -354,24 +366,11 @@
     clearWithOpenGL(clip,0,0,0,0);
 }
 
-template <typename T>
-static inline
-void swap(T& a, T& b) {
-    T t(a);
-    a = b;
-    b = t;
-}
-
-void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
+void LayerBase::drawWithOpenGL(const Region& clip) const
 {
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     const uint32_t fbHeight = hw.getHeight();
     const State& s(drawingState());
-    
-    // bind our texture
-    TextureManager::activateTexture(texture, needsFiltering());
-    uint32_t width  = texture.width; 
-    uint32_t height = texture.height;
 
     GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
     if (UNLIKELY(s.alpha < 0xFF)) {
@@ -387,7 +386,7 @@
     } else {
         glColor4f(1, 1, 1, 1);
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        if (needsBlending()) {
+        if (!isOpaque()) {
             glEnable(GL_BLEND);
             glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
         } else {
@@ -395,86 +394,20 @@
         }
     }
 
-    /*
-     *  compute texture coordinates
-     *  here, we handle NPOT, cropping and buffer transformations
-     */
-
-    GLfloat cl, ct, cr, cb;
-    if (!mBufferCrop.isEmpty()) {
-        // source is cropped
-        const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width;
-        const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height;
-        cl = mBufferCrop.left   * us;
-        ct = mBufferCrop.top    * vs;
-        cr = mBufferCrop.right  * us;
-        cb = mBufferCrop.bottom * vs;
-    } else {
-        cl = 0;
-        ct = 0;
-        cr = (texture.NPOTAdjust ? texture.wScale : 1.0f);
-        cb = (texture.NPOTAdjust ? texture.hScale : 1.0f);
-    }
-
-    /*
-     * For the buffer transformation, we apply the rotation last.
-     * Since we're transforming the texture-coordinates, we need
-     * to apply the inverse of the buffer transformation:
-     *   inverse( FLIP_V -> FLIP_H -> ROT_90 )
-     *   <=> inverse( ROT_90 * FLIP_H * FLIP_V )
-     *    =  inverse(FLIP_V) * inverse(FLIP_H) * inverse(ROT_90)
-     *    =  FLIP_V * FLIP_H * ROT_270
-     *   <=> ROT_270 -> FLIP_H -> FLIP_V
-     *
-     * The rotation is performed first, in the texture coordinate space.
-     *
-     */
-
     struct TexCoords {
         GLfloat u;
         GLfloat v;
     };
 
-    enum {
-        // name of the corners in the texture map
-        LB = 0, // left-bottom
-        LT = 1, // left-top
-        RT = 2, // right-top
-        RB = 3  // right-bottom
-    };
-
-    // vertices in screen space
-    int vLT = LB;
-    int vLB = LT;
-    int vRB = RT;
-    int vRT = RB;
-
-    // the texture's source is rotated
-    uint32_t transform = mBufferTransform;
-    if (transform & HAL_TRANSFORM_ROT_90) {
-        vLT = RB;
-        vLB = LB;
-        vRB = LT;
-        vRT = RT;
-    }
-    if (transform & HAL_TRANSFORM_FLIP_V) {
-        swap(vLT, vLB);
-        swap(vRT, vRB);
-    }
-    if (transform & HAL_TRANSFORM_FLIP_H) {
-        swap(vLT, vRT);
-        swap(vLB, vRB);
-    }
-
     TexCoords texCoords[4];
-    texCoords[vLT].u = cl;
-    texCoords[vLT].v = ct;
-    texCoords[vLB].u = cl;
-    texCoords[vLB].v = cb;
-    texCoords[vRB].u = cr;
-    texCoords[vRB].v = cb;
-    texCoords[vRT].u = cr;
-    texCoords[vRT].v = ct;
+    texCoords[0].u = 0;
+    texCoords[0].v = 1;
+    texCoords[1].u = 0;
+    texCoords[1].v = 0;
+    texCoords[2].u = 1;
+    texCoords[2].v = 0;
+    texCoords[3].u = 1;
+    texCoords[3].v = 1;
 
     if (needsDithering()) {
         glEnable(GL_DITHER);
@@ -497,20 +430,6 @@
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 }
 
-void LayerBase::setBufferCrop(const Rect& crop) {
-    if (mBufferCrop != crop) {
-        mBufferCrop = crop;
-        mFlinger->invalidateHwcGeometry();
-    }
-}
-
-void LayerBase::setBufferTransform(uint32_t transform) {
-    if (mBufferTransform != transform) {
-        mBufferTransform = transform;
-        mFlinger->invalidateHwcGeometry();
-    }
-}
-
 void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
 {
     const Layer::State& s(drawingState());
@@ -518,10 +437,10 @@
             "+ %s %p\n"
             "      "
             "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
-            "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
+            "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, "
             "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
             getTypeId(), this, s.z, tx(), ty(), s.w, s.h,
-            needsBlending(), needsDithering(), contentDirty,
+            isOpaque(), needsDithering(), contentDirty,
             s.alpha, s.flags,
             s.transform[0][0], s.transform[0][1],
             s.transform[1][0], s.transform[1][1]);
@@ -555,9 +474,22 @@
     }
 }
 
-sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
+sp<ISurface> LayerBaseClient::createSurface()
 {
-    sp<Surface> s;
+    class BSurface : public BnSurface, public LayerCleaner {
+        virtual sp<ISurfaceTexture> getSurfaceTexture() const { return 0; }
+    public:
+        BSurface(const sp<SurfaceFlinger>& flinger,
+                const sp<LayerBaseClient>& layer)
+            : LayerCleaner(flinger, layer) { }
+    };
+    sp<ISurface> sur(new BSurface(mFlinger, this));
+    return sur;
+}
+
+sp<ISurface> LayerBaseClient::getSurface()
+{
+    sp<ISurface> s;
     Mutex::Autolock _l(mLock);
 
     LOG_ALWAYS_FATAL_IF(mHasSurface,
@@ -573,12 +505,6 @@
     return mClientSurfaceBinder;
 }
 
-sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
-{
-    return new Surface(mFlinger, mIdentity,
-            const_cast<LayerBaseClient *>(this));
-}
-
 void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
 {
     LayerBase::dump(result, buffer, SIZE);
@@ -601,44 +527,14 @@
 
 // ---------------------------------------------------------------------------
 
-LayerBaseClient::Surface::Surface(
-        const sp<SurfaceFlinger>& flinger,
-        int identity,
-        const sp<LayerBaseClient>& owner) 
-    : mFlinger(flinger), mIdentity(identity), mOwner(owner)
-{
+LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
+        const sp<LayerBaseClient>& layer)
+    : mFlinger(flinger), mLayer(layer) {
 }
 
-LayerBaseClient::Surface::~Surface() 
-{
-    /*
-     * This is a good place to clean-up all client resources 
-     */
-
+LayerBaseClient::LayerCleaner::~LayerCleaner() {
     // destroy client resources
-    mFlinger->destroySurface(mOwner);
-}
-
-sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
-    sp<LayerBaseClient> owner(mOwner.promote());
-    return owner;
-}
-
-status_t LayerBaseClient::Surface::onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    return BnSurface::onTransact(code, data, reply, flags);
-}
-
-sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int bufferIdx,
-        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
-{
-    return NULL; 
-}
-
-status_t LayerBaseClient::Surface::setBufferCount(int bufferCount)
-{
-    return INVALID_OPERATION;
+    mFlinger->destroySurface(mLayer);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 6c49a19..faf71dd 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -29,7 +29,6 @@
 #include <ui/Region.h>
 
 #include <surfaceflinger/ISurfaceComposerClient.h>
-#include <private/surfaceflinger/SharedBufferStack.h>
 #include <private/surfaceflinger/LayerState.h>
 
 #include <pixelflinger/pixelflinger.h>
@@ -43,13 +42,12 @@
 
 // ---------------------------------------------------------------------------
 
-class DisplayHardware;
 class Client;
+class DisplayHardware;
 class GraphicBuffer;
 class GraphicPlane;
 class LayerBaseClient;
 class SurfaceFlinger;
-class Texture;
 
 // ---------------------------------------------------------------------------
 
@@ -121,7 +119,7 @@
      * to perform the actual drawing.  
      */
     virtual void draw(const Region& clip) const;
-    virtual void drawForSreenShot() const;
+    virtual void drawForSreenShot();
     
     /**
      * onDraw - draws the surface.
@@ -174,9 +172,9 @@
     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
     
     /**
-     * needsBlending - true if this surface needs blending
+     * isOpaque - true if this surface is opaque
      */
-    virtual bool needsBlending() const  { return false; }
+    virtual bool isOpaque() const  { return true; }
 
     /**
      * needsDithering - true if this surface needs dithering
@@ -184,11 +182,9 @@
     virtual bool needsDithering() const { return false; }
 
     /**
-     * needsLinearFiltering - true if this surface needs filtering
+     * needsLinearFiltering - true if this surface's state requires filtering
      */
-    virtual bool needsFiltering() const {
-        return (!(mFlags & DisplayHardware::SLOW_CONFIG)) && mNeedsFiltering;
-    }
+    virtual bool needsFiltering() const { return mNeedsFiltering; }
 
     /**
      * isSecure - true if this surface is secure, that is if it prevents
@@ -231,21 +227,25 @@
           void clearWithOpenGL(const Region& clip, GLclampf r, GLclampf g,
                                GLclampf b, GLclampf alpha) const;
           void clearWithOpenGL(const Region& clip) const;
-          void drawWithOpenGL(const Region& clip, const Texture& texture) const;
-          
-          // these must be called from the post/drawing thread
-          void setBufferCrop(const Rect& crop);
-          void setBufferTransform(uint32_t transform);
+          void drawWithOpenGL(const Region& clip) const;
+
+          void setFiltering(bool filtering);
+          bool getFiltering() const;
 
                 sp<SurfaceFlinger> mFlinger;
                 uint32_t        mFlags;
 
-                // post/drawing thread
-                Rect mBufferCrop;
-                uint32_t mBufferTransform;
+private:
+                // accessed only in the main thread
+                // Whether filtering is forced on or not
+                bool            mFiltering;
 
                 // cached during validateVisibility()
+                // Whether filtering is needed b/c of the drawingstate
                 bool            mNeedsFiltering;
+
+protected:
+                // cached during validateVisibility()
                 int32_t         mOrientation;
                 GLfloat         mVertices[4][2];
                 Rect            mTransformedBounds;
@@ -281,52 +281,38 @@
 class LayerBaseClient : public LayerBase
 {
 public:
-    class Surface;
-
             LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
                         const sp<Client>& client);
-    virtual ~LayerBaseClient();
 
-            sp<Surface> getSurface();
+            virtual ~LayerBaseClient();
+
+            sp<ISurface> getSurface();
             wp<IBinder> getSurfaceBinder() const;
-    virtual sp<Surface> createSurface() const;
+
     virtual sp<LayerBaseClient> getLayerBaseClient() const {
         return const_cast<LayerBaseClient*>(this); }
+
     virtual const char* getTypeId() const { return "LayerBaseClient"; }
 
     uint32_t getIdentity() const { return mIdentity; }
 
-    class Surface : public BnSurface  {
-    public:
-        int32_t getIdentity() const { return mIdentity; }
-        
-    protected:
-        Surface(const sp<SurfaceFlinger>& flinger, int identity,
-                const sp<LayerBaseClient>& owner);
-        virtual ~Surface();
-        virtual status_t onTransact(uint32_t code, const Parcel& data,
-                Parcel* reply, uint32_t flags);
-        sp<LayerBaseClient> getOwner() const;
-
-    private:
-        virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
-                uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
-        virtual status_t setBufferCount(int bufferCount);
-
-    protected:
-        friend class LayerBaseClient;
-        sp<SurfaceFlinger>  mFlinger;
-        int32_t             mIdentity;
-        wp<LayerBaseClient> mOwner;
-    };
-
-    friend class Surface;
-
 protected:
     virtual void dump(String8& result, char* scratch, size_t size) const;
     virtual void shortDump(String8& result, char* scratch, size_t size) const;
 
+    class LayerCleaner {
+        sp<SurfaceFlinger> mFlinger;
+        wp<LayerBaseClient> mLayer;
+    protected:
+        ~LayerCleaner();
+    public:
+        LayerCleaner(const sp<SurfaceFlinger>& flinger,
+                const sp<LayerBaseClient>& layer);
+    };
+
 private:
+    virtual sp<ISurface> createSurface();
+
     mutable Mutex mLock;
     mutable bool mHasSurface;
     wp<IBinder> mClientSurfaceBinder;
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index f79166d..654817d 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -65,8 +65,6 @@
             glDisable(GL_TEXTURE_EXTERNAL_OES);
         }
 #endif
-        glDisable(GL_TEXTURE_2D);
-
         glVertexPointer(2, GL_FLOAT, 0, mVertices);
 
         while (it != end) {
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index 75f9a89..8770e6d 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -37,7 +37,7 @@
         virtual ~LayerDim();
 
     virtual void onDraw(const Region& clip) const;
-    virtual bool needsBlending() const    { return true; }
+    virtual bool isOpaque() const         { return false; }
     virtual bool isSecure() const         { return false; }
     virtual bool isProtectedByApp() const { return false; }
     virtual bool isProtectedByDRM() const { return false; }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b7a51a4..97edfee 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -53,6 +53,8 @@
 #include "DisplayHardware/DisplayHardware.h"
 #include "DisplayHardware/HWComposer.h"
 
+#include <private/surfaceflinger/SharedBufferStack.h>
+
 /* ideally AID_GRAPHICS would be in a semi-public header
  * or there would be a way to map a user/group name to its id
  */
@@ -133,17 +135,6 @@
     return bclient;
 }
 
-sp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
-{
-    sp<ISurfaceComposerClient> bclient;
-    sp<UserClient> client(new UserClient(this));
-    status_t err = client->initCheck();
-    if (err == NO_ERROR) {
-        bclient = client;
-    }
-    return bclient;
-}
-
 sp<IGraphicBufferAlloc> SurfaceFlinger::createGraphicBufferAlloc()
 {
     sp<GraphicBufferAlloc> gba(new GraphicBufferAlloc());
@@ -322,11 +313,6 @@
     mEventQueue.invalidate();
 }
 
-void SurfaceFlinger::signal() const {
-    // this is the IPC call
-    const_cast<SurfaceFlinger*>(this)->signalEvent();
-}
-
 bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const {
     Mutex::Autolock _l(mStateLock);
     sp<IBinder> surfBinder(surface->asBinder());
@@ -658,7 +644,7 @@
 
         // handle hidden surfaces by setting the visible region to empty
         if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
-            const bool translucent = layer->needsBlending();
+            const bool translucent = !layer->isOpaque();
             const Rect bounds(layer->visibleBounds());
             visibleRegion.set(bounds);
             visibleRegion.andSelf(screenRegion);
@@ -921,7 +907,7 @@
             for (size_t i=0 ; i<count ; i++) {
                 if (cur[i].hints & HWC_HINT_CLEAR_FB) {
                     const sp<LayerBase>& layer(layers[i]);
-                    if (!(layer->needsBlending())) {
+                    if (layer->isOpaque()) {
                         transparent.orSelf(layer->visibleRegionScreen);
                     }
                 }
@@ -979,8 +965,6 @@
         composeSurfaces(repaint);
     }
 
-    TextureManager::deactivateTextures();
-
     glDisable(GL_BLEND);
     glDisable(GL_DITHER);
     glDisable(GL_SCISSOR_TEST);
@@ -1070,6 +1054,7 @@
             glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
         }
         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        glDisable(GL_TEXTURE_2D);
         glLoadIdentity();
         glMatrixMode(GL_MODELVIEW);
     }
@@ -1269,7 +1254,7 @@
         uint32_t flags)
 {
     sp<LayerBaseClient> layer;
-    sp<LayerBaseClient::Surface> surfaceHandle;
+    sp<ISurface> surfaceHandle;
 
     if (int32_t(w|h) < 0) {
         LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
@@ -1300,13 +1285,13 @@
         surfaceHandle = layer->getSurface();
         if (surfaceHandle != 0) {
             params->token = token;
-            params->identity = surfaceHandle->getIdentity();
+            params->identity = layer->getIdentity();
             params->width = w;
             params->height = h;
             params->format = format;
             if (normalLayer != 0) {
                 Mutex::Autolock _l(mStateLock);
-                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
+                mLayerMap.add(layer->getSurfaceBinder(), normalLayer);
             }
         }
 
@@ -1782,7 +1767,6 @@
 
     GLfloat vtx[8];
     const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
-    glEnable(GL_TEXTURE_2D);
     glBindTexture(GL_TEXTURE_2D, tname);
     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -1900,6 +1884,7 @@
     glEnable(GL_SCISSOR_TEST);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDeleteTextures(1, &tname);
+    glDisable(GL_TEXTURE_2D);
     return NO_ERROR;
 }
 
@@ -1930,7 +1915,6 @@
 
     GLfloat vtx[8];
     const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
-    glEnable(GL_TEXTURE_2D);
     glBindTexture(GL_TEXTURE_2D, tname);
     glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -2044,6 +2028,7 @@
     glEnable(GL_SCISSOR_TEST);
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     glDeleteTextures(1, &tname);
+    glDisable(GL_TEXTURE_2D);
 
     return NO_ERROR;
 }
@@ -2408,20 +2393,72 @@
     return lbc;
 }
 
-sp<IMemoryHeap> Client::getControlBlock() const {
-    return 0;
+
+status_t Client::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    // these must be checked
+     IPCThreadState* ipc = IPCThreadState::self();
+     const int pid = ipc->getCallingPid();
+     const int uid = ipc->getCallingUid();
+     const int self_pid = getpid();
+     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS && uid != 0)) {
+         // we're called from a different process, do the real check
+         if (!checkCallingPermission(
+                 String16("android.permission.ACCESS_SURFACE_FLINGER")))
+         {
+             LOGE("Permission Denial: "
+                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
+             return PERMISSION_DENIED;
+         }
+     }
+     return BnSurfaceComposerClient::onTransact(code, data, reply, flags);
 }
-ssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
-    return -1;
-}
+
+
 sp<ISurface> Client::createSurface(
         ISurfaceComposerClient::surface_data_t* params,
         const String8& name,
         DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
         uint32_t flags)
 {
-    return mFlinger->createSurface(params, name, this,
-            display, w, h, format, flags);
+    /*
+     * createSurface must be called from the GL thread so that it can
+     * have access to the GL context.
+     */
+
+    class MessageCreateSurface : public MessageBase {
+        sp<ISurface> result;
+        SurfaceFlinger* flinger;
+        ISurfaceComposerClient::surface_data_t* params;
+        Client* client;
+        const String8& name;
+        DisplayID display;
+        uint32_t w, h;
+        PixelFormat format;
+        uint32_t flags;
+    public:
+        MessageCreateSurface(SurfaceFlinger* flinger,
+                ISurfaceComposerClient::surface_data_t* params,
+                const String8& name, Client* client,
+                DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
+                uint32_t flags)
+            : flinger(flinger), params(params), client(client), name(name),
+              display(display), w(w), h(h), format(format), flags(flags)
+        {
+        }
+        sp<ISurface> getResult() const { return result; }
+        virtual bool handler() {
+            result = flinger->createSurface(params, name, client,
+                    display, w, h, format, flags);
+            return true;
+        }
+    };
+
+    sp<MessageBase> msg = new MessageCreateSurface(mFlinger.get(),
+            params, name, this, display, w, h, format, flags);
+    mFlinger->postMessageSync(msg);
+    return static_cast<MessageCreateSurface*>( msg.get() )->getResult();
 }
 status_t Client::destroySurface(SurfaceID sid) {
     return mFlinger->removeSurface(this, sid);
@@ -2432,113 +2469,6 @@
 
 // ---------------------------------------------------------------------------
 
-UserClient::UserClient(const sp<SurfaceFlinger>& flinger)
-    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
-{
-    const int pgsize = getpagesize();
-    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
-
-    mCblkHeap = new MemoryHeapBase(cblksize, 0,
-            "SurfaceFlinger Client control-block");
-
-    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
-    if (ctrlblk) { // construct the shared structure in-place.
-        new(ctrlblk) SharedClient;
-    }
-}
-
-UserClient::~UserClient()
-{
-    if (ctrlblk) {
-        ctrlblk->~SharedClient();  // destroy our shared-structure.
-    }
-
-    /*
-     * When a UserClient dies, it's unclear what to do exactly.
-     * We could go ahead and destroy all surfaces linked to that client
-     * however, it wouldn't be fair to the main Client
-     * (usually the the window-manager), which might want to re-target
-     * the layer to another UserClient.
-     * I think the best is to do nothing, or not much; in most cases the
-     * WM itself will go ahead and clean things up when it detects a client of
-     * his has died.
-     * The remaining question is what to display? currently we keep
-     * just keep the current buffer.
-     */
-}
-
-status_t UserClient::initCheck() const {
-    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
-}
-
-void UserClient::detachLayer(const Layer* layer)
-{
-    int32_t name = layer->getToken();
-    if (name >= 0) {
-        int32_t mask = 1LU<<name;
-        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
-            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
-        }
-    }
-}
-
-sp<IMemoryHeap> UserClient::getControlBlock() const {
-    return mCblkHeap;
-}
-
-ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
-{
-    int32_t name = NAME_NOT_FOUND;
-    sp<Layer> layer(mFlinger->getLayer(sur));
-    if (layer == 0) {
-        return name;
-    }
-
-    // if this layer already has a token, just return it
-    name = layer->getToken();
-    if ((name >= 0) && (layer->getClient() == this)) {
-        return name;
-    }
-
-    name = 0;
-    do {
-        int32_t mask = 1LU<<name;
-        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
-            // we found and locked that name
-            status_t err = layer->setToken(
-                    const_cast<UserClient*>(this), ctrlblk, name);
-            if (err != NO_ERROR) {
-                // free the name
-                android_atomic_and(~mask, &mBitmap);
-                name = err;
-            }
-            break;
-        }
-        if (++name >= int32_t(SharedBufferStack::NUM_LAYERS_MAX))
-            name = NO_MEMORY;
-    } while(name >= 0);
-
-    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
-    //        sur->asBinder().get(), name, this, mBitmap);
-    return name;
-}
-
-sp<ISurface> UserClient::createSurface(
-        ISurfaceComposerClient::surface_data_t* params,
-        const String8& name,
-        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
-        uint32_t flags) {
-    return 0;
-}
-status_t UserClient::destroySurface(SurfaceID sid) {
-    return INVALID_OPERATION;
-}
-status_t UserClient::setState(int32_t count, const layer_state_t* states) {
-    return INVALID_OPERATION;
-}
-
-// ---------------------------------------------------------------------------
-
 GraphicBufferAlloc::GraphicBufferAlloc() {}
 
 GraphicBufferAlloc::~GraphicBufferAlloc() {}
@@ -2547,11 +2477,11 @@
         PixelFormat format, uint32_t usage) {
     sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
     status_t err = graphicBuffer->initCheck();
-    if (err != 0) {
-        LOGE("createGraphicBuffer: init check failed: %d", err);
-        return 0;
-    } else if (graphicBuffer->handle == 0) {
-        LOGE("createGraphicBuffer: unable to create GraphicBuffer");
+    if (err != 0 || graphicBuffer->handle == 0) {
+        GraphicBuffer::dumpAllocationsToSystemLog();
+        LOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
+             "failed (%s), handle=%p",
+                w, h, strerror(-err), graphicBuffer->handle);
         return 0;
     }
     return graphicBuffer;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 992861a..af1ef04 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -50,6 +50,7 @@
 class FreezeLock;
 class Layer;
 class LayerDim;
+struct surface_flinger_cblk_t;
 
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
@@ -72,14 +73,14 @@
 private:
 
     // ISurfaceComposerClient interface
-    virtual sp<IMemoryHeap> getControlBlock() const;
-    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const;
     virtual sp<ISurface> createSurface(
             surface_data_t* params, const String8& name,
             DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
             uint32_t flags);
     virtual status_t destroySurface(SurfaceID surfaceId);
     virtual status_t setState(int32_t count, const layer_state_t* states);
+    virtual status_t onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
 
     // constant
     sp<SurfaceFlinger> mFlinger;
@@ -92,40 +93,6 @@
     mutable Mutex mLock;
 };
 
-class UserClient : public BnSurfaceComposerClient
-{
-public:
-    // pointer to this client's control block
-    SharedClient* ctrlblk;
-
-public:
-        UserClient(const sp<SurfaceFlinger>& flinger);
-        ~UserClient();
-
-    status_t initCheck() const;
-
-    // protected by SurfaceFlinger::mStateLock
-    void detachLayer(const Layer* layer);
-
-private:
-
-    // ISurfaceComposerClient interface
-    virtual sp<IMemoryHeap> getControlBlock() const;
-    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const;
-    virtual sp<ISurface> createSurface(
-            surface_data_t* params, const String8& name,
-            DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
-            uint32_t flags);
-    virtual status_t destroySurface(SurfaceID surfaceId);
-    virtual status_t setState(int32_t count, const layer_state_t* states);
-
-    // atomic-ops
-    mutable volatile int32_t mBitmap;
-
-    sp<IMemoryHeap> mCblkHeap;
-    sp<SurfaceFlinger> mFlinger;
-};
-
 class GraphicBufferAlloc : public BnGraphicBufferAlloc
 {
 public:
@@ -199,7 +166,6 @@
 
     // ISurfaceComposer interface
     virtual sp<ISurfaceComposerClient>  createConnection();
-    virtual sp<ISurfaceComposerClient>  createClientConnection();
     virtual sp<IGraphicBufferAlloc>     createGraphicBufferAlloc();
     virtual sp<IMemoryHeap>             getCblk() const;
     virtual void                        bootFinished();
@@ -208,7 +174,6 @@
     virtual status_t                    freezeDisplay(DisplayID dpy, uint32_t flags);
     virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
     virtual int                         setOrientation(DisplayID dpy, int orientation, uint32_t flags);
-    virtual void                        signal() const;
     virtual bool                        authenticateSurface(const sp<ISurface>& surface) const;
 
     virtual status_t captureScreen(DisplayID dpy,
@@ -235,7 +200,6 @@
     friend class Client;
     friend class LayerBase;
     friend class LayerBaseClient;
-    friend class LayerBaseClient::Surface;
     friend class Layer;
     friend class LayerDim;
 
diff --git a/services/surfaceflinger/SurfaceTextureLayer.cpp b/services/surfaceflinger/SurfaceTextureLayer.cpp
new file mode 100644
index 0000000..60fa965
--- /dev/null
+++ b/services/surfaceflinger/SurfaceTextureLayer.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+
+#include "Layer.h"
+#include "SurfaceTextureLayer.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+
+SurfaceTextureLayer::SurfaceTextureLayer(GLuint tex, const sp<Layer>& layer)
+    : SurfaceTexture(tex), mLayer(layer) {
+}
+
+SurfaceTextureLayer::~SurfaceTextureLayer() {
+}
+
+
+status_t SurfaceTextureLayer::setDefaultBufferSize(uint32_t w, uint32_t h)
+{
+    //LOGD("%s, w=%u, h=%u", __PRETTY_FUNCTION__, w, h);
+    return SurfaceTexture::setDefaultBufferSize(w, h);
+}
+
+status_t SurfaceTextureLayer::setDefaultBufferFormat(uint32_t format)
+{
+    mDefaultFormat = format;
+    return NO_ERROR;
+}
+
+status_t SurfaceTextureLayer::setBufferCount(int bufferCount) {
+    status_t res = SurfaceTexture::setBufferCount(bufferCount);
+    return res;
+}
+
+status_t SurfaceTextureLayer::dequeueBuffer(int *buf,
+        uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
+
+    status_t res(NO_INIT);
+    sp<Layer> layer(mLayer.promote());
+    if (layer != NULL) {
+        if (format == 0)
+            format = mDefaultFormat;
+        uint32_t effectiveUsage = layer->getEffectiveUsage(usage);
+        //LOGD("%s, w=%u, h=%u, format=%u, usage=%08x, effectiveUsage=%08x",
+        //        __PRETTY_FUNCTION__, w, h, format, usage, effectiveUsage);
+        res = SurfaceTexture::dequeueBuffer(buf, w, h, format, effectiveUsage);
+        if (res == NO_ERROR) {
+            layer->setFixedSize(w && h);
+        }
+    }
+    return res;
+}
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/services/surfaceflinger/SurfaceTextureLayer.h b/services/surfaceflinger/SurfaceTextureLayer.h
new file mode 100644
index 0000000..7faff54
--- /dev/null
+++ b/services/surfaceflinger/SurfaceTextureLayer.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 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 ANDROID_SURFACE_TEXTURE_LAYER_H
+#define ANDROID_SURFACE_TEXTURE_LAYER_H
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <gui/SurfaceTexture.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Layer;
+
+class SurfaceTextureLayer : public SurfaceTexture
+{
+    wp<Layer> mLayer;
+    uint32_t mDefaultFormat;
+
+public:
+    SurfaceTextureLayer(GLuint tex, const sp<Layer>& layer);
+    ~SurfaceTextureLayer();
+
+    status_t setDefaultBufferSize(uint32_t w, uint32_t h);
+    status_t setDefaultBufferFormat(uint32_t format);
+
+public:
+    virtual status_t setBufferCount(int bufferCount);
+
+protected:
+    virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
+            uint32_t format, uint32_t usage);
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SURFACE_TEXTURE_LAYER_H
diff --git a/services/surfaceflinger/clz.h b/services/surfaceflinger/clz.h
index 0ddf986..ca44555 100644
--- a/services/surfaceflinger/clz.h
+++ b/services/surfaceflinger/clz.h
@@ -20,18 +20,10 @@
 
 namespace android {
 
-int clz_impl(int32_t x);
-
-int inline clz(int32_t x)
-{
-#if defined(__arm__) && !defined(__thumb__)
+int inline clz(int32_t x) {
     return __builtin_clz(x);
-#else
-    return clz_impl(x);
-#endif
 }
 
-
 }; // namespace android
 
 #endif /* ANDROID_SURFACE_FLINGER_CLZ_H */