Integrate from //sandbox/mathias/donut/...@145728

SurfaceFlinger rework for new EGL driver model support.
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index 2212436..ebd588b 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -5,9 +5,9 @@
     clz.cpp.arm \
     DisplayHardware/DisplayHardware.cpp \
     DisplayHardware/DisplayHardwareBase.cpp \
-    GPUHardware/GPUHardware.cpp \
     BootAnimation.cpp \
     BlurFilter.cpp.arm \
+    BufferAllocator.cpp \
     CPUGauge.cpp \
     Layer.cpp \
     LayerBase.cpp \
@@ -20,9 +20,10 @@
     OrientationAnimation.cpp \
     SurfaceFlinger.cpp \
     Tokenizer.cpp \
-    Transform.cpp \
-    VRamHeap.cpp
+    Transform.cpp
 
+LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
 
 # need "-lrt" on Linux simulator to pick up clock_gettime
 ifeq ($(TARGET_SIMULATOR),true)
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
index db40385..4aa8c2c 100644
--- a/libs/surfaceflinger/BootAnimation.cpp
+++ b/libs/surfaceflinger/BootAnimation.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "BootAnimation"
-
 #include <stdint.h>
 #include <sys/types.h>
 #include <math.h>
@@ -147,9 +145,7 @@
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     eglChooseConfig(display, attribs, &config, 1, &numConfigs);
 
-    mNativeWindowSurface = new EGLNativeWindowSurface(s);
-    surface = eglCreateWindowSurface(display, config, 
-            mNativeWindowSurface.get(), NULL);
+    surface = eglCreateWindowSurface(display, config, s.get(), NULL);
 
     context = eglCreateContext(display, config, NULL, NULL);
     eglQuerySurface(display, surface, EGL_WIDTH, &w);
@@ -180,7 +176,7 @@
     eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglDestroyContext(mDisplay, mContext);
     eglDestroySurface(mDisplay, mSurface);
-    mNativeWindowSurface.clear();
+    mFlingerSurface.clear();
     return r;
 }
 
@@ -199,8 +195,7 @@
     const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h);
 
     // draw and update only what we need
-    mNativeWindowSurface->setSwapRectangle(updateRect.left,
-            updateRect.top, updateRect.width(), updateRect.height());
+    mFlingerSurface->setSwapRectangle(updateRect);
 
     glEnable(GL_SCISSOR_TEST);
     glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(),
diff --git a/libs/surfaceflinger/BootAnimation.h b/libs/surfaceflinger/BootAnimation.h
index 3fb6670..8484623 100644
--- a/libs/surfaceflinger/BootAnimation.h
+++ b/libs/surfaceflinger/BootAnimation.h
@@ -72,7 +72,6 @@
     EGLDisplay  mContext;
     EGLDisplay  mSurface;
     sp<Surface> mFlingerSurface;
-    sp<EGLNativeWindowSurface> mNativeWindowSurface;
     Barrier mBarrier;
 };
 
diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp
new file mode 100644
index 0000000..ac32985
--- /dev/null
+++ b/libs/surfaceflinger/BufferAllocator.cpp
@@ -0,0 +1,162 @@
+/* 
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#include <sys/mman.h>
+#include <utils/CallStack.h>
+#include <cutils/ashmem.h>
+#include <cutils/log.h>
+#include <utils/String8.h>
+
+#include <ui/BufferMapper.h>
+
+#include "BufferAllocator.h"
+
+// FIXME: ANDROID_GRALLOC_DEBUG must only be used with *our* gralloc
+#define ANDROID_GRALLOC_DEBUG 1
+
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+Mutex BufferAllocator::sLock;
+KeyedVector<buffer_handle_t, BufferAllocator::alloc_rec_t> BufferAllocator::sAllocList;
+
+BufferAllocator::BufferAllocator()
+    : mAllocDev(0)
+{
+    hw_module_t const* module;
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
+    if (err == 0) {
+        gralloc_open(module, &mAllocDev);
+    }
+}
+
+BufferAllocator::~BufferAllocator()
+{
+    gralloc_close(mAllocDev);
+}
+
+void BufferAllocator::dump(String8& result) const
+{
+    Mutex::Autolock _l(sLock);
+    KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+    size_t total = 0;
+    const size_t SIZE = 512;
+    char buffer[SIZE];
+    snprintf(buffer, SIZE, "Allocated buffers:\n");
+    result.append(buffer);
+    const size_t c = list.size();
+    for (size_t i=0 ; i<c ; i++) {
+        const alloc_rec_t& rec(list.valueAt(i));
+        snprintf(buffer, SIZE, "%10p: %10p | %7.2f KB | %4u x %4u | %2d | 0x%08x\n",
+            list.keyAt(i), rec.vaddr, rec.size/1024.0f,
+            rec.w, rec.h, rec.format, rec.usage);
+        result.append(buffer);
+        total += rec.size;
+    }
+    snprintf(buffer, SIZE, "Total allocated: %.2f KB\n", total/1024.0f);
+    result.append(buffer);
+}
+
+status_t BufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
+        int usage, buffer_handle_t* handle, int32_t* stride)
+{
+    Mutex::Autolock _l(mLock);
+    
+    // we have a h/w allocator and h/w buffer is requested
+    status_t err = mAllocDev->alloc(mAllocDev,
+            w, h, format, usage, handle, stride);
+    LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
+            w, h, format, usage, err, strerror(-err));
+    
+    if (err == NO_ERROR) {
+        Mutex::Autolock _l(sLock);
+        KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+        alloc_rec_t rec;
+        rec.w = w;
+        rec.h = h;
+        rec.format = format;
+        rec.usage = usage;
+        rec.vaddr = 0;
+        rec.size = h * stride[0] * bytesPerPixel(format);
+        list.add(*handle, rec);
+    }
+
+    return err;
+}
+
+status_t BufferAllocator::free(buffer_handle_t handle)
+{
+    Mutex::Autolock _l(mLock);
+
+#if ANDROID_GRALLOC_DEBUG    
+    if (handle->data[2]) {
+            CallStack s;
+            s.update();
+            s.dump("");
+    }
+#endif
+
+    status_t err = mAllocDev->free(mAllocDev, handle);
+    LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err));
+
+    if (err == NO_ERROR) {
+        Mutex::Autolock _l(sLock);
+        KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+        list.removeItem(handle);
+    }
+
+    return err;
+}
+
+status_t BufferAllocator::map(buffer_handle_t handle, void** addr)
+{
+    Mutex::Autolock _l(mLock);
+    status_t err = BufferMapper::get().map(handle, addr);
+    if (err == NO_ERROR) {
+        Mutex::Autolock _l(sLock);
+        KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+        ssize_t idx = list.indexOfKey(handle);
+        if (idx >= 0)
+            list.editValueAt(idx).vaddr = addr;
+    }
+
+    return err;
+}
+
+status_t BufferAllocator::unmap(buffer_handle_t handle)
+{
+    Mutex::Autolock _l(mLock);
+    gralloc_module_t* mod = (gralloc_module_t*)mAllocDev->common.module;
+    status_t err = mod->unmap(mod, handle);
+    LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err));
+    
+    if (err == NO_ERROR) {
+        Mutex::Autolock _l(sLock);
+        KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+        ssize_t idx = list.indexOfKey(handle);
+        if (idx >= 0)
+            list.editValueAt(idx).vaddr = 0;
+    }
+
+    return err;
+}
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger/BufferAllocator.h b/libs/surfaceflinger/BufferAllocator.h
new file mode 100644
index 0000000..0b69b8e
--- /dev/null
+++ b/libs/surfaceflinger/BufferAllocator.h
@@ -0,0 +1,100 @@
+/* 
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#ifndef ANDROID_BUFFER_ALLOCATOR_H
+#define ANDROID_BUFFER_ALLOCATOR_H
+
+#include <stdint.h>
+
+#include <cutils/native_handle.h>
+
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Singleton.h>
+
+#include <ui/PixelFormat.h>
+
+#include <hardware/gralloc.h>
+
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class String8;
+
+class BufferAllocator : public Singleton<BufferAllocator>
+{
+public:
+    enum {
+        USAGE_SW_READ_NEVER     = GRALLOC_USAGE_SW_READ_NEVER,
+        USAGE_SW_READ_RARELY    = GRALLOC_USAGE_SW_READ_RARELY,
+        USAGE_SW_READ_OFTEN     = GRALLOC_USAGE_SW_READ_OFTEN,
+        USAGE_SW_READ_MASK      = GRALLOC_USAGE_SW_READ_MASK,
+        
+        USAGE_SW_WRITE_NEVER    = GRALLOC_USAGE_SW_WRITE_NEVER,
+        USAGE_SW_WRITE_RARELY   = GRALLOC_USAGE_SW_WRITE_RARELY,
+        USAGE_SW_WRITE_OFTEN    = GRALLOC_USAGE_SW_WRITE_OFTEN,
+        USAGE_SW_WRITE_MASK     = GRALLOC_USAGE_SW_WRITE_MASK,
+        
+        USAGE_SOFTWARE_MASK     = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK,
+        
+        USAGE_HW_TEXTURE        = GRALLOC_USAGE_HW_TEXTURE,
+        USAGE_HW_RENDER         = GRALLOC_USAGE_HW_RENDER,
+        USAGE_HW_2D             = GRALLOC_USAGE_HW_2D,
+        USAGE_HW_MASK           = GRALLOC_USAGE_HW_MASK
+    };
+
+    static inline BufferAllocator& get() { return getInstance(); }
+    
+
+    status_t alloc(uint32_t w, uint32_t h, PixelFormat format, int usage,
+            buffer_handle_t* handle, int32_t* stride);
+
+    status_t free(buffer_handle_t handle);
+
+    status_t map(buffer_handle_t handle, void** addr);
+    
+    status_t unmap(buffer_handle_t handle);
+    
+    void dump(String8& res) const;
+
+private:
+    struct alloc_rec_t {
+        uint32_t w;
+        uint32_t h;
+        PixelFormat format;
+        uint32_t usage;
+        void* vaddr;
+        size_t size;
+    };
+    
+    static Mutex sLock;
+    static KeyedVector<buffer_handle_t, alloc_rec_t> sAllocList;
+    
+    friend class Singleton<BufferAllocator>;
+    BufferAllocator();
+    ~BufferAllocator();
+    
+    mutable Mutex mLock;
+    alloc_device_t  *mAllocDev;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_BUFFER_ALLOCATOR_H
diff --git a/libs/surfaceflinger/CPUGauge.cpp b/libs/surfaceflinger/CPUGauge.cpp
index 74a9270..91dd236 100644
--- a/libs/surfaceflinger/CPUGauge.cpp
+++ b/libs/surfaceflinger/CPUGauge.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CPUGauge"
-
 #include <stdint.h>
 #include <limits.h>
 #include <sys/types.h>
@@ -113,7 +111,7 @@
                 fb.version = sizeof(GGLSurface);
                 fb.width   = info.w;
                 fb.height  = info.h;
-                fb.stride  = info.w;
+                fb.stride  = info.s;
                 fb.format  = info.format;
                 fb.data = (GGLubyte*)info.bits;
 
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index f14d7e9..1f7211c 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -23,18 +21,24 @@
 
 #include <cutils/properties.h>
 
+#include <utils/RefBase.h>
 #include <utils/Log.h>
 
-#include <ui/EGLDisplaySurface.h>
+#include <ui/PixelFormat.h>
+#include <ui/EGLNativeWindowSurface.h>
 
 #include <GLES/gl.h>
+#include <EGL/egl.h>
 #include <EGL/eglext.h>
+#include <EGL/android_natives.h>
 
+#include <pixelflinger/pixelflinger.h>
 
 #include "DisplayHardware/DisplayHardware.h"
 
 #include <hardware/copybit.h>
 #include <hardware/overlay.h>
+#include <hardware/gralloc.h>
 
 using namespace android;
 
@@ -108,17 +112,28 @@
 
 void DisplayHardware::init(uint32_t dpy)
 {
+    hw_module_t const* module;
+
+    mNativeWindow = new FramebufferNativeWindow();
+
+    mOverlayEngine = NULL;
+    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
+        overlay_control_open(module, &mOverlayEngine);
+    }
+
+    framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
+
+    PixelFormatInfo fbFormatInfo;
+    getPixelFormatInfo(PixelFormat(fbDev->format), &fbFormatInfo);
+
     // initialize EGL
     const EGLint attribs[] = {
-            EGL_RED_SIZE,       5,
-            EGL_GREEN_SIZE,     6,
-            EGL_BLUE_SIZE,      5,
+            EGL_BUFFER_SIZE,    fbFormatInfo.bitsPerPixel,
             EGL_DEPTH_SIZE,     0,
             EGL_NONE
     };
     EGLint w, h, dummy;
-    EGLint numConfigs, n;
-    EGLConfig config;
+    EGLint numConfigs=0, n=0;
     EGLSurface surface;
     EGLContext context;
     mFlags = 0;
@@ -129,7 +144,31 @@
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     eglInitialize(display, NULL, NULL);
     eglGetConfigs(display, NULL, 0, &numConfigs);
-    eglChooseConfig(display, attribs, &config, 1, &n);
+
+    // Get all the "potential match" configs...
+    EGLConfig* const configs = new EGLConfig[numConfigs];
+    eglChooseConfig(display, attribs, configs, numConfigs, &n);
+    LOGE_IF(n<=0, "no EGLConfig available!");
+    EGLConfig config = configs[0];
+    if (n > 1) {
+        // if there is more than one candidate, go through the list
+        // and pick one that matches our framebuffer format
+        int fbSzA = fbFormatInfo.getSize(PixelFormatInfo::INDEX_ALPHA);
+        int fbSzR = fbFormatInfo.getSize(PixelFormatInfo::INDEX_RED);
+        int fbSzG = fbFormatInfo.getSize(PixelFormatInfo::INDEX_GREEN);
+        int fbSzB = fbFormatInfo.getSize(PixelFormatInfo::INDEX_BLUE); 
+        for (int i=0 ; i<n ; i++) {
+            EGLint r,g,b,a;
+            eglGetConfigAttrib(display, configs[i], EGL_RED_SIZE,   &r);
+            eglGetConfigAttrib(display, configs[i], EGL_GREEN_SIZE, &g);
+            eglGetConfigAttrib(display, configs[i], EGL_BLUE_SIZE,  &b);
+            eglGetConfigAttrib(display, configs[i], EGL_ALPHA_SIZE, &a);
+            if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB  == b) {
+                config = configs[i];
+            }
+        }
+    }
+    delete [] configs;
 
     /*
      * Gather EGL extensions
@@ -145,11 +184,8 @@
     LOGI("extensions: %s", egl_extensions);
     LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
 
-    // TODO: get this from the devfb driver (probably should be HAL module)
-    mFlags |= SWAP_RECTANGLE_EXTENSION;
-    
     // TODO: get the real "update_on_demand" behavior (probably should be HAL module)
-    mFlags |= UPDATE_ON_DEMAND;
+    // FIXME: mFlags |= UPDATE_ON_DEMAND;
 
     if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
         if (dummy == EGL_SLOW_CONFIG)
@@ -160,33 +196,20 @@
      * Create our main surface
      */
 
-    mDisplaySurface = new EGLDisplaySurface();
+    
+    surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
+    checkEGLErrors("eglCreateDisplaySurfaceANDROID");
 
-    surface = eglCreateWindowSurface(display, config, mDisplaySurface.get(), NULL);
-    //checkEGLErrors("eglCreateDisplaySurfaceANDROID");
-
+    
     if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
         if (dummy == EGL_BUFFER_PRESERVED) {
             mFlags |= BUFFER_PRESERVED;
         }
     }
     
-    GLint value = EGL_UNKNOWN;
-    eglQuerySurface(display, surface, EGL_HORIZONTAL_RESOLUTION, &value);
-    if (value == EGL_UNKNOWN) {
-        mDpiX = 160.0f;
-    } else {
-        mDpiX = 25.4f * float(value)/EGL_DISPLAY_SCALING;
-    }
-    value = EGL_UNKNOWN;
-    eglQuerySurface(display, surface, EGL_VERTICAL_RESOLUTION, &value);
-    if (value == EGL_UNKNOWN) {
-        mDpiY = 160.0f;
-    } else {
-        mDpiY = 25.4f * float(value)/EGL_DISPLAY_SCALING;
-    }
-    mRefreshRate = 60.f;    // TODO: get the real refresh rate 
-    
+    mDpiX = mNativeWindow->xdpi;
+    mDpiX = mNativeWindow->ydpi;
+    mRefreshRate = mNativeWindow->getDevice()->fps; 
     
     char property[PROPERTY_VALUE_MAX];
     if (property_get("ro.sf.lcd_density", property, NULL) <= 0) {
@@ -225,7 +248,10 @@
     if (strstr(gl_extensions, "GL_OES_draw_texture")) {
         mFlags |= DRAW_TEXTURE_EXTENSION;
     }
-    if (strstr(gl_extensions, "GL_ANDROID_direct_texture")) {
+    if (strstr( gl_extensions, "GL_OES_EGL_image") &&
+        (strstr(egl_extensions, "KHR_image_base") || 
+                strstr(egl_extensions, "EGL_KHR_image")) &&
+        strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) {
         mFlags |= DIRECT_TEXTURE;
     }
 
@@ -236,19 +262,8 @@
     mConfig  = config;
     mSurface = surface;
     mContext = context;
-    mFormat  = GGL_PIXEL_FORMAT_RGB_565;
-    
-    hw_module_t const* module;
-
-    mBlitEngine = NULL;
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        copybit_open(module, &mBlitEngine);
-    }
-
-    mOverlayEngine = NULL;
-    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
-        overlay_control_open(module, &mOverlayEngine);
-    }
+    mFormat  = fbDev->format;
+    mPageFlipCount = 0;
 }
 
 /*
@@ -262,7 +277,6 @@
 {
     eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglTerminate(mDisplay);
-    copybit_close(mBlitEngine);
     overlay_control_close(mOverlayEngine);
 }
 
@@ -276,28 +290,8 @@
     DisplayHardwareBase::acquireScreen();
 }
 
-void DisplayHardware::getDisplaySurface(copybit_image_t* img) const
-{
-    img->w      = mDisplaySurface->stride;
-    img->h      = mDisplaySurface->height;
-    img->format = mDisplaySurface->format;
-    img->offset = mDisplaySurface->offset;
-    img->base   = (void*)mDisplaySurface->base;
-    img->fd     = mDisplaySurface->fd;
-}
-
-void DisplayHardware::getDisplaySurface(GGLSurface* fb) const
-{
-    fb->version= sizeof(GGLSurface);
-    fb->width  = mDisplaySurface->width;
-    fb->height = mDisplaySurface->height;
-    fb->stride = mDisplaySurface->stride;
-    fb->format = mDisplaySurface->format;
-    fb->data   = (GGLubyte*)mDisplaySurface->base + mDisplaySurface->offset;
-}
-
 uint32_t DisplayHardware::getPageFlipCount() const {
-    return mDisplaySurface->getPageFlipCount();
+    return mPageFlipCount;
 }
 
 /*
@@ -315,17 +309,14 @@
     newDirty.andSelf(Rect(mWidth, mHeight));
 
     if (mFlags & BUFFER_PRESERVED) {
-        const Region copyback(mDirty.subtract(newDirty));
         mDirty = newDirty;
-        mDisplaySurface->copyFrontToBack(copyback);
     } 
 
-    if (mFlags & SWAP_RECTANGLE_EXTENSION) {
-        const Rect& b(newDirty.bounds());
-        mDisplaySurface->setSwapRectangle(
-                b.left, b.top, b.width(), b.height());
-    }
+    const Rect& b(newDirty.bounds());
+    mNativeWindow->android_native_window_t::setSwapRectangle(
+            mNativeWindow.get(), b.left, b.top, b.width(), b.height());
 
+    mPageFlipCount++;
     eglSwapBuffers(dpy, surface);
     checkEGLErrors("eglSwapBuffers");
 
@@ -345,9 +336,9 @@
 }
 
 void DisplayHardware::copyFrontToImage(const copybit_image_t& front) const {
-    mDisplaySurface->copyFrontToImage(front);
+    // FIXME: we need to get rid of this
 }
 
 void DisplayHardware::copyBackToImage(const copybit_image_t& front) const {
-    mDisplaySurface->copyBackToImage(front);
+    // FIXME: we need to get rid of this
 }
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index 550a4d1..97a68a5 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -22,25 +22,28 @@
 #include <ui/PixelFormat.h>
 #include <ui/Region.h>
 
+#include <GLES/gl.h>
+#include <GLES/glext.h>
 #include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <pixelflinger/pixelflinger.h>
 
 #include "DisplayHardware/DisplayHardwareBase.h"
 
 struct overlay_control_device_t;
-struct copybit_device_t;
+struct framebuffer_device_t;
 struct copybit_image_t;
-struct copybit_t;
 
 namespace android {
 
-class EGLDisplaySurface;
+class FramebufferNativeWindow;
 
 class DisplayHardware : public DisplayHardwareBase
 {
 public:
     enum {
         DIRECT_TEXTURE          = 0x00000002,
-        SWAP_RECTANGLE_EXTENSION= 0x00000004,
         COPY_BITS_EXTENSION     = 0x00000008,
         NPOT_EXTENSION          = 0x00000100,
         DRAW_TEXTURE_EXTENSION  = 0x00000200,
@@ -73,10 +76,7 @@
     void        makeCurrent() const;
 
     uint32_t getPageFlipCount() const;
-    void getDisplaySurface(copybit_image_t* img) const;
-    void getDisplaySurface(GGLSurface* fb) const;
     EGLDisplay getEGLDisplay() const { return mDisplay; }
-    copybit_device_t* getBlitEngine() const { return mBlitEngine; }
     overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
     
     void copyFrontToImage(const copybit_image_t& front) const;
@@ -103,8 +103,9 @@
     PixelFormat     mFormat;
     uint32_t        mFlags;
     mutable Region  mDirty;
-    sp<EGLDisplaySurface> mDisplaySurface;
-    copybit_device_t*     mBlitEngine;
+    mutable uint32_t mPageFlipCount;
+    
+    sp<FramebufferNativeWindow> mNativeWindow;
     overlay_control_device_t* mOverlayEngine;
 };
 
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
index f75e5c2..1d09f84 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index f65d669..980b78b 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -14,26 +14,25 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <cutils/properties.h>
+#include <cutils/native_handle.h>
 
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/StopWatch.h>
+#include <utils/IMemory.h>
 
 #include <ui/PixelFormat.h>
-#include <ui/EGLDisplaySurface.h>
+#include <ui/Surface.h>
 
 #include "clz.h"
 #include "Layer.h"
 #include "LayerBitmap.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 #include "DisplayHardware/DisplayHardware.h"
 
 
@@ -54,8 +53,7 @@
         mSecure(false),
         mFrontBufferIndex(1),
         mNeedsBlending(true),
-        mResizeTransactionDone(false),
-        mTextureName(-1U), mTextureWidth(0), mTextureHeight(0)
+        mResizeTransactionDone(false)
 {
     // no OpenGL operation is possible here, since we might not be
     // in the OpenGL thread.
@@ -63,11 +61,16 @@
 
 Layer::~Layer()
 {
-    client->free(clientIndex());
-    // this should always be called from the OpenGL thread
-    if (mTextureName != -1U) {
-        //glDeleteTextures(1, &mTextureName);
-        deletedTextures.add(mTextureName);
+    for (int i=0 ; i<NUM_BUFFERS ; i++) {
+        if (mTextures[i].name != -1U) {
+            // FIXME: this was originally to work-around a bug in the
+            // adreno driver. this should be fixed now.
+            deletedTextures.add(mTextures[i].name);
+        }
+        if (mTextures[i].image != EGL_NO_IMAGE_KHR) {
+            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+            eglDestroyImageKHR(dpy, mTextures[i].image);
+        }
     }
 }
 
@@ -79,7 +82,7 @@
         lcblk->flags |= eNoCopyBack;
 }
 
-sp<LayerBaseClient::Surface> Layer::getSurface() const
+sp<LayerBaseClient::Surface> Layer::createSurface() const
 {
     return mSurface;
 }
@@ -92,25 +95,15 @@
     status_t err = getPixelFormatInfo(format, &info);
     if (err) return err;
 
-    // TODO: if eHardware is explicitly requested, we should fail
-    // on systems where we can't allocate memory that can be used with
-    // DMA engines for instance.
-    
-    // FIXME: we always ask for hardware for now (this should come from copybit)
-    flags |= ISurfaceComposer::eHardware;
+    uint32_t bufferFlags = 0;
+    if (flags & ISurfaceComposer::eGPU)
+        bufferFlags |= Buffer::GPU;
 
-    const uint32_t memory_flags = flags & 
-            (ISurfaceComposer::eGPU | 
-             ISurfaceComposer::eHardware | 
-             ISurfaceComposer::eSecure);
-    
-    // pixel-alignment. the final alignment may be bigger because
-    // we always force a 4-byte aligned bpr.
-    uint32_t alignment = 1;
+    if (flags & ISurfaceComposer::eSecure)
+        bufferFlags |= Buffer::SECURE;
 
-    if (flags & ISurfaceComposer::eGPU) {
-        // FIXME: this value should come from the h/w
-        alignment = 8; 
+    
+    if (bufferFlags & Buffer::GPU) {
         // FIXME: this is msm7201A specific, as its GPU only supports
         // BGRA_8888.
         if (format == PIXEL_FORMAT_RGBA_8888) {
@@ -118,45 +111,94 @@
         }
     }
 
-    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
+    mSecure = (bufferFlags & Buffer::SECURE) ? true : false;
     mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
-    sp<MemoryDealer> allocators[2];
     for (int i=0 ; i<2 ; i++) {
-        allocators[i] = client->createAllocator(memory_flags);
-        if (allocators[i] == 0)
-            return NO_MEMORY;
-        mBuffers[i].init(allocators[i]);
-        int err = mBuffers[i].setBits(w, h, alignment, format, LayerBitmap::SECURE_BITS);
-        if (err != NO_ERROR)
+        err = mBuffers[i].init(lcblk->surface + i, w, h, format, bufferFlags);
+        if (err != NO_ERROR) {
             return err;
-        mBuffers[i].clear(); // clear the bits for security
-        mBuffers[i].getInfo(lcblk->surface + i);
+        }
     }
-
-    mSurface = new Surface(clientIndex(),
-            allocators[0]->getMemoryHeap(),
-            allocators[1]->getMemoryHeap(),
-            mIdentity);
-
+    mSurface = new SurfaceLayer(clientIndex(), this);
     return NO_ERROR;
 }
 
 void Layer::reloadTexture(const Region& dirty)
 {
-    if (UNLIKELY(mTextureName == -1U)) {
-        // create the texture name the first time
-        // can't do that in the ctor, because it runs in another thread.
-        mTextureName = createTexture();
+    const sp<const Buffer>& buffer(frontBuffer().getBuffer());
+     if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) {
+        int index = mFrontBufferIndex;
+        if (LIKELY(!mTextures[index].dirty)) {
+            glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
+        } else {
+            // we need to recreate the texture
+            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+            
+            // create the new texture name if needed
+            if (UNLIKELY(mTextures[index].name == -1U)) {
+                mTextures[index].name = createTexture();
+            } else {
+                glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
+            }
+
+            // free the previous image
+            if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
+                eglDestroyImageKHR(dpy, mTextures[index].image);
+                mTextures[index].image = EGL_NO_IMAGE_KHR;
+            }
+            
+            // construct an EGL_NATIVE_BUFFER_ANDROID
+            android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
+            
+            // create the new EGLImageKHR
+            const EGLint attrs[] = { 
+                    EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE, 
+                    EGL_NONE,                   EGL_NONE 
+            };
+            mTextures[index].image = eglCreateImageKHR(
+                    dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+                    (EGLClientBuffer)clientBuf, attrs);
+
+            LOGE_IF(mTextures[index].image == EGL_NO_IMAGE_KHR,
+                    "eglCreateImageKHR() failed. err=0x%4x",
+                    eglGetError());
+            
+            if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
+                glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 
+                        (GLeglImageOES)mTextures[index].image);
+                GLint error = glGetError();
+                if (UNLIKELY(error != GL_NO_ERROR)) {
+                    // this failed, for instance, because we don't support
+                    // NPOT.
+                    // FIXME: do something!
+                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
+                } else {
+                    // Everything went okay!
+                    mTextures[index].dirty = false;
+                }
+            }                
+        }
+    } else {
+        GGLSurface t;
+        if (LIKELY(buffer->getBitmapSurface(&t) == NO_ERROR)) {
+            if (UNLIKELY(mTextures[0].name == -1U)) {
+                mTextures[0].name = createTexture();
+            }
+            loadTexture(dirty, mTextures[0].name, t, 
+                    mTextures[0].width, mTextures[0].height);
+        }
     }
-    const GGLSurface& t(frontBuffer().surface());
-    loadTexture(dirty, mTextureName, t, mTextureWidth, mTextureHeight);
 }
 
 
 void Layer::onDraw(const Region& clip) const
 {
-    if (UNLIKELY(mTextureName == -1LU)) {
-        //LOGW("Layer %p doesn't have a texture", this);
+    const int index = (mFlags & DisplayHardware::DIRECT_TEXTURE) ? 
+            mFrontBufferIndex : 0;
+    GLuint textureName = mTextures[index].name;
+
+    if (UNLIKELY(textureName == -1LU)) {
+        LOGW("Layer %p doesn't have a texture", this);
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. this happens frequently with
         // SurfaceView.
@@ -164,63 +206,66 @@
         return;
     }
 
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    const LayerBitmap& front(frontBuffer());
-    const GGLSurface& t(front.surface());
-
-    status_t err = NO_ERROR;
-    const int can_use_copybit = canUseCopybit();
-    if (can_use_copybit)  {
-        // StopWatch watch("copybit");
-        const State& s(drawingState());
-
-        copybit_image_t dst;
-        hw.getDisplaySurface(&dst);
-        const copybit_rect_t& drect
-            = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
-
-        copybit_image_t src;
-        front.getBitmapSurface(&src);
-        copybit_rect_t srect = { 0, 0, t.width, t.height };
-
-        copybit_device_t* copybit = mFlinger->getBlitEngine();
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation());
-        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
-        copybit->set_parameter(copybit, COPYBIT_DITHER,
-                s.flags & ISurfaceComposer::eLayerDither ?
-                        COPYBIT_ENABLE : COPYBIT_DISABLE);
-
-        region_iterator it(clip);
-        err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-    }
-
-    if (!can_use_copybit || err) {
-        drawWithOpenGL(clip, mTextureName, t);
-    }
+    GGLSurface t;
+    sp<const Buffer> buffer(frontBuffer().getBuffer());
+    buffer->getBitmapSurface(&t);
+    drawWithOpenGL(clip, textureName, t);
 }
 
-status_t Layer::reallocateBuffer(int32_t index, uint32_t w, uint32_t h)
+sp<SurfaceBuffer> Layer::peekBuffer()
 {
-    LOGD_IF(DEBUG_RESIZE,
-                "reallocateBuffer (layer=%p), "
-                "requested (%dx%d), "
-                "index=%d, (%dx%d), (%dx%d)",
-                this,
-                int(w), int(h),
-                int(index),
-                int(mBuffers[0].width()), int(mBuffers[0].height()),
-                int(mBuffers[1].width()), int(mBuffers[1].height()));
+    /*
+     * This is called from the client's Surface::lock(), after it locked
+     * the surface successfully. We're therefore guaranteed that the
+     * back-buffer is not in use by ourselves.
+     * Of course, we need to validate all this, which is not trivial.
+     *
+     * FIXME: A resize could happen at any time here. What to do about this?
+     *  - resize() form post()
+     *  - resize() from doTransaction()
+     *  
+     *  We'll probably need an internal lock for this.
+     *     
+     * 
+     * TODO: We need to make sure that post() doesn't swap
+     *       the buffers under us.
+     */
 
-    status_t err = mBuffers[index].resize(w, h);
-    if (err == NO_ERROR) {
-        mBuffers[index].getInfo(lcblk->surface + index);
-    } else {
-        LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s",
-            index, w, h, err, strerror(err));
-        // XXX: what to do, what to do? We could try to free some
-        // hidden surfaces, instead of killing this one?
+    // it's okay to read swapState for the purpose of figuring out the 
+    // backbuffer index, which cannot change (since the app has locked it).
+    const uint32_t state = lcblk->swapState;
+    const int32_t backBufferIndex = layer_cblk_t::backBuffer(state);
+    
+    // get rid of the EGL image, since we shouldn't need it anymore
+    // (note that we're in a different thread than where it is being used)
+    if (mTextures[backBufferIndex].image != EGL_NO_IMAGE_KHR) {
+        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+        eglDestroyImageKHR(dpy, mTextures[backBufferIndex].image);
+        mTextures[backBufferIndex].image = EGL_NO_IMAGE_KHR;
     }
-    return err;
+    
+    LayerBitmap& layerBitmap(mBuffers[backBufferIndex]);
+    sp<SurfaceBuffer> buffer = layerBitmap.allocate();
+    
+    LOGD_IF(DEBUG_RESIZE,
+            "Layer::getBuffer(this=%p), index=%d, (%d,%d), (%d,%d)",
+            this, backBufferIndex,
+            layerBitmap.getWidth(),
+            layerBitmap.getHeight(),
+            layerBitmap.getBuffer()->getWidth(),
+            layerBitmap.getBuffer()->getHeight());
+
+    if (UNLIKELY(buffer == 0)) {
+        // XXX: what to do, what to do?
+    } else {
+        // texture is now dirty...
+        mTextures[backBufferIndex].dirty = true;
+        // ... so it the visible region (because we consider the surface's
+        // buffer size for visibility calculations)
+        forceVisibilityTransaction();
+        mFlinger->setTransactionFlags(eTraversalNeeded);
+    }
+    return buffer;
 }
 
 uint32_t Layer::doTransaction(uint32_t flags)
@@ -232,7 +277,7 @@
     // that the size changed back to its previous value before the buffer
     // was resized (in the eLocked case below), in which case, we still
     // need to execute the code below so the clients have a chance to be
-    // release. resze() deals with the fact that the size can be the same.
+    // release. resize() deals with the fact that the size can be the same.
 
     /*
      *  Various states we could be in...
@@ -276,8 +321,8 @@
                 int(temp.w), int(temp.h),
                 int(drawingState().w), int(drawingState().h),
                 int(clientBackBufferIndex),
-                int(mBuffers[0].width()), int(mBuffers[0].height()),
-                int(mBuffers[1].width()), int(mBuffers[1].height()));
+                int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+                int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
         // if we get there we're pretty screwed. the only reasonable
         // thing to do is to pretend we should do the resize since
         // backbufferChanged is set (this also will give a chance to
@@ -299,8 +344,8 @@
                     int(temp.w), int(temp.h),
                     int(drawingState().w), int(drawingState().h),
                     int(clientBackBufferIndex),
-                    int(mBuffers[0].width()), int(mBuffers[0].height()),
-                    int(mBuffers[1].width()), int(mBuffers[1].height()));
+                    int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+                    int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
 
         if (state & eLocked) {
             // if the buffer is locked, we can't resize anything because
@@ -314,7 +359,8 @@
             status_t err =
                 resize(clientBackBufferIndex, temp.w, temp.h, "transaction");
             if (err == NO_ERROR) {
-                const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
+                const uint32_t mask = clientBackBufferIndex ?
+                        eResizeBuffer1 : eResizeBuffer0;
                 android_atomic_and(~mask, &(lcblk->swapState));
                 // since a buffer became available, we can let the client go...
                 mFlinger->scheduleBroadcast(client);
@@ -353,14 +399,15 @@
 {
     /*
      * handle resize (backbuffer and frontbuffer reallocation)
+     * this is called from post() or from doTransaction()
      */
 
     const LayerBitmap& clientBackBuffer(mBuffers[clientBackBufferIndex]);
 
     // if the new (transaction) size is != from the the backbuffer
     // then we need to reallocate the backbuffer
-    bool backbufferChanged = (clientBackBuffer.width()  != width) ||
-                             (clientBackBuffer.height() != height);
+    bool backbufferChanged = (clientBackBuffer.getWidth()  != width) ||
+                             (clientBackBuffer.getHeight() != height);
 
     LOGD_IF(!backbufferChanged,
             "(%s) eResizeRequested (layer=%p), but size not changed: "
@@ -372,18 +419,28 @@
             int(currentState().w), int(currentState().h),
             long(lcblk->swapState),
             int(clientBackBufferIndex),
-            int(mBuffers[0].width()), int(mBuffers[0].height()),
-            int(mBuffers[1].width()), int(mBuffers[1].height()));
+            int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+            int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
 
     // this can happen when changing the size back and forth quickly
     status_t err = NO_ERROR;
     if (backbufferChanged) {
-        err = reallocateBuffer(clientBackBufferIndex, width, height);
-    }
-    if (UNLIKELY(err != NO_ERROR)) {
-        // couldn't reallocate the surface
-        android_atomic_write(eInvalidSurface, &lcblk->swapState);
-        memset(lcblk->surface+clientBackBufferIndex, 0, sizeof(surface_info_t));
+
+        LOGD_IF(DEBUG_RESIZE,
+                "resize (layer=%p), requested (%dx%d), "
+                "index=%d, (%dx%d), (%dx%d)",
+                this, int(width), int(height), int(clientBackBufferIndex),
+                int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+                int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
+
+        err = mBuffers[clientBackBufferIndex].setSize(width, height);
+        if (UNLIKELY(err != NO_ERROR)) {
+            // This really should never happen
+            LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s",
+                    clientBackBufferIndex, width, height, err, strerror(err));
+            // couldn't reallocate the surface
+            android_atomic_write(eInvalidSurface, &lcblk->swapState);
+        }
     }
     return err;
 }
@@ -457,15 +514,21 @@
 
     } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
     *previousSate = oldValue;
-
+    
     const int32_t index = (newValue & eIndex) ^ 1;
     mFrontBufferIndex = index;
 
+    /* NOTE: it's safe to set this flag here because this is only touched
+     * from LayerBitmap::allocate(), which by construction cannot happen
+     * while we're in post().
+     */
+    lcblk->surface[index].flags &= ~surface_info_t::eBufferDirty;
+
     // ... post the new front-buffer
     Region dirty(lcblk->region + index);
-    dirty.andSelf(frontBuffer().bounds());
+    dirty.andSelf(frontBuffer().getBounds());
 
-    //LOGI("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n",
+    //LOGD("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n",
     //    oldValue, newValue, mFrontBufferIndex);
     //dirty.dump("dirty");
 
@@ -476,8 +539,8 @@
                      "index=%d, (%dx%d), (%dx%d)",
                      this,  newValue,
                      int(1-index),
-                     int(mBuffers[0].width()), int(mBuffers[0].height()),
-                     int(mBuffers[1].width()), int(mBuffers[1].height()));
+                     int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+                     int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
 
         // here, we just posted the surface and we have resolved
         // the front/back buffer indices. The client is blocked, so
@@ -522,8 +585,8 @@
 
 Point Layer::getPhysicalSize() const
 {
-    const LayerBitmap& front(frontBuffer());
-    return Point(front.width(), front.height());
+    sp<const Buffer> front(frontBuffer().getBuffer());
+    return Point(front->getWidth(), front->getHeight());
 }
 
 void Layer::unlockPageFlip(
@@ -561,6 +624,22 @@
     mFlinger->scheduleBroadcast(client);
 }
 
+// ---------------------------------------------------------------------------
+
+Layer::SurfaceLayer::SurfaceLayer(SurfaceID id, const sp<Layer>& owner)
+    : Surface(id, owner->getIdentity(), owner)
+{
+}
+
+sp<SurfaceBuffer> Layer::SurfaceLayer::getBuffer()
+{
+    sp<SurfaceBuffer> buffer = 0;
+    sp<Layer> owner(getOwner());
+    if (owner != 0) {
+        buffer = owner->peekBuffer();
+    }
+    return buffer;
+}
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index 2867f2b..dc03d35 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -27,6 +27,11 @@
 
 #include <pixelflinger/pixelflinger.h>
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
 #include "LayerBitmap.h"
 #include "LayerBase.h"
 #include "Transform.h"
@@ -42,6 +47,8 @@
 
 // ---------------------------------------------------------------------------
 
+const int NUM_BUFFERS = 2;
+
 class Layer : public LayerBaseClient
 {
 public:    
@@ -56,7 +63,7 @@
         virtual ~Layer();
 
     inline PixelFormat pixelFormat() const {
-        return frontBuffer().pixelFormat();
+        return frontBuffer().getPixelFormat();
     }
 
     status_t setBuffers(    Client* client,
@@ -73,8 +80,7 @@
     virtual void finishPageFlip();
     virtual bool needsBlending() const      { return mNeedsBlending; }
     virtual bool isSecure() const           { return mSecure; }
-    virtual GLuint getTextureName() const   { return mTextureName; }
-    virtual sp<Surface> getSurface() const;
+    virtual sp<Surface> createSurface() const;
 
     const LayerBitmap& getBuffer(int i) const { return mBuffers[i]; }
           LayerBitmap& getBuffer(int i)       { return mBuffers[i]; }
@@ -96,21 +102,43 @@
 
     status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what);
     Region post(uint32_t* oldState, bool& recomputeVisibleRegions);
-    status_t reallocateBuffer(int32_t index, uint32_t w, uint32_t h);
+    sp<SurfaceBuffer> peekBuffer();
+    
+    
+    class SurfaceLayer : public LayerBaseClient::Surface
+    {
+    public:
+                SurfaceLayer(SurfaceID id, const sp<Layer>& owner);
 
+    private:
+        virtual sp<SurfaceBuffer> getBuffer();
+
+        sp<Layer> getOwner() const {
+            return static_cast<Layer*>(Surface::getOwner().get());
+        }
+    };
+    friend class SurfaceLayer;
+    
+    struct Texture {
+        Texture() : name(-1U), width(0), height(0), image(EGL_NO_IMAGE_KHR),
+            dirty(true) { }
+        GLuint      name;
+        GLuint      width;
+        GLuint      height;
+        EGLImageKHR image;
+        bool        dirty;
+    };
+    
     sp<Surface>             mSurface;
 
             bool            mSecure;
-            LayerBitmap     mBuffers[2];
+            LayerBitmap     mBuffers[NUM_BUFFERS];
+            Texture         mTextures[NUM_BUFFERS];
             int32_t         mFrontBufferIndex;
             bool            mNeedsBlending;
             bool            mResizeTransactionDone;
             Region          mPostedDirtyRegion;
             sp<FreezeLock>  mFreezeLock;
-            
-            GLuint          mTextureName;
-            GLuint          mTextureWidth;
-            GLuint          mTextureHeight;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 0cf53f7..6da0bf7 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/Errors.h>
 #include <utils/Log.h>
+#include <utils/IPCThreadState.h>
+#include <utils/IServiceManager.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
@@ -62,7 +62,6 @@
       mFlinger(flinger),
       mTransformed(false),
       mOrientation(0),
-      mCanUseCopyBit(false),
       mTransactionFlags(0),
       mPremultipliedAlpha(true),
       mIdentity(uint32_t(android_atomic_inc(&sIdentity))),
@@ -265,43 +264,6 @@
     mTransformed = transformed;
     mLeft = tr.tx();
     mTop  = tr.ty();
-
-    // see if we can/should use 2D h/w with the new configuration
-    mCanUseCopyBit = false;
-    copybit_device_t* copybit = mFlinger->getBlitEngine();
-    if (copybit) { 
-        const int step = copybit->get(copybit, COPYBIT_ROTATION_STEP_DEG);
-        const int scaleBits = copybit->get(copybit, COPYBIT_SCALING_FRAC_BITS);
-        mCanUseCopyBit = true;
-        if ((mOrientation < 0) && (step > 1)) {
-            // arbitrary orientations not supported
-            mCanUseCopyBit = false;
-        } else if ((mOrientation > 0) && (step > 90)) {
-            // 90 deg rotations not supported
-            mCanUseCopyBit = false;
-        } else if ((tr.getType() & SkMatrix::kScale_Mask) && (scaleBits < 12)) { 
-            // arbitrary scaling not supported
-            mCanUseCopyBit = false;
-        }
-#if HONOR_PREMULTIPLIED_ALPHA 
-        else if (needsBlending() && mPremultipliedAlpha) {
-            // pre-multiplied alpha not supported
-            mCanUseCopyBit = false;
-        }
-#endif
-        else {
-            // here, we determined we can use copybit
-            if (tr.getType() & SkMatrix::kScale_Mask) {
-                // and we have scaling
-                if (!transparentRegionScreen.isRect()) {
-                    // we punt because blending is cheap (h/w) and the region is
-                    // complex, which may causes artifacts when copying
-                    // scaled content
-                    transparentRegionScreen.clear();
-                }
-            }
-        }
-    }
 }
 
 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
@@ -565,8 +527,7 @@
 
     /*
      * In OpenGL ES we can't specify a stride with glTexImage2D (however,
-     * GL_UNPACK_ALIGNMENT is 4, which in essence allows a limited form of
-     * stride).
+     * GL_UNPACK_ALIGNMENT is a limited form of stride).
      * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
      * need to do something reasonable (here creating a bigger texture).
      * 
@@ -579,9 +540,11 @@
      *
      * This should never be a problem with POT textures
      */
-
-    tw += (((t.stride - tw) * bytesPerPixel(t.format)) / 4);
-
+    
+    int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
+    unpack = 1 << ((unpack > 3) ? 3 : unpack);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
+    
     /*
      * round to POT if needed 
      */
@@ -594,108 +557,80 @@
         texture_h = 1 << (31 - clz(t.height));
         if (texture_w < t.width)  texture_w <<= 1;
         if (texture_h < t.height) texture_h <<= 1;
-        if (texture_w != tw || texture_h != th) {
-            // we can't use DIRECT_TEXTURE since we changed the size
-            // of the texture
-            flags &= ~DisplayHardware::DIRECT_TEXTURE;
-        }
     }
-
-    if (flags & DisplayHardware::DIRECT_TEXTURE) {
-        // here we're guaranteed that texture_{w|h} == t{w|h}
-        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
-            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
-                    GL_RGB, tw, th, 0,
-                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t.data);
-        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
-            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
-                    GL_RGBA, tw, th, 0,
-                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t.data);
-        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
-            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
-                    GL_RGBA, tw, th, 0,
-                    GL_RGBA, GL_UNSIGNED_BYTE, t.data);
-        } else if (t.format == GGL_PIXEL_FORMAT_BGRA_8888) {
-            // TODO: add GL_BGRA extension
-        } else {
-            // oops, we don't handle this format, try the regular path
-            goto regular;
-        }
-        textureWidth = tw;
-        textureHeight = th;
-    } else {
+    
 regular:
-        Rect bounds(dirty.bounds());
-        GLvoid* data = 0;
-        if (texture_w!=textureWidth || texture_h!=textureHeight) {
-            // texture size changed, we need to create a new one
+    Rect bounds(dirty.bounds());
+    GLvoid* data = 0;
+    if (texture_w!=textureWidth || texture_h!=textureHeight) {
+        // texture size changed, we need to create a new one
 
-            if (!textureWidth || !textureHeight) {
-                // this is the first time, load the whole texture
-                if (texture_w==tw && texture_h==th) {
-                    // we can do it one pass
-                    data = t.data;
-                } else {
-                    // we have to create the texture first because it
-                    // doesn't match the size of the buffer
-                    bounds.set(Rect(tw, th));
-                }
-            }
-            
-            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
-                glTexImage2D(GL_TEXTURE_2D, 0,
-                        GL_RGB, texture_w, texture_h, 0,
-                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
-            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
-                glTexImage2D(GL_TEXTURE_2D, 0,
-                        GL_RGBA, texture_w, texture_h, 0,
-                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
-            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
-                glTexImage2D(GL_TEXTURE_2D, 0,
-                        GL_RGBA, texture_w, texture_h, 0,
-                        GL_RGBA, GL_UNSIGNED_BYTE, data);
-            } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
-                        t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
-                // just show the Y plane of YUV buffers
+        if (!textureWidth || !textureHeight) {
+            // this is the first time, load the whole texture
+            if (texture_w==tw && texture_h==th) {
+                // we can do it one pass
                 data = t.data;
-                glTexImage2D(GL_TEXTURE_2D, 0,
-                        GL_LUMINANCE, texture_w, texture_h, 0,
-                        GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
             } else {
-                // oops, we don't handle this format!
-                LOGE("layer %p, texture=%d, using format %d, which is not "
-                     "supported by the GL", this, textureName, t.format);
-                textureName = -1;
+                // we have to create the texture first because it
+                // doesn't match the size of the buffer
+                bounds.set(Rect(tw, th));
             }
-            textureWidth = texture_w;
-            textureHeight = texture_h;
         }
-        if (!data && textureName>=0) {
-            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
-                glTexSubImage2D(GL_TEXTURE_2D, 0,
-                        0, bounds.top, t.width, bounds.height(),
-                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
-                        t.data + bounds.top*t.width*2);
-            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
-                glTexSubImage2D(GL_TEXTURE_2D, 0,
-                        0, bounds.top, t.width, bounds.height(),
-                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
-                        t.data + bounds.top*t.width*2);
-            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
-                glTexSubImage2D(GL_TEXTURE_2D, 0,
-                        0, bounds.top, t.width, bounds.height(),
-                        GL_RGBA, GL_UNSIGNED_BYTE,
-                        t.data + bounds.top*t.width*4);
-            }
+        
+        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_RGB, texture_w, texture_h, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_RGBA, texture_w, texture_h, 0,
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_RGBA, texture_w, texture_h, 0,
+                    GL_RGBA, GL_UNSIGNED_BYTE, data);
+        } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
+                    t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
+            // just show the Y plane of YUV buffers
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_LUMINANCE, texture_w, texture_h, 0,
+                    GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+        } else {
+            // oops, we don't handle this format!
+            LOGE("layer %p, texture=%d, using format %d, which is not "
+                 "supported by the GL", this, textureName, t.format);
+            textureName = -1;
+        }
+        textureWidth = texture_w;
+        textureHeight = texture_h;
+    }
+    if (!data && textureName>=0) {
+        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+                    t.data + bounds.top*t.stride*2);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
+                    t.data + bounds.top*t.stride*2);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_RGBA, GL_UNSIGNED_BYTE,
+                    t.data + bounds.top*t.stride*4);
+        } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
+                    t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
+            // just show the Y plane of YUV buffers
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_LUMINANCE, GL_UNSIGNED_BYTE,
+                    t.data + bounds.top*t.stride);
         }
     }
 }
 
-bool LayerBase::canUseCopybit() const
-{
-    return mCanUseCopyBit;
-}
-
 // ---------------------------------------------------------------------------
 
 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
@@ -704,9 +639,12 @@
       lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ),
       mIndex(i)
 {
-    if (client) {
-        client->bindLayer(this, i);
+}
 
+void LayerBaseClient::onFirstRef()
+{    
+    if (client) {
+        client->bindLayer(this, mIndex);
         // Initialize this layer's control block
         memset(this->lcblk, 0, sizeof(layer_cblk_t));
         this->lcblk->identity = mIdentity;
@@ -729,11 +667,106 @@
     return 0xFFFF0000 | mIndex;
 }
 
-sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() const
+sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
 {
-    return new Surface(clientIndex(), mIdentity);
+    sp<Surface> s;
+    Mutex::Autolock _l(mLock);
+    s = mClientSurface.promote();
+    if (s == 0) {
+        s = createSurface();
+        mClientSurface = s;
+    }
+    return s;
 }
 
+sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
+{
+    return new Surface(clientIndex(), mIdentity,
+            const_cast<LayerBaseClient *>(this));
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBaseClient::Surface::Surface(SurfaceID id, int identity, 
+        const sp<LayerBaseClient>& owner) 
+    : mToken(id), mIdentity(identity), mOwner(owner)
+{ 
+}
+
+
+LayerBaseClient::Surface::~Surface() {
+    // TODO: We now have a point here were we can clean-up the
+    // client's mess.
+    // This is also where surface id should be recycled.
+    //LOGD("Surface %d, heaps={%p, %p} destroyed",
+    //        mId, mHeap[0].get(), mHeap[1].get());
+}
+
+sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
+    sp<LayerBaseClient> owner(mOwner.promote());
+    return owner;
+}
+
+
+void LayerBaseClient::Surface::getSurfaceData(
+        ISurfaceFlingerClient::surface_data_t* params) const 
+{
+    params->token = mToken;
+    params->identity = mIdentity;
+}
+
+status_t LayerBaseClient::Surface::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case REGISTER_BUFFERS:
+        case UNREGISTER_BUFFERS:
+        case CREATE_OVERLAY:
+        {
+            // codes that require permission check
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int self_pid = getpid();
+            if (LIKELY(pid != self_pid)) {
+                // we're called from a different process, do the real check
+                if (!checkCallingPermission(
+                        String16("android.permission.ACCESS_SURFACE_FLINGER")))
+                {
+                    const int uid = ipc->getCallingUid();
+                    LOGE("Permission Denial: "
+                            "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+                    return PERMISSION_DENIED;
+                }
+            }
+        }
+    }
+    return BnSurface::onTransact(code, data, reply, flags);
+}
+
+sp<SurfaceBuffer> LayerBaseClient::Surface::getBuffer() 
+{
+    return NULL; 
+}
+
+status_t LayerBaseClient::Surface::registerBuffers(
+        const ISurface::BufferHeap& buffers) 
+{ 
+    return INVALID_OPERATION; 
+}
+
+void LayerBaseClient::Surface::postBuffer(ssize_t offset) 
+{
+}
+
+void LayerBaseClient::Surface::unregisterBuffers() 
+{
+}
+
+sp<OverlayRef> LayerBaseClient::Surface::createOverlay(
+        uint32_t w, uint32_t h, int32_t format) 
+{
+    return NULL;
+};
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index a020f44..2a4e133 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -22,6 +22,8 @@
 
 #include <private/ui/LayerState.h>
 
+#include <utils/RefBase.h>
+
 #include <ui/Region.h>
 #include <ui/Overlay.h>
 
@@ -37,10 +39,11 @@
 class DisplayHardware;
 class GraphicPlane;
 class Client;
+class SurfaceBuffer;
 
 // ---------------------------------------------------------------------------
 
-class LayerBase
+class LayerBase : public RefBase
 {
     // poor man's dynamic_cast below
     template<typename T>
@@ -72,7 +75,6 @@
     static Vector<GLuint> deletedTextures; 
 
     LayerBase(SurfaceFlinger* flinger, DisplayID display);
-    virtual ~LayerBase();
     
     DisplayID           dpy;
     mutable bool        contentDirty;
@@ -215,7 +217,9 @@
     inline  const State&    currentState() const    { return mCurrentState; }
     inline  State&          currentState()          { return mCurrentState; }
 
-    static int compareCurrentStateZ(LayerBase*const* layerA, LayerBase*const* layerB) {
+    static int compareCurrentStateZ(
+            sp<LayerBase> const * layerA,
+            sp<LayerBase> const * layerB) {
         return layerA[0]->currentState().z - layerB[0]->currentState().z;
     }
 
@@ -240,8 +244,6 @@
                   GLint textureName, const GGLSurface& t,
                   GLuint& textureWidth, GLuint& textureHeight) const;
 
-          bool canUseCopybit() const;
-          
                 SurfaceFlinger* mFlinger;
                 uint32_t        mFlags;
 
@@ -250,7 +252,6 @@
                 int32_t         mOrientation;
                 GLfixed         mVertices[4][2];
                 Rect            mTransformedBounds;
-                bool            mCanUseCopyBit;
                 int             mLeft;
                 int             mTop;
             
@@ -269,9 +270,13 @@
     volatile    int32_t         mInvalidate;
                 
 
+protected:
+    virtual ~LayerBase();
+
 private:
-                void validateTexture(GLint textureName) const;
-    static      int32_t         sIdentity;
+    LayerBase(const LayerBase& rhs);
+    void validateTexture(GLint textureName) const;
+    static int32_t sIdentity;
 };
 
 
@@ -289,64 +294,55 @@
     LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 
             Client* client, int32_t i);
     virtual ~LayerBaseClient();
-
+    virtual void onFirstRef();
 
     Client*             const client;
     layer_cblk_t*       const lcblk;
 
+    inline  uint32_t    getIdentity() const { return mIdentity; }
     inline  int32_t     clientIndex() const { return mIndex; }
             int32_t     serverIndex() const;
 
-    virtual sp<Surface> getSurface() const;
    
-            uint32_t    getIdentity() const { return mIdentity; }
+            sp<Surface> getSurface();
+    virtual sp<Surface> createSurface() const;
+    
 
     class Surface : public BnSurface 
     {
     public:
-        Surface(SurfaceID id, int identity) { 
-            mParams.token = id;
-            mParams.identity = identity;
-        }
-        Surface(SurfaceID id, 
-                const sp<IMemoryHeap>& heap0,
-                const sp<IMemoryHeap>& heap1,
-                int identity)
-        {
-            mParams.token = id;
-            mParams.identity = identity;
-            mParams.heap[0] = heap0;
-            mParams.heap[1] = heap1;
-        }
-        virtual ~Surface() {
-            // TODO: We now have a point here were we can clean-up the
-            // client's mess.
-            // This is also where surface id should be recycled.
-            //LOGD("Surface %d, heaps={%p, %p} destroyed",
-            //        mId, mHeap[0].get(), mHeap[1].get());
-        }
-
+        
         virtual void getSurfaceData(
-                ISurfaceFlingerClient::surface_data_t* params) const {
-            *params = mParams;
-        }
+                ISurfaceFlingerClient::surface_data_t* params) const;
 
-        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers) 
-                { return INVALID_OPERATION; }
-        virtual void postBuffer(ssize_t offset) { }
-        virtual void unregisterBuffers() { };
-        virtual sp<OverlayRef> createOverlay(
-                uint32_t w, uint32_t h, int32_t format) {
-            return NULL;
-        };
+    protected:
+        Surface(SurfaceID id, int identity, const sp<LayerBaseClient>& owner);
+        virtual ~Surface();
+        virtual status_t onTransact(uint32_t code, const Parcel& data,
+                Parcel* reply, uint32_t flags);
+        sp<LayerBaseClient> getOwner() const;
 
     private:
-        ISurfaceFlingerClient::surface_data_t mParams;
+        virtual sp<SurfaceBuffer> getBuffer();
+        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); 
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        virtual sp<OverlayRef> createOverlay(uint32_t w, uint32_t h,
+                int32_t format);
+
+    private:
+        friend class LayerBaseClient;
+        int32_t             mToken;
+        int32_t             mIdentity;
+        wp<LayerBaseClient> mOwner;
     };
 
-private:
-    int32_t mIndex;
+    friend class Surface;
 
+private:
+                int32_t         mIndex;
+    mutable     Mutex           mLock;
+    mutable     wp<Surface>     mClientSurface;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
index e844350..d633a2d 100644
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -14,170 +14,204 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <cutils/memory.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
 #include <utils/IMemory.h>
+
 #include <ui/PixelFormat.h>
+#include <ui/Surface.h>
 #include <pixelflinger/pixelflinger.h>
 
+#include "BufferAllocator.h"
 #include "LayerBitmap.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 
 
 namespace android {
 
-// ---------------------------------------------------------------------------
+// ===========================================================================
+// Buffer and implementation of android_native_buffer_t
+// ===========================================================================
+
+Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
+    : SurfaceBuffer(), mInitCheck(NO_INIT), mFlags(flags), 
+    mVStride(0)
+{
+    this->format = format;
+    if (w>0 && h>0) {
+        mInitCheck = initSize(w, h);
+    }
+}
+
+Buffer::~Buffer()
+{
+    if (handle) {
+        BufferAllocator& allocator = BufferAllocator::get();
+        if (usage & BufferAllocator::USAGE_SW_READ_MASK) {
+            allocator.unmap(handle);
+        }
+        allocator.free(handle);
+    }
+}
+
+status_t Buffer::initCheck() const {
+    return mInitCheck;
+}
+
+android_native_buffer_t* Buffer::getNativeBuffer() const
+{
+    return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this));
+}
+
+status_t Buffer::initSize(uint32_t w, uint32_t h)
+{
+    status_t err = NO_ERROR;
+
+    BufferAllocator& allocator = BufferAllocator::get();
+        
+    /*
+     *  buffers used for software rendering, but h/w composition
+     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
+     *  
+     *  buffers used for h/w rendering and h/w composition
+     *  are allocated with  HW_RENDER | HW_TEXTURE
+     *  
+     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
+     *  are allocated with SW_READ_RARELY | HW_RENDER 
+     *  
+     */
+    
+    if (mFlags & Buffer::SECURE) {
+        // secure buffer, don't store it into the GPU
+        usage = BufferAllocator::USAGE_SW_READ_OFTEN | 
+                BufferAllocator::USAGE_SW_WRITE_OFTEN;
+    } else {
+        if (mFlags & Buffer::GPU) {
+            // the client wants to do GL rendering
+            usage = BufferAllocator::USAGE_HW_RENDER |
+                    BufferAllocator::USAGE_HW_TEXTURE;
+        } else {
+            // software rendering-client, h/w composition
+            usage = BufferAllocator::USAGE_SW_READ_OFTEN | 
+                    BufferAllocator::USAGE_SW_WRITE_OFTEN |
+                    BufferAllocator::USAGE_HW_TEXTURE;
+        }
+    }
+
+    err = allocator.alloc(w, h, format, usage, &handle, &stride);
+    
+    if (err == NO_ERROR) {
+        if (usage & BufferAllocator::USAGE_SW_READ_MASK) {
+            err = allocator.map(handle, &bits);
+        }
+        if (err == NO_ERROR) {
+            width  = w;
+            height = h;
+            mVStride = 0;
+        }
+    }
+
+    return err;
+}
+
+status_t Buffer::getBitmapSurface(copybit_image_t* img) const
+{
+    img->w = stride  ?: width;
+    img->h = mVStride ?: height;
+    img->format = format;
+    
+    // FIXME: this should use a native_handle
+    img->offset = 0;    
+    img->base = bits;
+    img->fd = getHandle()->data[0];
+    
+    return NO_ERROR;
+}
+
+status_t Buffer::getBitmapSurface(GGLSurface* sur) const
+{
+    sur->version = sizeof(GGLSurface);
+    sur->width = width;
+    sur->height = height;
+    sur->stride = stride;
+    sur->format = format;
+    sur->vstride = mVStride;
+    sur->data = static_cast<GGLubyte*>(bits);
+    return NO_ERROR;
+}
+
+// ===========================================================================
+// LayerBitmap
+// ===========================================================================
+
 
 LayerBitmap::LayerBitmap()
-    : mAllocFlags(0), mOffset(0), mSize(-1U), mAlignment(2)
+    : mInfo(0), mWidth(0), mHeight(0)
 {
-    memset(&mSurface, 0, sizeof(mSurface));
 }
 
 LayerBitmap::~LayerBitmap()
 {
-    mSurface.data = 0;
 }
 
-status_t LayerBitmap::init(const sp<MemoryDealer>& allocator)
+status_t LayerBitmap::init(surface_info_t* info,
+        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
 {
-    if (mAllocator != NULL)
+    if (info == NULL)
         return BAD_VALUE;
-    mAllocator = allocator;
+    
+    mFormat = format;
+    mFlags = flags;
+    mWidth = w;
+    mHeight = h;
+
+    mInfo = info;
+    memset(info, 0, sizeof(surface_info_t));
+    info->flags = surface_info_t::eNeedNewBuffer;
+    
+    // init the buffer, but don't trigger an allocation
+    mBuffer = new Buffer(0, 0, format, flags);
     return NO_ERROR;
 }
 
-status_t LayerBitmap::setBits(uint32_t w, uint32_t h, uint32_t alignment, 
-        PixelFormat format, uint32_t flags)
+status_t LayerBitmap::setSize(uint32_t w, uint32_t h)
 {
-    const sp<MemoryDealer>& allocator(mAllocator);
-    if (allocator == NULL)
-        return NO_INIT;
-
-    if (UNLIKELY(w == mSurface.width && h == mSurface.height &&
-            format == mSurface.format))
-    { // same format and size, do nothing.
-        return NO_ERROR;
-    }
-
-    PixelFormatInfo info;
-    getPixelFormatInfo(format, &info);
-
-    uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED;
-    const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT
-    const uint32_t Bpp = info.bytesPerPixel;
-    uint32_t stride = (w + (alignment-1)) & ~(alignment-1);
-    stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp;
-    size_t size = info.getScanlineSize(stride) * h;
-    if (allocFlags & MemoryDealer::PAGE_ALIGNED) {
-        size_t pagesize = getpagesize();
-        size = (size + (pagesize-1)) & ~(pagesize-1);
-    }
-
-    /* FIXME: we should be able to have a h/v stride because the user of the
-     * surface might have stride limitation (for instance h/w codecs often do)
-     */
-    int32_t vstride = 0;
-
-    mAlignment = alignment;
-    mAllocFlags = allocFlags;
-    mOffset = 0;
-    if (mSize != size) {
-        // would be nice to have a reallocate() api
-        mBitsMemory.clear(); // free-memory
-        mBitsMemory = allocator->allocate(size, allocFlags);
-        mSize = size;
-    } else {
-        // don't erase memory if we didn't have to reallocate
-        flags &= ~SECURE_BITS;
-    }
-    if (mBitsMemory != 0) {
-        mOffset = mBitsMemory->offset();
-        mSurface.data = static_cast<GGLubyte*>(mBitsMemory->pointer());
-        mSurface.version = sizeof(GGLSurface);
-        mSurface.width  = w;
-        mSurface.height = h;
-        mSurface.stride = stride;
-        mSurface.vstride = vstride;
-        mSurface.format = format;
-        if (flags & SECURE_BITS)
-            clear();
-    }
-
-    if (mBitsMemory==0 || mSurface.data==0) {
-        LOGE("not enough memory for layer bitmap size=%u", size);
-        allocator->dump("LayerBitmap");
-        mSurface.data = 0;
-        mSize = -1U;
-        return NO_MEMORY;
+    Mutex::Autolock _l(mLock);
+    if ((w != mWidth) || (h != mHeight)) {
+        mWidth  = w;
+        mHeight = h;
+        // this will signal the client that it needs to asks us for a new buffer
+        mInfo->flags = surface_info_t::eNeedNewBuffer;
     }
     return NO_ERROR;
 }
 
-void LayerBitmap::clear()
+sp<Buffer> LayerBitmap::allocate()
 {
-    // NOTE: this memset should not be necessary, at least for
-    // opaque surface. However, for security reasons it's better to keep it
-    // (in the case of pmem, it's possible that the memory contains old
-    // data)
-    if (mSurface.data) {
-        memset(mSurface.data, 0, mSize);
-        //if (bytesPerPixel(mSurface.format) == 4) {
-        //    android_memset32((uint32_t*)mSurface.data, 0xFF0000FF, mSize);
-        //} else  {
-        //    android_memset16((uint16_t*)mSurface.data, 0xF800, mSize);
-        //}
+    Mutex::Autolock _l(mLock);
+    sp<Buffer> buffer(mBuffer);
+    const uint32_t w = mWidth; 
+    const uint32_t h = mHeight;
+    if (w != buffer->getWidth() || h != buffer->getHeight()) {
+        surface_info_t* info = mInfo;
+        buffer = new Buffer(w, h, mFormat, mFlags);
+        status_t err = buffer->initCheck();
+        if (LIKELY(err == NO_ERROR)) {
+            info->flags  = surface_info_t::eBufferDirty;
+            info->status = NO_ERROR;
+        } else {
+            memset(info, 0, sizeof(surface_info_t));
+            info->status = NO_MEMORY;
+        }
+        mBuffer = buffer;
     }
-}
-
-status_t LayerBitmap::getInfo(surface_info_t* info) const
-{
-    if (mSurface.data == 0) {
-        memset(info, 0, sizeof(surface_info_t));
-        info->bits_offset = NO_MEMORY;
-        return NO_MEMORY;
-    }
-    info->w     = uint16_t(width());
-    info->h     = uint16_t(height());
-    info->stride= uint16_t(stride());
-    info->bpr   = uint16_t(stride() * bytesPerPixel(pixelFormat()));
-    info->format= uint8_t(pixelFormat());
-    info->flags = surface_info_t::eBufferDirty;
-    info->bits_offset = ssize_t(mOffset);
-    return NO_ERROR;
-}
-
-status_t LayerBitmap::resize(uint32_t w, uint32_t h)
-{
-    int err = setBits(w, h, mAlignment, pixelFormat(), SECURE_BITS);
-    return err;
-}
-
-size_t LayerBitmap::size() const
-{
-    return mSize;
-}
-
-void LayerBitmap::getBitmapSurface(copybit_image_t* img) const
-{
-    const sp<IMemoryHeap>& mh(getAllocator()->getMemoryHeap());
-    void* sbase = mh->base();
-    const GGLSurface& t(surface());
-    img->w = t.stride  ?: t.width;
-    img->h = t.vstride ?: t.height;
-    img->format = t.format;
-    img->offset = intptr_t(t.data) - intptr_t(sbase);
-    img->base = sbase;
-    img->fd = mh->heapID();
+    return buffer;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
index 9ad64c4..d1f7802 100644
--- a/libs/surfaceflinger/LayerBitmap.h
+++ b/libs/surfaceflinger/LayerBitmap.h
@@ -20,63 +20,117 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <hardware/gralloc.h>
+
 #include <utils/Atomic.h>
+
 #include <ui/PixelFormat.h>
 #include <ui/Rect.h>
-#include <private/ui/SharedState.h>
+#include <ui/Surface.h>
+
+#include <EGL/android_natives.h>
+
 #include <pixelflinger/pixelflinger.h>
 
+#include <private/ui/SharedState.h>
+
+
 class copybit_image_t;
+struct android_native_buffer_t;
 
 namespace android {
 
 // ---------------------------------------------------------------------------
-
 class IMemory;
 class MemoryDealer;
 class LayerBitmap;
 
-// ---------------------------------------------------------------------------
+// ===========================================================================
+// Buffer
+// ===========================================================================
+
+class NativeBuffer;
+
+class Buffer : public SurfaceBuffer
+{
+public:
+    enum {
+        DONT_CLEAR  = 0x00000001,
+        GPU         = 0x00000002,
+        SECURE      = 0x00000004
+    };
+
+    // creates w * h buffer
+    Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags = 0);
+
+    // return status
+    status_t initCheck() const;
+
+    uint32_t getWidth() const           { return width; }
+    uint32_t getHeight() const          { return height; }
+    uint32_t getStride() const          { return stride; }
+    uint32_t getUsage() const           { return usage; }
+    PixelFormat getPixelFormat() const  { return format; }
+    Rect getBounds() const              { return Rect(width, height); }
+    
+    status_t getBitmapSurface(copybit_image_t* img) const;
+    status_t getBitmapSurface(GGLSurface* surface) const;
+
+    android_native_buffer_t* getNativeBuffer() const;
+    
+private:
+    friend class LightRefBase<Buffer>;
+    Buffer(const Buffer& rhs);
+    ~Buffer();
+    Buffer& operator = (const Buffer& rhs);
+    const Buffer& operator = (const Buffer& rhs) const;
+
+    status_t initSize(uint32_t w, uint32_t h);
+
+    ssize_t                 mInitCheck;
+    uint32_t                mFlags;
+    uint32_t                mVStride;
+};
+
+// ===========================================================================
+// LayerBitmap
+// ===========================================================================
 
 class LayerBitmap
 {
 public:
-
     enum {
-        // erase memory to ensure security when necessary
-        SECURE_BITS = 0x00000001
+        DONT_CLEAR  = Buffer::DONT_CLEAR,
+        GPU         = Buffer::GPU,
+        SECURE      = Buffer::SECURE
     };
+    LayerBitmap();
+    ~LayerBitmap();
 
-                LayerBitmap();
-                ~LayerBitmap();
-    status_t    init(const sp<MemoryDealer>& allocator);
+    status_t init(surface_info_t* info,
+            uint32_t w, uint32_t h, PixelFormat format, uint32_t flags = 0);
 
-    status_t    setBits(uint32_t w, uint32_t h, uint32_t alignment,
-                        PixelFormat format, uint32_t flags = 0);
-    void        clear();
+    status_t setSize(uint32_t w, uint32_t h);
 
-    status_t    getInfo(surface_info_t* info) const;
-    status_t    resize(uint32_t w, uint32_t h);
+    sp<Buffer> allocate();
 
-    const GGLSurface& surface() const   { return mSurface; }
-    Rect bounds() const                 { return Rect(width(), height()); }
-    uint32_t width() const              { return surface().width; }
-    uint32_t height() const             { return surface().height; }
-    uint32_t stride() const             { return surface().stride; }
-    PixelFormat pixelFormat() const     { return surface().format; }
-    void* serverBits() const            { return surface().data; }
-    size_t size() const;
-    const sp<MemoryDealer>& getAllocator() const { return mAllocator; }
-    void getBitmapSurface(copybit_image_t* img) const;
-
+    sp<const Buffer>  getBuffer() const { return mBuffer; }
+    sp<Buffer>        getBuffer()       { return mBuffer; }
+    
+    uint32_t getWidth() const           { return mWidth; }
+    uint32_t getHeight() const          { return mHeight; }
+    PixelFormat getPixelFormat() const  { return mBuffer->getPixelFormat(); }
+    Rect getBounds() const              { return mBuffer->getBounds(); }
+    
 private:
-    sp<MemoryDealer>        mAllocator;
-    sp<IMemory>             mBitsMemory;
-    uint32_t                mAllocFlags;
-    ssize_t                 mOffset;
-    GGLSurface              mSurface;
-    size_t                  mSize;
-    uint32_t                mAlignment;
+    surface_info_t* mInfo;
+    sp<Buffer>      mBuffer;
+    uint32_t        mWidth;
+    uint32_t        mHeight;
+    PixelFormat     mFormat;
+    uint32_t        mFlags;
+    // protects setSize() and allocate()
+    mutable Mutex   mLock;
 };
 
 }; // namespace android
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index d3e456f..54d5c52 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 00fab70..f22ff59 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <math.h>
@@ -25,15 +23,10 @@
 #include <utils/Log.h>
 #include <utils/StopWatch.h>
 
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-
 #include <ui/PixelFormat.h>
-#include <ui/EGLDisplaySurface.h>
 
 #include "LayerBuffer.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 #include "DisplayHardware/DisplayHardware.h"
 
 
@@ -55,30 +48,12 @@
 
 LayerBuffer::~LayerBuffer()
 {
-    sp<SurfaceBuffer> s(getClientSurface());
-    if (s != 0) {
-        s->disown();
-        mClientSurface.clear();
-    }
 }
 
-sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const
+sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const
 {
-    Mutex::Autolock _l(mLock);
-    return mClientSurface.promote();
-}
-
-sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const
-{
-    sp<SurfaceBuffer> s;
-    Mutex::Autolock _l(mLock);
-    s = mClientSurface.promote();
-    if (s == 0) {
-        s = new SurfaceBuffer(clientIndex(),
+    return new SurfaceBuffer(clientIndex(),
                 const_cast<LayerBuffer *>(this));
-        mClientSurface = s;
-    }
-    return s;
 }
 
 bool LayerBuffer::needsBlending() const {
@@ -192,82 +167,49 @@
 // LayerBuffer::SurfaceBuffer
 // ============================================================================
 
-LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner)
-: LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner)
+LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, 
+        const sp<LayerBuffer>& owner)
+    : LayerBaseClient::Surface(id, owner->getIdentity(), owner)
 {
 }
 
 LayerBuffer::SurfaceBuffer::~SurfaceBuffer()
 {
     unregisterBuffers();
-    mOwner = 0;
 }
 
-status_t LayerBuffer::SurfaceBuffer::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+status_t LayerBuffer::SurfaceBuffer::registerBuffers(
+        const ISurface::BufferHeap& buffers)
 {
-    switch (code) {
-        case REGISTER_BUFFERS:
-        case UNREGISTER_BUFFERS:
-        case CREATE_OVERLAY:
-        {
-            // codes that require permission check
-            IPCThreadState* ipc = IPCThreadState::self();
-            const int pid = ipc->getCallingPid();
-            const int self_pid = getpid();
-            if (LIKELY(pid != self_pid)) {
-                // we're called from a different process, do the real check
-                if (!checkCallingPermission(
-                        String16("android.permission.ACCESS_SURFACE_FLINGER")))
-                {
-                    const int uid = ipc->getCallingUid();
-                    LOGE("Permission Denial: "
-                            "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
-                    return PERMISSION_DENIED;
-                }
-            }
-        }
-    }
-    return LayerBaseClient::Surface::onTransact(code, data, reply, flags);
-}
-
-status_t LayerBuffer::SurfaceBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
-{
-    LayerBuffer* owner(getOwner());
-    if (owner)
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
         return owner->registerBuffers(buffers);
     return NO_INIT;
 }
 
 void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset)
 {
-    LayerBuffer* owner(getOwner());
-    if (owner)
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
         owner->postBuffer(offset);
 }
 
 void LayerBuffer::SurfaceBuffer::unregisterBuffers()
 {
-    LayerBuffer* owner(getOwner());
-    if (owner)
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
         owner->unregisterBuffers();
 }
 
 sp<OverlayRef> LayerBuffer::SurfaceBuffer::createOverlay(
         uint32_t w, uint32_t h, int32_t format) {
     sp<OverlayRef> result;
-    LayerBuffer* owner(getOwner());
-    if (owner)
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
         result = owner->createOverlay(w, h, format);
     return result;
 }
 
-void LayerBuffer::SurfaceBuffer::disown()
-{
-    Mutex::Autolock _l(mLock);
-    mOwner = 0;
-}
-
 // ============================================================================
 // LayerBuffer::Buffer
 // ============================================================================
@@ -437,115 +379,27 @@
     status_t err = NO_ERROR;
     NativeBuffer src(buffer->getBuffer());
     const Rect& transformedBounds = mLayer.getTransformedBounds();
-    const int can_use_copybit = mLayer.canUseCopybit();
 
-    if (can_use_copybit)  {
-        const int src_width  = src.crop.r - src.crop.l;
-        const int src_height = src.crop.b - src.crop.t;
-        int W = transformedBounds.width();
-        int H = transformedBounds.height();
-        if (mLayer.getOrientation() & Transform::ROT_90) {
-            int t(W); W=H; H=t;
-        }
-
-        /* With LayerBuffer, it is likely that we'll have to rescale the
-         * surface, because this is often used for video playback or
-         * camera-preview. Since we want these operation as fast as possible
-         * we make sure we can use the 2D H/W even if it doesn't support
-         * the requested scale factor, in which case we perform the scaling
-         * in several passes. */
-
-        copybit_device_t* copybit = mLayer.mFlinger->getBlitEngine();
-        const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
-        const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
-
-        float xscale = 1.0f;
-        if (src_width > W*min)          xscale = 1.0f / min;
-        else if (src_width*mag < W)     xscale = mag;
-
-        float yscale = 1.0f;
-        if (src_height > H*min)         yscale = 1.0f / min;
-        else if (src_height*mag < H)    yscale = mag;
-
-        if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
-            if (UNLIKELY(mTemporaryDealer == 0)) {
-                // allocate a memory-dealer for this the first time
-                mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager()
-                    ->createHeap(ISurfaceComposer::eHardware);
-                mTempBitmap.init(mTemporaryDealer);
-            }
-
-            const int tmp_w = floorf(src_width  * xscale);
-            const int tmp_h = floorf(src_height * yscale);
-            err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format);
-
-            if (LIKELY(err == NO_ERROR)) {
-                NativeBuffer tmp;
-                mTempBitmap.getBitmapSurface(&tmp.img);
-                tmp.crop.l = 0;
-                tmp.crop.t = 0;
-                tmp.crop.r = tmp.img.w;
-                tmp.crop.b = tmp.img.h;
-
-                region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b)));
-                copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-                copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-                copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-                err = copybit->stretch(copybit,
-                        &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it);
-                src = tmp;
-            }
-        }
-
-        const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware());
-        copybit_image_t dst;
-        hw.getDisplaySurface(&dst);
-        const copybit_rect_t& drect
-            = reinterpret_cast<const copybit_rect_t&>(transformedBounds);
-        const State& s(mLayer.drawingState());
-        region_iterator it(clip);
-        
-        // pick the right orientation for this buffer
-        int orientation = mLayer.getOrientation();
-        if (UNLIKELY(mBufferHeap.transform)) {
-            Transform rot90;
-            GraphicPlane::orientationToTransfrom(
-                    ISurfaceComposer::eOrientation90, 0, 0, &rot90);
-            const Transform& planeTransform(mLayer.graphicPlane(0).transform());
-            const Layer::State& s(mLayer.drawingState());
-            Transform tr(planeTransform * s.transform * rot90);
-            orientation = tr.getOrientation();
-        }
-        
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation);
-        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
-        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-
-        err = copybit->stretch(copybit,
-                &dst, &src.img, &drect, &src.crop, &it);
-        if (err != NO_ERROR) {
-            LOGE("copybit failed (%s)", strerror(err));
-        }
+    // FIXME: We should model this after the overlay stuff
+    
+    if (UNLIKELY(mTextureName == -1LU)) {
+        mTextureName = mLayer.createTexture();
     }
+    GLuint w = 0;
+    GLuint h = 0;
+    GGLSurface t;
+    t.version = sizeof(GGLSurface);
+    t.width  = src.crop.r;
+    t.height = src.crop.b;
+    t.stride = src.img.w;
+    t.vstride= src.img.h;
+    t.format = src.img.format;
+    t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset);
+    const Region dirty(Rect(t.width, t.height));
 
-    if (!can_use_copybit || err) {
-        if (UNLIKELY(mTextureName == -1LU)) {
-            mTextureName = mLayer.createTexture();
-        }
-        GLuint w = 0;
-        GLuint h = 0;
-        GGLSurface t;
-        t.version = sizeof(GGLSurface);
-        t.width  = src.crop.r;
-        t.height = src.crop.b;
-        t.stride = src.img.w;
-        t.vstride= src.img.h;
-        t.format = src.img.format;
-        t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset);
-        const Region dirty(Rect(t.width, t.height));
-        mLayer.loadTexture(dirty, mTextureName, t, w, h);
-        mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform);
-    }
+    // FIXME: Use EGLImage extension for this
+    mLayer.loadTexture(dirty, mTextureName, t, w, h);
+    mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform);
 }
 
 
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 2dc77f1..2d44121 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -22,7 +22,6 @@
 
 #include <utils/IMemory.h>
 #include <private/ui/LayerState.h>
-#include <EGL/eglnatives.h>
 
 #include "LayerBase.h"
 #include "LayerBitmap.h"
@@ -64,7 +63,7 @@
 
     virtual bool needsBlending() const;
 
-    virtual sp<LayerBaseClient::Surface> getSurface() const;
+    virtual sp<LayerBaseClient::Surface> createSurface() const;
     virtual void onDraw(const Region& clip) const;
     virtual uint32_t doTransaction(uint32_t flags);
     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
@@ -126,8 +125,7 @@
         status_t        mStatus;
         ISurface::BufferHeap mBufferHeap;
         size_t          mBufferSize;
-        mutable sp<MemoryDealer> mTemporaryDealer;
-        mutable LayerBitmap mTempBitmap;
+        mutable sp<android::Buffer>  mTempBitmap;
         mutable GLuint  mTextureName;
     };
     
@@ -179,23 +177,19 @@
     class SurfaceBuffer : public LayerBaseClient::Surface
     {
     public:
-                SurfaceBuffer(SurfaceID id, LayerBuffer* owner);
+                SurfaceBuffer(SurfaceID id, const sp<LayerBuffer>& owner);
         virtual ~SurfaceBuffer();
-        virtual status_t onTransact(
-            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+
         virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
+        
         virtual sp<OverlayRef> createOverlay(
                 uint32_t w, uint32_t h, int32_t format);
-       void disown();
     private:
-        LayerBuffer* getOwner() const {
-            Mutex::Autolock _l(mLock);
-            return mOwner;
+        sp<LayerBuffer> getOwner() const {
+            return static_cast<LayerBuffer*>(Surface::getOwner().get());
         }
-        mutable Mutex   mLock;
-        LayerBuffer*    mOwner;
     };
 
     friend class SurfaceFlinger;
@@ -203,10 +197,8 @@
 
     mutable Mutex   mLock;
     sp<Source>      mSource;
-
     bool            mInvalidate;
     bool            mNeedsBlending;
-    mutable wp<SurfaceBuffer> mClientSurface;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
index 0c347cc..f2519c4 100644
--- a/libs/surfaceflinger/LayerDim.cpp
+++ b/libs/surfaceflinger/LayerDim.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
@@ -25,7 +23,6 @@
 
 #include "LayerDim.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 #include "DisplayHardware/DisplayHardware.h"
 
 namespace android {
@@ -33,8 +30,6 @@
 
 const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
 const char* const LayerDim::typeID = "LayerDim";
-sp<MemoryDealer> LayerDim::mDimmerDealer;
-LayerBitmap LayerDim::mDimmerBitmap;
 
 // ---------------------------------------------------------------------------
 
@@ -46,14 +41,6 @@
 
 void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
 {
-    // must only be called once.
-    mDimmerDealer = flinger->getSurfaceHeapManager()
-            ->createHeap(ISurfaceComposer::eHardware);
-    if (mDimmerDealer != 0) {
-        mDimmerBitmap.init(mDimmerDealer);
-        mDimmerBitmap.setBits(w, h, 1, PIXEL_FORMAT_RGB_565);
-        mDimmerBitmap.clear();
-    }
 }
 
 LayerDim::~LayerDim()
@@ -62,48 +49,25 @@
 
 void LayerDim::onDraw(const Region& clip) const
 {
+    // FIXME: on some h/w (like msm7K, it will be faster to use a texture)
+    
     const State& s(drawingState());
-
     Region::iterator iterator(clip);
     if (s.alpha>0 && iterator) {
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
-
-        status_t err = NO_ERROR;
-        const int can_use_copybit = canUseCopybit();
-        if (can_use_copybit)  {
-            // StopWatch watch("copybit");
-            copybit_image_t dst;
-            hw.getDisplaySurface(&dst);
-            const copybit_rect_t& drect
-                = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
-
-            copybit_image_t src;
-            mDimmerBitmap.getBitmapSurface(&src);
-            const copybit_rect_t& srect(drect);
-
-            copybit_device_t* copybit = mFlinger->getBlitEngine();
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-            region_iterator it(clip);
-            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-        }
-
-        if (!can_use_copybit || err) {
-            const GGLfixed alpha = (s.alpha << 16)/255;
-            const uint32_t fbHeight = hw.getHeight();
-            glDisable(GL_TEXTURE_2D);
-            glDisable(GL_DITHER);
-            glEnable(GL_BLEND);
-            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-            glColor4x(0, 0, 0, alpha);
-            glVertexPointer(2, GL_FIXED, 0, mVertices);
-            Rect r;
-            while (iterator.iterate(&r)) {
-                const GLint sy = fbHeight - (r.top + r.height());
-                glScissor(r.left, sy, r.width(), r.height());
-                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
-            }
+        const GGLfixed alpha = (s.alpha << 16)/255;
+        const uint32_t fbHeight = hw.getHeight();
+        glDisable(GL_TEXTURE_2D);
+        glDisable(GL_DITHER);
+        glEnable(GL_BLEND);
+        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+        glColor4x(0, 0, 0, alpha);
+        glVertexPointer(2, GL_FIXED, 0, mVertices);
+        Rect r;
+        while (iterator.iterate(&r)) {
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
         }
     }
 }
diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h
index 3e37a47..0d5bb98 100644
--- a/libs/surfaceflinger/LayerDim.h
+++ b/libs/surfaceflinger/LayerDim.h
@@ -44,10 +44,6 @@
     virtual bool isSecure() const       { return false; }
 
     static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h);
-
-private:
-    static sp<MemoryDealer> mDimmerDealer;
-    static LayerBitmap mDimmerBitmap;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/LayerOrientationAnim.cpp
index 3e4035e..095fed8 100644
--- a/libs/surfaceflinger/LayerOrientationAnim.cpp
+++ b/libs/surfaceflinger/LayerOrientationAnim.cpp
@@ -24,10 +24,6 @@
 #include <utils/Log.h>
 #include <utils/StopWatch.h>
 
-#include <core/SkBitmap.h>
-
-#include <ui/EGLDisplaySurface.h>
-
 #include "BlurFilter.h"
 #include "LayerBase.h"
 #include "LayerOrientationAnim.h"
@@ -57,8 +53,8 @@
 LayerOrientationAnim::LayerOrientationAnim(
         SurfaceFlinger* flinger, DisplayID display, 
         OrientationAnimation* anim, 
-        const LayerBitmap& bitmapIn,
-        const LayerBitmap& bitmapOut)
+        const sp<Buffer>& bitmapIn,
+        const sp<Buffer>& bitmapOut)
     : LayerOrientationAnimBase(flinger, display), mAnim(anim), 
       mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), 
       mTextureName(-1), mTextureNameIn(-1)
@@ -108,11 +104,6 @@
     mTop  = tr.ty();
     transparentRegionScreen.clear();
     mTransformed = true;
-    mCanUseCopyBit = false;
-    copybit_device_t* copybit = mFlinger->getBlitEngine();
-    if (copybit) { 
-        mCanUseCopyBit = true;
-    }
 }
 
 void LayerOrientationAnim::onOrientationCompleted()
@@ -135,7 +126,7 @@
             
             // make a copy of what's on screen
             copybit_image_t image;
-            mBitmapOut.getBitmapSurface(&image);
+            mBitmapOut->getBitmapSurface(&image);
             const DisplayHardware& hw(graphicPlane(0).displayHardware());
             hw.copyBackToImage(image);
 
@@ -194,7 +185,7 @@
     copybit_image_t dst;
     const GraphicPlane& plane(graphicPlane(0));
     const DisplayHardware& hw(plane.displayHardware());
-    hw.getDisplaySurface(&dst);
+    //hw.getDisplaySurface(&dst);
 
     // clear screen
     // TODO: with update on demand, we may be able 
@@ -212,10 +203,10 @@
     }
     
     copybit_image_t src;
-    mBitmapIn.getBitmapSurface(&src);
+    mBitmapIn->getBitmapSurface(&src);
 
     copybit_image_t srcOut;
-    mBitmapOut.getBitmapSurface(&srcOut);
+    mBitmapOut->getBitmapSurface(&srcOut);
 
     const int w = dst.w*scale; 
     const int h = dst.h*scale; 
@@ -225,78 +216,54 @@
     const copybit_rect_t srect = { 0, 0, src.w, src.h };
     const Region reg(Rect( drect.l, drect.t, drect.r, drect.b ));
 
-    int err = NO_ERROR;
-    const int can_use_copybit = canUseCopybit();
-    if (can_use_copybit)  {
-        copybit_device_t* copybit = mFlinger->getBlitEngine();
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-        
-        if (alphaIn > 0) {
-            region_iterator it(reg);
-            copybit->set_parameter(copybit, COPYBIT_BLUR, COPYBIT_ENABLE);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, int(alphaIn*255));
-            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-        }
+    GGLSurface t;
+    t.version = sizeof(GGLSurface);
+    t.width  = src.w;
+    t.height = src.h;
+    t.stride = src.w;
+    t.vstride= src.h;
+    t.format = src.format;
+    t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
 
-        if (!err && alphaOut > 0.0f) {
-            region_iterator it(reg);
-            copybit->set_parameter(copybit, COPYBIT_BLUR, COPYBIT_DISABLE);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, int(alphaOut*255));
-            err = copybit->stretch(copybit, &dst, &srcOut, &drect, &srect, &it);
-        }
-        LOGE_IF(err != NO_ERROR, "copybit failed (%s)", strerror(err));
+    Transform tr;
+    tr.set(scale,0,0,scale);
+    tr.set(xc, yc);
+    
+    // FIXME: we should not access mVertices and mDrawingState like that,
+    // but since we control the animation, we know it's going to work okay.
+    // eventually we'd need a more formal way of doing things like this.
+    LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
+    tr.transform(self.mVertices[0], 0, 0);
+    tr.transform(self.mVertices[1], 0, src.h);
+    tr.transform(self.mVertices[2], src.w, src.h);
+    tr.transform(self.mVertices[3], src.w, 0);
+    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
+        // Too slow to do this in software
+        self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
     }
-    if (!can_use_copybit || err) {   
-        GGLSurface t;
-        t.version = sizeof(GGLSurface);
-        t.width  = src.w;
-        t.height = src.h;
-        t.stride = src.w;
-        t.vstride= src.h;
-        t.format = src.format;
+
+    if (alphaIn > 0.0f) {
         t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
-
-        Transform tr;
-        tr.set(scale,0,0,scale);
-        tr.set(xc, yc);
-        
-        // FIXME: we should not access mVertices and mDrawingState like that,
-        // but since we control the animation, we know it's going to work okay.
-        // eventually we'd need a more formal way of doing things like this.
-        LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
-        tr.transform(self.mVertices[0], 0, 0);
-        tr.transform(self.mVertices[1], 0, src.h);
-        tr.transform(self.mVertices[2], src.w, src.h);
-        tr.transform(self.mVertices[3], src.w, 0);
-        if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
-            // Too slow to do this in software
-            self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
+        if (UNLIKELY(mTextureNameIn == -1LU)) {
+            mTextureNameIn = createTexture();
+            GLuint w=0, h=0;
+            const Region dirty(Rect(t.width, t.height));
+            loadTexture(dirty, mTextureNameIn, t, w, h);
         }
+        self.mDrawingState.alpha = int(alphaIn*255);
+        drawWithOpenGL(reg, mTextureNameIn, t);
+    }
 
-        if (alphaIn > 0.0f) {
-            t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
-            if (UNLIKELY(mTextureNameIn == -1LU)) {
-                mTextureNameIn = createTexture();
-                GLuint w=0, h=0;
-                const Region dirty(Rect(t.width, t.height));
-                loadTexture(dirty, mTextureNameIn, t, w, h);
-            }
-            self.mDrawingState.alpha = int(alphaIn*255);
-            drawWithOpenGL(reg, mTextureNameIn, t);
+    if (alphaOut > 0.0f) {
+        t.data = (GGLubyte*)(intptr_t(srcOut.base) + srcOut.offset);
+        if (UNLIKELY(mTextureName == -1LU)) {
+            mTextureName = createTexture();
+            GLuint w=0, h=0;
+            const Region dirty(Rect(t.width, t.height));
+            loadTexture(dirty, mTextureName, t, w, h);
         }
-
-        if (alphaOut > 0.0f) {
-            t.data = (GGLubyte*)(intptr_t(srcOut.base) + srcOut.offset);
-            if (UNLIKELY(mTextureName == -1LU)) {
-                mTextureName = createTexture();
-                GLuint w=0, h=0;
-                const Region dirty(Rect(t.width, t.height));
-                loadTexture(dirty, mTextureName, t, w, h);
-            }
-            self.mDrawingState.alpha = int(alphaOut*255);
-            drawWithOpenGL(reg, mTextureName, t);
-        }
+        self.mDrawingState.alpha = int(alphaOut*255);
+        drawWithOpenGL(reg, mTextureName, t);
     }
 }
 
diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/LayerOrientationAnim.h
index 365c6ae..472c45a 100644
--- a/libs/surfaceflinger/LayerOrientationAnim.h
+++ b/libs/surfaceflinger/LayerOrientationAnim.h
@@ -52,8 +52,8 @@
     
                 LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display,
                         OrientationAnimation* anim, 
-                        const LayerBitmap& bitmapIn,
-                        const LayerBitmap& bitmapOut);
+                        const sp<Buffer>& bitmapIn,
+                        const sp<Buffer>& bitmapOut);
         virtual ~LayerOrientationAnim();
 
             void onOrientationCompleted();
@@ -90,8 +90,8 @@
     };
     
     OrientationAnimation* mAnim;
-    LayerBitmap mBitmapIn;
-    LayerBitmap mBitmapOut;
+    sp<Buffer> mBitmapIn;
+    sp<Buffer> mBitmapOut;
     nsecs_t mStartTime;
     nsecs_t mFinishTime;
     bool mOrientationCompleted;
diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/LayerOrientationAnimRotate.cpp
index 89ffb19..a3bf014 100644
--- a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp
+++ b/libs/surfaceflinger/LayerOrientationAnimRotate.cpp
@@ -23,10 +23,6 @@
 #include <utils/Errors.h>
 #include <utils/Log.h>
 
-#include <core/SkBitmap.h>
-
-#include <ui/EGLDisplaySurface.h>
-
 #include "LayerBase.h"
 #include "LayerOrientationAnim.h"
 #include "LayerOrientationAnimRotate.h"
@@ -51,10 +47,10 @@
 LayerOrientationAnimRotate::LayerOrientationAnimRotate(
         SurfaceFlinger* flinger, DisplayID display, 
         OrientationAnimation* anim, 
-        const LayerBitmap& bitmap,
-        const LayerBitmap& bitmapIn)
+        const sp<Buffer>& bitmapIn,
+        const sp<Buffer>& bitmapOut)
     : LayerOrientationAnimBase(flinger, display), mAnim(anim), 
-      mBitmap(bitmap), mBitmapIn(bitmapIn), 
+      mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), 
       mTextureName(-1), mTextureNameIn(-1)
 {
     mStartTime = systemTime();
@@ -103,7 +99,6 @@
     mTop  = tr.ty();
     transparentRegionScreen.clear();
     mTransformed = true;
-    mCanUseCopyBit = false;
 }
 
 void LayerOrientationAnimRotate::onOrientationCompleted()
@@ -126,7 +121,7 @@
         if (mFirstRedraw) {
             // make a copy of what's on screen
             copybit_image_t image;
-            mBitmapIn.getBitmapSurface(&image);
+            mBitmapIn->getBitmapSurface(&image);
             const DisplayHardware& hw(graphicPlane(0).displayHardware());
             hw.copyBackToImage(image);
             
@@ -185,7 +180,7 @@
     copybit_image_t dst;
     const GraphicPlane& plane(graphicPlane(0));
     const DisplayHardware& hw(plane.displayHardware());
-    hw.getDisplaySurface(&dst);
+    //hw.getDisplaySurface(&dst);
 
     // clear screen
     // TODO: with update on demand, we may be able 
@@ -200,7 +195,7 @@
     const int h = dst.h; 
 
     copybit_image_t src;
-    mBitmap.getBitmapSurface(&src);
+    mBitmapIn->getBitmapSurface(&src);
     const copybit_rect_t srect = { 0, 0, src.w, src.h };
 
 
@@ -255,7 +250,7 @@
         tr.transform(self.mVertices[3], src.w, 0);
 
         copybit_image_t src;
-        mBitmapIn.getBitmapSurface(&src);
+        mBitmapIn->getBitmapSurface(&src);
         t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
         if (UNLIKELY(mTextureNameIn == -1LU)) {
             mTextureNameIn = createTexture();
diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.h b/libs/surfaceflinger/LayerOrientationAnimRotate.h
index 5fbbd42..a675c79 100644
--- a/libs/surfaceflinger/LayerOrientationAnimRotate.h
+++ b/libs/surfaceflinger/LayerOrientationAnimRotate.h
@@ -40,8 +40,8 @@
     
     LayerOrientationAnimRotate(SurfaceFlinger* flinger, DisplayID display,
                         OrientationAnimation* anim, 
-                        const LayerBitmap& zoomOut,
-                        const LayerBitmap& zoomIn);
+                        const sp<Buffer>& bitmapIn,
+                        const sp<Buffer>& bitmapOut);
         virtual ~LayerOrientationAnimRotate();
 
             void onOrientationCompleted();
@@ -55,8 +55,8 @@
     void drawScaled(float angle, float scale, float alpha) const;
     
     OrientationAnimation* mAnim;
-    LayerBitmap mBitmap;
-    LayerBitmap mBitmapIn;
+    sp<Buffer> mBitmapIn;
+    sp<Buffer> mBitmapOut;
     nsecs_t mStartTime;
     nsecs_t mFinishTime;
     bool mOrientationCompleted;
diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/OrientationAnimation.cpp
index 70eec8d..a6c9c28 100644
--- a/libs/surfaceflinger/OrientationAnimation.cpp
+++ b/libs/surfaceflinger/OrientationAnimation.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdint.h>
 #include <sys/types.h>
 #include <limits.h>
@@ -24,7 +22,6 @@
 #include "LayerOrientationAnimRotate.h"
 #include "OrientationAnimation.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 
 #include "DisplayHardware/DisplayHardware.h"
 
@@ -35,9 +32,6 @@
 OrientationAnimation::OrientationAnimation(const sp<SurfaceFlinger>& flinger)
     : mFlinger(flinger), mLayerOrientationAnim(NULL), mState(DONE)
 {
-    // allocate a memory-dealer for this the first time
-    mTemporaryDealer = mFlinger->getSurfaceHeapManager()->createHeap(
-            ISurfaceComposer::eHardware);
 }
 
 OrientationAnimation::~OrientationAnimation()
@@ -98,19 +92,14 @@
     const uint32_t w = hw.getWidth();
     const uint32_t h = hw.getHeight();
 
-    LayerBitmap bitmap;
-    bitmap.init(mTemporaryDealer);
-    bitmap.setBits(w, h, 1, hw.getFormat());
-
-    LayerBitmap bitmapIn;
-    bitmapIn.init(mTemporaryDealer);
-    bitmapIn.setBits(w, h, 1, hw.getFormat());
+    sp<Buffer> bitmap = new Buffer(w, h, hw.getFormat());
+    sp<Buffer> bitmapIn = new Buffer(w, h, hw.getFormat());
 
     copybit_image_t front;
-    bitmap.getBitmapSurface(&front);
-    hw.copyFrontToImage(front);
+    bitmap->getBitmapSurface(&front);
+    hw.copyFrontToImage(front); // FIXME: we need an extension to do this
 
-    LayerOrientationAnimBase* l;
+    sp<LayerOrientationAnimBase> l;
     
     if (mType & 0x80) {
         l = new LayerOrientationAnimRotate(
@@ -152,7 +141,7 @@
 {
     mState = DONE;
     mFlinger->removeLayer(mLayerOrientationAnim);
-    mLayerOrientationAnim = NULL;
+    mLayerOrientationAnim.clear();
     return true;
 }
 
diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/OrientationAnimation.h
index cafa38d..8ba6621 100644
--- a/libs/surfaceflinger/OrientationAnimation.h
+++ b/libs/surfaceflinger/OrientationAnimation.h
@@ -72,8 +72,7 @@
     bool finished();
 
     sp<SurfaceFlinger> mFlinger;
-    sp<MemoryDealer> mTemporaryDealer;
-    LayerOrientationAnimBase* mLayerOrientationAnim;
+    sp< LayerOrientationAnimBase > mLayerOrientationAnim;
     int mState;
     uint32_t mType;
 };
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index de64f55..b4f443f 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdint.h>
@@ -40,12 +38,12 @@
 
 #include <ui/PixelFormat.h>
 #include <ui/DisplayInfo.h>
-#include <ui/EGLDisplaySurface.h>
 
 #include <pixelflinger/pixelflinger.h>
 #include <GLES/gl.h>
 
 #include "clz.h"
+#include "BufferAllocator.h"
 #include "CPUGauge.h"
 #include "Layer.h"
 #include "LayerBlur.h"
@@ -55,10 +53,8 @@
 #include "LayerOrientationAnim.h"
 #include "OrientationAnimation.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 
 #include "DisplayHardware/DisplayHardware.h"
-#include "GPUHardware/GPUHardware.h"
 
 
 #define DISPLAY_COUNT       1
@@ -86,30 +82,30 @@
 }
 
 ssize_t SurfaceFlinger::LayerVector::indexOf(
-        LayerBase* key, size_t guess) const
+        const sp<LayerBase>& key, size_t guess) const
 {
     if (guess<size() && lookup.keyAt(guess) == key)
         return guess;
     const ssize_t i = lookup.indexOfKey(key);
     if (i>=0) {
         const size_t idx = lookup.valueAt(i);
-        LOG_ASSERT(layers[idx]==key,
+        LOGE_IF(layers[idx]!=key,
             "LayerVector[%p]: layers[%d]=%p, key=%p",
-            this, int(idx), layers[idx], key);
+            this, int(idx), layers[idx].get(), key.get());
         return idx;
     }
     return i;
 }
 
 ssize_t SurfaceFlinger::LayerVector::add(
-        LayerBase* layer,
-        Vector<LayerBase*>::compar_t cmp)
+        const sp<LayerBase>& layer,
+        Vector< sp<LayerBase> >::compar_t cmp)
 {
     size_t count = layers.size();
     ssize_t l = 0;
     ssize_t h = count-1;
     ssize_t mid;
-    LayerBase* const* a = layers.array();
+    sp<LayerBase> const* a = layers.array();
     while (l <= h) {
         mid = l + (h - l)/2;
         const int c = cmp(a+mid, &layer);
@@ -132,14 +128,14 @@
     return order;
 }
 
-ssize_t SurfaceFlinger::LayerVector::remove(LayerBase* layer)
+ssize_t SurfaceFlinger::LayerVector::remove(const sp<LayerBase>& layer)
 {
     const ssize_t keyIndex = lookup.indexOfKey(layer);
     if (keyIndex >= 0) {
         const size_t index = lookup.valueAt(keyIndex);
-        LOG_ASSERT(layers[index]==layer,
+        LOGE_IF(layers[index]!=layer,
                 "LayerVector[%p]: layers[%u]=%p, layer=%p",
-                this, int(index), layers[index], layer);
+                this, int(index), layers[index].get(), layer.get());
         layers.removeItemsAt(index);
         lookup.removeItemsAt(keyIndex);
         const size_t count = lookup.size();
@@ -154,8 +150,8 @@
 }
 
 ssize_t SurfaceFlinger::LayerVector::reorder(
-        LayerBase* layer,
-        Vector<LayerBase*>::compar_t cmp)
+        const sp<LayerBase>& layer,
+        Vector< sp<LayerBase> >::compar_t cmp)
 {
     // XXX: it's a little lame. but oh well...
     ssize_t err = remove(layer);
@@ -173,6 +169,7 @@
     :   BnSurfaceComposer(), Thread(false),
         mTransactionFlags(0),
         mTransactionCount(0),
+        mLayersRemoved(false),
         mBootTime(systemTime()),
         mLastScheduledBroadcast(NULL),
         mVisibleRegionsDirty(false),
@@ -223,11 +220,6 @@
     delete mOrientationAnimation;
 }
 
-copybit_device_t* SurfaceFlinger::getBlitEngine() const
-{
-    return graphicPlane(0).displayHardware().getBlitEngine();
-}
-
 overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
 {
     return graphicPlane(0).displayHardware().getOverlayEngine();
@@ -238,20 +230,6 @@
     return mServerCblkMemory;
 }
 
-status_t SurfaceFlinger::requestGPU(const sp<IGPUCallback>& callback,
-        gpu_info_t* gpu)
-{
-    IPCThreadState* ipc = IPCThreadState::self();
-    const int pid = ipc->getCallingPid();
-    status_t err = mGPU->request(pid, callback, gpu);
-    return err;
-}
-
-status_t SurfaceFlinger::revokeGPU()
-{
-    return mGPU->friendlyRevoke();
-}
-
 sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
 {
     Mutex::Autolock _l(mStateLock);
@@ -279,11 +257,13 @@
     Client* const client = mClientsMap.valueFor(cid);
     if (client) {
         // free all the layers this client owns
-        const Vector<LayerBaseClient*>& layers = client->getLayers();
+        const Vector< wp<LayerBaseClient> >& layers = client->getLayers();
         const size_t count = layers.size();
         for (size_t i=0 ; i<count ; i++) {
-            LayerBaseClient* const layer = layers[i];
-            removeLayer_l(layer);
+            sp<LayerBaseClient> layer(layers[i].promote());
+            if (layer != 0) {
+                removeLayer_l(layer);
+            }
         }
 
         // the resources associated with this client will be freed
@@ -338,9 +318,6 @@
     return (r<<11)|(g<<5)|b;
 }
 
-// this is defined in libGLES_CM.so
-extern ISurfaceComposer* GLES_localSurfaceManager;
-
 status_t SurfaceFlinger::readyToRun()
 {
     LOGI(   "SurfaceFlinger's main thread ready to run. "
@@ -357,17 +334,6 @@
     LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
     new(mServerCblk) surface_flinger_cblk_t;
 
-    // get a reference to the GPU if we have one
-    mGPU = GPUFactory::getGPU();
-
-    // create the surface Heap manager, which manages the heaps
-    // (be it in RAM or VRAM) where surfaces are allocated
-    // We give 8 MB per client.
-    mSurfaceHeapManager = new SurfaceHeapManager(this, 8 << 20);
-
-    
-    GLES_localSurfaceManager = static_cast<ISurfaceComposer*>(this);
-
     // we only support one display currently
     int dpy = 0;
 
@@ -597,13 +563,11 @@
     if (mDeferReleaseConsole && hw.canDraw()) {
         // We got the release signal before the aquire signal
         mDeferReleaseConsole = false;
-        revokeGPU();
         hw.releaseScreen();
     }
 
     if (what & eConsoleReleased) {
         if (hw.canDraw()) {
-            revokeGPU();
             hw.releaseScreen();
         } else {
             mDeferReleaseConsole = true;
@@ -628,7 +592,7 @@
     const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
     if (layersNeedTransaction) {
         for (size_t i=0 ; i<count ; i++) {
-            LayerBase* const layer = currentLayers[i];
+            const sp<LayerBase>& layer = currentLayers[i];
             uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
             if (!trFlags) continue;
 
@@ -685,8 +649,7 @@
 
         // some layers might have been removed, so
         // we need to update the regions they're exposing.
-        size_t c = mRemovedLayers.size();
-        if (c) {
+        if (mLayersRemoved) {
             mVisibleRegionsDirty = true;
         }
 
@@ -723,7 +686,7 @@
 
     size_t i = currentLayers.size();
     while (i--) {
-        LayerBase* const layer = currentLayers[i];
+        const sp<LayerBase>& layer = currentLayers[i];
         layer->validateVisibility(planeTransform);
 
         // start with the whole surface at its current location
@@ -823,9 +786,9 @@
 {
     bool recomputeVisibleRegions = false;
     size_t count = currentLayers.size();
-    LayerBase* const* layers = currentLayers.array();
+    sp<LayerBase> const* layers = currentLayers.array();
     for (size_t i=0 ; i<count ; i++) {
-        LayerBase* const layer = layers[i];
+        const sp<LayerBase>& layer = layers[i];
         layer->lockPageFlip(recomputeVisibleRegions);
     }
     return recomputeVisibleRegions;
@@ -836,9 +799,9 @@
     const GraphicPlane& plane(graphicPlane(0));
     const Transform& planeTransform(plane.transform());
     size_t count = currentLayers.size();
-    LayerBase* const* layers = currentLayers.array();
+    sp<LayerBase> const* layers = currentLayers.array();
     for (size_t i=0 ; i<count ; i++) {
-        LayerBase* const layer = layers[i];
+        const sp<LayerBase>& layer = layers[i];
         layer->unlockPageFlip(planeTransform, mDirtyRegion);
     }
 }
@@ -889,9 +852,9 @@
     const SurfaceFlinger& flinger(*this);
     const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
     const size_t count = drawingLayers.size();
-    LayerBase const* const* const layers = drawingLayers.array();
+    sp<LayerBase> const* const layers = drawingLayers.array();
     for (size_t i=0 ; i<count ; ++i) {
-        LayerBase const * const layer = layers[i];
+        const sp<LayerBase>& layer = layers[i];
         const Region& visibleRegion(layer->visibleRegionScreen);
         if (!visibleRegion.isEmpty())  {
             const Region clip(dirty.intersect(visibleRegion));
@@ -906,9 +869,9 @@
 {
     const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
     const size_t count = drawingLayers.size();
-    LayerBase* const* const layers = drawingLayers.array();
+    sp<LayerBase> const* const layers = drawingLayers.array();
     for (size_t i=0 ; i<count ; ++i) {
-        LayerBase* const layer = layers[i];
+        const sp<LayerBase>& layer = layers[i];
         layer->finishPageFlip();
     }
 }
@@ -1051,7 +1014,7 @@
     // XXX: mFPS has the value we want
  }
 
-status_t SurfaceFlinger::addLayer(LayerBase* layer)
+status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
 {
     Mutex::Autolock _l(mStateLock);
     addLayer_l(layer);
@@ -1059,7 +1022,7 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer(LayerBase* layer)
+status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
 {
     Mutex::Autolock _l(mStateLock);
     removeLayer_l(layer);
@@ -1067,32 +1030,31 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::invalidateLayerVisibility(LayerBase* layer)
+status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
 {
     layer->forceVisibilityTransaction();
     setTransactionFlags(eTraversalNeeded);
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::addLayer_l(LayerBase* layer)
+status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
 {
     ssize_t i = mCurrentState.layersSortedByZ.add(
                 layer, &LayerBase::compareCurrentStateZ);
-    LayerBaseClient* lbc = LayerBase::dynamicCast<LayerBaseClient*>(layer);
-    if (lbc) {
+    sp<LayerBaseClient> lbc = LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
+    if (lbc != 0) {
         mLayerMap.add(lbc->serverIndex(), lbc);
     }
-    mRemovedLayers.remove(layer);
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer_l(LayerBase* layerBase)
+status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
 {
     ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
     if (index >= 0) {
-        mRemovedLayers.add(layerBase);
-        LayerBaseClient* layer = LayerBase::dynamicCast<LayerBaseClient*>(layerBase);
-        if (layer) {
+        mLayersRemoved = true;
+        sp<LayerBaseClient> layer = LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get());
+        if (layer != 0) {
             mLayerMap.removeItem(layer->serverIndex());
         }
         return NO_ERROR;
@@ -1107,8 +1069,8 @@
 void SurfaceFlinger::free_resources_l()
 {
     // Destroy layers that were removed
-    destroy_all_removed_layers_l();
-
+    mLayersRemoved = false;
+    
     // free resources associated with disconnected clients
     SortedVector<Client*>& scheduledBroadcasts(mScheduledBroadcasts);
     Vector<Client*>& disconnectedClients(mDisconnectedClients);
@@ -1128,22 +1090,6 @@
     disconnectedClients.clear();
 }
 
-void SurfaceFlinger::destroy_all_removed_layers_l()
-{
-    size_t c = mRemovedLayers.size();
-    while (c--) {
-        LayerBase* const removed_layer = mRemovedLayers[c];
-
-        LOGE_IF(mCurrentState.layersSortedByZ.indexOf(removed_layer) >= 0,
-            "layer %p removed but still in the current state list",
-            removed_layer);
-
-        delete removed_layer;
-    }
-    mRemovedLayers.clear();
-}
-
-
 uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
 {
     return android_atomic_and(~flags, &mTransactionFlags) & flags;
@@ -1227,7 +1173,7 @@
         DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
         uint32_t flags)
 {
-    LayerBaseClient* layer = 0;
+    sp<LayerBaseClient> layer;
     sp<LayerBaseClient::Surface> surfaceHandle;
     Mutex::Autolock _l(mStateLock);
     Client* const c = mClientsMap.valueFor(clientId);
@@ -1259,7 +1205,7 @@
             break;
     }
 
-    if (layer) {
+    if (layer != 0) {
         setTransactionFlags(eTransactionNeeded);
         surfaceHandle = layer->getSurface();
         if (surfaceHandle != 0)
@@ -1269,7 +1215,7 @@
     return surfaceHandle;
 }
 
-LayerBaseClient* SurfaceFlinger::createNormalSurfaceLocked(
+sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked(
         Client* client, DisplayID display,
         int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
 {
@@ -1284,44 +1230,43 @@
         break;
     }
 
-    Layer* layer = new Layer(this, display, client, id);
+    sp<Layer> layer = new Layer(this, display, client, id);
     status_t err = layer->setBuffers(client, w, h, format, flags);
     if (LIKELY(err == NO_ERROR)) {
         layer->initStates(w, h, flags);
         addLayer_l(layer);
     } else {
         LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
-        delete layer;
-        return 0;
+        layer.clear();
     }
     return layer;
 }
 
-LayerBaseClient* SurfaceFlinger::createBlurSurfaceLocked(
+sp<LayerBaseClient> SurfaceFlinger::createBlurSurfaceLocked(
         Client* client, DisplayID display,
         int32_t id, uint32_t w, uint32_t h, uint32_t flags)
 {
-    LayerBlur* layer = new LayerBlur(this, display, client, id);
+    sp<LayerBlur> layer = new LayerBlur(this, display, client, id);
     layer->initStates(w, h, flags);
     addLayer_l(layer);
     return layer;
 }
 
-LayerBaseClient* SurfaceFlinger::createDimSurfaceLocked(
+sp<LayerBaseClient> SurfaceFlinger::createDimSurfaceLocked(
         Client* client, DisplayID display,
         int32_t id, uint32_t w, uint32_t h, uint32_t flags)
 {
-    LayerDim* layer = new LayerDim(this, display, client, id);
+    sp<LayerDim> layer = new LayerDim(this, display, client, id);
     layer->initStates(w, h, flags);
     addLayer_l(layer);
     return layer;
 }
 
-LayerBaseClient* SurfaceFlinger::createPushBuffersSurfaceLocked(
+sp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurfaceLocked(
         Client* client, DisplayID display,
         int32_t id, uint32_t w, uint32_t h, uint32_t flags)
 {
-    LayerBuffer* layer = new LayerBuffer(this, display, client, id);
+    sp<LayerBuffer> layer = new LayerBuffer(this, display, client, id);
     layer->initStates(w, h, flags);
     addLayer_l(layer);
     return layer;
@@ -1330,7 +1275,7 @@
 status_t SurfaceFlinger::destroySurface(SurfaceID index)
 {
     Mutex::Autolock _l(mStateLock);
-    LayerBaseClient* const layer = getLayerUser_l(index);
+    const sp<LayerBaseClient>& layer = getLayerUser_l(index);
     status_t err = removeLayer_l(layer);
     if (err < 0)
         return err;
@@ -1348,8 +1293,8 @@
     cid <<= 16;
     for (int i=0 ; i<count ; i++) {
         const layer_state_t& s = states[i];
-        LayerBaseClient* layer = getLayerUser_l(s.surface | cid);
-        if (layer) {
+        const sp<LayerBaseClient>& layer = getLayerUser_l(s.surface | cid);
+        if (layer != 0) {
             const uint32_t what = s.what;
             // check if it has been destroyed first
             if (what & eDestroyed) {
@@ -1401,9 +1346,10 @@
     return NO_ERROR;
 }
 
-LayerBaseClient* SurfaceFlinger::getLayerUser_l(SurfaceID s) const
+sp<LayerBaseClient> SurfaceFlinger::getLayerUser_l(SurfaceID s) const
 {
-    return mLayerMap.valueFor(s);
+    sp<LayerBaseClient> layer = mLayerMap.valueFor(s);
+    return layer;
 }
 
 void SurfaceFlinger::screenReleased(int dpy)
@@ -1446,7 +1392,7 @@
         const size_t count = currentLayers.size();
         for (size_t i=0 ; i<count ; i++) {
             /*** LayerBase ***/
-            LayerBase const * const layer = currentLayers[i];
+            const sp<LayerBase>& layer = currentLayers[i];
             const Layer::State& s = layer->drawingState();
             snprintf(buffer, SIZE,
                     "+ %s %p\n"
@@ -1454,7 +1400,7 @@
                     "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
                     "needsBlending=%1d, invalidate=%1d, "
                     "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
-                    layer->getTypeID(), layer,
+                    layer->getTypeID(), layer.get(),
                     s.z, layer->tx(), layer->ty(), s.w, s.h,
                     layer->needsBlending(), layer->contentDirty,
                     s.alpha, s.flags,
@@ -1463,9 +1409,9 @@
             result.append(buffer);
             buffer[0] = 0;
             /*** LayerBaseClient ***/
-            LayerBaseClient* const lbc =
-                LayerBase::dynamicCast<LayerBaseClient*>((LayerBase*)layer);
-            if (lbc) {
+            sp<LayerBaseClient> lbc =
+                LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
+            if (lbc != 0) {
                 snprintf(buffer, SIZE,
                         "      "
                         "id=0x%08x, client=0x%08x, identity=%u\n",
@@ -1475,18 +1421,20 @@
             result.append(buffer);
             buffer[0] = 0;
             /*** Layer ***/
-            Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer);
-            if (l) {
+            sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get());
+            if (l != 0) {
                 const LayerBitmap& buf0(l->getBuffer(0));
                 const LayerBitmap& buf1(l->getBuffer(1));
                 snprintf(buffer, SIZE,
                         "      "
-                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u], mTextureName=%d,"
+                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
                         " freezeLock=%p, swapState=0x%08x\n",
                         l->pixelFormat(),
-                        buf0.width(), buf0.height(), buf0.stride(),
-                        buf1.width(), buf1.height(), buf1.stride(),
-                        l->getTextureName(), l->getFreezeLock().get(),
+                        buf0.getWidth(), buf0.getHeight(), 
+                        buf0.getBuffer()->getStride(),
+                        buf1.getWidth(), buf1.getHeight(), 
+                        buf1.getBuffer()->getStride(),
+                        l->getFreezeLock().get(),
                         l->lcblk->swapState);
             }
             result.append(buffer);
@@ -1503,19 +1451,8 @@
                 mCurrentState.orientation, hw.canDraw());
         result.append(buffer);
 
-        sp<AllocatorInterface> allocator;
-        if (mGPU != 0) {
-            snprintf(buffer, SIZE, "  GPU owner: %d\n", mGPU->getOwner());
-            result.append(buffer);
-            allocator = mGPU->getAllocator();
-            if (allocator != 0) {
-                allocator->dump(result, "GPU Allocator");
-            }
-        }
-        allocator = mSurfaceHeapManager->getAllocator(NATIVE_MEMORY_TYPE_PMEM);
-        if (allocator != 0) {
-            allocator->dump(result, "PMEM Allocator");
-        }
+        const BufferAllocator& alloc(BufferAllocator::get());
+        alloc.dump(result);
     }
     write(fd, result.string(), result.size());
     return NO_ERROR;
@@ -1532,7 +1469,6 @@
         case FREEZE_DISPLAY:
         case UNFREEZE_DISPLAY:
         case BOOT_FINISHED:
-        case REVOKE_GPU:
         {
             // codes that require permission check
             IPCThreadState* ipc = IPCThreadState::self();
@@ -1599,12 +1535,6 @@
                 signalEvent();
             }
             return NO_ERROR;
-            case 1005: // ask GPU revoke
-                mGPU->friendlyRevoke();
-                return NO_ERROR;
-            case 1006: // revoke GPU
-                mGPU->unconditionalRevoke();
-                return NO_ERROR;
             case 1007: // set mFreezeCount
                 mFreezeCount = data.readInt32();
                 return NO_ERROR;
@@ -1633,7 +1563,6 @@
 Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
     : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
 {
-    mSharedHeapAllocator = getSurfaceHeapManager()->createHeap();
     const int pgsize = getpagesize();
     const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
     mCblkHeap = new MemoryDealer(cblksize);
@@ -1653,10 +1582,6 @@
     }
 }
 
-const sp<SurfaceHeapManager>& Client::getSurfaceHeapManager() const {
-    return mFlinger->getSurfaceHeapManager();
-}
-
 int32_t Client::generateId(int pid)
 {
     const uint32_t i = clz( ~mBitmap );
@@ -1668,13 +1593,15 @@
     mBitmap |= 1<<(31-i);
     return i;
 }
-status_t Client::bindLayer(LayerBaseClient* layer, int32_t id)
+
+status_t Client::bindLayer(const sp<LayerBaseClient>& layer, int32_t id)
 {
     ssize_t idx = mInUse.indexOf(id);
     if (idx < 0)
         return NAME_NOT_FOUND;
     return mLayers.insertAt(layer, idx);
 }
+
 void Client::free(int32_t id)
 {
     ssize_t idx = mInUse.remove(uint8_t(id));
@@ -1684,27 +1611,18 @@
     }
 }
 
-sp<MemoryDealer> Client::createAllocator(uint32_t flags)
-{
-    sp<MemoryDealer> allocator;
-    allocator = getSurfaceHeapManager()->createHeap(
-            flags, getClientPid(), mSharedHeapAllocator);
-    return allocator;
-}
-
 bool Client::isValid(int32_t i) const {
     return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
 }
-const uint8_t* Client::inUseArray() const {
-    return mInUse.array();
-}
-size_t Client::numActiveLayers() const {
-    return mInUse.size();
-}
-LayerBaseClient* Client::getLayerUser(int32_t i) const {
+
+sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
+    sp<LayerBaseClient> lbc;
     ssize_t idx = mInUse.indexOf(uint8_t(i));
-    if (idx<0) return 0;
-    return mLayers[idx];
+    if (idx >= 0) {
+        lbc = mLayers[idx].promote();
+        LOGE_IF(lbc==0, "getLayerUser(i=%d), idx=%d is dead", int(i), int(idx));
+    }
+    return lbc;
 }
 
 void Client::dump(const char* what)
@@ -1841,6 +1759,10 @@
     return mGlobalTransform;
 }
 
+EGLDisplay GraphicPlane::getEGLDisplay() const {
+    return mHw->getEGLDisplay();
+}
+
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index e023182..57c6ca8 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -26,6 +26,7 @@
 #include <utils/Atomic.h>
 #include <utils/Errors.h>
 #include <utils/MemoryDealer.h>
+#include <utils/RefBase.h>
 
 #include <ui/PixelFormat.h>
 #include <ui/ISurfaceComposer.h>
@@ -52,13 +53,10 @@
 class BClient;
 class DisplayHardware;
 class FreezeLock;
-class GPUHardwareInterface;
-class IGPUCallback;
 class Layer;
 class LayerBuffer;
 class LayerOrientationAnim;
 class OrientationAnimation;
-class SurfaceHeapManager;
 
 typedef int32_t ClientID;
 
@@ -75,17 +73,13 @@
 
             int32_t                 generateId(int pid);
             void                    free(int32_t id);
-            status_t                bindLayer(LayerBaseClient* layer, int32_t id);
-            sp<MemoryDealer>        createAllocator(uint32_t memory_type);
+            status_t                bindLayer(const sp<LayerBaseClient>& layer, int32_t id);
 
     inline  bool                    isValid(int32_t i) const;
-    inline  const uint8_t*          inUseArray() const;
-    inline  size_t                  numActiveLayers() const;
-    LayerBaseClient*                getLayerUser(int32_t i) const;
-    const Vector<LayerBaseClient*>& getLayers() const { return mLayers; }
+    sp<LayerBaseClient>             getLayerUser(int32_t i) const;
+    const Vector< wp<LayerBaseClient> >& getLayers() const { return mLayers; }
     const sp<IMemory>&              controlBlockMemory() const { return mCblkMemory; }
     void                            dump(const char* what);
-    const sp<SurfaceHeapManager>&   getSurfaceHeapManager() const;
     
     // pointer to this client's control block
     per_client_cblk_t*      ctrlblk;
@@ -95,15 +89,13 @@
 private:
     int                     getClientPid() const { return mPid; }
         
-    int                         mPid;
-    uint32_t                    mBitmap;
-    SortedVector<uint8_t>       mInUse;
-    Vector<LayerBaseClient*>    mLayers;
-    sp<MemoryDealer>            mCblkHeap;
-    sp<SurfaceFlinger>          mFlinger;
-    sp<MemoryDealer>            mSharedHeapAllocator;
-    sp<MemoryDealer>            mPMemAllocator;
-    sp<IMemory>                 mCblkMemory;
+    int                             mPid;
+    uint32_t                        mBitmap;
+    SortedVector<uint8_t>           mInUse;
+    Vector< wp<LayerBaseClient> >   mLayers;
+    sp<MemoryDealer>                mCblkHeap;
+    sp<SurfaceFlinger>              mFlinger;
+    sp<IMemory>                     mCblkMemory;
 };
 
 // ---------------------------------------------------------------------------
@@ -126,6 +118,8 @@
 
         const DisplayHardware&  displayHardware() const;
         const Transform&        transform() const;
+        EGLDisplay              getEGLDisplay() const;
+        
 private:
                                 GraphicPlane(const GraphicPlane&);
         GraphicPlane            operator = (const GraphicPlane&);
@@ -169,28 +163,16 @@
     virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
     virtual int                         setOrientation(DisplayID dpy, int orientation, uint32_t flags);
     virtual void                        signal() const;
-    virtual status_t requestGPU(const sp<IGPUCallback>& callback, 
-            gpu_info_t* gpu);
-    virtual status_t revokeGPU();
 
             void                        screenReleased(DisplayID dpy);
             void                        screenAcquired(DisplayID dpy);
 
-            const sp<SurfaceHeapManager>& getSurfaceHeapManager() const { 
-                return mSurfaceHeapManager; 
-            }
-
-            const sp<GPUHardwareInterface>& getGPU() const {
-                return mGPU; 
-            }
-
-            copybit_device_t* getBlitEngine() const;
             overlay_control_device_t* getOverlayEngine() const;
 
             
-    status_t removeLayer(LayerBase* layer);
-    status_t addLayer(LayerBase* layer);
-    status_t invalidateLayerVisibility(LayerBase* layer);
+    status_t removeLayer(const sp<LayerBase>& layer);
+    status_t addLayer(const sp<LayerBase>& layer);
+    status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
     
 private:
     friend class BClient;
@@ -205,20 +187,25 @@
             DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
             uint32_t flags);
 
-    LayerBaseClient* createNormalSurfaceLocked(Client* client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+    sp<LayerBaseClient> createNormalSurfaceLocked(
+            Client* client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, 
+            PixelFormat format, uint32_t flags);
 
-    LayerBaseClient* createBlurSurfaceLocked(Client* client, DisplayID display,
+    sp<LayerBaseClient> createBlurSurfaceLocked(
+            Client* client, DisplayID display,
             int32_t id, uint32_t w, uint32_t h, uint32_t flags);
 
-    LayerBaseClient* createDimSurfaceLocked(Client* client, DisplayID display,
+    sp<LayerBaseClient> createDimSurfaceLocked(
+            Client* client, DisplayID display,
             int32_t id, uint32_t w, uint32_t h, uint32_t flags);
 
-    LayerBaseClient* createPushBuffersSurfaceLocked(Client* client, DisplayID display,
+    sp<LayerBaseClient> createPushBuffersSurfaceLocked(
+            Client* client, DisplayID display,
             int32_t id, uint32_t w, uint32_t h, uint32_t flags);
 
-    status_t    destroySurface(SurfaceID surface_id);
-    status_t    setClientState(ClientID cid, int32_t count, const layer_state_t* states);
+    status_t destroySurface(SurfaceID surface_id);
+    status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states);
 
 
     class LayerVector {
@@ -226,15 +213,15 @@
         inline              LayerVector() { }
                             LayerVector(const LayerVector&);
         inline size_t       size() const { return layers.size(); }
-        inline LayerBase*const* array() const { return layers.array(); }
-        ssize_t             add(LayerBase*, Vector<LayerBase*>::compar_t);
-        ssize_t             remove(LayerBase*);
-        ssize_t             reorder(LayerBase*, Vector<LayerBase*>::compar_t);
-        ssize_t             indexOf(LayerBase* key, size_t guess=0) const;
-        inline LayerBase*   operator [] (size_t i) const { return layers[i]; }
+        inline sp<LayerBase> const* array() const { return layers.array(); }
+        ssize_t             add(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t);
+        ssize_t             remove(const sp<LayerBase>&);
+        ssize_t             reorder(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t);
+        ssize_t             indexOf(const sp<LayerBase>& key, size_t guess=0) const;
+        inline sp<LayerBase> operator [] (size_t i) const { return layers[i]; }
     private:
-        KeyedVector<LayerBase*, size_t> lookup;
-        Vector<LayerBase*>              layers;
+        KeyedVector< sp<LayerBase> , size_t> lookup;
+        Vector< sp<LayerBase> >              layers;
     };
 
     struct State {
@@ -299,10 +286,9 @@
 
 
             void        destroyConnection(ClientID cid);
-            LayerBaseClient* getLayerUser_l(SurfaceID index) const;
-            status_t    addLayer_l(LayerBase* layer);
-            status_t    removeLayer_l(LayerBase* layer);
-            void        destroy_all_removed_layers_l();
+            sp<LayerBaseClient> getLayerUser_l(SurfaceID index) const;
+            status_t    addLayer_l(const sp<LayerBase>& layer);
+            status_t    removeLayer_l(const sp<LayerBase>& layer);
             void        free_resources_l();
 
             uint32_t    getTransactionFlags(uint32_t flags);
@@ -335,17 +321,15 @@
                 // protected by mStateLock (but we could use another lock)
                 Tokenizer                               mTokens;
                 DefaultKeyedVector<ClientID, Client*>   mClientsMap;
-                DefaultKeyedVector<SurfaceID, LayerBaseClient*>   mLayerMap;
+                DefaultKeyedVector<SurfaceID, sp<LayerBaseClient> >   mLayerMap;
                 GraphicPlane                            mGraphicPlanes[1];
-                SortedVector<LayerBase*>                mRemovedLayers;
+                bool                                    mLayersRemoved;
                 Vector<Client*>                         mDisconnectedClients;
 
                 // constant members (no synchronization needed for access)
                 sp<MemoryDealer>            mServerHeap;
                 sp<IMemory>                 mServerCblkMemory;
                 surface_flinger_cblk_t*     mServerCblk;
-                sp<SurfaceHeapManager>      mSurfaceHeapManager;
-                sp<GPUHardwareInterface>    mGPU;
                 GLuint                      mWormholeTexName;
                 sp<BootAnimation>           mBootAnimation;
                 nsecs_t                     mBootTime;
diff --git a/libs/surfaceflinger/Tokenizer.cpp b/libs/surfaceflinger/Tokenizer.cpp
index ef51d6a..be3a239 100644
--- a/libs/surfaceflinger/Tokenizer.cpp
+++ b/libs/surfaceflinger/Tokenizer.cpp
@@ -162,9 +162,10 @@
 {
     const run_t* ranges = mRanges.array();
     const size_t c = mRanges.size();
-    printf("Tokenizer (%p, size = %lu)\n", this, c);
+    printf("Tokenizer (%p, size = %d)\n", this, int(c));
     for (size_t i=0 ; i<c ; i++) {
-        printf("%lu: (%u, %u)\n", i, ranges[i].first, ranges[i].length);
+        printf("%u: (%u, %u)\n", i,
+                uint32_t(ranges[i].first), uint32_t(ranges[i].length));
     }
 }
 
diff --git a/libs/surfaceflinger/purgatory/VRamHeap.cpp b/libs/surfaceflinger/purgatory/VRamHeap.cpp
new file mode 100644
index 0000000..f3ed790
--- /dev/null
+++ b/libs/surfaceflinger/purgatory/VRamHeap.cpp
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryBase.h>
+#include <utils/MemoryHeapPmem.h>
+#include <utils/MemoryHeapBase.h>
+
+#include "GPUHardware/GPUHardware.h"
+#include "SurfaceFlinger.h"
+#include "VRamHeap.h"
+
+#if HAVE_ANDROID_OS
+#include <linux/android_pmem.h>
+#endif
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+/*
+ * Amount of memory we reserve for surface, per client in PMEM
+ * (PMEM is used for 2D acceleration)
+ * 8 MB of address space per client should be enough.
+ */
+static const int PMEM_SIZE = int(8 * 1024 * 1024);
+
+int SurfaceHeapManager::global_pmem_heap = 0;
+
+// ---------------------------------------------------------------------------
+
+SurfaceHeapManager::SurfaceHeapManager(const sp<SurfaceFlinger>& flinger, 
+        size_t clientHeapSize)
+    : mFlinger(flinger), mClientHeapSize(clientHeapSize)
+{
+    SurfaceHeapManager::global_pmem_heap = 1;
+}
+
+SurfaceHeapManager::~SurfaceHeapManager()
+{
+}
+
+void SurfaceHeapManager::onFirstRef()
+{
+    if (global_pmem_heap) {
+        const char* device = "/dev/pmem";
+        mPMemHeap = new PMemHeap(device, PMEM_SIZE);
+        if (mPMemHeap->base() == MAP_FAILED) {
+            mPMemHeap.clear();
+            global_pmem_heap = 0;
+        }
+    }
+}
+
+sp<MemoryDealer> SurfaceHeapManager::createHeap(
+        uint32_t flags,
+        pid_t client_pid,
+        const sp<MemoryDealer>& defaultAllocator)
+{
+    sp<MemoryDealer> dealer; 
+
+    if (flags & ISurfaceComposer::eGPU) {
+        // don't grant GPU memory if GPU is disabled
+        char value[PROPERTY_VALUE_MAX];
+        property_get("debug.egl.hw", value, "1");
+        if (atoi(value) == 0) {
+            flags &= ~ISurfaceComposer::eGPU;
+        }
+    }
+
+    if (flags & ISurfaceComposer::eGPU) {
+        // FIXME: this is msm7201A specific, where gpu surfaces may not be secure
+        if (!(flags & ISurfaceComposer::eSecure)) {
+            // if GPU doesn't work, we try eHardware
+            flags |= ISurfaceComposer::eHardware;
+            // asked for GPU memory, try that first
+            dealer = mFlinger->getGPU()->request(client_pid);
+        }
+    }
+
+    if (dealer == NULL) {
+        if (defaultAllocator != NULL)
+            // if a default allocator is given, use that
+            dealer = defaultAllocator;
+    }
+    
+    if (dealer == NULL) {
+        // always try h/w accelerated memory first
+        if (global_pmem_heap) {
+            const sp<PMemHeap>& heap(mPMemHeap);
+            if (dealer == NULL && heap != NULL) {
+                dealer = new MemoryDealer( 
+                        heap->createClientHeap(),
+                        heap->getAllocator());
+            }
+        }
+    }
+
+    if (dealer == NULL) {
+        // return the ashmem allocator (software rendering)
+        dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap");
+    }
+    return dealer;
+}
+
+sp<SimpleBestFitAllocator> SurfaceHeapManager::getAllocator(int type) const 
+{
+    Mutex::Autolock _l(mLock);
+    sp<SimpleBestFitAllocator> allocator;
+
+    // this is only used for debugging
+    switch (type) {
+        case NATIVE_MEMORY_TYPE_PMEM:
+            if (mPMemHeap != 0) {
+                allocator = mPMemHeap->getAllocator();
+            }
+            break;
+    }
+    return allocator;
+}
+
+// ---------------------------------------------------------------------------
+
+PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved)
+    : MemoryHeapBase(device, size)
+{
+    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
+    if (base() != MAP_FAILED) {
+        //LOGD("%s, %u bytes", device, virtualSize());
+        if (reserved == 0)
+            reserved = virtualSize();
+        mAllocator = new SimpleBestFitAllocator(reserved);
+    }
+}
+
+PMemHeap::~PMemHeap() {
+    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
+}
+
+sp<MemoryHeapPmem> PMemHeap::createClientHeap() {
+    sp<MemoryHeapBase> parentHeap(this);
+    return new MemoryHeapPmem(parentHeap);
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger/purgatory/VRamHeap.h b/libs/surfaceflinger/purgatory/VRamHeap.h
new file mode 100644
index 0000000..9140167
--- /dev/null
+++ b/libs/surfaceflinger/purgatory/VRamHeap.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VRAM_HEAP_H
+#define ANDROID_VRAM_HEAP_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/MemoryDealer.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class PMemHeap;
+class MemoryHeapPmem;
+class SurfaceFlinger; 
+
+// ---------------------------------------------------------------------------
+
+class SurfaceHeapManager  : public RefBase
+{
+public:
+    SurfaceHeapManager(const sp<SurfaceFlinger>& flinger, size_t clientHeapSize);
+    virtual ~SurfaceHeapManager();
+    virtual void onFirstRef();
+    /* use ISurfaceComposer flags eGPU|eHArdware|eSecure */
+    sp<MemoryDealer> createHeap(uint32_t flags=0, pid_t client_pid = 0,
+            const sp<MemoryDealer>& defaultAllocator = 0);
+    
+    // used for debugging only...
+    sp<SimpleBestFitAllocator> getAllocator(int type) const;
+
+private:
+    sp<PMemHeap> getHeap(int type) const;
+
+    sp<SurfaceFlinger> mFlinger;
+    mutable Mutex   mLock;
+    size_t          mClientHeapSize;
+    sp<PMemHeap>    mPMemHeap;
+    static int global_pmem_heap;
+};
+
+// ---------------------------------------------------------------------------
+
+class PMemHeap : public MemoryHeapBase
+{
+public:
+                PMemHeap(const char* const vram,
+                        size_t size=0, size_t reserved=0);
+    virtual     ~PMemHeap();
+    
+    virtual const sp<SimpleBestFitAllocator>& getAllocator() const {
+        return mAllocator; 
+    }
+    virtual sp<MemoryHeapPmem> createClientHeap();
+    
+private:
+    sp<SimpleBestFitAllocator>  mAllocator;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_VRAM_HEAP_H
diff --git a/libs/surfaceflinger/tests/resize/Android.mk b/libs/surfaceflinger/tests/resize/Android.mk
new file mode 100644
index 0000000..ef1532f
--- /dev/null
+++ b/libs/surfaceflinger/tests/resize/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	resize.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+    libui
+
+LOCAL_MODULE:= test-resize
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/surfaceflinger/tests/resize/resize.cpp b/libs/surfaceflinger/tests/resize/resize.cpp
new file mode 100644
index 0000000..21c6ab6
--- /dev/null
+++ b/libs/surfaceflinger/tests/resize/resize.cpp
@@ -0,0 +1,60 @@
+#include <cutils/memory.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/ProcessState.h>
+#include <utils/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <ui/Surface.h>
+#include <ui/ISurface.h>
+#include <ui/Overlay.h>
+#include <ui/SurfaceComposerClient.h>
+
+using namespace android;
+
+namespace android {
+class Test {
+public:
+    static const sp<ISurface>& getISurface(const sp<Surface>& s) {
+        return s->getISurface();
+    }
+};
+};
+
+int main(int argc, char** argv)
+{
+    // set up the thread-pool
+    sp<ProcessState> proc(ProcessState::self());
+    ProcessState::self()->startThreadPool();
+
+    // create a client to surfaceflinger
+    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
+    
+    // create pushbuffer surface
+    sp<Surface> surface = client->createSurface(getpid(), 0, 160, 240, 
+            PIXEL_FORMAT_RGB_565);
+
+
+    client->openTransaction();
+    surface->setLayer(100000);
+    client->closeTransaction();
+
+    Surface::SurfaceInfo info;
+    surface->lock(&info);
+    ssize_t bpr = info.s * bytesPerPixel(info.format);
+    android_memset16((uint16_t*)info.bits, 0xF800, bpr*info.h);
+    surface->unlockAndPost();
+
+    surface->lock(&info);
+    android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h);
+    surface->unlockAndPost();
+
+    client->openTransaction();
+    surface->setSize(320, 240);
+    client->closeTransaction();
+
+    
+    IPCThreadState::self()->joinThreadPool();
+    
+    return 0;
+}