diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index b1aeb32..544b664 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -25,8 +25,8 @@
 	SensorEventQueue.cpp \
 	SensorManager.cpp \
 	Surface.cpp \
+	SurfaceControl.cpp \
 	SurfaceComposerClient.cpp \
-	SurfaceTextureClient.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
 	libbinder \
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 81fc019..410ad5d 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2010 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.
@@ -15,359 +15,851 @@
  */
 
 #define LOG_TAG "Surface"
-
-#include <stdint.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+//#define LOG_NDEBUG 0
 
 #include <android/native_window.h>
 
-#include <utils/CallStack.h>
-#include <utils/Errors.h>
+#include <binder/Parcel.h>
+
 #include <utils/Log.h>
-#include <utils/threads.h>
+#include <utils/Trace.h>
 
-#include <binder/IPCThreadState.h>
+#include <ui/Fence.h>
 
-#include <ui/DisplayInfo.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/Rect.h>
-
-#include <gui/ISurface.h>
 #include <gui/ISurfaceComposer.h>
-#include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
-#include <gui/SurfaceTextureClient.h>
+#include <gui/GLConsumer.h>
+#include <gui/Surface.h>
+
+#include <private/gui/ComposerService.h>
 
 namespace android {
 
-// ============================================================================
-//  SurfaceControl
-// ============================================================================
-
-SurfaceControl::SurfaceControl(
-        const sp<SurfaceComposerClient>& client, 
-        const sp<ISurface>& surface)
-    : mClient(client)
+Surface::Surface(
+        const sp<IGraphicBufferProducer>& bufferProducer)
 {
-    if (surface != 0) {
-        mSurface = surface->asBinder();
+    Surface::init();
+    Surface::setIGraphicBufferProducer(bufferProducer);
+}
+
+Surface::Surface() {
+    Surface::init();
+}
+
+Surface::~Surface() {
+    if (mConnectedToCpu) {
+        Surface::disconnect(NATIVE_WINDOW_API_CPU);
     }
 }
-        
-SurfaceControl::~SurfaceControl()
-{
-    destroy();
+
+void Surface::init() {
+    // Initialize the ANativeWindow function pointers.
+    ANativeWindow::setSwapInterval  = hook_setSwapInterval;
+    ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
+    ANativeWindow::cancelBuffer     = hook_cancelBuffer;
+    ANativeWindow::queueBuffer      = hook_queueBuffer;
+    ANativeWindow::query            = hook_query;
+    ANativeWindow::perform          = hook_perform;
+
+    ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
+    ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
+    ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
+    ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;
+
+    const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
+    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
+
+    mReqWidth = 0;
+    mReqHeight = 0;
+    mReqFormat = 0;
+    mReqUsage = 0;
+    mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
+    mCrop.clear();
+    mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
+    mTransform = 0;
+    mDefaultWidth = 0;
+    mDefaultHeight = 0;
+    mUserWidth = 0;
+    mUserHeight = 0;
+    mTransformHint = 0;
+    mConsumerRunningBehind = false;
+    mConnectedToCpu = false;
 }
 
-void SurfaceControl::destroy()
+void Surface::setIGraphicBufferProducer(
+        const sp<IGraphicBufferProducer>& bufferProducer)
 {
-    if (isValid()) {
-        mClient->destroySurface(mSurface);
+    mGraphicBufferProducer = bufferProducer;
+}
+
+sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const {
+    return mGraphicBufferProducer;
+}
+
+int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
+    Surface* c = getSelf(window);
+    return c->setSwapInterval(interval);
+}
+
+int Surface::hook_dequeueBuffer(ANativeWindow* window,
+        ANativeWindowBuffer** buffer, int* fenceFd) {
+    Surface* c = getSelf(window);
+    return c->dequeueBuffer(buffer, fenceFd);
+}
+
+int Surface::hook_cancelBuffer(ANativeWindow* window,
+        ANativeWindowBuffer* buffer, int fenceFd) {
+    Surface* c = getSelf(window);
+    return c->cancelBuffer(buffer, fenceFd);
+}
+
+int Surface::hook_queueBuffer(ANativeWindow* window,
+        ANativeWindowBuffer* buffer, int fenceFd) {
+    Surface* c = getSelf(window);
+    return c->queueBuffer(buffer, fenceFd);
+}
+
+int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
+        ANativeWindowBuffer** buffer) {
+    Surface* c = getSelf(window);
+    ANativeWindowBuffer* buf;
+    int fenceFd = -1;
+    int result = c->dequeueBuffer(&buf, &fenceFd);
+    sp<Fence> fence(new Fence(fenceFd));
+    int waitResult = fence->waitForever(1000, "dequeueBuffer_DEPRECATED");
+    if (waitResult != OK) {
+        ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
+                waitResult);
+        c->cancelBuffer(buf, -1);
+        return waitResult;
     }
-    // clear all references and trigger an IPC now, to make sure things
-    // happen without delay, since these resources are quite heavy.
-    mClient.clear();
-    mSurface.clear();
-    IPCThreadState::self()->flushCommands();
+    *buffer = buf;
+    return result;
 }
 
-void SurfaceControl::clear() 
-{
-    // here, the window manager tells us explicitly that we should destroy
-    // the surface's resource. Soon after this call, it will also release
-    // its last reference (which will call the dtor); however, it is possible
-    // that a client living in the same process still holds references which
-    // would delay the call to the dtor -- that is why we need this explicit
-    // "clear()" call.
-    destroy();
+int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
+        ANativeWindowBuffer* buffer) {
+    Surface* c = getSelf(window);
+    return c->cancelBuffer(buffer, -1);
 }
 
-bool SurfaceControl::isSameSurface(
-        const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) 
-{
-    if (lhs == 0 || rhs == 0)
-        return false;
-    return lhs->mSurface == rhs->mSurface;
+int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
+        ANativeWindowBuffer* buffer) {
+    Surface* c = getSelf(window);
+    return c->lockBuffer_DEPRECATED(buffer);
 }
 
-status_t SurfaceControl::setLayerStack(int32_t layerStack) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setLayerStack(mSurface, layerStack);
-}
-status_t SurfaceControl::setLayer(int32_t layer) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setLayer(mSurface, layer);
-}
-status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setPosition(mSurface, x, y);
-}
-status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setSize(mSurface, w, h);
-}
-status_t SurfaceControl::hide() {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->hide(mSurface);
-}
-status_t SurfaceControl::show() {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->show(mSurface);
-}
-status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setFlags(mSurface, flags, mask);
-}
-status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setTransparentRegionHint(mSurface, transparent);
-}
-status_t SurfaceControl::setAlpha(float alpha) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setAlpha(mSurface, alpha);
-}
-status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setMatrix(mSurface, dsdx, dtdx, dsdy, dtdy);
-}
-status_t SurfaceControl::setCrop(const Rect& crop) {
-    status_t err = validate();
-    if (err < 0) return err;
-    const sp<SurfaceComposerClient>& client(mClient);
-    return client->setCrop(mSurface, crop);
+int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
+        ANativeWindowBuffer* buffer) {
+    Surface* c = getSelf(window);
+    return c->queueBuffer(buffer, -1);
 }
 
-status_t SurfaceControl::validate() const
-{
-    if (mSurface==0 || mClient==0) {
-        ALOGE("invalid ISurface (%p) or client (%p)",
-                mSurface.get(), mClient.get());
-        return NO_INIT;
+int Surface::hook_query(const ANativeWindow* window,
+                                int what, int* value) {
+    const Surface* c = getSelf(window);
+    return c->query(what, value);
+}
+
+int Surface::hook_perform(ANativeWindow* window, int operation, ...) {
+    va_list args;
+    va_start(args, operation);
+    Surface* c = getSelf(window);
+    return c->perform(operation, args);
+}
+
+int Surface::setSwapInterval(int interval) {
+    ATRACE_CALL();
+    // EGL specification states:
+    //  interval is silently clamped to minimum and maximum implementation
+    //  dependent values before being stored.
+    // Although we don't have to, we apply the same logic here.
+
+    if (interval < minSwapInterval)
+        interval = minSwapInterval;
+
+    if (interval > maxSwapInterval)
+        interval = maxSwapInterval;
+
+    status_t res = mGraphicBufferProducer->setSynchronousMode(interval ? true : false);
+
+    return res;
+}
+
+int Surface::dequeueBuffer(android_native_buffer_t** buffer,
+        int* fenceFd) {
+    ATRACE_CALL();
+    ALOGV("Surface::dequeueBuffer");
+    Mutex::Autolock lock(mMutex);
+    int buf = -1;
+    int reqW = mReqWidth ? mReqWidth : mUserWidth;
+    int reqH = mReqHeight ? mReqHeight : mUserHeight;
+    sp<Fence> fence;
+    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, fence, reqW, reqH,
+            mReqFormat, mReqUsage);
+    if (result < 0) {
+        ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d)"
+             "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
+             result);
+        return result;
     }
-    return NO_ERROR;
-}
-
-status_t SurfaceControl::writeSurfaceToParcel(
-        const sp<SurfaceControl>& control, Parcel* parcel)
-{
-    sp<IBinder> sur;
-    if (SurfaceControl::isValid(control)) {
-        sur = control->mSurface;
-    }
-    parcel->writeStrongBinder(sur);
-    parcel->writeStrongBinder(NULL);  // NULL IGraphicBufferProducer in this case.
-    return NO_ERROR;
-}
-
-sp<Surface> SurfaceControl::getSurface() const
-{
-    Mutex::Autolock _l(mLock);
-    if (mSurfaceData == 0) {
-        sp<SurfaceControl> surface_control(const_cast<SurfaceControl*>(this));
-        mSurfaceData = new Surface(surface_control);
-    }
-    return mSurfaceData;
-}
-
-// ============================================================================
-//  Surface
-// ============================================================================
-
-Surface::Surface(const sp<SurfaceControl>& surface)
-    : SurfaceTextureClient()
-{
-    mSurface = interface_cast<ISurface>(surface->mSurface);
-    sp<IGraphicBufferProducer> st;
-    if (mSurface != NULL) {
-        st = mSurface->getSurfaceTexture();
-    }
-    init(st);
-}
-
-Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
-    : SurfaceTextureClient()
-{
-    mSurface = interface_cast<ISurface>(ref);
-    sp<IBinder> st_binder(parcel.readStrongBinder());
-    sp<IGraphicBufferProducer> st;
-    if (st_binder != NULL) {
-        st = interface_cast<IGraphicBufferProducer>(st_binder);
-    } else if (mSurface != NULL) {
-        st = mSurface->getSurfaceTexture();
-    }
-    init(st);
-}
-
-Surface::Surface(const sp<IGraphicBufferProducer>& st)
-    : SurfaceTextureClient(),
-      mSurface(NULL)
-{
-    init(st);
-}
-
-status_t Surface::writeToParcel(
-        const sp<Surface>& surface, Parcel* parcel)
-{
-    sp<ISurface> sur;
-    sp<IGraphicBufferProducer> st;
-    uint32_t identity = 0;
-    if (Surface::isValid(surface)) {
-        sur      = surface->mSurface;
-        st       = surface->getISurfaceTexture();
-    } else if (surface != 0 &&
-            (surface->mSurface != NULL ||
-             surface->getISurfaceTexture() != NULL)) {
-        ALOGE("Parceling invalid surface with non-NULL ISurface/IGraphicBufferProducer "
-             "as NULL: mSurface = %p, bufferProducer = %p ",
-             surface->mSurface.get(), surface->getISurfaceTexture().get());
+    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
+    if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
+        freeAllBuffers();
     }
 
-    parcel->writeStrongBinder(sur != NULL ? sur->asBinder() : NULL);
-    parcel->writeStrongBinder(st != NULL ? st->asBinder() : NULL);
-    return NO_ERROR;
+    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
+        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
+        if (result != NO_ERROR) {
+            ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d",
+                    result);
+            return result;
+        }
+    }
 
-}
-
-Mutex Surface::sCachedSurfacesLock;
-DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces;
-
-sp<Surface> Surface::readFromParcel(const Parcel& data) {
-    Mutex::Autolock _l(sCachedSurfacesLock);
-    sp<IBinder> binder(data.readStrongBinder());
-    sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote();
-    if (surface == 0) {
-       surface = new Surface(data, binder);
-       sCachedSurfaces.add(binder, surface);
+    if (fence->isValid()) {
+        *fenceFd = fence->dup();
+        if (*fenceFd == -1) {
+            ALOGE("dequeueBuffer: error duping fence: %d", errno);
+            // dup() should never fail; something is badly wrong. Soldier on
+            // and hope for the best; the worst that should happen is some
+            // visible corruption that lasts until the next frame.
+        }
     } else {
-        // The Surface was found in the cache, but we still should clear any
-        // remaining data from the parcel.
-        data.readStrongBinder();  // IGraphicBufferProducer
-        data.readInt32();         // identity
+        *fenceFd = -1;
     }
-    if (surface->mSurface == NULL && surface->getISurfaceTexture() == NULL) {
-        surface = 0;
-    }
-    cleanCachedSurfacesLocked();
-    return surface;
+
+    *buffer = gbuf.get();
+    return OK;
 }
 
-// Remove the stale entries from the surface cache.  This should only be called
-// with sCachedSurfacesLock held.
-void Surface::cleanCachedSurfacesLocked() {
-    for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
-        wp<Surface> s(sCachedSurfaces.valueAt(i));
-        if (s == 0 || s.promote() == 0) {
-            sCachedSurfaces.removeItemsAt(i);
+int Surface::cancelBuffer(android_native_buffer_t* buffer,
+        int fenceFd) {
+    ATRACE_CALL();
+    ALOGV("Surface::cancelBuffer");
+    Mutex::Autolock lock(mMutex);
+    int i = getSlotFromBufferLocked(buffer);
+    if (i < 0) {
+        return i;
+    }
+    sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
+    mGraphicBufferProducer->cancelBuffer(i, fence);
+    return OK;
+}
+
+int Surface::getSlotFromBufferLocked(
+        android_native_buffer_t* buffer) const {
+    bool dumpedState = false;
+    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+        if (mSlots[i].buffer != NULL &&
+                mSlots[i].buffer->handle == buffer->handle) {
+            return i;
         }
     }
+    ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
+    return BAD_VALUE;
 }
 
-void Surface::init(const sp<IGraphicBufferProducer>& bufferProducer)
-{
-    if (mSurface != NULL || bufferProducer != NULL) {
-        ALOGE_IF(bufferProducer==0, "got a NULL IGraphicBufferProducer from ISurface");
-        if (bufferProducer != NULL) {
-            setISurfaceTexture(bufferProducer);
-            setUsage(GraphicBuffer::USAGE_HW_RENDER);
-        }
+int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) {
+    ALOGV("Surface::lockBuffer");
+    Mutex::Autolock lock(mMutex);
+    return OK;
+}
 
-        // TODO: the display metrics should come from the display manager
-        DisplayInfo dinfo;
-        sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(
-                ISurfaceComposer::eDisplayIdMain);
-        SurfaceComposerClient::getDisplayInfo(display, &dinfo);
-        const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
-        const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
-        const_cast<uint32_t&>(ANativeWindow::flags) = 0;
+int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
+    ATRACE_CALL();
+    ALOGV("Surface::queueBuffer");
+    Mutex::Autolock lock(mMutex);
+    int64_t timestamp;
+    if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
+        timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+        ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
+             timestamp / 1000000.f);
+    } else {
+        timestamp = mTimestamp;
     }
-}
+    int i = getSlotFromBufferLocked(buffer);
+    if (i < 0) {
+        return i;
+    }
 
-Surface::~Surface()
-{
-    // clear all references and trigger an IPC now, to make sure things
-    // happen without delay, since these resources are quite heavy.
-    mSurface.clear();
-    IPCThreadState::self()->flushCommands();
-}
 
-bool Surface::isValid() {
-    return getISurfaceTexture() != NULL;
-}
+    // Make sure the crop rectangle is entirely inside the buffer.
+    Rect crop;
+    mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
 
-sp<IGraphicBufferProducer> Surface::getSurfaceTexture() {
-    return getISurfaceTexture();
-}
+    sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
+    IGraphicBufferProducer::QueueBufferOutput output;
+    IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode,
+            mTransform, fence);
+    status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
+    if (err != OK)  {
+        ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
+    }
+    uint32_t numPendingBuffers = 0;
+    output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
+            &numPendingBuffers);
 
-sp<IBinder> Surface::asBinder() const {
-    return mSurface!=0 ? mSurface->asBinder() : 0;
-}
+    mConsumerRunningBehind = (numPendingBuffers >= 2);
 
-// ----------------------------------------------------------------------------
+    return err;
+}
 
 int Surface::query(int what, int* value) const {
-    switch (what) {
-    case NATIVE_WINDOW_CONCRETE_TYPE:
-        *value = NATIVE_WINDOW_SURFACE;
-        return NO_ERROR;
+    ATRACE_CALL();
+    ALOGV("Surface::query");
+    { // scope for the lock
+        Mutex::Autolock lock(mMutex);
+        switch (what) {
+            case NATIVE_WINDOW_FORMAT:
+                if (mReqFormat) {
+                    *value = mReqFormat;
+                    return NO_ERROR;
+                }
+                break;
+            case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
+                sp<ISurfaceComposer> composer(
+                        ComposerService::getComposerService());
+                if (composer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
+                    *value = 1;
+                } else {
+                    *value = 0;
+                }
+                return NO_ERROR;
+            }
+            case NATIVE_WINDOW_CONCRETE_TYPE:
+                *value = NATIVE_WINDOW_SURFACE;
+                return NO_ERROR;
+            case NATIVE_WINDOW_DEFAULT_WIDTH:
+                *value = mUserWidth ? mUserWidth : mDefaultWidth;
+                return NO_ERROR;
+            case NATIVE_WINDOW_DEFAULT_HEIGHT:
+                *value = mUserHeight ? mUserHeight : mDefaultHeight;
+                return NO_ERROR;
+            case NATIVE_WINDOW_TRANSFORM_HINT:
+                *value = mTransformHint;
+                return NO_ERROR;
+            case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
+                status_t err = NO_ERROR;
+                if (!mConsumerRunningBehind) {
+                    *value = 0;
+                } else {
+                    err = mGraphicBufferProducer->query(what, value);
+                    if (err == NO_ERROR) {
+                        mConsumerRunningBehind = *value;
+                    }
+                }
+                return err;
+            }
+        }
     }
-    return SurfaceTextureClient::query(what, value);
+    return mGraphicBufferProducer->query(what, value);
 }
 
-// ----------------------------------------------------------------------------
+int Surface::perform(int operation, va_list args)
+{
+    int res = NO_ERROR;
+    switch (operation) {
+    case NATIVE_WINDOW_CONNECT:
+        // deprecated. must return NO_ERROR.
+        break;
+    case NATIVE_WINDOW_DISCONNECT:
+        // deprecated. must return NO_ERROR.
+        break;
+    case NATIVE_WINDOW_SET_USAGE:
+        res = dispatchSetUsage(args);
+        break;
+    case NATIVE_WINDOW_SET_CROP:
+        res = dispatchSetCrop(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFER_COUNT:
+        res = dispatchSetBufferCount(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
+        res = dispatchSetBuffersGeometry(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
+        res = dispatchSetBuffersTransform(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
+        res = dispatchSetBuffersTimestamp(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
+        res = dispatchSetBuffersDimensions(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
+        res = dispatchSetBuffersUserDimensions(args);
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
+        res = dispatchSetBuffersFormat(args);
+        break;
+    case NATIVE_WINDOW_LOCK:
+        res = dispatchLock(args);
+        break;
+    case NATIVE_WINDOW_UNLOCK_AND_POST:
+        res = dispatchUnlockAndPost(args);
+        break;
+    case NATIVE_WINDOW_SET_SCALING_MODE:
+        res = dispatchSetScalingMode(args);
+        break;
+    case NATIVE_WINDOW_API_CONNECT:
+        res = dispatchConnect(args);
+        break;
+    case NATIVE_WINDOW_API_DISCONNECT:
+        res = dispatchDisconnect(args);
+        break;
+    default:
+        res = NAME_NOT_FOUND;
+        break;
+    }
+    return res;
+}
 
-status_t Surface::lock(SurfaceInfo* other, Region* inOutDirtyRegion) {
-    ANativeWindow_Buffer outBuffer;
+int Surface::dispatchConnect(va_list args) {
+    int api = va_arg(args, int);
+    return connect(api);
+}
 
-    ARect temp;
-    ARect* inOutDirtyBounds = NULL;
-    if (inOutDirtyRegion) {
-        temp = inOutDirtyRegion->getBounds();
-        inOutDirtyBounds = &temp;
+int Surface::dispatchDisconnect(va_list args) {
+    int api = va_arg(args, int);
+    return disconnect(api);
+}
+
+int Surface::dispatchSetUsage(va_list args) {
+    int usage = va_arg(args, int);
+    return setUsage(usage);
+}
+
+int Surface::dispatchSetCrop(va_list args) {
+    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
+    return setCrop(reinterpret_cast<Rect const*>(rect));
+}
+
+int Surface::dispatchSetBufferCount(va_list args) {
+    size_t bufferCount = va_arg(args, size_t);
+    return setBufferCount(bufferCount);
+}
+
+int Surface::dispatchSetBuffersGeometry(va_list args) {
+    int w = va_arg(args, int);
+    int h = va_arg(args, int);
+    int f = va_arg(args, int);
+    int err = setBuffersDimensions(w, h);
+    if (err != 0) {
+        return err;
+    }
+    return setBuffersFormat(f);
+}
+
+int Surface::dispatchSetBuffersDimensions(va_list args) {
+    int w = va_arg(args, int);
+    int h = va_arg(args, int);
+    return setBuffersDimensions(w, h);
+}
+
+int Surface::dispatchSetBuffersUserDimensions(va_list args) {
+    int w = va_arg(args, int);
+    int h = va_arg(args, int);
+    return setBuffersUserDimensions(w, h);
+}
+
+int Surface::dispatchSetBuffersFormat(va_list args) {
+    int f = va_arg(args, int);
+    return setBuffersFormat(f);
+}
+
+int Surface::dispatchSetScalingMode(va_list args) {
+    int m = va_arg(args, int);
+    return setScalingMode(m);
+}
+
+int Surface::dispatchSetBuffersTransform(va_list args) {
+    int transform = va_arg(args, int);
+    return setBuffersTransform(transform);
+}
+
+int Surface::dispatchSetBuffersTimestamp(va_list args) {
+    int64_t timestamp = va_arg(args, int64_t);
+    return setBuffersTimestamp(timestamp);
+}
+
+int Surface::dispatchLock(va_list args) {
+    ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
+    ARect* inOutDirtyBounds = va_arg(args, ARect*);
+    return lock(outBuffer, inOutDirtyBounds);
+}
+
+int Surface::dispatchUnlockAndPost(va_list args) {
+    return unlockAndPost();
+}
+
+
+int Surface::connect(int api) {
+    ATRACE_CALL();
+    ALOGV("Surface::connect");
+    Mutex::Autolock lock(mMutex);
+    IGraphicBufferProducer::QueueBufferOutput output;
+    int err = mGraphicBufferProducer->connect(api, &output);
+    if (err == NO_ERROR) {
+        uint32_t numPendingBuffers = 0;
+        output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
+                &numPendingBuffers);
+        mConsumerRunningBehind = (numPendingBuffers >= 2);
+    }
+    if (!err && api == NATIVE_WINDOW_API_CPU) {
+        mConnectedToCpu = true;
+    }
+    return err;
+}
+
+int Surface::disconnect(int api) {
+    ATRACE_CALL();
+    ALOGV("Surface::disconnect");
+    Mutex::Autolock lock(mMutex);
+    freeAllBuffers();
+    int err = mGraphicBufferProducer->disconnect(api);
+    if (!err) {
+        mReqFormat = 0;
+        mReqWidth = 0;
+        mReqHeight = 0;
+        mReqUsage = 0;
+        mCrop.clear();
+        mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
+        mTransform = 0;
+        if (api == NATIVE_WINDOW_API_CPU) {
+            mConnectedToCpu = false;
+        }
+    }
+    return err;
+}
+
+int Surface::setUsage(uint32_t reqUsage)
+{
+    ALOGV("Surface::setUsage");
+    Mutex::Autolock lock(mMutex);
+    mReqUsage = reqUsage;
+    return OK;
+}
+
+int Surface::setCrop(Rect const* rect)
+{
+    ATRACE_CALL();
+
+    Rect realRect;
+    if (rect == NULL || rect->isEmpty()) {
+        realRect.clear();
+    } else {
+        realRect = *rect;
     }
 
-    status_t err = SurfaceTextureClient::lock(&outBuffer, inOutDirtyBounds);
+    ALOGV("Surface::setCrop rect=[%d %d %d %d]",
+            realRect.left, realRect.top, realRect.right, realRect.bottom);
+
+    Mutex::Autolock lock(mMutex);
+    mCrop = realRect;
+    return NO_ERROR;
+}
+
+int Surface::setBufferCount(int bufferCount)
+{
+    ATRACE_CALL();
+    ALOGV("Surface::setBufferCount");
+    Mutex::Autolock lock(mMutex);
+
+    status_t err = mGraphicBufferProducer->setBufferCount(bufferCount);
+    ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
+            bufferCount, strerror(-err));
 
     if (err == NO_ERROR) {
-        other->w = uint32_t(outBuffer.width);
-        other->h = uint32_t(outBuffer.height);
-        other->s = uint32_t(outBuffer.stride);
-        other->usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
-        other->format = uint32_t(outBuffer.format);
-        other->bits = outBuffer.bits;
-    }
-
-    if (inOutDirtyRegion) {
-        inOutDirtyRegion->set( static_cast<Rect const&>(temp) );
+        freeAllBuffers();
     }
 
     return err;
 }
 
-status_t Surface::unlockAndPost() {
-    return SurfaceTextureClient::unlockAndPost();
+int Surface::setBuffersDimensions(int w, int h)
+{
+    ATRACE_CALL();
+    ALOGV("Surface::setBuffersDimensions");
+
+    if (w<0 || h<0)
+        return BAD_VALUE;
+
+    if ((w && !h) || (!w && h))
+        return BAD_VALUE;
+
+    Mutex::Autolock lock(mMutex);
+    mReqWidth = w;
+    mReqHeight = h;
+    return NO_ERROR;
+}
+
+int Surface::setBuffersUserDimensions(int w, int h)
+{
+    ATRACE_CALL();
+    ALOGV("Surface::setBuffersUserDimensions");
+
+    if (w<0 || h<0)
+        return BAD_VALUE;
+
+    if ((w && !h) || (!w && h))
+        return BAD_VALUE;
+
+    Mutex::Autolock lock(mMutex);
+    mUserWidth = w;
+    mUserHeight = h;
+    return NO_ERROR;
+}
+
+int Surface::setBuffersFormat(int format)
+{
+    ALOGV("Surface::setBuffersFormat");
+
+    if (format<0)
+        return BAD_VALUE;
+
+    Mutex::Autolock lock(mMutex);
+    mReqFormat = format;
+    return NO_ERROR;
+}
+
+int Surface::setScalingMode(int mode)
+{
+    ATRACE_CALL();
+    ALOGV("Surface::setScalingMode(%d)", mode);
+
+    switch (mode) {
+        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
+        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
+        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
+            break;
+        default:
+            ALOGE("unknown scaling mode: %d", mode);
+            return BAD_VALUE;
+    }
+
+    Mutex::Autolock lock(mMutex);
+    mScalingMode = mode;
+    return NO_ERROR;
+}
+
+int Surface::setBuffersTransform(int transform)
+{
+    ATRACE_CALL();
+    ALOGV("Surface::setBuffersTransform");
+    Mutex::Autolock lock(mMutex);
+    mTransform = transform;
+    return NO_ERROR;
+}
+
+int Surface::setBuffersTimestamp(int64_t timestamp)
+{
+    ALOGV("Surface::setBuffersTimestamp");
+    Mutex::Autolock lock(mMutex);
+    mTimestamp = timestamp;
+    return NO_ERROR;
+}
+
+void Surface::freeAllBuffers() {
+    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
+        mSlots[i].buffer = 0;
+    }
+}
+
+// ----------------------------------------------------------------------
+// the lock/unlock APIs must be used from the same thread
+
+static status_t copyBlt(
+        const sp<GraphicBuffer>& dst,
+        const sp<GraphicBuffer>& src,
+        const Region& reg)
+{
+    // src and dst with, height and format must be identical. no verification
+    // is done here.
+    status_t err;
+    uint8_t const * src_bits = NULL;
+    err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
+    ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
+
+    uint8_t* dst_bits = NULL;
+    err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
+    ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
+
+    Region::const_iterator head(reg.begin());
+    Region::const_iterator tail(reg.end());
+    if (head != tail && src_bits && dst_bits) {
+        const size_t bpp = bytesPerPixel(src->format);
+        const size_t dbpr = dst->stride * bpp;
+        const size_t sbpr = src->stride * bpp;
+
+        while (head != tail) {
+            const Rect& r(*head++);
+            ssize_t h = r.height();
+            if (h <= 0) continue;
+            size_t size = r.width() * bpp;
+            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
+            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
+            if (dbpr==sbpr && size==sbpr) {
+                size *= h;
+                h = 1;
+            }
+            do {
+                memcpy(d, s, size);
+                d += dbpr;
+                s += sbpr;
+            } while (--h > 0);
+        }
+    }
+
+    if (src_bits)
+        src->unlock();
+
+    if (dst_bits)
+        dst->unlock();
+
+    return err;
 }
 
 // ----------------------------------------------------------------------------
+
+status_t Surface::writeToParcel(
+        const sp<Surface>& surface, Parcel* parcel) {
+    sp<IGraphicBufferProducer> bp;
+    if (surface != NULL) {
+        bp = surface->mGraphicBufferProducer;
+    }
+    return parcel->writeStrongBinder(bp->asBinder());
+}
+
+sp<Surface> Surface::readFromParcel(const Parcel& data) {
+    sp<IBinder> binder(data.readStrongBinder());
+    sp<IGraphicBufferProducer> bp(interface_cast<IGraphicBufferProducer>(binder));
+    return new Surface(bp);
+}
+
+// ----------------------------------------------------------------------------
+
+status_t Surface::lock(
+        ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
+{
+    if (mLockedBuffer != 0) {
+        ALOGE("Surface::lock failed, already locked");
+        return INVALID_OPERATION;
+    }
+
+    if (!mConnectedToCpu) {
+        int err = Surface::connect(NATIVE_WINDOW_API_CPU);
+        if (err) {
+            return err;
+        }
+        // we're intending to do software rendering from this point
+        setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+    }
+
+    ANativeWindowBuffer* out;
+    int fenceFd = -1;
+    status_t err = dequeueBuffer(&out, &fenceFd);
+    ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
+    if (err == NO_ERROR) {
+        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
+        sp<Fence> fence(new Fence(fenceFd));
+
+        err = fence->waitForever(1000, "Surface::lock");
+        if (err != OK) {
+            ALOGE("Fence::wait failed (%s)", strerror(-err));
+            cancelBuffer(out, fenceFd);
+            return err;
+        }
+
+        const Rect bounds(backBuffer->width, backBuffer->height);
+
+        Region newDirtyRegion;
+        if (inOutDirtyBounds) {
+            newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
+            newDirtyRegion.andSelf(bounds);
+        } else {
+            newDirtyRegion.set(bounds);
+        }
+
+        // figure out if we can copy the frontbuffer back
+        const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
+        const bool canCopyBack = (frontBuffer != 0 &&
+                backBuffer->width  == frontBuffer->width &&
+                backBuffer->height == frontBuffer->height &&
+                backBuffer->format == frontBuffer->format);
+
+        if (canCopyBack) {
+            // copy the area that is invalid and not repainted this round
+            const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
+            if (!copyback.isEmpty())
+                copyBlt(backBuffer, frontBuffer, copyback);
+        } else {
+            // if we can't copy-back anything, modify the user's dirty
+            // region to make sure they redraw the whole buffer
+            newDirtyRegion.set(bounds);
+            mDirtyRegion.clear();
+            Mutex::Autolock lock(mMutex);
+            for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
+                mSlots[i].dirtyRegion.clear();
+            }
+        }
+
+
+        { // scope for the lock
+            Mutex::Autolock lock(mMutex);
+            int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
+            if (backBufferSlot >= 0) {
+                Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
+                mDirtyRegion.subtract(dirtyRegion);
+                dirtyRegion = newDirtyRegion;
+            }
+        }
+
+        mDirtyRegion.orSelf(newDirtyRegion);
+        if (inOutDirtyBounds) {
+            *inOutDirtyBounds = newDirtyRegion.getBounds();
+        }
+
+        void* vaddr;
+        status_t res = backBuffer->lock(
+                GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                newDirtyRegion.bounds(), &vaddr);
+
+        ALOGW_IF(res, "failed locking buffer (handle = %p)",
+                backBuffer->handle);
+
+        if (res != 0) {
+            err = INVALID_OPERATION;
+        } else {
+            mLockedBuffer = backBuffer;
+            outBuffer->width  = backBuffer->width;
+            outBuffer->height = backBuffer->height;
+            outBuffer->stride = backBuffer->stride;
+            outBuffer->format = backBuffer->format;
+            outBuffer->bits   = vaddr;
+        }
+    }
+    return err;
+}
+
+status_t Surface::unlockAndPost()
+{
+    if (mLockedBuffer == 0) {
+        ALOGE("Surface::unlockAndPost failed, no locked buffer");
+        return INVALID_OPERATION;
+    }
+
+    status_t err = mLockedBuffer->unlock();
+    ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
+
+    err = queueBuffer(mLockedBuffer.get(), -1);
+    ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
+            mLockedBuffer->handle, strerror(-err));
+
+    mPostedBuffer = mLockedBuffer;
+    mLockedBuffer = 0;
+    return err;
+}
+
 }; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 0bafc92..e8e208f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -31,6 +31,7 @@
 
 #include <ui/DisplayInfo.h>
 
+#include <gui/IGraphicBufferProducer.h>
 #include <gui/ISurface.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/ISurfaceComposerClient.h>
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
new file mode 100644
index 0000000..ef52269
--- /dev/null
+++ b/libs/gui/SurfaceControl.cpp
@@ -0,0 +1,194 @@
+/*
+ * 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 "SurfaceControl"
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <android/native_window.h>
+
+#include <utils/CallStack.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+
+#include <binder/IPCThreadState.h>
+
+#include <ui/DisplayInfo.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/Rect.h>
+
+#include <gui/ISurface.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/SurfaceControl.h>
+
+namespace android {
+
+// ============================================================================
+//  SurfaceControl
+// ============================================================================
+
+SurfaceControl::SurfaceControl(
+        const sp<SurfaceComposerClient>& client, 
+        const sp<ISurface>& surface)
+    : mClient(client)
+{
+    if (surface != 0) {
+        mSurface = surface->asBinder();
+        mGraphicBufferProducer = surface->getSurfaceTexture();
+    }
+}
+        
+SurfaceControl::~SurfaceControl()
+{
+    destroy();
+}
+
+void SurfaceControl::destroy()
+{
+    if (isValid()) {
+        mClient->destroySurface(mSurface);
+    }
+    // clear all references and trigger an IPC now, to make sure things
+    // happen without delay, since these resources are quite heavy.
+    mClient.clear();
+    mSurface.clear();
+    mGraphicBufferProducer.clear();
+    IPCThreadState::self()->flushCommands();
+}
+
+void SurfaceControl::clear() 
+{
+    // here, the window manager tells us explicitly that we should destroy
+    // the surface's resource. Soon after this call, it will also release
+    // its last reference (which will call the dtor); however, it is possible
+    // that a client living in the same process still holds references which
+    // would delay the call to the dtor -- that is why we need this explicit
+    // "clear()" call.
+    destroy();
+}
+
+bool SurfaceControl::isSameSurface(
+        const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) 
+{
+    if (lhs == 0 || rhs == 0)
+        return false;
+    return lhs->mSurface == rhs->mSurface;
+}
+
+status_t SurfaceControl::setLayerStack(int32_t layerStack) {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->setLayerStack(mSurface, layerStack);
+}
+status_t SurfaceControl::setLayer(int32_t layer) {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->setLayer(mSurface, layer);
+}
+status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->setPosition(mSurface, x, y);
+}
+status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->setSize(mSurface, w, h);
+}
+status_t SurfaceControl::hide() {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->hide(mSurface);
+}
+status_t SurfaceControl::show() {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->show(mSurface);
+}
+status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->setFlags(mSurface, flags, mask);
+}
+status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->setTransparentRegionHint(mSurface, transparent);
+}
+status_t SurfaceControl::setAlpha(float alpha) {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->setAlpha(mSurface, alpha);
+}
+status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->setMatrix(mSurface, dsdx, dtdx, dsdy, dtdy);
+}
+status_t SurfaceControl::setCrop(const Rect& crop) {
+    status_t err = validate();
+    if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
+    return client->setCrop(mSurface, crop);
+}
+
+status_t SurfaceControl::validate() const
+{
+    if (mSurface==0 || mClient==0) {
+        ALOGE("invalid ISurface (%p) or client (%p)",
+                mSurface.get(), mClient.get());
+        return NO_INIT;
+    }
+    return NO_ERROR;
+}
+
+status_t SurfaceControl::writeSurfaceToParcel(
+        const sp<SurfaceControl>& control, Parcel* parcel)
+{
+    sp<IGraphicBufferProducer> bp;
+    if (control != NULL) {
+        bp = control->mGraphicBufferProducer;
+    }
+    return parcel->writeStrongBinder(bp->asBinder());
+}
+
+sp<Surface> SurfaceControl::getSurface() const
+{
+    Mutex::Autolock _l(mLock);
+    if (mSurfaceData == 0) {
+        mSurfaceData = new Surface(mGraphicBufferProducer);
+    }
+    return mSurfaceData;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
deleted file mode 100644
index 5ed2e38..0000000
--- a/libs/gui/SurfaceTextureClient.cpp
+++ /dev/null
@@ -1,846 +0,0 @@
-/*
- * Copyright (C) 2010 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 "SurfaceTextureClient"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-//#define LOG_NDEBUG 0
-
-#include <android/native_window.h>
-
-#include <utils/Log.h>
-#include <utils/Trace.h>
-
-#include <ui/Fence.h>
-
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/GLConsumer.h>
-#include <gui/SurfaceTextureClient.h>
-
-#include <private/gui/ComposerService.h>
-
-namespace android {
-
-SurfaceTextureClient::SurfaceTextureClient(
-        const sp<IGraphicBufferProducer>& bufferProducer)
-{
-    SurfaceTextureClient::init();
-    SurfaceTextureClient::setISurfaceTexture(bufferProducer);
-}
-
-SurfaceTextureClient::SurfaceTextureClient() {
-    SurfaceTextureClient::init();
-}
-
-SurfaceTextureClient::~SurfaceTextureClient() {
-    if (mConnectedToCpu) {
-        SurfaceTextureClient::disconnect(NATIVE_WINDOW_API_CPU);
-    }
-}
-
-void SurfaceTextureClient::init() {
-    // Initialize the ANativeWindow function pointers.
-    ANativeWindow::setSwapInterval  = hook_setSwapInterval;
-    ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
-    ANativeWindow::cancelBuffer     = hook_cancelBuffer;
-    ANativeWindow::queueBuffer      = hook_queueBuffer;
-    ANativeWindow::query            = hook_query;
-    ANativeWindow::perform          = hook_perform;
-
-    ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
-    ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
-    ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
-    ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;
-
-    const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
-    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
-
-    mReqWidth = 0;
-    mReqHeight = 0;
-    mReqFormat = 0;
-    mReqUsage = 0;
-    mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
-    mCrop.clear();
-    mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
-    mTransform = 0;
-    mDefaultWidth = 0;
-    mDefaultHeight = 0;
-    mUserWidth = 0;
-    mUserHeight = 0;
-    mTransformHint = 0;
-    mConsumerRunningBehind = false;
-    mConnectedToCpu = false;
-}
-
-void SurfaceTextureClient::setISurfaceTexture(
-        const sp<IGraphicBufferProducer>& bufferProducer)
-{
-    mSurfaceTexture = bufferProducer;
-}
-
-sp<IGraphicBufferProducer> SurfaceTextureClient::getISurfaceTexture() const {
-    return mSurfaceTexture;
-}
-
-int SurfaceTextureClient::hook_setSwapInterval(ANativeWindow* window, int interval) {
-    SurfaceTextureClient* c = getSelf(window);
-    return c->setSwapInterval(interval);
-}
-
-int SurfaceTextureClient::hook_dequeueBuffer(ANativeWindow* window,
-        ANativeWindowBuffer** buffer, int* fenceFd) {
-    SurfaceTextureClient* c = getSelf(window);
-    return c->dequeueBuffer(buffer, fenceFd);
-}
-
-int SurfaceTextureClient::hook_cancelBuffer(ANativeWindow* window,
-        ANativeWindowBuffer* buffer, int fenceFd) {
-    SurfaceTextureClient* c = getSelf(window);
-    return c->cancelBuffer(buffer, fenceFd);
-}
-
-int SurfaceTextureClient::hook_queueBuffer(ANativeWindow* window,
-        ANativeWindowBuffer* buffer, int fenceFd) {
-    SurfaceTextureClient* c = getSelf(window);
-    return c->queueBuffer(buffer, fenceFd);
-}
-
-int SurfaceTextureClient::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
-        ANativeWindowBuffer** buffer) {
-    SurfaceTextureClient* c = getSelf(window);
-    ANativeWindowBuffer* buf;
-    int fenceFd = -1;
-    int result = c->dequeueBuffer(&buf, &fenceFd);
-    sp<Fence> fence(new Fence(fenceFd));
-    int waitResult = fence->waitForever(1000, "dequeueBuffer_DEPRECATED");
-    if (waitResult != OK) {
-        ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
-                waitResult);
-        c->cancelBuffer(buf, -1);
-        return waitResult;
-    }
-    *buffer = buf;
-    return result;
-}
-
-int SurfaceTextureClient::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
-        ANativeWindowBuffer* buffer) {
-    SurfaceTextureClient* c = getSelf(window);
-    return c->cancelBuffer(buffer, -1);
-}
-
-int SurfaceTextureClient::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
-        ANativeWindowBuffer* buffer) {
-    SurfaceTextureClient* c = getSelf(window);
-    return c->lockBuffer_DEPRECATED(buffer);
-}
-
-int SurfaceTextureClient::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
-        ANativeWindowBuffer* buffer) {
-    SurfaceTextureClient* c = getSelf(window);
-    return c->queueBuffer(buffer, -1);
-}
-
-int SurfaceTextureClient::hook_query(const ANativeWindow* window,
-                                int what, int* value) {
-    const SurfaceTextureClient* c = getSelf(window);
-    return c->query(what, value);
-}
-
-int SurfaceTextureClient::hook_perform(ANativeWindow* window, int operation, ...) {
-    va_list args;
-    va_start(args, operation);
-    SurfaceTextureClient* c = getSelf(window);
-    return c->perform(operation, args);
-}
-
-int SurfaceTextureClient::setSwapInterval(int interval) {
-    ATRACE_CALL();
-    // EGL specification states:
-    //  interval is silently clamped to minimum and maximum implementation
-    //  dependent values before being stored.
-    // Although we don't have to, we apply the same logic here.
-
-    if (interval < minSwapInterval)
-        interval = minSwapInterval;
-
-    if (interval > maxSwapInterval)
-        interval = maxSwapInterval;
-
-    status_t res = mSurfaceTexture->setSynchronousMode(interval ? true : false);
-
-    return res;
-}
-
-int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer,
-        int* fenceFd) {
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::dequeueBuffer");
-    Mutex::Autolock lock(mMutex);
-    int buf = -1;
-    int reqW = mReqWidth ? mReqWidth : mUserWidth;
-    int reqH = mReqHeight ? mReqHeight : mUserHeight;
-    sp<Fence> fence;
-    status_t result = mSurfaceTexture->dequeueBuffer(&buf, fence, reqW, reqH,
-            mReqFormat, mReqUsage);
-    if (result < 0) {
-        ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d)"
-             "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
-             result);
-        return result;
-    }
-    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
-    if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
-        freeAllBuffers();
-    }
-
-    if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
-        result = mSurfaceTexture->requestBuffer(buf, &gbuf);
-        if (result != NO_ERROR) {
-            ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d",
-                    result);
-            return result;
-        }
-    }
-
-    if (fence->isValid()) {
-        *fenceFd = fence->dup();
-        if (*fenceFd == -1) {
-            ALOGE("dequeueBuffer: error duping fence: %d", errno);
-            // dup() should never fail; something is badly wrong. Soldier on
-            // and hope for the best; the worst that should happen is some
-            // visible corruption that lasts until the next frame.
-        }
-    } else {
-        *fenceFd = -1;
-    }
-
-    *buffer = gbuf.get();
-    return OK;
-}
-
-int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer,
-        int fenceFd) {
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::cancelBuffer");
-    Mutex::Autolock lock(mMutex);
-    int i = getSlotFromBufferLocked(buffer);
-    if (i < 0) {
-        return i;
-    }
-    sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
-    mSurfaceTexture->cancelBuffer(i, fence);
-    return OK;
-}
-
-int SurfaceTextureClient::getSlotFromBufferLocked(
-        android_native_buffer_t* buffer) const {
-    bool dumpedState = false;
-    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
-        if (mSlots[i].buffer != NULL &&
-                mSlots[i].buffer->handle == buffer->handle) {
-            return i;
-        }
-    }
-    ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
-    return BAD_VALUE;
-}
-
-int SurfaceTextureClient::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) {
-    ALOGV("SurfaceTextureClient::lockBuffer");
-    Mutex::Autolock lock(mMutex);
-    return OK;
-}
-
-int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::queueBuffer");
-    Mutex::Autolock lock(mMutex);
-    int64_t timestamp;
-    if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
-        timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
-        ALOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms",
-             timestamp / 1000000.f);
-    } else {
-        timestamp = mTimestamp;
-    }
-    int i = getSlotFromBufferLocked(buffer);
-    if (i < 0) {
-        return i;
-    }
-
-
-    // Make sure the crop rectangle is entirely inside the buffer.
-    Rect crop;
-    mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
-
-    sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
-    IGraphicBufferProducer::QueueBufferOutput output;
-    IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode,
-            mTransform, fence);
-    status_t err = mSurfaceTexture->queueBuffer(i, input, &output);
-    if (err != OK)  {
-        ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
-    }
-    uint32_t numPendingBuffers = 0;
-    output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
-            &numPendingBuffers);
-
-    mConsumerRunningBehind = (numPendingBuffers >= 2);
-
-    return err;
-}
-
-int SurfaceTextureClient::query(int what, int* value) const {
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::query");
-    { // scope for the lock
-        Mutex::Autolock lock(mMutex);
-        switch (what) {
-            case NATIVE_WINDOW_FORMAT:
-                if (mReqFormat) {
-                    *value = mReqFormat;
-                    return NO_ERROR;
-                }
-                break;
-            case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
-                sp<ISurfaceComposer> composer(
-                        ComposerService::getComposerService());
-                if (composer->authenticateSurfaceTexture(mSurfaceTexture)) {
-                    *value = 1;
-                } else {
-                    *value = 0;
-                }
-                return NO_ERROR;
-            }
-            case NATIVE_WINDOW_CONCRETE_TYPE:
-                *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
-                return NO_ERROR;
-            case NATIVE_WINDOW_DEFAULT_WIDTH:
-                *value = mUserWidth ? mUserWidth : mDefaultWidth;
-                return NO_ERROR;
-            case NATIVE_WINDOW_DEFAULT_HEIGHT:
-                *value = mUserHeight ? mUserHeight : mDefaultHeight;
-                return NO_ERROR;
-            case NATIVE_WINDOW_TRANSFORM_HINT:
-                *value = mTransformHint;
-                return NO_ERROR;
-            case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
-                status_t err = NO_ERROR;
-                if (!mConsumerRunningBehind) {
-                    *value = 0;
-                } else {
-                    err = mSurfaceTexture->query(what, value);
-                    if (err == NO_ERROR) {
-                        mConsumerRunningBehind = *value;
-                    }
-                }
-                return err;
-            }
-        }
-    }
-    return mSurfaceTexture->query(what, value);
-}
-
-int SurfaceTextureClient::perform(int operation, va_list args)
-{
-    int res = NO_ERROR;
-    switch (operation) {
-    case NATIVE_WINDOW_CONNECT:
-        // deprecated. must return NO_ERROR.
-        break;
-    case NATIVE_WINDOW_DISCONNECT:
-        // deprecated. must return NO_ERROR.
-        break;
-    case NATIVE_WINDOW_SET_USAGE:
-        res = dispatchSetUsage(args);
-        break;
-    case NATIVE_WINDOW_SET_CROP:
-        res = dispatchSetCrop(args);
-        break;
-    case NATIVE_WINDOW_SET_BUFFER_COUNT:
-        res = dispatchSetBufferCount(args);
-        break;
-    case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
-        res = dispatchSetBuffersGeometry(args);
-        break;
-    case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
-        res = dispatchSetBuffersTransform(args);
-        break;
-    case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
-        res = dispatchSetBuffersTimestamp(args);
-        break;
-    case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
-        res = dispatchSetBuffersDimensions(args);
-        break;
-    case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
-        res = dispatchSetBuffersUserDimensions(args);
-        break;
-    case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
-        res = dispatchSetBuffersFormat(args);
-        break;
-    case NATIVE_WINDOW_LOCK:
-        res = dispatchLock(args);
-        break;
-    case NATIVE_WINDOW_UNLOCK_AND_POST:
-        res = dispatchUnlockAndPost(args);
-        break;
-    case NATIVE_WINDOW_SET_SCALING_MODE:
-        res = dispatchSetScalingMode(args);
-        break;
-    case NATIVE_WINDOW_API_CONNECT:
-        res = dispatchConnect(args);
-        break;
-    case NATIVE_WINDOW_API_DISCONNECT:
-        res = dispatchDisconnect(args);
-        break;
-    default:
-        res = NAME_NOT_FOUND;
-        break;
-    }
-    return res;
-}
-
-int SurfaceTextureClient::dispatchConnect(va_list args) {
-    int api = va_arg(args, int);
-    return connect(api);
-}
-
-int SurfaceTextureClient::dispatchDisconnect(va_list args) {
-    int api = va_arg(args, int);
-    return disconnect(api);
-}
-
-int SurfaceTextureClient::dispatchSetUsage(va_list args) {
-    int usage = va_arg(args, int);
-    return setUsage(usage);
-}
-
-int SurfaceTextureClient::dispatchSetCrop(va_list args) {
-    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
-    return setCrop(reinterpret_cast<Rect const*>(rect));
-}
-
-int SurfaceTextureClient::dispatchSetBufferCount(va_list args) {
-    size_t bufferCount = va_arg(args, size_t);
-    return setBufferCount(bufferCount);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) {
-    int w = va_arg(args, int);
-    int h = va_arg(args, int);
-    int f = va_arg(args, int);
-    int err = setBuffersDimensions(w, h);
-    if (err != 0) {
-        return err;
-    }
-    return setBuffersFormat(f);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersDimensions(va_list args) {
-    int w = va_arg(args, int);
-    int h = va_arg(args, int);
-    return setBuffersDimensions(w, h);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersUserDimensions(va_list args) {
-    int w = va_arg(args, int);
-    int h = va_arg(args, int);
-    return setBuffersUserDimensions(w, h);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersFormat(va_list args) {
-    int f = va_arg(args, int);
-    return setBuffersFormat(f);
-}
-
-int SurfaceTextureClient::dispatchSetScalingMode(va_list args) {
-    int m = va_arg(args, int);
-    return setScalingMode(m);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersTransform(va_list args) {
-    int transform = va_arg(args, int);
-    return setBuffersTransform(transform);
-}
-
-int SurfaceTextureClient::dispatchSetBuffersTimestamp(va_list args) {
-    int64_t timestamp = va_arg(args, int64_t);
-    return setBuffersTimestamp(timestamp);
-}
-
-int SurfaceTextureClient::dispatchLock(va_list args) {
-    ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
-    ARect* inOutDirtyBounds = va_arg(args, ARect*);
-    return lock(outBuffer, inOutDirtyBounds);
-}
-
-int SurfaceTextureClient::dispatchUnlockAndPost(va_list args) {
-    return unlockAndPost();
-}
-
-
-int SurfaceTextureClient::connect(int api) {
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::connect");
-    Mutex::Autolock lock(mMutex);
-    IGraphicBufferProducer::QueueBufferOutput output;
-    int err = mSurfaceTexture->connect(api, &output);
-    if (err == NO_ERROR) {
-        uint32_t numPendingBuffers = 0;
-        output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
-                &numPendingBuffers);
-        mConsumerRunningBehind = (numPendingBuffers >= 2);
-    }
-    if (!err && api == NATIVE_WINDOW_API_CPU) {
-        mConnectedToCpu = true;
-    }
-    return err;
-}
-
-int SurfaceTextureClient::disconnect(int api) {
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::disconnect");
-    Mutex::Autolock lock(mMutex);
-    freeAllBuffers();
-    int err = mSurfaceTexture->disconnect(api);
-    if (!err) {
-        mReqFormat = 0;
-        mReqWidth = 0;
-        mReqHeight = 0;
-        mReqUsage = 0;
-        mCrop.clear();
-        mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
-        mTransform = 0;
-        if (api == NATIVE_WINDOW_API_CPU) {
-            mConnectedToCpu = false;
-        }
-    }
-    return err;
-}
-
-int SurfaceTextureClient::setUsage(uint32_t reqUsage)
-{
-    ALOGV("SurfaceTextureClient::setUsage");
-    Mutex::Autolock lock(mMutex);
-    mReqUsage = reqUsage;
-    return OK;
-}
-
-int SurfaceTextureClient::setCrop(Rect const* rect)
-{
-    ATRACE_CALL();
-
-    Rect realRect;
-    if (rect == NULL || rect->isEmpty()) {
-        realRect.clear();
-    } else {
-        realRect = *rect;
-    }
-
-    ALOGV("SurfaceTextureClient::setCrop rect=[%d %d %d %d]",
-            realRect.left, realRect.top, realRect.right, realRect.bottom);
-
-    Mutex::Autolock lock(mMutex);
-    mCrop = realRect;
-    return NO_ERROR;
-}
-
-int SurfaceTextureClient::setBufferCount(int bufferCount)
-{
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::setBufferCount");
-    Mutex::Autolock lock(mMutex);
-
-    status_t err = mSurfaceTexture->setBufferCount(bufferCount);
-    ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
-            bufferCount, strerror(-err));
-
-    if (err == NO_ERROR) {
-        freeAllBuffers();
-    }
-
-    return err;
-}
-
-int SurfaceTextureClient::setBuffersDimensions(int w, int h)
-{
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::setBuffersDimensions");
-
-    if (w<0 || h<0)
-        return BAD_VALUE;
-
-    if ((w && !h) || (!w && h))
-        return BAD_VALUE;
-
-    Mutex::Autolock lock(mMutex);
-    mReqWidth = w;
-    mReqHeight = h;
-    return NO_ERROR;
-}
-
-int SurfaceTextureClient::setBuffersUserDimensions(int w, int h)
-{
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::setBuffersUserDimensions");
-
-    if (w<0 || h<0)
-        return BAD_VALUE;
-
-    if ((w && !h) || (!w && h))
-        return BAD_VALUE;
-
-    Mutex::Autolock lock(mMutex);
-    mUserWidth = w;
-    mUserHeight = h;
-    return NO_ERROR;
-}
-
-int SurfaceTextureClient::setBuffersFormat(int format)
-{
-    ALOGV("SurfaceTextureClient::setBuffersFormat");
-
-    if (format<0)
-        return BAD_VALUE;
-
-    Mutex::Autolock lock(mMutex);
-    mReqFormat = format;
-    return NO_ERROR;
-}
-
-int SurfaceTextureClient::setScalingMode(int mode)
-{
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::setScalingMode(%d)", mode);
-
-    switch (mode) {
-        case NATIVE_WINDOW_SCALING_MODE_FREEZE:
-        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
-        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
-            break;
-        default:
-            ALOGE("unknown scaling mode: %d", mode);
-            return BAD_VALUE;
-    }
-
-    Mutex::Autolock lock(mMutex);
-    mScalingMode = mode;
-    return NO_ERROR;
-}
-
-int SurfaceTextureClient::setBuffersTransform(int transform)
-{
-    ATRACE_CALL();
-    ALOGV("SurfaceTextureClient::setBuffersTransform");
-    Mutex::Autolock lock(mMutex);
-    mTransform = transform;
-    return NO_ERROR;
-}
-
-int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp)
-{
-    ALOGV("SurfaceTextureClient::setBuffersTimestamp");
-    Mutex::Autolock lock(mMutex);
-    mTimestamp = timestamp;
-    return NO_ERROR;
-}
-
-void SurfaceTextureClient::freeAllBuffers() {
-    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
-        mSlots[i].buffer = 0;
-    }
-}
-
-// ----------------------------------------------------------------------
-// the lock/unlock APIs must be used from the same thread
-
-static status_t copyBlt(
-        const sp<GraphicBuffer>& dst,
-        const sp<GraphicBuffer>& src,
-        const Region& reg)
-{
-    // src and dst with, height and format must be identical. no verification
-    // is done here.
-    status_t err;
-    uint8_t const * src_bits = NULL;
-    err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
-    ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
-
-    uint8_t* dst_bits = NULL;
-    err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
-    ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
-
-    Region::const_iterator head(reg.begin());
-    Region::const_iterator tail(reg.end());
-    if (head != tail && src_bits && dst_bits) {
-        const size_t bpp = bytesPerPixel(src->format);
-        const size_t dbpr = dst->stride * bpp;
-        const size_t sbpr = src->stride * bpp;
-
-        while (head != tail) {
-            const Rect& r(*head++);
-            ssize_t h = r.height();
-            if (h <= 0) continue;
-            size_t size = r.width() * bpp;
-            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
-            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
-            if (dbpr==sbpr && size==sbpr) {
-                size *= h;
-                h = 1;
-            }
-            do {
-                memcpy(d, s, size);
-                d += dbpr;
-                s += sbpr;
-            } while (--h > 0);
-        }
-    }
-
-    if (src_bits)
-        src->unlock();
-
-    if (dst_bits)
-        dst->unlock();
-
-    return err;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t SurfaceTextureClient::lock(
-        ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
-{
-    if (mLockedBuffer != 0) {
-        ALOGE("Surface::lock failed, already locked");
-        return INVALID_OPERATION;
-    }
-
-    if (!mConnectedToCpu) {
-        int err = SurfaceTextureClient::connect(NATIVE_WINDOW_API_CPU);
-        if (err) {
-            return err;
-        }
-        // we're intending to do software rendering from this point
-        setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
-    }
-
-    ANativeWindowBuffer* out;
-    int fenceFd = -1;
-    status_t err = dequeueBuffer(&out, &fenceFd);
-    ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
-    if (err == NO_ERROR) {
-        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
-        sp<Fence> fence(new Fence(fenceFd));
-
-        err = fence->waitForever(1000, "SurfaceTextureClient::lock");
-        if (err != OK) {
-            ALOGE("Fence::wait failed (%s)", strerror(-err));
-            cancelBuffer(out, fenceFd);
-            return err;
-        }
-
-        const Rect bounds(backBuffer->width, backBuffer->height);
-
-        Region newDirtyRegion;
-        if (inOutDirtyBounds) {
-            newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds));
-            newDirtyRegion.andSelf(bounds);
-        } else {
-            newDirtyRegion.set(bounds);
-        }
-
-        // figure out if we can copy the frontbuffer back
-        const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
-        const bool canCopyBack = (frontBuffer != 0 &&
-                backBuffer->width  == frontBuffer->width &&
-                backBuffer->height == frontBuffer->height &&
-                backBuffer->format == frontBuffer->format);
-
-        if (canCopyBack) {
-            // copy the area that is invalid and not repainted this round
-            const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
-            if (!copyback.isEmpty())
-                copyBlt(backBuffer, frontBuffer, copyback);
-        } else {
-            // if we can't copy-back anything, modify the user's dirty
-            // region to make sure they redraw the whole buffer
-            newDirtyRegion.set(bounds);
-            mDirtyRegion.clear();
-            Mutex::Autolock lock(mMutex);
-            for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) {
-                mSlots[i].dirtyRegion.clear();
-            }
-        }
-
-
-        { // scope for the lock
-            Mutex::Autolock lock(mMutex);
-            int backBufferSlot(getSlotFromBufferLocked(backBuffer.get()));
-            if (backBufferSlot >= 0) {
-                Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion);
-                mDirtyRegion.subtract(dirtyRegion);
-                dirtyRegion = newDirtyRegion;
-            }
-        }
-
-        mDirtyRegion.orSelf(newDirtyRegion);
-        if (inOutDirtyBounds) {
-            *inOutDirtyBounds = newDirtyRegion.getBounds();
-        }
-
-        void* vaddr;
-        status_t res = backBuffer->lock(
-                GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
-                newDirtyRegion.bounds(), &vaddr);
-
-        ALOGW_IF(res, "failed locking buffer (handle = %p)",
-                backBuffer->handle);
-
-        if (res != 0) {
-            err = INVALID_OPERATION;
-        } else {
-            mLockedBuffer = backBuffer;
-            outBuffer->width  = backBuffer->width;
-            outBuffer->height = backBuffer->height;
-            outBuffer->stride = backBuffer->stride;
-            outBuffer->format = backBuffer->format;
-            outBuffer->bits   = vaddr;
-        }
-    }
-    return err;
-}
-
-status_t SurfaceTextureClient::unlockAndPost()
-{
-    if (mLockedBuffer == 0) {
-        ALOGE("Surface::unlockAndPost failed, no locked buffer");
-        return INVALID_OPERATION;
-    }
-
-    status_t err = mLockedBuffer->unlock();
-    ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
-
-    err = queueBuffer(mLockedBuffer.get(), -1);
-    ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)",
-            mLockedBuffer->handle, strerror(-err));
-
-    mPostedBuffer = mLockedBuffer;
-    mLockedBuffer = 0;
-    return err;
-}
-
-}; // namespace android
diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp
index 72a36bf..12ae19c 100644
--- a/libs/gui/tests/CpuConsumer_test.cpp
+++ b/libs/gui/tests/CpuConsumer_test.cpp
@@ -26,7 +26,7 @@
 
 #include <gtest/gtest.h>
 #include <gui/CpuConsumer.h>
-#include <gui/SurfaceTextureClient.h>
+#include <gui/Surface.h>
 #include <ui/GraphicBuffer.h>
 #include <utils/String8.h>
 #include <utils/Thread.h>
@@ -64,7 +64,7 @@
         mCC = new CpuConsumer(params.maxLockedBuffers);
         String8 name("CpuConsumer_Under_Test");
         mCC->setName(name);
-        mSTC = new SurfaceTextureClient(mCC->getProducerInterface());
+        mSTC = new Surface(mCC->getProducerInterface());
         mANW = mSTC;
     }
 
@@ -149,7 +149,7 @@
     };
 
     sp<CpuConsumer> mCC;
-    sp<SurfaceTextureClient> mSTC;
+    sp<Surface> mSTC;
     sp<ANativeWindow> mANW;
 };
 
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 2df83a0..58ae170 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -19,7 +19,7 @@
 
 #include <EGL/egl.h>
 #include <gtest/gtest.h>
-#include <gui/SurfaceTextureClient.h>
+#include <gui/Surface.h>
 #include <system/graphics.h>
 #include <utils/Log.h>
 #include <utils/Thread.h>
@@ -41,7 +41,7 @@
                 testInfo->name());
 
         mST = new GLConsumer(123);
-        mSTC = new SurfaceTextureClient(mST->getBufferQueue());
+        mSTC = new Surface(mST->getBufferQueue());
         mANW = mSTC;
 
         // We need a valid GL context so we can test updateTexImage()
@@ -103,7 +103,7 @@
     }
 
     sp<GLConsumer> mST;
-    sp<SurfaceTextureClient> mSTC;
+    sp<Surface> mSTC;
     sp<ANativeWindow> mANW;
 
     EGLDisplay mEglDisplay;
@@ -128,7 +128,7 @@
     int result = -123;
     int err = mANW->query(mANW.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result);
     EXPECT_EQ(NO_ERROR, err);
-    EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result);
+    EXPECT_EQ(NATIVE_WINDOW_SURFACE, result);
 }
 
 TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) {
@@ -686,7 +686,7 @@
 
         for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) {
             sp<GLConsumer> st(new GLConsumer(i));
-            sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st->getBufferQueue()));
+            sp<Surface> stc(new Surface(st->getBufferQueue()));
             mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig,
                     static_cast<ANativeWindow*>(stc.get()), NULL);
             ASSERT_EQ(EGL_SUCCESS, eglGetError());
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 9062f84..fbaf6aa 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -19,7 +19,6 @@
 
 #include <gtest/gtest.h>
 #include <gui/GLConsumer.h>
-#include <gui/SurfaceTextureClient.h>
 #include <ui/GraphicBuffer.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
@@ -383,7 +382,7 @@
     virtual void SetUp() {
         GLTest::SetUp();
         mST = new GLConsumer(TEX_ID);
-        mSTC = new SurfaceTextureClient(mST->getBufferQueue());
+        mSTC = new Surface(mST->getBufferQueue());
         mANW = mSTC;
         mTextureRenderer = new TextureRenderer(TEX_ID, mST);
         ASSERT_NO_FATAL_FAILURE(mTextureRenderer->SetUp());
@@ -574,7 +573,7 @@
     };
 
     sp<GLConsumer> mST;
-    sp<SurfaceTextureClient> mSTC;
+    sp<Surface> mSTC;
     sp<ANativeWindow> mANW;
     sp<TextureRenderer> mTextureRenderer;
     sp<FrameWaiter> mFW;
