Merge "Add Thread::isRunning and Condition::signal(WakeUpType)" into jb-mr2-dev
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index fd390f5..d081590 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -31,6 +31,7 @@
 #include <sys/klog.h>
 #include <time.h>
 #include <unistd.h>
+#include <sys/prctl.h>
 
 #include <cutils/debugger.h>
 #include <cutils/properties.h>
@@ -264,6 +265,9 @@
         const char *args[1024] = {command};
         size_t arg;
 
+        /* make sure the child dies when dumpstate dies */
+        prctl(PR_SET_PDEATHSIG, SIGKILL);
+
         va_list ap;
         va_start(ap, command);
         if (title) printf("------ %s (%s", title, command);
diff --git a/cmds/surfaceflinger/main_surfaceflinger.cpp b/cmds/surfaceflinger/main_surfaceflinger.cpp
index 28e58e4..ce7fde0 100644
--- a/cmds/surfaceflinger/main_surfaceflinger.cpp
+++ b/cmds/surfaceflinger/main_surfaceflinger.cpp
@@ -20,9 +20,9 @@
 using namespace android;
 
 int main(int argc, char** argv) {
-    SurfaceFlinger::publishAndJoinThreadPool(true);
     // When SF is launched in its own process, limit the number of
     // binder threads to 4.
     ProcessState::self()->setThreadPoolMaxThreadCount(4);
+    SurfaceFlinger::publishAndJoinThreadPool(true);
     return 0;
 }
diff --git a/include/binder/BinderService.h b/include/binder/BinderService.h
index 6460268..5ac36d9 100644
--- a/include/binder/BinderService.h
+++ b/include/binder/BinderService.h
@@ -36,13 +36,18 @@
 public:
     static status_t publish(bool allowIsolated = false) {
         sp<IServiceManager> sm(defaultServiceManager());
-        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
+        return sm->addService(
+                String16(SERVICE::getServiceName()),
+                new SERVICE(), allowIsolated);
     }
 
     static void publishAndJoinThreadPool(bool allowIsolated = false) {
         sp<IServiceManager> sm(defaultServiceManager());
-        sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);
+        sm->addService(
+                String16(SERVICE::getServiceName()),
+                new SERVICE(), allowIsolated);
         ProcessState::self()->startThreadPool();
+        ProcessState::self()->giveThreadPoolName();
         IPCThreadState::self()->joinThreadPool();
     }
 
diff --git a/include/binder/ProcessState.h b/include/binder/ProcessState.h
index 8caf1af..e63a0d0 100644
--- a/include/binder/ProcessState.h
+++ b/include/binder/ProcessState.h
@@ -71,6 +71,7 @@
             void                spawnPooledThread(bool isMain);
             
             status_t            setThreadPoolMaxThreadCount(size_t maxThreads);
+            void                giveThreadPoolName();
 
 private:
     friend class IPCThreadState;
@@ -80,6 +81,7 @@
 
                                 ProcessState(const ProcessState& o);
             ProcessState&       operator=(const ProcessState& o);
+            String8             makeBinderThreadName();
             
             struct handle_entry {
                 IBinder* binder;
diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h
index 23d1d4c..4afc860 100644
--- a/include/gui/ISurfaceComposerClient.h
+++ b/include/gui/ISurfaceComposerClient.h
@@ -48,9 +48,7 @@
         eProtectedByDRM     = 0x00001000,
 
         eFXSurfaceNormal    = 0x00000000,
-        eFXSurfaceBlur      = 0x00010000, // deprecated, same as Dim
         eFXSurfaceDim       = 0x00020000,
-        eFXSurfaceScreenshot= 0x00030000,
         eFXSurfaceMask      = 0x000F0000,
     };
 
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 4b9b5a8..ea9368d 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -24,6 +24,7 @@
 #include <ui/PixelFormat.h>
 #include <ui/Rect.h>
 #include <utils/Flattenable.h>
+#include <utils/RefBase.h>
 
 
 struct ANativeWindowBuffer;
@@ -37,10 +38,8 @@
 // ===========================================================================
 
 class GraphicBuffer
-    : public ANativeObjectBase<
-        ANativeWindowBuffer,
-        GraphicBuffer, 
-        LightRefBase<GraphicBuffer> >, public Flattenable
+    : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >,
+      public Flattenable
 {
 public:
 
diff --git a/include/utils/AndroidThreads.h b/include/utils/AndroidThreads.h
index f67648f..4eee14d 100644
--- a/include/utils/AndroidThreads.h
+++ b/include/utils/AndroidThreads.h
@@ -56,6 +56,9 @@
                                      size_t threadStackSize,
                                      android_thread_id_t *threadId);
 
+// set the same of the running thread
+extern void androidSetThreadName(const char* name);
+
 // Used by the Java Runtime to control how threads are created, so that
 // they can be proper and lovely Java threads.
 typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index d95fd6f..294e1d4 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -283,15 +283,20 @@
     }
 }
 
+String8 ProcessState::makeBinderThreadName() {
+    int32_t s = android_atomic_add(1, &mThreadPoolSeq);
+    String8 name;
+    name.appendFormat("Binder_%X", s);
+    return name;
+}
+
 void ProcessState::spawnPooledThread(bool isMain)
 {
     if (mThreadPoolStarted) {
-        int32_t s = android_atomic_add(1, &mThreadPoolSeq);
-        char buf[16];
-        snprintf(buf, sizeof(buf), "Binder_%X", s);
-        ALOGV("Spawning new pooled thread, name=%s\n", buf);
+        String8 name = makeBinderThreadName();
+        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
         sp<Thread> t = new PoolThread(isMain);
-        t->run(buf);
+        t->run(name.string());
     }
 }
 
@@ -304,6 +309,10 @@
     return result;
 }
 
+void ProcessState::giveThreadPoolName() {
+    androidSetThreadName( makeBinderThreadName().string() );
+}
+
 static int open_driver()
 {
     int fd = open("/dev/binder", O_RDWR);
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index fbaf6aa..2d30305 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -1636,6 +1636,81 @@
     }
 }
 
+TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentBeforeConsumerDeathUnrefsBuffers) {
+    sp<GraphicBuffer> buffer;
+
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+
+    // Produce a frame
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Destroy the EGLSurface.
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    mProducerEglSurface = EGL_NO_SURFACE;
+    mSTC.clear();
+    mANW.clear();
+    mTextureRenderer.clear();
+
+    // Consume a frame
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    buffer = mST->getCurrentBuffer();
+
+    // Destroy the GL texture object to release its ref
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // make un-current, all references to buffer should be gone
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
+            EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+    // Destroy consumer
+    mST.clear();
+
+    EXPECT_EQ(1, buffer->getStrongCount());
+}
+
+TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentAfterConsumerDeathUnrefsBuffers) {
+    sp<GraphicBuffer> buffer;
+
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
+            mProducerEglSurface, mProducerEglContext));
+
+    // Produce a frame
+    glClear(GL_COLOR_BUFFER_BIT);
+    EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+
+    // Destroy the EGLSurface.
+    EXPECT_TRUE(eglDestroySurface(mEglDisplay, mProducerEglSurface));
+    ASSERT_EQ(EGL_SUCCESS, eglGetError());
+    mProducerEglSurface = EGL_NO_SURFACE;
+    mSTC.clear();
+    mANW.clear();
+    mTextureRenderer.clear();
+
+    // Consume a frame
+    ASSERT_EQ(NO_ERROR, mST->updateTexImage());
+    buffer = mST->getCurrentBuffer();
+
+    // Destroy the GL texture object to release its ref
+    GLuint texID = TEX_ID;
+    glDeleteTextures(1, &texID);
+
+    // Destroy consumer
+    mST.clear();
+
+    // make un-current, all references to buffer should be gone
+    EXPECT_TRUE(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE,
+            EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+    EXPECT_EQ(1, buffer->getStrongCount());
+}
+
+
 TEST_F(SurfaceTextureGLToGLTest, EglSurfaceDefaultsToSynchronousMode) {
     // This test requires 3 buffers to run on a single thread.
     mST->setDefaultMaxBufferCount(3);
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index e80a795..2b39bce 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -199,7 +199,7 @@
         {
             char name[100];
             snprintf(name, 100, "/data/%p.stack", this);
-            int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
+            int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644);
             if (rc >= 0) {
                 write(rc, text.string(), text.length());
                 close(rc);
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 1d61457..7b877e0 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -109,30 +109,34 @@
         }
         
         if (name) {
-#if defined(HAVE_PRCTL)
-            // Mac OS doesn't have this, and we build libutil for the host too
-            int hasAt = 0;
-            int hasDot = 0;
-            char *s = name;
-            while (*s) {
-                if (*s == '.') hasDot = 1;
-                else if (*s == '@') hasAt = 1;
-                s++;
-            }
-            int len = s - name;
-            if (len < 15 || hasAt || !hasDot) {
-                s = name;
-            } else {
-                s = name + len - 15;
-            }
-            prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
-#endif
+            androidSetThreadName(name);
             free(name);
         }
         return f(u);
     }
 };
 
+void androidSetThreadName(const char* name) {
+#if defined(HAVE_PRCTL)
+    // Mac OS doesn't have this, and we build libutil for the host too
+    int hasAt = 0;
+    int hasDot = 0;
+    const char *s = name;
+    while (*s) {
+        if (*s == '.') hasDot = 1;
+        else if (*s == '@') hasAt = 1;
+        s++;
+    }
+    int len = s - name;
+    if (len < 15 || hasAt || !hasDot) {
+        s = name;
+    } else {
+        s = name + len - 15;
+    }
+    prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
+#endif
+}
+
 int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
                                void *userData,
                                const char* threadName,
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 172ef95..0ed5727 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -147,6 +147,7 @@
     EGLDisplay          dpy;
     EGLConfig           config;
     EGLContext          ctx;
+    bool                zombie;
 
                 egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat);
     virtual     ~egl_surface_t();
@@ -173,7 +174,7 @@
 egl_surface_t::egl_surface_t(EGLDisplay dpy,
         EGLConfig config,
         int32_t depthFormat)
-    : magic(MAGIC), dpy(dpy), config(config), ctx(0)
+    : magic(MAGIC), dpy(dpy), config(config), ctx(0), zombie(false)
 {
     depth.version = sizeof(GGLSurface);
     depth.data = 0;
@@ -419,9 +420,8 @@
         bits = NULL;
         unlock(buffer);
     }
-    // enqueue the last frame
-    nativeWindow->queueBuffer(nativeWindow, buffer, -1);
     if (buffer) {
+        nativeWindow->cancelBuffer(nativeWindow, buffer, -1);
         buffer->common.decRef(&buffer->common);
         buffer = 0;
     }
@@ -1580,11 +1580,12 @@
         if (surface->dpy != dpy)
             return setError(EGL_BAD_DISPLAY, EGL_FALSE);
         if (surface->ctx) {
-            // FIXME: this surface is current check what the spec says
+            // defer disconnect/delete until no longer current
+            surface->zombie = true;
+        } else {
             surface->disconnect();
-            surface->ctx = 0;
+            delete surface;
         }
-        delete surface;
     }
     return EGL_TRUE;
 }
@@ -1736,6 +1737,9 @@
             if (c->draw) {
                 egl_surface_t* s = reinterpret_cast<egl_surface_t*>(c->draw);
                 s->disconnect();
+                s->ctx = EGL_NO_CONTEXT;
+                if (s->zombie)
+                    delete s;
             }
             if (c->read) {
                 // FIXME: unlock/disconnect the read surface too 
@@ -1777,8 +1781,10 @@
                 egl_surface_t* r = (egl_surface_t*)c->read;
                 if (d) {
                     c->draw = 0;
-                    d->ctx = EGL_NO_CONTEXT;
                     d->disconnect();
+                    d->ctx = EGL_NO_CONTEXT;
+                    if (d->zombie)
+                        delete d;
                 }
                 if (r) {
                     c->read = 0;
diff --git a/opengl/tests/gl2_yuvtex/Android.mk b/opengl/tests/gl2_yuvtex/Android.mk
index 7d43759..bb3cc0c 100644
--- a/opengl/tests/gl2_yuvtex/Android.mk
+++ b/opengl/tests/gl2_yuvtex/Android.mk
@@ -5,9 +5,10 @@
 	gl2_yuvtex.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-	libcutils \
+    libcutils \
     libEGL \
     libGLESv2 \
+    libutils \
     libui
 
 LOCAL_C_INCLUDES += $(call include-path-for, opengl-tests-includes)
diff --git a/opengl/tests/gl_yuvtex/Android.mk b/opengl/tests/gl_yuvtex/Android.mk
index 9e5dba0..e0e2c16 100644
--- a/opengl/tests/gl_yuvtex/Android.mk
+++ b/opengl/tests/gl_yuvtex/Android.mk
@@ -5,9 +5,10 @@
 	gl_yuvtex.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-	libcutils \
+    libcutils \
     libEGL \
     libGLESv1_CM \
+    libutils \
     libui
 
 LOCAL_C_INCLUDES += $(call include-path-for, opengl-tests-includes)
diff --git a/opengl/tests/hwc/Android.mk b/opengl/tests/hwc/Android.mk
index 9eb58b1..177eb63 100644
--- a/opengl/tests/hwc/Android.mk
+++ b/opengl/tests/hwc/Android.mk
@@ -39,6 +39,7 @@
     libcutils \
     libEGL \
     libGLESv2 \
+    libutils \
     libui \
     libhardware \
 
@@ -70,6 +71,7 @@
     libcutils \
     libEGL \
     libGLESv2 \
+    libutils \
     libui \
     libhardware \
 
@@ -99,6 +101,7 @@
     libcutils \
     libEGL \
     libGLESv2 \
+    libutils \
     libui \
     libhardware \
 
@@ -128,6 +131,7 @@
     libcutils \
     libEGL \
     libGLESv2 \
+    libutils \
     libui \
     libhardware \
 
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index b4b19b4..5ff8154 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -7,9 +7,7 @@
     EventThread.cpp                         \
     FrameTracker.cpp                        \
     Layer.cpp                               \
-    LayerBase.cpp                           \
     LayerDim.cpp                            \
-    LayerScreenshot.cpp                     \
     DisplayHardware/FramebufferSurface.cpp  \
     DisplayHardware/HWComposer.cpp          \
     DisplayHardware/PowerHAL.cpp            \
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 0f56f99..0575e35 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -23,7 +23,6 @@
 
 #include "Client.h"
 #include "Layer.h"
-#include "LayerBase.h"
 #include "SurfaceFlinger.h"
 
 namespace android {
@@ -43,7 +42,7 @@
 {
     const size_t count = mLayers.size();
     for (size_t i=0 ; i<count ; i++) {
-        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
+        sp<Layer> layer(mLayers.valueAt(i).promote());
         if (layer != 0) {
             mFlinger->removeLayer(layer);
         }
@@ -54,13 +53,13 @@
     return NO_ERROR;
 }
 
-void Client::attachLayer(const sp<IBinder>& handle, const sp<LayerBaseClient>& layer)
+void Client::attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer)
 {
     Mutex::Autolock _l(mLock);
     mLayers.add(handle, layer);
 }
 
-void Client::detachLayer(const LayerBaseClient* layer)
+void Client::detachLayer(const Layer* layer)
 {
     Mutex::Autolock _l(mLock);
     // we do a linear search here, because this doesn't happen often
@@ -72,11 +71,11 @@
         }
     }
 }
-sp<LayerBaseClient> Client::getLayerUser(const sp<IBinder>& handle) const
+sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const
 {
     Mutex::Autolock _l(mLock);
-    sp<LayerBaseClient> lbc;
-    wp<LayerBaseClient> layer(mLayers.valueFor(handle));
+    sp<Layer> lbc;
+    wp<Layer> layer(mLayers.valueFor(handle));
     if (layer != 0) {
         lbc = layer.promote();
         ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get());
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index e6a7165..4f34b86 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -30,7 +30,7 @@
 
 // ---------------------------------------------------------------------------
 
-class LayerBaseClient;
+class Layer;
 class SurfaceFlinger;
 
 // ---------------------------------------------------------------------------
@@ -44,11 +44,11 @@
     status_t initCheck() const;
 
     // protected by SurfaceFlinger::mStateLock
-    void attachLayer(const sp<IBinder>& handle, const sp<LayerBaseClient>& layer);
+    void attachLayer(const sp<IBinder>& handle, const sp<Layer>& layer);
 
-    void detachLayer(const LayerBaseClient* layer);
+    void detachLayer(const Layer* layer);
 
-    sp<LayerBaseClient> getLayerUser(const sp<IBinder>& handle) const;
+    sp<Layer> getLayerUser(const sp<IBinder>& handle) const;
 
 private:
     // ISurfaceComposerClient interface
@@ -66,7 +66,7 @@
     sp<SurfaceFlinger> mFlinger;
 
     // protected by mLock
-    DefaultKeyedVector< wp<IBinder>, wp<LayerBaseClient> > mLayers;
+    DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;
 
     // thread-safe
     mutable Mutex mLock;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index ed2768c..2bbe49c 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -42,7 +42,7 @@
 #include "DisplayDevice.h"
 #include "GLExtensions.h"
 #include "SurfaceFlinger.h"
-#include "LayerBase.h"
+#include "Layer.h"
 
 // ----------------------------------------------------------------------------
 using namespace android;
@@ -282,19 +282,19 @@
 
 // ----------------------------------------------------------------------------
 
-void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) {
+void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
     mVisibleLayersSortedByZ = layers;
     mSecureLayerVisible = false;
     size_t count = layers.size();
     for (size_t i=0 ; i<count ; i++) {
-        const sp<LayerBase>& layer(layers[i]);
+        const sp<Layer>& layer(layers[i]);
         if (layer->isSecure()) {
             mSecureLayerVisible = true;
         }
     }
 }
 
-const Vector< sp<LayerBase> >& DisplayDevice::getVisibleLayersSortedByZ() const {
+const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
     return mVisibleLayersSortedByZ;
 }
 
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 91f34db..f671017 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -38,7 +38,7 @@
 
 class DisplayInfo;
 class FramebufferSurface;
-class LayerBase;
+class Layer;
 class SurfaceFlinger;
 class HWComposer;
 
@@ -99,8 +99,8 @@
 
     EGLSurface  getEGLSurface() const;
 
-    void                    setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers);
-    const Vector< sp<LayerBase> >& getVisibleLayersSortedByZ() const;
+    void                    setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers);
+    const Vector< sp<Layer> >& getVisibleLayersSortedByZ() const;
     bool                    getSecureLayerVisible() const;
     Region                  getDirtyRegion(bool repaintEverything) const;
 
@@ -186,7 +186,7 @@
      */
 
     // list of visible layers on that display
-    Vector< sp<LayerBase> > mVisibleLayersSortedByZ;
+    Vector< sp<Layer> > mVisibleLayersSortedByZ;
 
     // Whether we have a visible secure layer on this display
     bool mSecureLayerVisible;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 11f65f6..bb567e2 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -41,7 +41,6 @@
 #include <cutils/properties.h>
 
 #include "Layer.h"           // needed only for debugging
-#include "LayerBase.h"
 #include "HWComposer.h"
 #include "SurfaceFlinger.h"
 #include <utils/CallStack.h>
@@ -925,7 +924,7 @@
         for (size_t i=0 ; i<mNumDisplays ; i++) {
             const DisplayData& disp(mDisplayData[i]);
 
-            const Vector< sp<LayerBase> >& visibleLayersSortedByZ =
+            const Vector< sp<Layer> >& visibleLayersSortedByZ =
                     mFlinger->getLayerSortedByZForHwcDisplay(i);
 
             if (disp.connected) {
@@ -949,13 +948,11 @@
                     String8 name("unknown");
 
                     if (i < visibleLayersSortedByZ.size()) {
-                        const sp<LayerBase>& layer(visibleLayersSortedByZ[i]);
-                        if (layer->getLayer() != NULL) {
-                            const sp<GraphicBuffer>& buffer(
-                                layer->getLayer()->getActiveBuffer());
-                            if (buffer != NULL) {
-                                format = buffer->getPixelFormat();
-                            }
+                        const sp<Layer>& layer(visibleLayersSortedByZ[i]);
+                        const sp<GraphicBuffer>& buffer(
+                                layer->getActiveBuffer());
+                        if (buffer != NULL) {
+                            format = buffer->getPixelFormat();
                         }
                         name = layer->getName();
                     }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index f7ed1aa..9816a45 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -47,7 +47,6 @@
 
 class GraphicBuffer;
 class Fence;
-class LayerBase;
 class Region;
 class String8;
 class SurfaceFlinger;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c9f1eb5..44ef0b8 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -19,6 +19,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
+#include <math.h>
 
 #include <cutils/compiler.h>
 #include <cutils/native_handle.h>
@@ -49,37 +50,39 @@
 
 // ---------------------------------------------------------------------------
 
+int32_t Layer::sSequence = 1;
+
 Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client)
-    :   LayerBaseClient(flinger, client),
+    :   contentDirty(false),
+        sequence(uint32_t(android_atomic_inc(&sSequence))),
+        mFlinger(flinger),
         mTextureName(-1U),
+        mPremultipliedAlpha(true),
+        mName("unnamed"),
+        mDebug(false),
+        mFormat(PIXEL_FORMAT_NONE),
+        mGLExtensions(GLExtensions::getInstance()),
+        mOpaqueLayer(true),
+        mTransactionFlags(0),
         mQueuedFrames(0),
         mCurrentTransform(0),
         mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
         mCurrentOpacity(true),
         mRefreshPending(false),
         mFrameLatencyNeeded(false),
-        mFormat(PIXEL_FORMAT_NONE),
-        mGLExtensions(GLExtensions::getInstance()),
-        mOpaqueLayer(true),
+        mFiltering(false),
+        mNeedsFiltering(false),
         mSecure(false),
-        mProtectedByApp(false)
+        mProtectedByApp(false),
+        mHasSurface(false),
+        mClientRef(client)
 {
     mCurrentCrop.makeInvalid();
     glGenTextures(1, &mTextureName);
 }
 
-void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
-        HWComposer::HWCLayerInterface* layer) {
-    LayerBaseClient::onLayerDisplayed(hw, layer);
-    if (layer) {
-        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd());
-    }
-}
-
 void Layer::onFirstRef()
 {
-    LayerBaseClient::onFirstRef();
-
     // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
     sp<BufferQueue> bq = new SurfaceTextureLayer();
     mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mTextureName, true,
@@ -102,9 +105,25 @@
 
 Layer::~Layer()
 {
+    sp<Client> c(mClientRef.promote());
+    if (c != 0) {
+        c->detachLayer(this);
+    }
     mFlinger->deleteTextureAsync(mTextureName);
 }
 
+// ---------------------------------------------------------------------------
+// callbacks
+// ---------------------------------------------------------------------------
+
+void Layer::onLayerDisplayed(const sp<const DisplayDevice>& hw,
+        HWComposer::HWCLayerInterface* layer) {
+    if (layer) {
+        layer->onDisplayed();
+        mSurfaceFlingerConsumer->setReleaseFence(layer->getAndResetReleaseFenceFd());
+    }
+}
+
 void Layer::onFrameAvailable() {
     android_atomic_inc(&mQueuedFrames);
     mFlinger->signalLayerUpdate();
@@ -112,56 +131,45 @@
 
 // called with SurfaceFlinger::mStateLock as soon as the layer is entered
 // in the purgatory list
-void Layer::onRemoved()
-{
+void Layer::onRemoved() {
     mSurfaceFlingerConsumer->abandon();
 }
 
+// ---------------------------------------------------------------------------
+// set-up
+// ---------------------------------------------------------------------------
+
 void Layer::setName(const String8& name) {
-    LayerBase::setName(name);
+    mName = name;
     mSurfaceFlingerConsumer->setName(name);
 }
 
-sp<ISurface> Layer::createSurface()
-{
-    /*
-     * This class provides an implementation of BnSurface (the "native" or
-     * "remote" side of the Binder IPC interface ISurface), and mixes in
-     * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for
-     * this layer when the BSurface is destroyed.
-     *
-     * The idea is to provide a handle to the Layer through ISurface that
-     * is cleaned up automatically when the last reference to the ISurface
-     * goes away.  (The references will be held on the "proxy" side, while
-     * the Layer exists on the "native" side.)
-     *
-     * The Layer has a reference to an instance of SurfaceFlinger's variant
-     * of GLConsumer, which holds a reference to the BufferQueue.  The
-     * getSurfaceTexture() call returns a Binder interface reference for
-     * the producer interface of the buffer queue associated with the Layer.
-     */
-    class BSurface : public BnSurface, public LayerCleaner {
-        wp<const Layer> mOwner;
-        virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
-            sp<IGraphicBufferProducer> res;
-            sp<const Layer> that( mOwner.promote() );
-            if (that != NULL) {
-                res = that->mSurfaceFlingerConsumer->getBufferQueue();
-            }
-            return res;
-        }
-    public:
-        BSurface(const sp<SurfaceFlinger>& flinger,
-                const sp<Layer>& layer)
-            : LayerCleaner(flinger, layer), mOwner(layer) { }
-    };
-    sp<ISurface> sur(new BSurface(mFlinger, this));
-    return sur;
+String8 Layer::getName() const {
+    return mName;
 }
 
-wp<IBinder> Layer::getSurfaceTextureBinder() const
+void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags)
 {
-    return mSurfaceFlingerConsumer->getBufferQueue()->asBinder();
+    uint32_t layerFlags = 0;
+    if (flags & ISurfaceComposerClient::eHidden)
+        layerFlags = layer_state_t::eLayerHidden;
+
+    if (flags & ISurfaceComposerClient::eNonPremultiplied)
+        mPremultipliedAlpha = false;
+
+    mCurrentState.active.w = w;
+    mCurrentState.active.h = h;
+    mCurrentState.active.crop.makeInvalid();
+    mCurrentState.z = 0;
+    mCurrentState.alpha = 0xFF;
+    mCurrentState.layerStack = 0;
+    mCurrentState.flags = layerFlags;
+    mCurrentState.sequence = 0;
+    mCurrentState.transform.set(0, 0);
+    mCurrentState.requested = mCurrentState.active;
+
+    // drawing state & current state are identical
+    mDrawingState = mCurrentState;
 }
 
 status_t Layer::setBuffers( uint32_t w, uint32_t h,
@@ -199,6 +207,63 @@
     return NO_ERROR;
 }
 
+sp<ISurface> Layer::createSurface() {
+    /*
+     * This class provides an implementation of BnSurface (the "native" or
+     * "remote" side of the Binder IPC interface ISurface), and mixes in
+     * LayerCleaner to ensure that mFlinger->onLayerDestroyed() is called for
+     * this layer when the BSurface is destroyed.
+     *
+     * The idea is to provide a handle to the Layer through ISurface that
+     * is cleaned up automatically when the last reference to the ISurface
+     * goes away.  (The references will be held on the "proxy" side, while
+     * the Layer exists on the "native" side.)
+     *
+     * The Layer has a reference to an instance of SurfaceFlinger's variant
+     * of GLConsumer, which holds a reference to the BufferQueue.  The
+     * getSurfaceTexture() call returns a Binder interface reference for
+     * the producer interface of the buffer queue associated with the Layer.
+     */
+    class BSurface : public BnSurface, public LayerCleaner {
+        wp<const Layer> mOwner;
+        virtual sp<IGraphicBufferProducer> getSurfaceTexture() const {
+            sp<IGraphicBufferProducer> res;
+            sp<const Layer> that( mOwner.promote() );
+            if (that != NULL) {
+                res = that->mSurfaceFlingerConsumer->getBufferQueue();
+            }
+            return res;
+        }
+    public:
+        BSurface(const sp<SurfaceFlinger>& flinger,
+                const sp<Layer>& layer)
+            : LayerCleaner(flinger, layer), mOwner(layer) { }
+    };
+    sp<ISurface> sur(new BSurface(mFlinger, this));
+    return sur;
+}
+
+wp<IBinder> Layer::getSurfaceTextureBinder() const {
+    return mSurfaceFlingerConsumer->getBufferQueue()->asBinder();
+}
+
+sp<ISurface> Layer::getSurface()
+{
+    sp<ISurface> s;
+    Mutex::Autolock _l(mLock);
+
+    LOG_ALWAYS_FATAL_IF(mHasSurface,
+            "Layer::getSurface() has already been called");
+
+    mHasSurface = true;
+    s = createSurface();
+    return s;
+}
+
+// ---------------------------------------------------------------------------
+// h/w composer set-up
+// ---------------------------------------------------------------------------
+
 Rect Layer::getContentCrop() const {
     // this is the crop rectangle that applies to the buffer
     // itself (as opposed to the window)
@@ -220,11 +285,85 @@
     return mCurrentTransform;
 }
 
+Rect Layer::computeBounds() const {
+    const Layer::State& s(drawingState());
+    Rect win(s.active.w, s.active.h);
+    if (!s.active.crop.isEmpty()) {
+        win.intersect(s.active.crop, &win);
+    }
+    return win;
+}
+
+Rect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
+    /*
+     * The way we compute the crop (aka. texture coordinates when we have a
+     * Layer) produces a different output from the GL code in
+     * drawWithOpenGL() due to HWC being limited to integers. The difference
+     * can be large if getContentTransform() contains a large scale factor.
+     * See comments in drawWithOpenGL() for more details.
+     */
+
+    // the content crop is the area of the content that gets scaled to the
+    // layer's size.
+    Rect crop(getContentCrop());
+
+    // the active.crop is the area of the window that gets cropped, but not
+    // scaled in any ways.
+    const State& s(drawingState());
+
+    // apply the projection's clipping to the window crop in
+    // layerstack space, and convert-back to layer space.
+    // if there are no window scaling (or content scaling) involved,
+    // this operation will map to full pixels in the buffer.
+    // NOTE: should we revert to GL composition if a scaling is involved
+    // since it cannot be represented in the HWC API?
+    Rect activeCrop(s.transform.transform(s.active.crop));
+    activeCrop.intersect(hw->getViewport(), &activeCrop);
+    activeCrop = s.transform.inverse().transform(activeCrop);
+
+    // paranoia: make sure the window-crop is constrained in the
+    // window's bounds
+    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
+
+    if (!activeCrop.isEmpty()) {
+        // Transform the window crop to match the buffer coordinate system,
+        // which means using the inverse of the current transform set on the
+        // SurfaceFlingerConsumer.
+        uint32_t invTransform = getContentTransform();
+        int winWidth = s.active.w;
+        int winHeight = s.active.h;
+        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
+                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
+            winWidth = s.active.h;
+            winHeight = s.active.w;
+        }
+        const Rect winCrop = activeCrop.transform(
+                invTransform, s.active.w, s.active.h);
+
+        // the code below essentially performs a scaled intersection
+        // of crop and winCrop
+        float xScale = float(crop.width()) / float(winWidth);
+        float yScale = float(crop.height()) / float(winHeight);
+
+        int insetL = int(ceilf( winCrop.left                * xScale));
+        int insetT = int(ceilf( winCrop.top                 * yScale));
+        int insetR = int(ceilf((winWidth  - winCrop.right ) * xScale));
+        int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
+
+        crop.left   += insetL;
+        crop.top    += insetT;
+        crop.right  -= insetR;
+        crop.bottom -= insetB;
+    }
+    return crop;
+}
+
 void Layer::setGeometry(
     const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface& layer)
 {
-    LayerBaseClient::setGeometry(hw, layer);
+    layer.setDefaultState();
 
     // enable this layer
     layer.setSkip(false);
@@ -233,7 +372,21 @@
         layer.setSkip(true);
     }
 
+    // this gives us only the "orientation" component of the transform
     const State& s(drawingState());
+    if (!isOpaque() || s.alpha != 0xFF) {
+        layer.setBlending(mPremultipliedAlpha ?
+                HWC_BLENDING_PREMULT :
+                HWC_BLENDING_COVERAGE);
+    }
+
+    // apply the layer's transform, followed by the display's global transform
+    // here we're guaranteed that the layer's transform preserves rects
+    Rect frame(s.transform.transform(computeBounds()));
+    frame.intersect(hw->getViewport(), &frame);
+    const Transform& tr(hw->getTransform());
+    layer.setFrame(tr.transform(frame));
+    layer.setCrop(computeCrop(hw));
     layer.setPlaneAlpha(s.alpha);
 
     /*
@@ -245,22 +398,29 @@
      */
 
     const Transform bufferOrientation(mCurrentTransform);
-    const Transform tr(hw->getTransform() * s.transform * bufferOrientation);
+    const Transform transform(tr * s.transform * bufferOrientation);
 
     // this gives us only the "orientation" component of the transform
-    const uint32_t finalTransform = tr.getOrientation();
-
-    // we can only handle simple transformation
-    if (finalTransform & Transform::ROT_INVALID) {
+    const uint32_t orientation = transform.getOrientation();
+    if (orientation & Transform::ROT_INVALID) {
+        // we can only handle simple transformation
         layer.setSkip(true);
     } else {
-        layer.setTransform(finalTransform);
+        layer.setTransform(orientation);
     }
 }
 
 void Layer::setPerFrameData(const sp<const DisplayDevice>& hw,
         HWComposer::HWCLayerInterface& layer) {
-    LayerBaseClient::setPerFrameData(hw, layer);
+    // we have to set the visible region on every frame because
+    // we currently free it during onLayerDisplayed(), which is called
+    // after HWComposer::commit() -- every frame.
+    // Apply this display's projection's viewport to the visible region
+    // before giving it to the HWC HAL.
+    const Transform& tr = hw->getTransform();
+    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
+    layer.setVisibleRegionScreen(visible);
+
     // NOTE: buffer can be NULL if the client never drew into this
     // layer yet, or if we ran out of memory
     layer.setBuffer(mActiveBuffer);
@@ -285,6 +445,18 @@
     layer.setAcquireFenceFd(fenceFd);
 }
 
+// ---------------------------------------------------------------------------
+// drawing...
+// ---------------------------------------------------------------------------
+
+void Layer::draw(const sp<const DisplayDevice>& hw, const Region& clip) const {
+    onDraw(hw, clip);
+}
+
+void Layer::draw(const sp<const DisplayDevice>& hw) {
+    onDraw( hw, Region(hw->bounds()) );
+}
+
 void Layer::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
 {
     ATRACE_CALL();
@@ -304,8 +476,8 @@
                 mFlinger->mDrawingState.layersSortedByZ);
         const size_t count = drawingLayers.size();
         for (size_t i=0 ; i<count ; ++i) {
-            const sp<LayerBase>& layer(drawingLayers[i]);
-            if (layer.get() == static_cast<LayerBase const*>(this))
+            const sp<Layer>& layer(drawingLayers[i]);
+            if (layer.get() == static_cast<Layer const*>(this))
                 break;
             under.orSelf( hw->getTransform().transform(layer->visibleRegion) );
         }
@@ -365,6 +537,119 @@
     glDisable(GL_TEXTURE_2D);
 }
 
+
+void Layer::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
+        GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
+{
+    const uint32_t fbHeight = hw->getHeight();
+    glColor4f(red,green,blue,alpha);
+
+    glDisable(GL_TEXTURE_EXTERNAL_OES);
+    glDisable(GL_TEXTURE_2D);
+    glDisable(GL_BLEND);
+
+    LayerMesh mesh;
+    computeGeometry(hw, &mesh);
+
+    glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
+    glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
+}
+
+void Layer::clearWithOpenGL(
+        const sp<const DisplayDevice>& hw, const Region& clip) const {
+    clearWithOpenGL(hw, clip, 0,0,0,0);
+}
+
+void Layer::drawWithOpenGL(
+        const sp<const DisplayDevice>& hw, const Region& clip) const {
+    const uint32_t fbHeight = hw->getHeight();
+    const State& s(drawingState());
+
+    GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+    if (CC_UNLIKELY(s.alpha < 0xFF)) {
+        const GLfloat alpha = s.alpha * (1.0f/255.0f);
+        if (mPremultipliedAlpha) {
+            glColor4f(alpha, alpha, alpha, alpha);
+        } else {
+            glColor4f(1, 1, 1, alpha);
+        }
+        glEnable(GL_BLEND);
+        glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    } else {
+        glColor4f(1, 1, 1, 1);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        if (!isOpaque()) {
+            glEnable(GL_BLEND);
+            glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+        } else {
+            glDisable(GL_BLEND);
+        }
+    }
+
+    LayerMesh mesh;
+    computeGeometry(hw, &mesh);
+
+    // TODO: we probably want to generate the texture coords with the mesh
+    // here we assume that we only have 4 vertices
+
+    struct TexCoords {
+        GLfloat u;
+        GLfloat v;
+    };
+
+
+    /*
+     * NOTE: the way we compute the texture coordinates here produces
+     * different results than when we take the HWC path -- in the later case
+     * the "source crop" is rounded to texel boundaries.
+     * This can produce significantly different results when the texture
+     * is scaled by a large amount.
+     *
+     * The GL code below is more logical (imho), and the difference with
+     * HWC is due to a limitation of the HWC API to integers -- a question
+     * is suspend is wether we should ignore this problem or revert to
+     * GL composition when a buffer scaling is applied (maybe with some
+     * minimal value)? Or, we could make GL behave like HWC -- but this feel
+     * like more of a hack.
+     */
+    const Rect win(computeBounds());
+
+    GLfloat left   = GLfloat(win.left)   / GLfloat(s.active.w);
+    GLfloat top    = GLfloat(win.top)    / GLfloat(s.active.h);
+    GLfloat right  = GLfloat(win.right)  / GLfloat(s.active.w);
+    GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
+
+    TexCoords texCoords[4];
+    texCoords[0].u = left;
+    texCoords[0].v = top;
+    texCoords[1].u = left;
+    texCoords[1].v = bottom;
+    texCoords[2].u = right;
+    texCoords[2].v = bottom;
+    texCoords[3].u = right;
+    texCoords[3].v = top;
+    for (int i = 0; i < 4; i++) {
+        texCoords[i].v = 1.0f - texCoords[i].v;
+    }
+
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+    glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
+    glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
+
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDisable(GL_BLEND);
+}
+
+void Layer::setFiltering(bool filtering) {
+    mFiltering = filtering;
+}
+
+bool Layer::getFiltering() const {
+    return mFiltering;
+}
+
 // As documented in libhardware header, formats in the range
 // 0x100 - 0x1FF are specific to the HAL implementation, and
 // are known to have no alpha channel
@@ -383,6 +668,29 @@
     return (err || info.h_alpha <= info.l_alpha);
 }
 
+// ----------------------------------------------------------------------------
+// local state
+// ----------------------------------------------------------------------------
+
+void Layer::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
+{
+    const Layer::State& s(drawingState());
+    const Transform tr(hw->getTransform() * s.transform);
+    const uint32_t hw_h = hw->getHeight();
+    Rect win(s.active.w, s.active.h);
+    if (!s.active.crop.isEmpty()) {
+        win.intersect(s.active.crop, &win);
+    }
+    if (mesh) {
+        tr.transform(mesh->mVertices[0], win.left,  win.top);
+        tr.transform(mesh->mVertices[1], win.left,  win.bottom);
+        tr.transform(mesh->mVertices[2], win.right, win.bottom);
+        tr.transform(mesh->mVertices[3], win.right, win.top);
+        for (size_t i=0 ; i<4 ; i++) {
+            mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
+        }
+    }
+}
 
 bool Layer::isOpaque() const
 {
@@ -404,8 +712,39 @@
             (activeBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
 }
 
-uint32_t Layer::doTransaction(uint32_t flags)
-{
+bool Layer::isFixedSize() const {
+    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
+}
+
+bool Layer::isCropped() const {
+    return !mCurrentCrop.isEmpty();
+}
+
+bool Layer::needsFiltering(const sp<const DisplayDevice>& hw) const {
+    return mNeedsFiltering || hw->needsFiltering();
+}
+
+void Layer::setVisibleRegion(const Region& visibleRegion) {
+    // always called from main thread
+    this->visibleRegion = visibleRegion;
+}
+
+void Layer::setCoveredRegion(const Region& coveredRegion) {
+    // always called from main thread
+    this->coveredRegion = coveredRegion;
+}
+
+void Layer::setVisibleNonTransparentRegion(const Region&
+        setVisibleNonTransparentRegion) {
+    // always called from main thread
+    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
+}
+
+// ----------------------------------------------------------------------------
+// transaction
+// ----------------------------------------------------------------------------
+
+uint32_t Layer::doTransaction(uint32_t flags) {
     ATRACE_CALL();
 
     const Layer::State& front(drawingState());
@@ -464,7 +803,7 @@
                                    (temp.requested.h != temp.active.h);
 
         if (resizePending) {
-            // don't let LayerBase::doTransaction update the drawing state
+            // don't let Layer::doTransaction update the drawing state
             // if we have a pending resize, unless we are in fixed-size mode.
             // the drawing state will be updated only once we receive a buffer
             // with the correct size.
@@ -477,15 +816,117 @@
         }
     }
 
-    return LayerBase::doTransaction(flags);
+    // always set active to requested, unless we're asked not to
+    // this is used by Layer, which special cases resizes.
+    if (flags & eDontUpdateGeometryState)  {
+    } else {
+        Layer::State& editTemp(currentState());
+        editTemp.active = temp.requested;
+    }
+
+    if (front.active != temp.active) {
+        // invalidate and recompute the visible regions if needed
+        flags |= Layer::eVisibleRegion;
+    }
+
+    if (temp.sequence != front.sequence) {
+        // invalidate and recompute the visible regions if needed
+        flags |= eVisibleRegion;
+        this->contentDirty = true;
+
+        // we may use linear filtering, if the matrix scales us
+        const uint8_t type = temp.transform.getType();
+        mNeedsFiltering = (!temp.transform.preserveRects() ||
+                (type >= Transform::SCALE));
+    }
+
+    // Commit the transaction
+    commitTransaction();
+    return flags;
 }
 
-bool Layer::isFixedSize() const {
-    return mCurrentScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE;
+void Layer::commitTransaction() {
+    mDrawingState = mCurrentState;
 }
 
-bool Layer::isCropped() const {
-    return !mCurrentCrop.isEmpty();
+uint32_t Layer::getTransactionFlags(uint32_t flags) {
+    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+}
+
+uint32_t Layer::setTransactionFlags(uint32_t flags) {
+    return android_atomic_or(flags, &mTransactionFlags);
+}
+
+bool Layer::setPosition(float x, float y) {
+    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.transform.set(x, y);
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+bool Layer::setLayer(uint32_t z) {
+    if (mCurrentState.z == z)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.z = z;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+bool Layer::setSize(uint32_t w, uint32_t h) {
+    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
+        return false;
+    mCurrentState.requested.w = w;
+    mCurrentState.requested.h = h;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+bool Layer::setAlpha(uint8_t alpha) {
+    if (mCurrentState.alpha == alpha)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.alpha = alpha;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
+    mCurrentState.sequence++;
+    mCurrentState.transform.set(
+            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+bool Layer::setTransparentRegionHint(const Region& transparent) {
+    mCurrentState.sequence++;
+    mCurrentState.transparentRegion = transparent;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+bool Layer::setFlags(uint8_t flags, uint8_t mask) {
+    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
+    if (mCurrentState.flags == newFlags)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.flags = newFlags;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+bool Layer::setCrop(const Rect& crop) {
+    if (mCurrentState.requested.crop == crop)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.requested.crop = crop;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
+}
+
+bool Layer::setLayerStack(uint32_t layerStack) {
+    if (mCurrentState.layerStack == layerStack)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.layerStack = layerStack;
+    setTransactionFlags(eTransactionNeeded);
+    return true;
 }
 
 // ----------------------------------------------------------------------------
@@ -528,7 +969,9 @@
 }
 
 bool Layer::isVisible() const {
-    return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
+    const Layer::State& s(mDrawingState);
+    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha
+            && (mActiveBuffer != NULL);
 }
 
 Region Layer::latchBuffer(bool& recomputeVisibleRegions)
@@ -702,44 +1145,6 @@
     return outDirtyRegion;
 }
 
-void Layer::dump(String8& result, char* buffer, size_t SIZE) const
-{
-    LayerBaseClient::dump(result, buffer, SIZE);
-
-    sp<const GraphicBuffer> buf0(mActiveBuffer);
-    uint32_t w0=0, h0=0, s0=0, f0=0;
-    if (buf0 != 0) {
-        w0 = buf0->getWidth();
-        h0 = buf0->getHeight();
-        s0 = buf0->getStride();
-        f0 = buf0->format;
-    }
-    snprintf(buffer, SIZE,
-            "      "
-            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
-            " queued-frames=%d, mRefreshPending=%d\n",
-            mFormat, w0, h0, s0,f0,
-            mQueuedFrames, mRefreshPending);
-
-    result.append(buffer);
-
-    if (mSurfaceFlingerConsumer != 0) {
-        mSurfaceFlingerConsumer->dump(result, "            ", buffer, SIZE);
-    }
-}
-
-void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
-{
-    LayerBaseClient::dumpStats(result, buffer, SIZE);
-    mFrameTracker.dump(result);
-}
-
-void Layer::clearStats()
-{
-    LayerBaseClient::clearStats();
-    mFrameTracker.clear();
-}
-
 uint32_t Layer::getEffectiveUsage(uint32_t usage) const
 {
     // TODO: should we do something special if mSecure is set?
@@ -766,6 +1171,86 @@
     mSurfaceFlingerConsumer->setTransformHint(orientation);
 }
 
+// ----------------------------------------------------------------------------
+// debugging
+// ----------------------------------------------------------------------------
+
+void Layer::dump(String8& result, char* buffer, size_t SIZE) const
+{
+    const Layer::State& s(drawingState());
+
+    snprintf(buffer, SIZE,
+            "+ %s %p (%s)\n",
+            getTypeId(), this, getName().string());
+    result.append(buffer);
+
+    s.transparentRegion.dump(result, "transparentRegion");
+    visibleRegion.dump(result, "visibleRegion");
+    sp<Client> client(mClientRef.promote());
+
+    snprintf(buffer, SIZE,
+            "      "
+            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
+            "isOpaque=%1d, invalidate=%1d, "
+            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n"
+            "      client=%p\n",
+            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
+            s.active.crop.left, s.active.crop.top,
+            s.active.crop.right, s.active.crop.bottom,
+            isOpaque(), contentDirty,
+            s.alpha, s.flags,
+            s.transform[0][0], s.transform[0][1],
+            s.transform[1][0], s.transform[1][1],
+            client.get());
+    result.append(buffer);
+
+    sp<const GraphicBuffer> buf0(mActiveBuffer);
+    uint32_t w0=0, h0=0, s0=0, f0=0;
+    if (buf0 != 0) {
+        w0 = buf0->getWidth();
+        h0 = buf0->getHeight();
+        s0 = buf0->getStride();
+        f0 = buf0->format;
+    }
+    snprintf(buffer, SIZE,
+            "      "
+            "format=%2d, activeBuffer=[%4ux%4u:%4u,%3X],"
+            " queued-frames=%d, mRefreshPending=%d\n",
+            mFormat, w0, h0, s0,f0,
+            mQueuedFrames, mRefreshPending);
+
+    result.append(buffer);
+
+    if (mSurfaceFlingerConsumer != 0) {
+        mSurfaceFlingerConsumer->dump(result, "            ", buffer, SIZE);
+    }
+}
+
+
+void Layer::shortDump(String8& result, char* scratch, size_t size) const {
+    Layer::dump(result, scratch, size);
+}
+
+void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const {
+    mFrameTracker.dump(result);
+}
+
+void Layer::clearStats() {
+    mFrameTracker.clear();
+}
+
+// ---------------------------------------------------------------------------
+
+Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
+        const sp<Layer>& layer)
+    : mFlinger(flinger), mLayer(layer) {
+}
+
+Layer::LayerCleaner::~LayerCleaner() {
+    // destroy client resources
+    mFlinger->onLayerDestroyed(mLayer);
+}
+
 // ---------------------------------------------------------------------------
 
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index e57fb59..5fb6d8b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -20,118 +20,356 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/Timers.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
-
-#include <gui/ISurfaceComposerClient.h>
-
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
-#include "SurfaceFlingerConsumer.h"
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/Timers.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <ui/Region.h>
+
+#include <gui/ISurfaceComposerClient.h>
+
+#include <private/gui/LayerState.h>
+
 #include "FrameTracker.h"
-#include "LayerBase.h"
+#include "Client.h"
+#include "SurfaceFlinger.h"
+#include "SurfaceFlingerConsumer.h"
 #include "SurfaceTextureLayer.h"
 #include "Transform.h"
 
+#include "DisplayHardware/HWComposer.h"
+
 namespace android {
 
 // ---------------------------------------------------------------------------
 
 class Client;
+class DisplayDevice;
+class GraphicBuffer;
+class SurfaceFlinger;
 class GLExtensions;
 
 // ---------------------------------------------------------------------------
 
 /*
- * The Layer class is essentially a LayerBase combined with a BufferQueue.
  * A new BufferQueue and a new SurfaceFlingerConsumer are created when the
  * Layer is first referenced.
  *
  * This also implements onFrameAvailable(), which notifies SurfaceFlinger
  * that new data has arrived.
  */
-class Layer : public LayerBaseClient,
-              public SurfaceFlingerConsumer::FrameAvailableListener
-{
+class Layer : public SurfaceFlingerConsumer::FrameAvailableListener {
+    static int32_t sSequence;
+
 public:
+    mutable bool contentDirty;
+    // regions below are in window-manager space
+    Region visibleRegion;
+    Region coveredRegion;
+    Region visibleNonTransparentRegion;
+    int32_t sequence;
+
+    enum { // flags for doTransaction()
+        eDontUpdateGeometryState = 0x00000001,
+        eVisibleRegion = 0x00000002,
+    };
+
+    struct Geometry {
+        uint32_t w;
+        uint32_t h;
+        Rect crop;
+        inline bool operator ==(const Geometry& rhs) const {
+            return (w == rhs.w && h == rhs.h && crop == rhs.crop);
+        }
+        inline bool operator !=(const Geometry& rhs) const {
+            return !operator ==(rhs);
+        }
+    };
+
+    struct State {
+        Geometry active;
+        Geometry requested;
+        uint32_t z;
+        uint32_t layerStack;
+        uint8_t alpha;
+        uint8_t flags;
+        uint8_t reserved[2];
+        int32_t sequence; // changes when visible regions can change
+        Transform transform;
+        Region transparentRegion;
+    };
+
+    class LayerMesh {
+        friend class Layer;
+        GLfloat mVertices[4][2];
+        size_t mNumVertices;
+    public:
+        LayerMesh() :
+                mNumVertices(4) {
+        }
+        GLfloat const* getVertices() const {
+            return &mVertices[0][0];
+        }
+        size_t getVertexCount() const {
+            return mNumVertices;
+        }
+    };
+
+    // -----------------------------------------------------------------------
+
     Layer(SurfaceFlinger* flinger, const sp<Client>& client);
     virtual ~Layer();
 
-    virtual const char* getTypeId() const { return "Layer"; }
-
     // the this layer's size and format
     status_t setBuffers(uint32_t w, uint32_t h, 
             PixelFormat format, uint32_t flags=0);
 
-    bool isFixedSize() const;
+    // Creates an ISurface associated with this object.  This may only be
+    // called once. to provide your own ISurface, override createSurface().
+    sp<ISurface> getSurface();
 
-    // LayerBase interface
+    // modify current state
+    bool setPosition(float x, float y);
+    bool setLayer(uint32_t z);
+    bool setSize(uint32_t w, uint32_t h);
+    bool setAlpha(uint8_t alpha);
+    bool setMatrix(const layer_state_t::matrix22_t& matrix);
+    bool setTransparentRegionHint(const Region& transparent);
+    bool setFlags(uint8_t flags, uint8_t mask);
+    bool setCrop(const Rect& crop);
+    bool setLayerStack(uint32_t layerStack);
+
+    void commitTransaction();
+
+    uint32_t getTransactionFlags(uint32_t flags);
+    uint32_t setTransactionFlags(uint32_t flags);
+
+    void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const;
+    Rect computeBounds() const;
+
+    // -----------------------------------------------------------------------
+
+    /*
+     * initStates - called just after construction
+     */
+    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+
+    virtual const char* getTypeId() const { return "Layer"; }
+
+    virtual void setName(const String8& name);
+    String8 getName() const;
+
     virtual void setGeometry(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
     virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
     virtual void setAcquireFence(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface& layer);
+
+    /*
+     * called after page-flip
+     */
     virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw,
             HWComposer::HWCLayerInterface* layer);
+
+    /*
+     * called before composition.
+     * returns true if the layer has pending updates.
+     */
     virtual bool onPreComposition();
+
+    /*
+     *  called after composition.
+     */
     virtual void onPostComposition();
 
+    /*
+     * draw - performs some global clipping optimizations
+     * and calls onDraw().
+     * Typically this method is not overridden, instead implement onDraw()
+     * to perform the actual drawing.
+     */
+    virtual void draw(const sp<const DisplayDevice>& hw, const Region& clip) const;
+    virtual void draw(const sp<const DisplayDevice>& hw);
+
+    /*
+     * onDraw - draws the surface.
+     */
     virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const;
+
+    /*
+     * needsLinearFiltering - true if this surface's state requires filtering
+     */
+    virtual bool needsFiltering(const sp<const DisplayDevice>& hw) const;
+
+    /*
+     * doTransaction - process the transaction. This is a good place to figure
+     * out which attributes of the surface have changed.
+     */
     virtual uint32_t doTransaction(uint32_t transactionFlags);
+
+    /*
+     * setVisibleRegion - called to set the new visible region. This gives
+     * a chance to update the new visible region or record the fact it changed.
+     */
+    virtual void setVisibleRegion(const Region& visibleRegion);
+
+    /*
+     * setCoveredRegion - called when the covered region changes. The covered
+     * region corresponds to any area of the surface that is covered
+     * (transparently or not) by another surface.
+     */
+    virtual void setCoveredRegion(const Region& coveredRegion);
+
+    /*
+     * setVisibleNonTransparentRegion - called when the visible and
+     * non-transparent region changes.
+     */
+    virtual void setVisibleNonTransparentRegion(const Region&
+            visibleNonTransparentRegion);
+
+    /*
+     * latchBuffer - called each time the screen is redrawn and returns whether
+     * the visible regions need to be recomputed (this is a fairly heavy
+     * operation, so this should be set only if needed). Typically this is used
+     * to figure out if the content or size of a surface has changed.
+     */
     virtual Region latchBuffer(bool& recomputeVisibleRegions);
+
+    /*
+     * isOpaque - true if this surface is opaque
+     */
     virtual bool isOpaque() const;
+
+    /*
+     * isSecure - true if this surface is secure, that is if it prevents
+     * screenshots or VNC servers.
+     */
     virtual bool isSecure() const           { return mSecure; }
+
+    /*
+     * isProtected - true if the layer may contain protected content in the
+     * GRALLOC_USAGE_PROTECTED sense.
+     */
     virtual bool isProtected() const;
-    virtual void onRemoved();
-    virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
-    virtual void setName(const String8& name);
+
+    /*
+     * isVisible - true if this layer is visible, false otherwise
+     */
     virtual bool isVisible() const;
 
-    // LayerBaseClient interface
-    virtual wp<IBinder> getSurfaceTextureBinder() const;
+    /*
+     * isFixedSize - true if content has a fixed size
+     */
+    virtual bool isFixedSize() const;
 
-    // only for debugging
-    inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
+    /*
+     * called with the state lock when the surface is removed from the
+     * current list
+     */
+    virtual void onRemoved();
+
+
+    virtual wp<IBinder> getSurfaceTextureBinder() const;
 
     // Updates the transform hint in our SurfaceFlingerConsumer to match
     // the current orientation of the display device.
     virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const;
 
+    /*
+     * returns the rectangle that crops the content of the layer and scales it
+     * to the layer's size.
+     */
     virtual Rect getContentCrop() const;
+
+    /*
+     * returns the transform bits (90 rotation / h-flip / v-flip) of the
+     * layer's content
+     */
     virtual uint32_t getContentTransform() const;
 
-protected:
-    virtual void onFirstRef();
+    // -----------------------------------------------------------------------
+
+    void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
+    void setFiltering(bool filtering);
+    bool getFiltering() const;
+
+    // only for debugging
+    inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
+
+    inline  const State&    drawingState() const    { return mDrawingState; }
+    inline  const State&    currentState() const    { return mCurrentState; }
+    inline  State&          currentState()          { return mCurrentState; }
+
+
+    /* always call base class first */
     virtual void dump(String8& result, char* scratch, size_t size) const;
+    virtual void shortDump(String8& result, char* scratch, size_t size) const;
     virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
     virtual void clearStats();
 
-    sp<SurfaceFlingerConsumer> getConsumer() const {
-        return mSurfaceFlingerConsumer;
-    }
+protected:
+    // constant
+    sp<SurfaceFlinger> mFlinger;
+
+    virtual void onFirstRef();
+
+    /*
+     * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer)
+     * is called.
+     */
+    class LayerCleaner {
+        sp<SurfaceFlinger> mFlinger;
+        wp<Layer> mLayer;
+    protected:
+        ~LayerCleaner();
+    public:
+        LayerCleaner(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer);
+    };
+
 
 private:
     // Creates an instance of ISurface for this Layer.
     virtual sp<ISurface> createSurface();
 
+    // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener
+    virtual void onFrameAvailable();
+
+
     uint32_t getEffectiveUsage(uint32_t usage) const;
+    Rect computeCrop(const sp<const DisplayDevice>& hw) const;
     bool isCropped() const;
     static bool getOpacityForFormat(uint32_t format);
 
-    // Interface implementation for SurfaceFlingerConsumer::FrameAvailableListener
-    virtual void onFrameAvailable();
+    // drawing
+    void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
+            GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const;
+    void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
+
 
     // -----------------------------------------------------------------------
 
     // constants
     sp<SurfaceFlingerConsumer> mSurfaceFlingerConsumer;
     GLuint mTextureName;
+    bool mPremultipliedAlpha;
+    String8 mName;
+    mutable bool mDebug;
+    PixelFormat mFormat;
+    const GLExtensions& mGLExtensions;
+    bool mOpaqueLayer;
+
+    // these are protected by an external lock
+    State mCurrentState;
+    State mDrawingState;
+    volatile int32_t mTransactionFlags;
 
     // thread-safe
     volatile int32_t mQueuedFrames;
@@ -145,15 +383,20 @@
     bool mCurrentOpacity;
     bool mRefreshPending;
     bool mFrameLatencyNeeded;
-
-    // constants
-    PixelFormat mFormat;
-    const GLExtensions& mGLExtensions;
-    bool mOpaqueLayer;
+    // Whether filtering is forced on or not
+    bool mFiltering;
+    // Whether filtering is needed b/c of the drawingstate
+    bool mNeedsFiltering;
 
     // page-flip thread (currently main thread)
-    bool mSecure;         // no screenshots
+    bool mSecure; // no screenshots
     bool mProtectedByApp; // application requires protected path to external sink
+
+    // protected by mLock
+    mutable Mutex mLock;
+    // Set to true if an ISurface has been associated with this object.
+    mutable bool mHasSurface;
+    const wp<Client> mClientRef;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
deleted file mode 100644
index db2b20e..0000000
--- a/services/surfaceflinger/LayerBase.cpp
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <math.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include <hardware/hardware.h>
-
-#include "clz.h"
-#include "Client.h"
-#include "LayerBase.h"
-#include "Layer.h"
-#include "SurfaceFlinger.h"
-#include "DisplayDevice.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-int32_t LayerBase::sSequence = 1;
-
-LayerBase::LayerBase(SurfaceFlinger* flinger)
-    : contentDirty(false),
-      sequence(uint32_t(android_atomic_inc(&sSequence))),
-      mFlinger(flinger), mFiltering(false),
-      mNeedsFiltering(false),
-      mTransactionFlags(0),
-      mPremultipliedAlpha(true), mName("unnamed"), mDebug(false)
-{
-}
-
-LayerBase::~LayerBase()
-{
-}
-
-void LayerBase::setName(const String8& name) {
-    mName = name;
-}
-
-String8 LayerBase::getName() const {
-    return mName;
-}
-
-void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
-{
-    uint32_t layerFlags = 0;
-    if (flags & ISurfaceComposerClient::eHidden)
-        layerFlags = layer_state_t::eLayerHidden;
-
-    if (flags & ISurfaceComposerClient::eNonPremultiplied)
-        mPremultipliedAlpha = false;
-
-    mCurrentState.active.w = w;
-    mCurrentState.active.h = h;
-    mCurrentState.active.crop.makeInvalid();
-    mCurrentState.z = 0;
-    mCurrentState.alpha = 0xFF;
-    mCurrentState.layerStack = 0;
-    mCurrentState.flags = layerFlags;
-    mCurrentState.sequence = 0;
-    mCurrentState.transform.set(0, 0);
-    mCurrentState.requested = mCurrentState.active;
-
-    // drawing state & current state are identical
-    mDrawingState = mCurrentState;
-}
-
-bool LayerBase::needsFiltering(const sp<const DisplayDevice>& hw) const {
-    return mNeedsFiltering || hw->needsFiltering();
-}
-
-void LayerBase::commitTransaction() {
-    mDrawingState = mCurrentState;
-}
-void LayerBase::forceVisibilityTransaction() {
-    // this can be called without SurfaceFlinger.mStateLock, but if we
-    // can atomically increment the sequence number, it doesn't matter.
-    android_atomic_inc(&mCurrentState.sequence);
-    requestTransaction();
-}
-bool LayerBase::requestTransaction() {
-    int32_t old = setTransactionFlags(eTransactionNeeded);
-    return ((old & eTransactionNeeded) == 0);
-}
-uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
-    return android_atomic_and(~flags, &mTransactionFlags) & flags;
-}
-uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
-    return android_atomic_or(flags, &mTransactionFlags);
-}
-
-bool LayerBase::setPosition(float x, float y) {
-    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.transform.set(x, y);
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setLayer(uint32_t z) {
-    if (mCurrentState.z == z)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.z = z;
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setSize(uint32_t w, uint32_t h) {
-    if (mCurrentState.requested.w == w && mCurrentState.requested.h == h)
-        return false;
-    mCurrentState.requested.w = w;
-    mCurrentState.requested.h = h;
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setAlpha(uint8_t alpha) {
-    if (mCurrentState.alpha == alpha)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.alpha = alpha;
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
-    mCurrentState.sequence++;
-    mCurrentState.transform.set(
-            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setTransparentRegionHint(const Region& transparent) {
-    mCurrentState.sequence++;
-    mCurrentState.transparentRegion = transparent;
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
-    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
-    if (mCurrentState.flags == newFlags)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.flags = newFlags;
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setCrop(const Rect& crop) {
-    if (mCurrentState.requested.crop == crop)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.requested.crop = crop;
-    requestTransaction();
-    return true;
-}
-
-bool LayerBase::setLayerStack(uint32_t layerStack) {
-    if (mCurrentState.layerStack == layerStack)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.layerStack = layerStack;
-    requestTransaction();
-    return true;
-}
-
-void LayerBase::setVisibleRegion(const Region& visibleRegion) {
-    // always called from main thread
-    this->visibleRegion = visibleRegion;
-}
-
-void LayerBase::setCoveredRegion(const Region& coveredRegion) {
-    // always called from main thread
-    this->coveredRegion = coveredRegion;
-}
-
-void LayerBase::setVisibleNonTransparentRegion(const Region&
-        setVisibleNonTransparentRegion) {
-    // always called from main thread
-    this->visibleNonTransparentRegion = setVisibleNonTransparentRegion;
-}
-
-uint32_t LayerBase::doTransaction(uint32_t flags)
-{
-    const Layer::State& front(drawingState());
-    const Layer::State& temp(currentState());
-
-    // always set active to requested, unless we're asked not to
-    // this is used by Layer, which special cases resizes.
-    if (flags & eDontUpdateGeometryState)  {
-    } else {
-        Layer::State& editTemp(currentState());
-        editTemp.active = temp.requested;
-    }
-
-    if (front.active != temp.active) {
-        // invalidate and recompute the visible regions if needed
-        flags |= Layer::eVisibleRegion;
-    }
-
-    if (temp.sequence != front.sequence) {
-        // invalidate and recompute the visible regions if needed
-        flags |= eVisibleRegion;
-        this->contentDirty = true;
-
-        // we may use linear filtering, if the matrix scales us
-        const uint8_t type = temp.transform.getType();
-        mNeedsFiltering = (!temp.transform.preserveRects() ||
-                (type >= Transform::SCALE));
-    }
-
-    // Commit the transaction
-    commitTransaction();
-    return flags;
-}
-
-void LayerBase::computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const
-{
-    const Layer::State& s(drawingState());
-    const Transform tr(hw->getTransform() * s.transform);
-    const uint32_t hw_h = hw->getHeight();
-    Rect win(s.active.w, s.active.h);
-    if (!s.active.crop.isEmpty()) {
-        win.intersect(s.active.crop, &win);
-    }
-    if (mesh) {
-        tr.transform(mesh->mVertices[0], win.left,  win.top);
-        tr.transform(mesh->mVertices[1], win.left,  win.bottom);
-        tr.transform(mesh->mVertices[2], win.right, win.bottom);
-        tr.transform(mesh->mVertices[3], win.right, win.top);
-        for (size_t i=0 ; i<4 ; i++) {
-            mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
-        }
-    }
-}
-
-Rect LayerBase::computeBounds() const {
-    const Layer::State& s(drawingState());
-    Rect win(s.active.w, s.active.h);
-    if (!s.active.crop.isEmpty()) {
-        win.intersect(s.active.crop, &win);
-    }
-    return win;
-}
-
-Region LayerBase::latchBuffer(bool& recomputeVisibleRegions) {
-    Region result;
-    return result;
-}
-
-
-Rect LayerBase::getContentCrop() const {
-    // regular layers just use their active area as the content crop
-    const State& s(drawingState());
-    return Rect(s.active.w, s.active.h);
-}
-
-uint32_t LayerBase::getContentTransform() const {
-    // regular layers don't have a content transform
-    return 0;
-}
-
-Rect LayerBase::computeCrop(const sp<const DisplayDevice>& hw) const {
-    /*
-     * The way we compute the crop (aka. texture coordinates when we have a
-     * Layer) produces a different output from the GL code in
-     * drawWithOpenGL() due to HWC being limited to integers. The difference
-     * can be large if getContentTransform() contains a large scale factor.
-     * See comments in drawWithOpenGL() for more details.
-     */
-
-    // the content crop is the area of the content that gets scaled to the
-    // layer's size.
-    Rect crop(getContentCrop());
-
-    // the active.crop is the area of the window that gets cropped, but not
-    // scaled in any ways.
-    const State& s(drawingState());
-
-    // apply the projection's clipping to the window crop in
-    // layerstack space, and convert-back to layer space.
-    // if there are no window scaling (or content scaling) involved,
-    // this operation will map to full pixels in the buffer.
-    // NOTE: should we revert to GL composition if a scaling is involved
-    // since it cannot be represented in the HWC API?
-    Rect activeCrop(s.transform.transform(s.active.crop));
-    activeCrop.intersect(hw->getViewport(), &activeCrop);
-    activeCrop = s.transform.inverse().transform(activeCrop);
-
-    // paranoia: make sure the window-crop is constrained in the
-    // window's bounds
-    activeCrop.intersect(Rect(s.active.w, s.active.h), &activeCrop);
-
-    if (!activeCrop.isEmpty()) {
-        // Transform the window crop to match the buffer coordinate system,
-        // which means using the inverse of the current transform set on the
-        // SurfaceFlingerConsumer.
-        uint32_t invTransform = getContentTransform();
-        int winWidth = s.active.w;
-        int winHeight = s.active.h;
-        if (invTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
-            invTransform ^= NATIVE_WINDOW_TRANSFORM_FLIP_V |
-                    NATIVE_WINDOW_TRANSFORM_FLIP_H;
-            winWidth = s.active.h;
-            winHeight = s.active.w;
-        }
-        const Rect winCrop = activeCrop.transform(
-                invTransform, s.active.w, s.active.h);
-
-        // the code below essentially performs a scaled intersection
-        // of crop and winCrop
-        float xScale = float(crop.width()) / float(winWidth);
-        float yScale = float(crop.height()) / float(winHeight);
-
-        int insetL = int(ceilf( winCrop.left                * xScale));
-        int insetT = int(ceilf( winCrop.top                 * yScale));
-        int insetR = int(ceilf((winWidth  - winCrop.right ) * xScale));
-        int insetB = int(ceilf((winHeight - winCrop.bottom) * yScale));
-
-        crop.left   += insetL;
-        crop.top    += insetT;
-        crop.right  -= insetR;
-        crop.bottom -= insetB;
-    }
-    return crop;
-}
-
-void LayerBase::setGeometry(
-    const sp<const DisplayDevice>& hw,
-        HWComposer::HWCLayerInterface& layer)
-{
-    layer.setDefaultState();
-
-    // this gives us only the "orientation" component of the transform
-    const State& s(drawingState());
-    const uint32_t finalTransform = s.transform.getOrientation();
-    // we can only handle simple transformation
-    if (finalTransform & Transform::ROT_INVALID) {
-        layer.setTransform(0);
-    } else {
-        layer.setTransform(finalTransform);
-    }
-
-    if (!isOpaque() || s.alpha != 0xFF) {
-        layer.setBlending(mPremultipliedAlpha ?
-                HWC_BLENDING_PREMULT :
-                HWC_BLENDING_COVERAGE);
-    }
-
-
-    // apply the layer's transform, followed by the display's global transform
-    // here we're guaranteed that the layer's transform preserves rects
-
-    Rect frame(s.transform.transform(computeBounds()));
-    frame.intersect(hw->getViewport(), &frame);
-    const Transform& tr(hw->getTransform());
-    layer.setFrame(tr.transform(frame));
-    layer.setCrop(computeCrop(hw));
-}
-
-void LayerBase::setPerFrameData(const sp<const DisplayDevice>& hw,
-        HWComposer::HWCLayerInterface& layer) {
-    // we have to set the visible region on every frame because
-    // we currently free it during onLayerDisplayed(), which is called
-    // after HWComposer::commit() -- every frame.
-    // Apply this display's projection's viewport to the visible region
-    // before giving it to the HWC HAL.
-    const Transform& tr = hw->getTransform();
-    Region visible = tr.transform(visibleRegion.intersect(hw->getViewport()));
-    layer.setVisibleRegionScreen(visible);
-}
-
-void LayerBase::setAcquireFence(const sp<const DisplayDevice>& hw,
-        HWComposer::HWCLayerInterface& layer) {
-    layer.setAcquireFenceFd(-1);
-}
-
-void LayerBase::onLayerDisplayed(const sp<const DisplayDevice>& hw,
-        HWComposer::HWCLayerInterface* layer) {
-    if (layer) {
-        layer->onDisplayed();
-    }
-}
-
-void LayerBase::setFiltering(bool filtering)
-{
-    mFiltering = filtering;
-}
-
-bool LayerBase::getFiltering() const
-{
-    return mFiltering;
-}
-
-bool LayerBase::isVisible() const {
-    const Layer::State& s(mDrawingState);
-    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha;
-}
-
-void LayerBase::draw(const sp<const DisplayDevice>& hw, const Region& clip) const
-{
-    onDraw(hw, clip);
-}
-
-void LayerBase::draw(const sp<const DisplayDevice>& hw)
-{
-    onDraw( hw, Region(hw->bounds()) );
-}
-
-void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
-        GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const
-{
-    const uint32_t fbHeight = hw->getHeight();
-    glColor4f(red,green,blue,alpha);
-
-    glDisable(GL_TEXTURE_EXTERNAL_OES);
-    glDisable(GL_TEXTURE_2D);
-    glDisable(GL_BLEND);
-
-    LayerMesh mesh;
-    computeGeometry(hw, &mesh);
-
-    glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
-    glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
-}
-
-void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const
-{
-    clearWithOpenGL(hw, clip, 0,0,0,0);
-}
-
-void LayerBase::drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const
-{
-    const uint32_t fbHeight = hw->getHeight();
-    const State& s(drawingState());
-
-    GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
-    if (CC_UNLIKELY(s.alpha < 0xFF)) {
-        const GLfloat alpha = s.alpha * (1.0f/255.0f);
-        if (mPremultipliedAlpha) {
-            glColor4f(alpha, alpha, alpha, alpha);
-        } else {
-            glColor4f(1, 1, 1, alpha);
-        }
-        glEnable(GL_BLEND);
-        glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-    } else {
-        glColor4f(1, 1, 1, 1);
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        if (!isOpaque()) {
-            glEnable(GL_BLEND);
-            glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
-        } else {
-            glDisable(GL_BLEND);
-        }
-    }
-
-    LayerMesh mesh;
-    computeGeometry(hw, &mesh);
-
-    // TODO: we probably want to generate the texture coords with the mesh
-    // here we assume that we only have 4 vertices
-
-    struct TexCoords {
-        GLfloat u;
-        GLfloat v;
-    };
-
-
-    /*
-     * NOTE: the way we compute the texture coordinates here produces
-     * different results than when we take the HWC path -- in the later case
-     * the "source crop" is rounded to texel boundaries.
-     * This can produce significantly different results when the texture
-     * is scaled by a large amount.
-     *
-     * The GL code below is more logical (imho), and the difference with
-     * HWC is due to a limitation of the HWC API to integers -- a question
-     * is suspend is wether we should ignore this problem or revert to
-     * GL composition when a buffer scaling is applied (maybe with some
-     * minimal value)? Or, we could make GL behave like HWC -- but this feel
-     * like more of a hack.
-     */
-    const Rect win(computeBounds());
-
-    GLfloat left   = GLfloat(win.left)   / GLfloat(s.active.w);
-    GLfloat top    = GLfloat(win.top)    / GLfloat(s.active.h);
-    GLfloat right  = GLfloat(win.right)  / GLfloat(s.active.w);
-    GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h);
-
-    TexCoords texCoords[4];
-    texCoords[0].u = left;
-    texCoords[0].v = top;
-    texCoords[1].u = left;
-    texCoords[1].v = bottom;
-    texCoords[2].u = right;
-    texCoords[2].v = bottom;
-    texCoords[3].u = right;
-    texCoords[3].v = top;
-    for (int i = 0; i < 4; i++) {
-        texCoords[i].v = 1.0f - texCoords[i].v;
-    }
-
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
-    glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
-    glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
-
-    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    glDisable(GL_BLEND);
-}
-
-void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
-{
-    const Layer::State& s(drawingState());
-
-    snprintf(buffer, SIZE,
-            "+ %s %p (%s)\n",
-            getTypeId(), this, getName().string());
-    result.append(buffer);
-
-    s.transparentRegion.dump(result, "transparentRegion");
-    visibleRegion.dump(result, "visibleRegion");
-
-    snprintf(buffer, SIZE,
-            "      "
-            "layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), crop=(%4d,%4d,%4d,%4d), "
-            "isOpaque=%1d, needsDithering=%1d, invalidate=%1d, "
-            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
-            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
-            s.active.crop.left, s.active.crop.top,
-            s.active.crop.right, s.active.crop.bottom,
-            isOpaque(), needsDithering(), contentDirty,
-            s.alpha, s.flags,
-            s.transform[0][0], s.transform[0][1],
-            s.transform[1][0], s.transform[1][1]);
-    result.append(buffer);
-}
-
-void LayerBase::shortDump(String8& result, char* scratch, size_t size) const {
-    LayerBase::dump(result, scratch, size);
-}
-
-void LayerBase::dumpStats(String8& result, char* scratch, size_t SIZE) const {
-}
-
-void LayerBase::clearStats() {
-}
-
-sp<LayerBaseClient> LayerBase::getLayerBaseClient() const {
-    return 0;
-}
-
-sp<Layer> LayerBase::getLayer() const {
-    return 0;
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger,
-        const sp<Client>& client)
-    : LayerBase(flinger),
-      mHasSurface(false),
-      mClientRef(client)
-{
-}
-
-LayerBaseClient::~LayerBaseClient()
-{
-    sp<Client> c(mClientRef.promote());
-    if (c != 0) {
-        c->detachLayer(this);
-    }
-}
-
-sp<ISurface> LayerBaseClient::createSurface()
-{
-    class BSurface : public BnSurface, public LayerCleaner {
-        virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { return 0; }
-    public:
-        BSurface(const sp<SurfaceFlinger>& flinger,
-                const sp<LayerBaseClient>& layer)
-            : LayerCleaner(flinger, layer) { }
-    };
-    sp<ISurface> sur(new BSurface(mFlinger, this));
-    return sur;
-}
-
-sp<ISurface> LayerBaseClient::getSurface()
-{
-    sp<ISurface> s;
-    Mutex::Autolock _l(mLock);
-
-    LOG_ALWAYS_FATAL_IF(mHasSurface,
-            "LayerBaseClient::getSurface() has already been called");
-
-    mHasSurface = true;
-    s = createSurface();
-    mClientSurfaceBinder = s->asBinder();
-    return s;
-}
-
-wp<IBinder> LayerBaseClient::getSurfaceBinder() const {
-    return mClientSurfaceBinder;
-}
-
-wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const {
-    return 0;
-}
-
-void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
-{
-    LayerBase::dump(result, buffer, SIZE);
-    sp<Client> client(mClientRef.promote());
-    snprintf(buffer, SIZE, "      client=%p\n", client.get());
-    result.append(buffer);
-}
-
-
-void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
-{
-    LayerBaseClient::dump(result, scratch, size);
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBaseClient::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
-        const sp<LayerBaseClient>& layer)
-    : mFlinger(flinger), mLayer(layer) {
-}
-
-LayerBaseClient::LayerCleaner::~LayerCleaner() {
-    // destroy client resources
-    mFlinger->onLayerDestroyed(mLayer);
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
deleted file mode 100644
index ecae2d9..0000000
--- a/services/surfaceflinger/LayerBase.h
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_LAYER_BASE_H
-#define ANDROID_LAYER_BASE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES/gl.h>
-
-#include <utils/RefBase.h>
-#include <utils/String8.h>
-
-#include <ui/Region.h>
-
-#include <gui/ISurfaceComposerClient.h>
-
-#include <private/gui/LayerState.h>
-
-#include "Transform.h"
-#include "DisplayHardware/HWComposer.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class Client;
-class DisplayDevice;
-class GraphicBuffer;
-class Layer;
-class LayerBaseClient;
-class SurfaceFlinger;
-
-// ---------------------------------------------------------------------------
-
-/*
- * Layers are rectangular graphic entities, internal to SurfaceFlinger.
- * They have properties including width, height, Z-depth, and 2D
- * transformations (chiefly translation and 90-degree rotations).
- *
- * Layers are organized into "layer stacks".  Each layer is a member of
- * exactly one layer stack, identified by an integer in Layer::State.  A
- * given layer stack may appear on more than one display.
- *
- * Notable subclasses (below LayerBaseClient) include Layer, LayerDim, and
- * LayerScreenshot.
- */
-class LayerBase : virtual public RefBase
-{
-    static int32_t sSequence;
-
-public:
-            LayerBase(SurfaceFlinger* flinger);
-
-    mutable bool        contentDirty;
-            // regions below are in window-manager space
-            Region      visibleRegion;
-            Region      coveredRegion;
-            Region      visibleNonTransparentRegion;
-            int32_t     sequence;
-            
-            struct Geometry {
-                uint32_t w;
-                uint32_t h;
-                Rect crop;
-                inline bool operator == (const Geometry& rhs) const {
-                    return (w==rhs.w && h==rhs.h && crop==rhs.crop);
-                }
-                inline bool operator != (const Geometry& rhs) const {
-                    return !operator == (rhs);
-                }
-            };
-
-            struct State {
-                Geometry        active;
-                Geometry        requested;
-                uint32_t        z;
-                uint32_t        layerStack;
-                uint8_t         alpha;
-                uint8_t         flags;
-                uint8_t         reserved[2];
-                int32_t         sequence;   // changes when visible regions can change
-                Transform       transform;
-                Region          transparentRegion;
-            };
-
-            class LayerMesh {
-                friend class LayerBase;
-                GLfloat mVertices[4][2];
-                size_t mNumVertices;
-            public:
-                LayerMesh() : mNumVertices(4) { }
-                GLfloat const* getVertices() const {
-                    return &mVertices[0][0];
-                }
-                size_t getVertexCount() const {
-                    return mNumVertices;
-                }
-            };
-
-    virtual void setName(const String8& name);
-            String8 getName() const;
-
-            // modify current state
-            bool setPosition(float x, float y);
-            bool setLayer(uint32_t z);
-            bool setSize(uint32_t w, uint32_t h);
-            bool setAlpha(uint8_t alpha);
-            bool setMatrix(const layer_state_t::matrix22_t& matrix);
-            bool setTransparentRegionHint(const Region& transparent);
-            bool setFlags(uint8_t flags, uint8_t mask);
-            bool setCrop(const Rect& crop);
-            bool setLayerStack(uint32_t layerStack);
-
-            void commitTransaction();
-            bool requestTransaction();
-            void forceVisibilityTransaction();
-            
-            uint32_t getTransactionFlags(uint32_t flags);
-            uint32_t setTransactionFlags(uint32_t flags);
-
-            void computeGeometry(const sp<const DisplayDevice>& hw, LayerMesh* mesh) const;
-            Rect computeBounds() const;
-
-
-    virtual sp<LayerBaseClient> getLayerBaseClient() const;
-    virtual sp<Layer> getLayer() const;
-
-    virtual const char* getTypeId() const { return "LayerBase"; }
-
-    virtual void setGeometry(const sp<const DisplayDevice>& hw,
-            HWComposer::HWCLayerInterface& layer);
-    virtual void setPerFrameData(const sp<const DisplayDevice>& hw,
-            HWComposer::HWCLayerInterface& layer);
-    virtual void setAcquireFence(const sp<const DisplayDevice>& hw,
-            HWComposer::HWCLayerInterface& layer);
-
-    /**
-     * draw - performs some global clipping optimizations
-     * and calls onDraw().
-     * Typically this method is not overridden, instead implement onDraw()
-     * to perform the actual drawing.  
-     */
-    virtual void draw(const sp<const DisplayDevice>& hw, const Region& clip) const;
-    virtual void draw(const sp<const DisplayDevice>& hw);
-    
-    /**
-     * onDraw - draws the surface.
-     */
-    virtual void onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const = 0;
-    
-    /**
-     * initStates - called just after construction
-     */
-    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
-    
-    /**
-     * doTransaction - process the transaction. This is a good place to figure
-     * out which attributes of the surface have changed.
-     */
-    virtual uint32_t doTransaction(uint32_t transactionFlags);
-    
-    /**
-     * setVisibleRegion - called to set the new visible region. This gives
-     * a chance to update the new visible region or record the fact it changed.
-     */
-    virtual void setVisibleRegion(const Region& visibleRegion);
-    
-    /**
-     * setCoveredRegion - called when the covered region changes. The covered
-     * region corresponds to any area of the surface that is covered
-     * (transparently or not) by another surface.
-     */
-    virtual void setCoveredRegion(const Region& coveredRegion);
-
-    /**
-     * setVisibleNonTransparentRegion - called when the visible and
-     * non-transparent region changes.
-     */
-    virtual void setVisibleNonTransparentRegion(const Region&
-            visibleNonTransparentRegion);
-
-    /**
-     * latchBuffer - called each time the screen is redrawn and returns whether
-     * the visible regions need to be recomputed (this is a fairly heavy
-     * operation, so this should be set only if needed). Typically this is used
-     * to figure out if the content or size of a surface has changed.
-     */
-    virtual Region latchBuffer(bool& recomputeVisibleRegions);
-
-    /**
-     * isOpaque - true if this surface is opaque
-     */
-    virtual bool isOpaque() const  { return true; }
-
-    /**
-     * needsDithering - true if this surface needs dithering
-     */
-    virtual bool needsDithering() const { return false; }
-
-    /**
-     * needsLinearFiltering - true if this surface's state requires filtering
-     */
-    virtual bool needsFiltering(const sp<const DisplayDevice>& hw) const;
-
-    /**
-     * isSecure - true if this surface is secure, that is if it prevents
-     * screenshots or VNC servers.
-     */
-    virtual bool isSecure() const       { return false; }
-
-    /**
-     * isProtected - true if the layer may contain protected content in the
-     * GRALLOC_USAGE_PROTECTED sense.
-     */
-    virtual bool isProtected() const   { return false; }
-
-    /*
-     * isVisible - true if this layer is visibile, false otherwise
-     */
-    virtual bool isVisible() const;
-
-    /** called with the state lock when the surface is removed from the
-     *  current list */
-    virtual void onRemoved() { }
-
-    /** called after page-flip
-     */
-    virtual void onLayerDisplayed(const sp<const DisplayDevice>& hw,
-            HWComposer::HWCLayerInterface* layer);
-
-    /** called before composition.
-     * returns true if the layer has pending updates.
-     */
-    virtual bool onPreComposition() { return false; }
-
-    /** called before composition.
-     */
-    virtual void onPostComposition() { }
-
-    /**
-     * Updates the GLConsumer's transform hint, for layers that have
-     * a GLConsumer.
-     */
-    virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const { }
-
-    /**
-     * returns the rectangle that crops the content of the layer and scales it
-     * to the layer's size.
-     */
-    virtual Rect getContentCrop() const;
-
-    /*
-     * returns the transform bits (90 rotation / h-flip / v-flip) of the
-     * layer's content
-     */
-    virtual uint32_t getContentTransform() const;
-
-    /** always call base class first */
-    virtual void dump(String8& result, char* scratch, size_t size) const;
-    virtual void shortDump(String8& result, char* scratch, size_t size) const;
-    virtual void dumpStats(String8& result, char* buffer, size_t SIZE) const;
-    virtual void clearStats();
-
-
-    enum { // flags for doTransaction()
-        eDontUpdateGeometryState = 0x00000001,
-        eVisibleRegion           = 0x00000002,
-    };
-
-
-    inline  const State&    drawingState() const    { return mDrawingState; }
-    inline  const State&    currentState() const    { return mCurrentState; }
-    inline  State&          currentState()          { return mCurrentState; }
-
-    void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
-
-    void setFiltering(bool filtering);
-    bool getFiltering() const;
-
-private:
-    Rect computeCrop(const sp<const DisplayDevice>& hw) const;
-
-protected:
-          void clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip,
-                  GLclampf r, GLclampf g, GLclampf b, GLclampf alpha) const;
-          void drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const;
-
-                sp<SurfaceFlinger> mFlinger;
-
-private:
-                // accessed only in the main thread
-                // Whether filtering is forced on or not
-                bool            mFiltering;
-
-                // Whether filtering is needed b/c of the drawingstate
-                bool            mNeedsFiltering;
-
-protected:
-                // these are protected by an external lock
-                State           mCurrentState;
-                State           mDrawingState;
-    volatile    int32_t         mTransactionFlags;
-
-                // don't change, don't need a lock
-                bool            mPremultipliedAlpha;
-                String8         mName;
-    mutable     bool            mDebug;
-
-
-public:
-    // called from class SurfaceFlinger
-    virtual ~LayerBase();
-
-private:
-    LayerBase(const LayerBase& rhs);
-};
-
-
-// ---------------------------------------------------------------------------
-
-/*
- * This adds some additional fields and methods to support some Binder IPC
- * interactions.  In particular, the LayerBaseClient's lifetime can be
- * managed by references to an ISurface object in another process.
- */
-class LayerBaseClient : public LayerBase
-{
-public:
-    LayerBaseClient(SurfaceFlinger* flinger, const sp<Client>& client);
-
-    virtual ~LayerBaseClient();
-
-    // Creates an ISurface associated with this object.  This may only be
-    // called once (see also getSurfaceBinder()).
-    sp<ISurface> getSurface();
-
-    // Returns the Binder object for the ISurface associated with
-    // this object.
-    wp<IBinder> getSurfaceBinder() const;
-
-    virtual wp<IBinder> getSurfaceTextureBinder() const;
-
-    virtual sp<LayerBaseClient> getLayerBaseClient() const {
-        return const_cast<LayerBaseClient*>(this); }
-
-    virtual const char* getTypeId() const { return "LayerBaseClient"; }
-
-protected:
-    virtual void dump(String8& result, char* scratch, size_t size) const;
-    virtual void shortDump(String8& result, char* scratch, size_t size) const;
-
-    /*
-     * Trivial class, used to ensure that mFlinger->onLayerDestroyed(mLayer)
-     * is called.
-     */
-    class LayerCleaner {
-        sp<SurfaceFlinger> mFlinger;
-        wp<LayerBaseClient> mLayer;
-    protected:
-        ~LayerCleaner();
-    public:
-        LayerCleaner(const sp<SurfaceFlinger>& flinger,
-                const sp<LayerBaseClient>& layer);
-    };
-
-private:
-    virtual sp<ISurface> createSurface();
-
-    mutable Mutex mLock;
-
-    // Set to true if an ISurface has been associated with this object.
-    mutable bool mHasSurface;
-
-    // The ISurface's Binder object, set by getSurface().
-    wp<IBinder> mClientSurfaceBinder;
-
-    const wp<Client> mClientRef;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BASE_H
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index 25caa0a..23decff 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -34,12 +34,10 @@
 // ---------------------------------------------------------------------------
 
 LayerDim::LayerDim(SurfaceFlinger* flinger, const sp<Client>& client)
-    : LayerBaseClient(flinger, client)
-{
+    : Layer(flinger, client) {
 }
 
-LayerDim::~LayerDim()
-{
+LayerDim::~LayerDim() {
 }
 
 void LayerDim::onDraw(const sp<const DisplayDevice>& hw, const Region& clip) const
@@ -71,6 +69,25 @@
     }
 }
 
+sp<ISurface> LayerDim::createSurface()
+{
+    class BSurface : public BnSurface, public LayerCleaner {
+        virtual sp<IGraphicBufferProducer> getSurfaceTexture() const { return 0; }
+    public:
+        BSurface(const sp<SurfaceFlinger>& flinger,
+                const sp<Layer>& layer)
+            : LayerCleaner(flinger, layer) { }
+    };
+    sp<ISurface> sur(new BSurface(mFlinger, this));
+    return sur;
+}
+
+bool LayerDim::isVisible() const {
+    const Layer::State& s(drawingState());
+    return !(s.flags & layer_state_t::eLayerHidden) && s.alpha;
+}
+
+
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index 06f312d..e1ea9bd 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -23,13 +23,13 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include "LayerBase.h"
+#include "Layer.h"
 
 // ---------------------------------------------------------------------------
 
 namespace android {
 
-class LayerDim : public LayerBaseClient
+class LayerDim : public Layer
 {
 public:    
                 LayerDim(SurfaceFlinger* flinger, const sp<Client>& client);
@@ -41,6 +41,10 @@
     virtual bool isProtectedByApp() const { return false; }
     virtual bool isProtectedByDRM() const { return false; }
     virtual const char* getTypeId() const { return "LayerDim"; }
+
+    virtual bool isFixedSize() const      { return true; }
+    virtual bool isVisible() const;
+    virtual sp<ISurface> createSurface();
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
deleted file mode 100644
index 3470d67..0000000
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "LayerScreenshot.h"
-#include "SurfaceFlinger.h"
-#include "DisplayDevice.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger,
-        const sp<Client>& client)
-    : Layer(flinger, client)
-{
-}
-
-void LayerScreenshot::onFirstRef()
-{
-    Layer::onFirstRef();
-
-    // FIXME: we currently hardcode the default display
-    // it's unclear what should we do instead.
-    sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
-    mFlinger->captureScreenImplLocked(hw, getConsumer()->getBufferQueue(),
-            0, 0, 0, 0x7FFFFFFF);
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/services/surfaceflinger/LayerScreenshot.h b/services/surfaceflinger/LayerScreenshot.h
deleted file mode 100644
index a2ae03f..0000000
--- a/services/surfaceflinger/LayerScreenshot.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_LAYER_SCREENSHOT_H
-#define ANDROID_LAYER_SCREENSHOT_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "Layer.h"
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-class LayerScreenshot : public Layer
-{
-public:    
-    LayerScreenshot(SurfaceFlinger* flinger, const sp<Client>& client);
-protected:
-    virtual void onFirstRef();
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_SCREENSHOT_H
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a0d2827..5939dc8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -62,7 +62,6 @@
 #include "GLExtensions.h"
 #include "Layer.h"
 #include "LayerDim.h"
-#include "LayerScreenshot.h"
 #include "SurfaceFlinger.h"
 
 #include "DisplayHardware/FramebufferSurface.h"
@@ -581,17 +580,14 @@
     const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
     size_t count = currentLayers.size();
     for (size_t i=0 ; i<count ; i++) {
-        const sp<LayerBase>& layer(currentLayers[i]);
-        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
-        if (lbc != NULL) {
-            // If this is an instance of Layer (as opposed to, say, LayerDim),
-            // we will get the consumer interface of SurfaceFlingerConsumer's
-            // BufferQueue.  If it's the same Binder object as the graphic
-            // buffer producer interface, return success.
-            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
-            if (lbcBinder == surfaceTextureBinder) {
-                return true;
-            }
+        const sp<Layer>& layer(currentLayers[i]);
+        // If this is an instance of Layer (as opposed to, say, LayerDim),
+        // we will get the consumer interface of SurfaceFlingerConsumer's
+        // BufferQueue.  If it's the same Binder object as the graphic
+        // buffer producer interface, return success.
+        wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder();
+        if (lbcBinder == surfaceTextureBinder) {
+            return true;
         }
     }
 
@@ -604,13 +600,10 @@
     // should not cause any harm.
     size_t purgatorySize =  mLayerPurgatory.size();
     for (size_t i=0 ; i<purgatorySize ; i++) {
-        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
-        sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
-        if (lbc != NULL) {
-            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
-            if (lbcBinder == surfaceTextureBinder) {
-                return true;
-            }
+        const sp<Layer>& layer(mLayerPurgatory.itemAt(i));
+        wp<IBinder> lbcBinder = layer->getSurfaceTextureBinder();
+        if (lbcBinder == surfaceTextureBinder) {
+            return true;
         }
     }
 
@@ -915,7 +908,7 @@
         for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
             Region opaqueRegion;
             Region dirtyRegion;
-            Vector< sp<LayerBase> > layersSortedByZ;
+            Vector< sp<Layer> > layersSortedByZ;
             const sp<DisplayDevice>& hw(mDisplays[dpy]);
             const Transform& tr(hw->getTransform());
             const Rect bounds(hw->getBounds());
@@ -925,7 +918,7 @@
 
                 const size_t count = currentLayers.size();
                 for (size_t i=0 ; i<count ; i++) {
-                    const sp<LayerBase>& layer(currentLayers[i]);
+                    const sp<Layer>& layer(currentLayers[i]);
                     const Layer::State& s(layer->drawingState());
                     if (s.layerStack == hw->getLayerStack()) {
                         Region drawRegion(tr.transform(
@@ -955,14 +948,14 @@
                 sp<const DisplayDevice> hw(mDisplays[dpy]);
                 const int32_t id = hw->getHwcDisplayId();
                 if (id >= 0) {
-                    const Vector< sp<LayerBase> >& currentLayers(
+                    const Vector< sp<Layer> >& currentLayers(
                         hw->getVisibleLayersSortedByZ());
                     const size_t count = currentLayers.size();
                     if (hwc.createWorkList(id, count) == NO_ERROR) {
                         HWComposer::LayerListIterator cur = hwc.begin(id);
                         const HWComposer::LayerListIterator end = hwc.end(id);
                         for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
-                            const sp<LayerBase>& layer(currentLayers[i]);
+                            const sp<Layer>& layer(currentLayers[i]);
                             layer->setGeometry(hw, *cur);
                             if (mDebugDisableHWC || mDebugRegion) {
                                 cur->setSkip(true);
@@ -978,7 +971,7 @@
             sp<const DisplayDevice> hw(mDisplays[dpy]);
             const int32_t id = hw->getHwcDisplayId();
             if (id >= 0) {
-                const Vector< sp<LayerBase> >& currentLayers(
+                const Vector< sp<Layer> >& currentLayers(
                     hw->getVisibleLayersSortedByZ());
                 const size_t count = currentLayers.size();
                 HWComposer::LayerListIterator cur = hwc.begin(id);
@@ -988,7 +981,7 @@
                      * update the per-frame h/w composer data for each layer
                      * and build the transparent region of the FB
                      */
-                    const sp<LayerBase>& layer(currentLayers[i]);
+                    const sp<Layer>& layer(currentLayers[i]);
                     layer->setPerFrameData(hw, *cur);
                 }
             }
@@ -1042,7 +1035,7 @@
 
     for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
         sp<const DisplayDevice> hw(mDisplays[dpy]);
-        const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
+        const Vector< sp<Layer> >& currentLayers(hw->getVisibleLayersSortedByZ());
         hw->onSwapBuffersCompleted(hwc);
         const size_t count = currentLayers.size();
         int32_t id = hw->getHwcDisplayId();
@@ -1098,7 +1091,7 @@
 
     if (transactionFlags & eTraversalNeeded) {
         for (size_t i=0 ; i<count ; i++) {
-            const sp<LayerBase>& layer(currentLayers[i]);
+            const sp<Layer>& layer(currentLayers[i]);
             uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
             if (!trFlags) continue;
 
@@ -1245,8 +1238,8 @@
             // NOTE: we rely on the fact that layers are sorted by
             // layerStack first (so we don't have to traverse the list
             // of displays for every layer).
-            const sp<LayerBase>& layerBase(currentLayers[i]);
-            uint32_t layerStack = layerBase->drawingState().layerStack;
+            const sp<Layer>& layer(currentLayers[i]);
+            uint32_t layerStack = layer->drawingState().layerStack;
             if (i==0 || currentlayerStack != layerStack) {
                 currentlayerStack = layerStack;
                 // figure out if this layerstack is mirrored
@@ -1268,7 +1261,7 @@
             if (disp != NULL) {
                 // presumably this means this layer is using a layerStack
                 // that is not visible on any display
-                layerBase->updateTransformHint(disp);
+                layer->updateTransformHint(disp);
             }
         }
     }
@@ -1291,7 +1284,7 @@
         mVisibleRegionsDirty = true;
         const size_t count = previousLayers.size();
         for (size_t i=0 ; i<count ; i++) {
-            const sp<LayerBase>& layer(previousLayers[i]);
+            const sp<Layer>& layer(previousLayers[i]);
             if (currentLayers.indexOf(layer) < 0) {
                 // this layer is not visible anymore
                 // TODO: we could traverse the tree from front to back and
@@ -1342,7 +1335,7 @@
 
     size_t i = currentLayers.size();
     while (i--) {
-        const sp<LayerBase>& layer = currentLayers[i];
+        const sp<Layer>& layer = currentLayers[i];
 
         // start with the whole surface at its current location
         const Layer::State& s(layer->drawingState());
@@ -1485,7 +1478,7 @@
     const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
     const size_t count = currentLayers.size();
     for (size_t i=0 ; i<count ; i++) {
-        const sp<LayerBase>& layer(currentLayers[i]);
+        const sp<Layer>& layer(currentLayers[i]);
         const Region dirty(layer->latchBuffer(visibleRegions));
         const Layer::State& s(layer->drawingState());
         invalidateLayerStack(s.layerStack, dirty);
@@ -1607,13 +1600,13 @@
      * and then, render the layers targeted at the framebuffer
      */
 
-    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
+    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
     const size_t count = layers.size();
     const Transform& tr = hw->getTransform();
     if (cur != end) {
         // we're using h/w composer
         for (size_t i=0 ; i<count && cur!=end ; ++i, ++cur) {
-            const sp<LayerBase>& layer(layers[i]);
+            const sp<Layer>& layer(layers[i]);
             const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
             if (!clip.isEmpty()) {
                 switch (cur->getCompositionType()) {
@@ -1645,7 +1638,7 @@
     } else {
         // we're not using h/w composer
         for (size_t i=0 ; i<count ; ++i) {
-            const sp<LayerBase>& layer(layers[i]);
+            const sp<Layer>& layer(layers[i]);
             const Region clip(dirty.intersect(
                     tr.transform(layer->visibleRegion)));
             if (!clip.isEmpty()) {
@@ -1684,7 +1677,7 @@
 
 void SurfaceFlinger::addClientLayer(const sp<Client>& client,
         const sp<IBinder>& handle,
-        const sp<LayerBaseClient>& lbc)
+        const sp<Layer>& lbc)
 {
     // attach this layer to the client
     client->attachLayer(handle, lbc);
@@ -1694,7 +1687,7 @@
     mCurrentState.layersSortedByZ.add(lbc);
 }
 
-status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer)
 {
     Mutex::Autolock _l(mStateLock);
     status_t err = purgatorizeLayer_l(layer);
@@ -1703,9 +1696,9 @@
     return err;
 }
 
-status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
+status_t SurfaceFlinger::removeLayer_l(const sp<Layer>& layer)
 {
-    ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
+    ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
     if (index >= 0) {
         mLayersRemoved = true;
         return NO_ERROR;
@@ -1713,16 +1706,16 @@
     return status_t(index);
 }
 
-status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
+status_t SurfaceFlinger::purgatorizeLayer_l(const sp<Layer>& layer)
 {
     // First add the layer to the purgatory list, which makes sure it won't
     // go away, then remove it from the main list (through a transaction).
-    ssize_t err = removeLayer_l(layerBase);
+    ssize_t err = removeLayer_l(layer);
     if (err >= 0) {
-        mLayerPurgatory.add(layerBase);
+        mLayerPurgatory.add(layer);
     }
 
-    mLayersPendingRemoval.push(layerBase);
+    mLayersPendingRemoval.push(layer);
 
     // it's possible that we don't find a layer, because it might
     // have been destroyed already -- this is not technically an error
@@ -1873,7 +1866,7 @@
         const layer_state_t& s)
 {
     uint32_t flags = 0;
-    sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
+    sp<Layer> layer(client->getLayerUser(s.surface));
     if (layer != 0) {
         const uint32_t what = s.what;
         if (what & layer_state_t::ePositionChanged) {
@@ -1937,7 +1930,7 @@
         uint32_t w, uint32_t h, PixelFormat format,
         uint32_t flags)
 {
-    sp<LayerBaseClient> layer;
+    sp<Layer> layer;
     sp<ISurface> surfaceHandle;
 
     if (int32_t(w|h) < 0) {
@@ -1951,13 +1944,9 @@
         case ISurfaceComposerClient::eFXSurfaceNormal:
             layer = createNormalLayer(client, w, h, flags, format);
             break;
-        case ISurfaceComposerClient::eFXSurfaceBlur:
         case ISurfaceComposerClient::eFXSurfaceDim:
             layer = createDimLayer(client, w, h, flags);
             break;
-        case ISurfaceComposerClient::eFXSurfaceScreenshot:
-            layer = createScreenshotLayer(client, w, h, flags);
-            break;
     }
 
     if (layer != 0) {
@@ -2015,15 +2004,6 @@
     return layer;
 }
 
-sp<LayerScreenshot> SurfaceFlinger::createScreenshotLayer(
-        const sp<Client>& client,
-        uint32_t w, uint32_t h, uint32_t flags)
-{
-    sp<LayerScreenshot> layer = new LayerScreenshot(this, client);
-    layer->setBuffers(w, h, PIXEL_FORMAT_RGBA_8888, flags);
-    return layer;
-}
-
 status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
 {
     /*
@@ -2037,7 +2017,7 @@
 
     status_t err = NAME_NOT_FOUND;
     Mutex::Autolock _l(mStateLock);
-    sp<LayerBaseClient> layer = client->getLayerUser(handle);
+    sp<Layer> layer = client->getLayerUser(handle);
 
     if (layer != 0) {
         err = purgatorizeLayer_l(layer);
@@ -2048,11 +2028,11 @@
     return err;
 }
 
-status_t SurfaceFlinger::onLayerDestroyed(const wp<LayerBaseClient>& layer)
+status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
 {
     // called by ~ISurface() when all references are gone
     status_t err = NO_ERROR;
-    sp<LayerBaseClient> l(layer.promote());
+    sp<Layer> l(layer.promote());
     if (l != NULL) {
         Mutex::Autolock _l(mStateLock);
         err = removeLayer_l(l);
@@ -2269,7 +2249,7 @@
     const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
     const size_t count = currentLayers.size();
     for (size_t i=0 ; i<count ; i++) {
-        const sp<LayerBase>& layer(currentLayers[i]);
+        const sp<Layer>& layer(currentLayers[i]);
         snprintf(buffer, SIZE, "%s\n", layer->getName().string());
         result.append(buffer);
     }
@@ -2294,7 +2274,7 @@
         const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
         const size_t count = currentLayers.size();
         for (size_t i=0 ; i<count ; i++) {
-            const sp<LayerBase>& layer(currentLayers[i]);
+            const sp<Layer>& layer(currentLayers[i]);
             if (name == layer->getName()) {
                 layer->dumpStats(result, buffer, SIZE);
             }
@@ -2314,7 +2294,7 @@
     const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
     const size_t count = currentLayers.size();
     for (size_t i=0 ; i<count ; i++) {
-        const sp<LayerBase>& layer(currentLayers[i]);
+        const sp<Layer>& layer(currentLayers[i]);
         if (name.isEmpty() || (name == layer->getName())) {
             layer->clearStats();
         }
@@ -2370,7 +2350,7 @@
     snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
     result.append(buffer);
     for (size_t i=0 ; i<count ; i++) {
-        const sp<LayerBase>& layer(currentLayers[i]);
+        const sp<Layer>& layer(currentLayers[i]);
         layer->dump(result, buffer, SIZE);
     }
 
@@ -2382,7 +2362,7 @@
     snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
     result.append(buffer);
     for (size_t i=0 ; i<purgatorySize ; i++) {
-        const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+        const sp<Layer>& layer(mLayerPurgatory.itemAt(i));
         layer->shortDump(result, buffer, SIZE);
     }
 
@@ -2471,7 +2451,7 @@
     alloc.dump(result);
 }
 
-const Vector< sp<LayerBase> >&
+const Vector< sp<Layer> >&
 SurfaceFlinger::getLayerSortedByZForHwcDisplay(int disp) {
     // Note: mStateLock is held here
     return getDisplayDevice( getBuiltInDisplay(disp) )->getVisibleLayersSortedByZ();
@@ -2728,10 +2708,10 @@
     glClearColor(0,0,0,1);
     glClear(GL_COLOR_BUFFER_BIT);
 
-    const Vector< sp<LayerBase> >& layers(hw->getVisibleLayersSortedByZ());
+    const Vector< sp<Layer> >& layers(hw->getVisibleLayersSortedByZ());
     const size_t count = layers.size();
     for (size_t i=0 ; i<count ; ++i) {
-        const sp<LayerBase>& layer(layers[i]);
+        const sp<Layer>& layer(layers[i]);
         const uint32_t z = layer->drawingState().z;
         if (z >= minLayerZ && z <= maxLayerZ) {
             if (filtering) layer->setFiltering(true);
@@ -2740,6 +2720,9 @@
         }
     }
 
+    // compositionComplete is needed for older driver
+    hw->compositionComplete();
+
     // and finishing things up...
     if (eglSwapBuffers(mEGLDisplay, eglSurface) != EGL_TRUE) {
         ALOGE("captureScreenImplLocked: eglSwapBuffers() failed 0x%4x",
@@ -2830,6 +2813,9 @@
 
     glDeleteTextures(1, &tname);
 
+    DisplayDevice::makeCurrent(mEGLDisplay,
+            getDefaultDisplayDevice(), mEGLContext);
+
     return result;
 }
 
@@ -2896,15 +2882,15 @@
 }
 
 SurfaceFlinger::LayerVector::LayerVector(const LayerVector& rhs)
-    : SortedVector<sp<LayerBase> >(rhs) {
+    : SortedVector<sp<Layer> >(rhs) {
 }
 
 int SurfaceFlinger::LayerVector::do_compare(const void* lhs,
     const void* rhs) const
 {
     // sort layers per layer-stack, then by z-order and finally by sequence
-    const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
-    const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
+    const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
+    const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
 
     uint32_t ls = l->currentState().layerStack;
     uint32_t rs = r->currentState().layerStack;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d1221dc..241a7d6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -60,10 +60,7 @@
 class EventThread;
 class IGraphicBufferAlloc;
 class Layer;
-class LayerBase;
-class LayerBaseClient;
 class LayerDim;
-class LayerScreenshot;
 class Surface;
 
 // ---------------------------------------------------------------------------
@@ -125,15 +122,12 @@
 
     // for debugging only
     // TODO: this should be made accessible only to HWComposer
-    const Vector< sp<LayerBase> >& getLayerSortedByZForHwcDisplay(int disp);
+    const Vector< sp<Layer> >& getLayerSortedByZForHwcDisplay(int disp);
 
 private:
     friend class Client;
     friend class DisplayEventConnection;
-    friend class LayerBase;
-    friend class LayerBaseClient;
     friend class Layer;
-    friend class LayerScreenshot;
 
     // We're reference counted, never destroy SurfaceFlinger directly
     virtual ~SurfaceFlinger();
@@ -142,7 +136,7 @@
      * Internal data structures
      */
 
-    class LayerVector : public SortedVector<sp<LayerBase> > {
+    class LayerVector : public SortedVector< sp<Layer> > {
     public:
         LayerVector();
         LayerVector(const LayerVector& rhs);
@@ -272,9 +266,6 @@
     sp<LayerDim> createDimLayer(const sp<Client>& client,
             uint32_t w, uint32_t h, uint32_t flags);
 
-    sp<LayerScreenshot> createScreenshotLayer(const sp<Client>& client,
-            uint32_t w, uint32_t h, uint32_t flags);
-
     // called in response to the window-manager calling
     // ISurfaceComposerClient::destroySurface()
     // The specified layer is first placed in a purgatory list
@@ -284,17 +275,17 @@
     // called when all clients have released all their references to
     // this layer meaning it is entirely safe to destroy all
     // resources associated to this layer.
-    status_t onLayerDestroyed(const wp<LayerBaseClient>& layer);
+    status_t onLayerDestroyed(const wp<Layer>& layer);
 
     // remove a layer from SurfaceFlinger immediately
-    status_t removeLayer(const sp<LayerBase>& layer);
+    status_t removeLayer(const sp<Layer>& layer);
 
     // add a layer to SurfaceFlinger
     void addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,
-        const sp<LayerBaseClient>& lbc);
+        const sp<Layer>& lbc);
 
-    status_t removeLayer_l(const sp<LayerBase>& layer);
-    status_t purgatorizeLayer_l(const sp<LayerBase>& layer);
+    status_t removeLayer_l(const sp<Layer>& layer);
+    status_t purgatorizeLayer_l(const sp<Layer>& layer);
 
     /* ------------------------------------------------------------------------
      * Boot animation, on/off animations and screen capture
@@ -408,10 +399,10 @@
     State mCurrentState;
     volatile int32_t mTransactionFlags;
     Condition mTransactionCV;
-    SortedVector<sp<LayerBase> > mLayerPurgatory;
+    SortedVector< sp<Layer> > mLayerPurgatory;
     bool mTransactionPending;
     bool mAnimTransactionPending;
-    Vector<sp<LayerBase> > mLayersPendingRemoval;
+    Vector< sp<Layer> > mLayersPendingRemoval;
 
     // protected by mStateLock (but we could use another lock)
     bool mLayersRemoved;
@@ -460,7 +451,7 @@
 
     // protected by mDestroyedLayerLock;
     mutable Mutex mDestroyedLayerLock;
-    Vector<LayerBase const *> mDestroyedLayers;
+    Vector<Layer const *> mDestroyedLayers;
 
     /* ------------------------------------------------------------------------
      * Feature prototyping