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
