Merge change 23924 into eclair

* changes:
  	new file:   LowStorageTest/Android.mk 	new file:   LowStorageTest/AndroidManifest.xml 	new file:   LowStorageTest/res/layout/main.xml 	new file:   LowStorageTest/res/values/strings.xml 	new file:   LowStorageTest/src/com/android/lowstoragetest/LowStorageTest.java Add the test app which can eat up 100% of the data parition. This is for the low storage test.
diff --git a/include/private/ui/LayerState.h b/include/private/ui/LayerState.h
index b6fcd80..f1a2618 100644
--- a/include/private/ui/LayerState.h
+++ b/include/private/ui/LayerState.h
@@ -25,8 +25,6 @@
 #include <ui/ISurfaceFlingerClient.h>
 #include <ui/Region.h>
 
-#include <private/ui/SharedState.h>
-
 namespace android {
 
 class Parcel;
diff --git a/include/private/ui/SharedBufferStack.h b/include/private/ui/SharedBufferStack.h
new file mode 100644
index 0000000..2bd5344
--- /dev/null
+++ b/include/private/ui/SharedBufferStack.h
@@ -0,0 +1,327 @@
+/*
+ * 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_UI_SHARED_BUFFER_STACK_H
+#define ANDROID_UI_SHARED_BUFFER_STACK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/compiler.h>
+
+#include <utils/Debug.h>
+#include <utils/threads.h>
+#include <utils/String8.h>
+
+#include <ui/Rect.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+/*
+ * These classes manage a stack of buffers in shared memory.
+ * 
+ * SharedClient: represents a client with several stacks
+ * SharedBufferStack: represents a stack of buffers
+ * SharedBufferClient: manipulates the SharedBufferStack from the client side 
+ * SharedBufferServer: manipulates the SharedBufferStack from the server side 
+ *
+ * Buffers can be dequeued until there are none available, they can be locked
+ * unless they are in use by the server, which is only the case for the last 
+ * dequeue-able buffer. When these various conditions are not met, the caller
+ * waits until the condition is met.
+ *
+ * 
+ * CAVEATS:
+ * 
+ * In the current implementation there are several limitations:
+ * - buffers must be locked in the same order they've been dequeued
+ * - buffers must be enqueued in the same order they've been locked
+ * - dequeue() is not reentrant
+ * - no error checks are done on the condition above
+ * 
+ */
+
+// When changing these values, the COMPILE_TIME_ASSERT at the end of this
+// file need to be updated.
+const unsigned int NUM_LAYERS_MAX  = 31;
+const unsigned int NUM_BUFFER_MAX  = 4;
+const unsigned int NUM_DISPLAY_MAX = 4;
+
+// ----------------------------------------------------------------------------
+
+class Region;
+class SharedBufferStack;
+class SharedClient;
+
+// ----------------------------------------------------------------------------
+
+struct FlatRegion { // 12 bytes
+    static const unsigned int NUM_RECT_MAX = 1;
+    uint32_t    count;
+    uint16_t    rects[4*NUM_RECT_MAX];
+};
+
+// should be 128 bytes (32 longs)
+class SharedBufferStack
+{
+    friend class SharedClient;
+    friend class SharedBufferBase;
+    friend class SharedBufferClient;
+    friend class SharedBufferServer;
+
+public:
+    SharedBufferStack();
+    status_t setDirtyRegion(int buffer, const Region& reg);
+    Region getDirtyRegion(int buffer) const;
+
+    // these attributes are part of the conditions/updates
+    volatile int32_t head;      // server's current front buffer
+    volatile int32_t available; // number of dequeue-able buffers
+    volatile int32_t queued;    // number of buffers waiting for post
+    volatile int32_t inUse;     // buffer currently in use by SF
+
+    // not part of the conditions
+    volatile int32_t reallocMask;
+
+    int32_t     identity;       // surface's identity (const)
+    status_t    status;         // surface's status code
+    int32_t     reserved32[13];
+    FlatRegion  dirtyRegion[NUM_BUFFER_MAX];    // 12*4=48 bytes
+};
+
+// ----------------------------------------------------------------------------
+
+// 4 KB max
+class SharedClient
+{
+public:
+    SharedClient();
+    ~SharedClient();
+
+    status_t validate(size_t token) const;
+    uint32_t getIdentity(size_t token) const;
+    status_t setIdentity(size_t token, uint32_t identity);
+
+private:
+    friend class SharedBufferBase;
+    friend class SharedBufferClient;
+    friend class SharedBufferServer;
+
+    // FIXME: this should be replaced by a lock-less primitive
+    Mutex lock;
+    Condition cv;
+    SharedBufferStack surfaces[ NUM_LAYERS_MAX ];
+};
+
+// ============================================================================
+
+class SharedBufferBase
+{
+public:
+    SharedBufferBase(SharedClient* sharedClient, int surface, int num);
+    ~SharedBufferBase();
+    uint32_t getIdentity();
+    size_t getFrontBuffer() const;
+    String8 dump(char const* prefix) const;
+
+protected:
+    SharedClient* const mSharedClient;
+    SharedBufferStack* const mSharedStack;
+    const int mNumBuffers;
+
+    friend struct Update;
+    friend struct QueueUpdate;
+
+    struct ConditionBase {
+        SharedBufferStack& stack;
+        inline ConditionBase(SharedBufferBase* sbc) 
+            : stack(*sbc->mSharedStack) { }
+    };
+
+    struct UpdateBase {
+        SharedBufferStack& stack;
+        inline UpdateBase(SharedBufferBase* sbb) 
+            : stack(*sbb->mSharedStack) { }
+    };
+
+    template <typename T>
+    status_t waitForCondition(T condition);
+
+    template <typename T>
+    status_t updateCondition(T update);
+};
+
+template <typename T>
+status_t SharedBufferBase::waitForCondition(T condition) 
+{
+    SharedClient& client( *mSharedClient );
+    const nsecs_t TIMEOUT = s2ns(1); 
+    Mutex::Autolock _l(client.lock);
+    while (!condition()) {
+        status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
+        
+        // handle errors and timeouts
+        if (CC_UNLIKELY(err != NO_ERROR)) {
+            if (err == TIMED_OUT) {
+                if (condition()) {
+                    LOGE("waitForCondition(%s) timed out (identity=%d), "
+                            "but condition is true! We recovered but it "
+                            "shouldn't happen." , 
+                            T::name(), mSharedStack->identity);
+                    break;
+                } else {
+                    LOGW("waitForCondition(%s) timed out (identity=%d). "
+                            "CPU may be pegged. trying again.",
+                            T::name(), mSharedStack->identity);
+                }
+            } else {
+                LOGE("waitForCondition(%s) error (%s) ",
+                        T::name(), strerror(-err));
+                return err;
+            }
+        }
+    }
+    return NO_ERROR;
+}
+
+
+template <typename T>
+status_t SharedBufferBase::updateCondition(T update) {
+    SharedClient& client( *mSharedClient );
+    Mutex::Autolock _l(client.lock);
+    ssize_t result = update();
+    client.cv.broadcast();    
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+
+class SharedBufferClient : public SharedBufferBase
+{
+public:
+    SharedBufferClient(SharedClient* sharedClient, int surface, int num);
+    
+    ssize_t dequeue();
+    status_t undoDequeue(int buf);
+    
+    status_t lock(int buf);
+    status_t queue(int buf);
+    bool needNewBuffer(int buffer) const;
+    status_t setDirtyRegion(int buffer, const Region& reg);
+
+private:
+    friend struct Condition;
+    friend struct DequeueCondition;
+    friend struct LockCondition;
+
+    struct QueueUpdate : public UpdateBase {
+        inline QueueUpdate(SharedBufferBase* sbb);
+        inline ssize_t operator()();
+    };
+
+    struct UndoDequeueUpdate : public UpdateBase {
+        inline UndoDequeueUpdate(SharedBufferBase* sbb);
+        inline ssize_t operator()();
+    };
+
+    // --
+
+    struct DequeueCondition : public ConditionBase {
+        inline DequeueCondition(SharedBufferClient* sbc);
+        inline bool operator()();
+        static inline const char* name() { return "DequeueCondition"; }
+    };
+
+    struct LockCondition : public ConditionBase {
+        int buf;
+        inline LockCondition(SharedBufferClient* sbc, int buf);
+        inline bool operator()();
+        static inline const char* name() { return "LockCondition"; }
+    };
+
+    int32_t tail;
+};
+
+// ----------------------------------------------------------------------------
+
+class SharedBufferServer : public SharedBufferBase
+{
+public:
+    SharedBufferServer(SharedClient* sharedClient, int surface, int num);
+
+    ssize_t retireAndLock();
+    status_t unlock(int buffer);
+    status_t reallocate();
+    status_t assertReallocate(int buffer);
+
+    Region getDirtyRegion(int buffer) const;
+
+private:
+    struct UnlockUpdate : public UpdateBase {
+        const int lockedBuffer;
+        inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
+        inline ssize_t operator()();
+    };
+
+    struct RetireUpdate : public UpdateBase {
+        const int numBuffers;
+        inline RetireUpdate(SharedBufferBase* sbb, int numBuffers);
+        inline ssize_t operator()();
+    };
+
+    struct ReallocateCondition : public ConditionBase {
+        int buf;
+        inline ReallocateCondition(SharedBufferBase* sbb, int buf);
+        inline bool operator()();
+        static inline const char* name() { return "ReallocateCondition"; }
+    };
+};
+
+// ===========================================================================
+
+struct display_cblk_t
+{
+    uint16_t    w;
+    uint16_t    h;
+    uint8_t     format;
+    uint8_t     orientation;
+    uint8_t     reserved[2];
+    float       fps;
+    float       density;
+    float       xdpi;
+    float       ydpi;
+    uint32_t    pad[2];
+};
+
+struct surface_flinger_cblk_t   // 4KB max
+{
+    uint8_t         connected;
+    uint8_t         reserved[3];
+    uint32_t        pad[7];
+    display_cblk_t  displays[NUM_DISPLAY_MAX];
+};
+
+// ---------------------------------------------------------------------------
+
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 4096)
+COMPILE_TIME_ASSERT(sizeof(SharedBufferStack) == 128)
+COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif /* ANDROID_UI_SHARED_BUFFER_STACK_H */
diff --git a/include/private/ui/SharedState.h b/include/private/ui/SharedState.h
deleted file mode 100644
index c9f6b5e..0000000
--- a/include/private/ui/SharedState.h
+++ /dev/null
@@ -1,154 +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_UI_SHARED_STATE_H
-#define ANDROID_UI_SHARED_STATE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Debug.h>
-#include <utils/threads.h>
-
-namespace android {
-
-/*
- * These structures are shared between the composer process and its clients
- */
-
-// ---------------------------------------------------------------------------
-
-struct surface_info_t { // 4 longs, 16 bytes
-    enum {
-        eBufferDirty    = 0x01,
-        eNeedNewBuffer  = 0x02
-    };
-    uint8_t     reserved[11];
-    uint8_t     flags;
-    status_t    status;
-};
-
-// ---------------------------------------------------------------------------
-
-const uint32_t NUM_LAYERS_MAX = 31;
-
-enum { // layer_cblk_t swapState
-    eIndex              = 0x00000001,
-    eFlipRequested      = 0x00000002,
-    
-    eResizeBuffer0      = 0x00000004,
-    eResizeBuffer1      = 0x00000008,    
-    eResizeRequested    = eResizeBuffer0 | eResizeBuffer1,
-    
-    eBusy               = 0x00000010,
-    eLocked             = 0x00000020,
-    eNextFlipPending    = 0x00000040,    
-    eInvalidSurface     = 0x00000080
-};
-
-enum { // layer_cblk_t flags
-    eLayerNotPosted     = 0x00000001,
-    eNoCopyBack         = 0x00000002,
-    eReserved           = 0x0000007C,
-    eBufferIndexShift   = 7,
-    eBufferIndex        = 1<<eBufferIndexShift,
-};
-
-struct flat_region_t    // 40 bytes
-{
-    int32_t     count;
-    int16_t     l;
-    int16_t     t;
-    int16_t     r;
-    int16_t     b;
-    uint16_t    runs[14];
-};
-
-struct layer_cblk_t     // (128 bytes)
-{
-    volatile    int32_t             swapState;      //  4
-    volatile    int32_t             flags;          //  4
-    volatile    int32_t             identity;       //  4
-                int32_t             reserved;       //  4
-                surface_info_t      surface[2];     // 32
-                flat_region_t       region[2];      // 80
-
-    static inline int backBuffer(uint32_t state) {
-        return ((state & eIndex) ^ ((state & eFlipRequested)>>1));
-    }
-    static inline int frontBuffer(uint32_t state) {
-        return 1 - backBuffer(state);
-    }
-};
-
-// ---------------------------------------------------------------------------
-
-struct per_client_cblk_t   // 4KB max
-{
-    per_client_cblk_t() : lock(Mutex::SHARED) { }
-
-                Mutex           lock;
-                Condition       cv;
-                layer_cblk_t    layers[NUM_LAYERS_MAX] __attribute__((aligned(32)));
-
-    enum {
-        BLOCKING = 0x00000001,
-        INSPECT  = 0x00000002
-    };
-
-    // these functions are used by the clients
-    status_t validate(size_t i) const;
-    int32_t lock_layer(size_t i, uint32_t flags);
-    uint32_t unlock_layer_and_post(size_t i);
-    void unlock_layer(size_t i);
-};
-// ---------------------------------------------------------------------------
-
-const uint32_t NUM_DISPLAY_MAX = 4;
-
-struct display_cblk_t
-{
-    uint16_t    w;
-    uint16_t    h;
-    uint8_t     format;
-    uint8_t     orientation;
-    uint8_t     reserved[2];
-    float       fps;
-    float       density;
-    float       xdpi;
-    float       ydpi;
-    uint32_t    pad[2];
-};
-
-struct surface_flinger_cblk_t   // 4KB max
-{
-    uint8_t         connected;
-    uint8_t         reserved[3];
-    uint32_t        pad[7];
-    display_cblk_t  displays[NUM_DISPLAY_MAX];
-};
-
-// ---------------------------------------------------------------------------
-
-COMPILE_TIME_ASSERT(sizeof(layer_cblk_t) == 128)
-COMPILE_TIME_ASSERT(sizeof(per_client_cblk_t) <= 4096)
-COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_UI_SHARED_STATE_H
-
diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h
index bf68406..73e517b 100644
--- a/include/private/ui/SurfaceBuffer.h
+++ b/include/private/ui/SurfaceBuffer.h
@@ -47,6 +47,9 @@
     status_t lock(uint32_t usage, const Rect& rect, void** vaddr);
     status_t unlock();
 
+    void setIndex(int index);
+    int getIndex() const;
+    
 protected:
             SurfaceBuffer();
             SurfaceBuffer(const Parcel& reply);
@@ -69,6 +72,7 @@
             android_native_buffer_t const* buffer);
     
     BufferMapper& mBufferMapper;
+    int mIndex;
 };
 
 }; // namespace android
diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h
index 7909c2f..1283033 100644
--- a/include/ui/ISurface.h
+++ b/include/ui/ISurface.h
@@ -44,13 +44,13 @@
         UNREGISTER_BUFFERS,
         POST_BUFFER, // one-way transaction
         CREATE_OVERLAY,
-        GET_BUFFER,
+        REQUEST_BUFFER,
     };
 
 public: 
     DECLARE_META_INTERFACE(Surface);
 
-    virtual sp<SurfaceBuffer> getBuffer(int usage) = 0; 
+    virtual sp<SurfaceBuffer> requestBuffer(int bufferIdx, int usage) = 0; 
     
     class BufferHeap {
     public:
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
index 30ab82f..118fb83 100644
--- a/include/ui/Surface.h
+++ b/include/ui/Surface.h
@@ -39,8 +39,8 @@
 class Rect;
 class Surface;
 class SurfaceComposerClient;
-struct per_client_cblk_t;
-struct layer_cblk_t;
+class SharedClient;
+class SharedBufferClient;
 
 // ---------------------------------------------------------------------------
 
@@ -109,7 +109,7 @@
 
     ~SurfaceControl();
 
-    status_t validate(per_client_cblk_t const* cblk) const;
+    status_t validate(SharedClient const* cblk) const;
     void destroy();
     
     sp<SurfaceComposerClient>   mClient;
@@ -190,8 +190,7 @@
 
     status_t getBufferLocked(int index, int usage);
    
-           status_t validate(per_client_cblk_t const* cblk) const;
-    static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty);
+           status_t validate(SharedClient const* cblk) const;
 
     inline const BufferMapper& getBufferMapper() const { return mBufferMapper; }
     inline BufferMapper& getBufferMapper() { return mBufferMapper; }
@@ -210,11 +209,10 @@
     int perform(int operation, va_list args);
 
     status_t dequeueBuffer(sp<SurfaceBuffer>* buffer);
-    status_t lockBuffer(const sp<SurfaceBuffer>& buffer);
-    status_t queueBuffer(const sp<SurfaceBuffer>& buffer);
 
     
     void setUsage(uint32_t reqUsage);
+    bool getUsage(uint32_t* usage);
     
     // constants
     sp<SurfaceComposerClient>   mClient;
@@ -224,21 +222,23 @@
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
     BufferMapper&               mBufferMapper;
+    SharedBufferClient*         mSharedBufferClient;
 
     // protected by mSurfaceLock
     Rect                        mSwapRectangle;
     uint32_t                    mUsage;
-    bool                        mUsageChanged;
+    int32_t                     mUsageChanged;
     
     // protected by mSurfaceLock. These are also used from lock/unlock
     // but in that case, they must be called form the same thread.
     sp<SurfaceBuffer>           mBuffers[2];
     mutable Region              mDirtyRegion;
-    mutable uint8_t             mBackbufferIndex;
 
     // must be used from the lock/unlock thread
     sp<SurfaceBuffer>           mLockedBuffer;
+    sp<SurfaceBuffer>           mPostedBuffer;
     mutable Region              mOldDirtyRegion;
+    bool                        mNeedFullUpdate;
 
     // query() must be called from dequeueBuffer() thread
     uint32_t                    mWidth;
@@ -246,6 +246,7 @@
 
     // Inherently thread-safe
     mutable Mutex               mSurfaceLock;
+    mutable Mutex               mApiLock;
 };
 
 }; // namespace android
diff --git a/include/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h
index 286f885..269959c 100644
--- a/include/ui/SurfaceComposerClient.h
+++ b/include/ui/SurfaceComposerClient.h
@@ -21,7 +21,6 @@
 #include <sys/types.h>
 
 #include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 
@@ -36,8 +35,7 @@
 
 class Region;
 class SurfaceFlingerSynchro;
-struct per_client_cblk_t;
-struct layer_cblk_t;
+class SharedClient;
 
 class SurfaceComposerClient : virtual public RefBase
 {
@@ -63,12 +61,12 @@
 
     //! Create a surface
     sp<SurfaceControl> createSurface(
-            int pid,            //!< pid of the process the surfacec is for
-            DisplayID display,  //!< Display to create this surface on
-            uint32_t w,         //!< width in pixel
-            uint32_t h,         //!< height in pixel
-            PixelFormat format, //!< pixel-format desired
-            uint32_t flags = 0  //!< usage flags
+            int pid,            // pid of the process the surface is for
+            DisplayID display,  // Display to create this surface on
+            uint32_t w,         // width in pixel
+            uint32_t h,         // height in pixel
+            PixelFormat format, // pixel-format desired
+            uint32_t flags = 0  // usage flags
     );
 
     // ------------------------------------------------------------------------
@@ -148,7 +146,7 @@
                 // these don't need to be protected because they never change
                 // after assignment
                 status_t                    mStatus;
-                per_client_cblk_t*          mControl;
+                SharedClient*               mControl;
                 sp<IMemoryHeap>             mControlMemory;
                 sp<ISurfaceFlingerClient>   mClient;
                 SurfaceFlingerSynchro*      mSignalServer;
diff --git a/include/utils/Errors.h b/include/utils/Errors.h
index 1bf9e6f..81f818b 100644
--- a/include/utils/Errors.h
+++ b/include/utils/Errors.h
@@ -63,7 +63,7 @@
     BAD_INDEX           = -EOVERFLOW,
     NOT_ENOUGH_DATA     = -ENODATA,
     WOULD_BLOCK         = -EWOULDBLOCK, 
-    TIMED_OUT           = -ETIME,
+    TIMED_OUT           = -ETIMEDOUT,
     UNKNOWN_TRANSACTION = -EBADMSG,
 #else    
     BAD_INDEX           = -E2BIG,
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 3a419b5..8cb89c3 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1319,19 +1319,20 @@
             mAudioMixer->setBufferProvider(track);
             mAudioMixer->enable(AudioMixer::MIXING);
 
-            int param;
-            if ( track->mFillingUpStatus == Track::FS_FILLED) {
+            int param = AudioMixer::VOLUME;
+            if (track->mFillingUpStatus == Track::FS_FILLED) {
                 // no ramp for the first volume setting
                 track->mFillingUpStatus = Track::FS_ACTIVE;
                 if (track->mState == TrackBase::RESUMING) {
                     track->mState = TrackBase::ACTIVE;
                     param = AudioMixer::RAMP_VOLUME;
-                } else {
-                    param = AudioMixer::VOLUME;
                 }
-            } else {
+            } else if (cblk->server != 0) {
+                // If the track is stopped before the first frame was mixed,
+                // do not apply ramp
                 param = AudioMixer::RAMP_VOLUME;
             }
+
             mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
             mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
             mAudioMixer->setParameter(
@@ -1365,7 +1366,7 @@
                     LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
                     tracksToRemove->add(track);
                 }
-                // For tracks using static shared memry buffer, make sure that we have
+                // For tracks using static shared memory buffer, make sure that we have
                 // written enough data to audio hardware before disabling the track
                 // NOTE: this condition with arrive before track->mRetryCount <= 0 so we
                 // don't care about code removing track from active list above.
@@ -1449,6 +1450,8 @@
         int j = activeTracks.indexOf(t);
         if (j >= 0) {
             mActiveTracks.add(t);
+            // force buffer refilling and no ramp volume when the track is mixed for the first time
+            t->mFillingUpStatus = Track::FS_FILLING;
         }
     }
 }
@@ -3512,10 +3515,11 @@
             if (tracks.size()) {
                 dstThread->putTracks(tracks, activeTracks);
             }
-            dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream);
         }
     }
 
+    dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream);
+
     return NO_ERROR;
 }
 
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index c4a70c8..49da111 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -6,12 +6,12 @@
     DisplayHardware/DisplayHardware.cpp \
     DisplayHardware/DisplayHardwareBase.cpp \
     BlurFilter.cpp.arm \
+    Buffer.cpp \
     BufferAllocator.cpp \
     Layer.cpp \
     LayerBase.cpp \
     LayerBuffer.cpp \
     LayerBlur.cpp \
-    LayerBitmap.cpp \
     LayerDim.cpp \
     MessageQueue.cpp \
     SurfaceFlinger.cpp \
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/Buffer.cpp
similarity index 60%
rename from libs/surfaceflinger/LayerBitmap.cpp
rename to libs/surfaceflinger/Buffer.cpp
index dd61e1a..4a7c55e 100644
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ b/libs/surfaceflinger/Buffer.cpp
@@ -27,8 +27,8 @@
 #include <ui/Surface.h>
 #include <pixelflinger/pixelflinger.h>
 
+#include "Buffer.h"
 #include "BufferAllocator.h"
-#include "LayerBitmap.h"
 #include "SurfaceFlinger.h"
 
 
@@ -38,15 +38,16 @@
 // Buffer and implementation of android_native_buffer_t
 // ===========================================================================
 
+Buffer::Buffer()
+    : SurfaceBuffer(), mInitCheck(NO_ERROR),  mVStride(0)
+{
+}
+
 Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format,
         uint32_t reqUsage, uint32_t flags)
-    : SurfaceBuffer(), mInitCheck(NO_INIT), mFlags(flags), 
-    mVStride(0)
+    : SurfaceBuffer(), mInitCheck(NO_INIT), mVStride(0)
 {
-    this->format = format;
-    if (w>0 && h>0) {
-        mInitCheck = initSize(w, h, reqUsage);
-    }
+    mInitCheck = initSize(w, h, format, reqUsage, flags);
 }
 
 Buffer::~Buffer()
@@ -66,7 +67,19 @@
     return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this));
 }
 
-status_t Buffer::initSize(uint32_t w, uint32_t h, uint32_t reqUsage)
+status_t Buffer::reallocate(uint32_t w, uint32_t h, PixelFormat f,
+        uint32_t reqUsage, uint32_t flags)
+{
+    if (handle) {
+        BufferAllocator& allocator(BufferAllocator::get());
+        allocator.free(handle);
+        handle = 0;
+    }
+    return initSize(w, h, f, reqUsage, flags);
+}
+
+status_t Buffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
+        uint32_t reqUsage, uint32_t flags)
 {
     status_t err = NO_ERROR;
 
@@ -84,7 +97,7 @@
      *  
      */
     
-    if (mFlags & Buffer::SECURE) {
+    if (flags & Buffer::SECURE) {
         // secure buffer, don't store it into the GPU
         usage = BufferAllocator::USAGE_SW_READ_OFTEN | 
                 BufferAllocator::USAGE_SW_WRITE_OFTEN;
@@ -95,10 +108,10 @@
     }
 
     err = allocator.alloc(w, h, format, usage, &handle, &stride);
-    
     if (err == NO_ERROR) {
-        width  = w;
-        height = h;
+        this->width  = w;
+        this->height = h;
+        this->format = format;
         mVStride = 0;
     }
 
@@ -121,78 +134,6 @@
     return res;
 }
 
-// ===========================================================================
-// LayerBitmap
-// ===========================================================================
-
-LayerBitmap::LayerBitmap()
-    : mInfo(0), mWidth(0), mHeight(0)
-{
-}
-
-LayerBitmap::~LayerBitmap()
-{
-}
-
-status_t LayerBitmap::init(surface_info_t* info,
-        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
-{
-    if (info == NULL)
-        return BAD_VALUE;
-    
-    mFormat = format;
-    mFlags = flags;
-    mWidth = w;
-    mHeight = h;
-
-    mInfo = info;
-    memset(info, 0, sizeof(surface_info_t));
-    info->flags = surface_info_t::eNeedNewBuffer;
-    
-    // init the buffer, but don't trigger an allocation
-    mBuffer = new Buffer(0, 0, format, flags);
-    return NO_ERROR;
-}
-
-status_t LayerBitmap::setSize(uint32_t w, uint32_t h)
-{
-    Mutex::Autolock _l(mLock);
-    if ((w != mWidth) || (h != mHeight)) {
-        mWidth  = w;
-        mHeight = h;
-        // this will signal the client that it needs to asks us for a new buffer
-        mInfo->flags = surface_info_t::eNeedNewBuffer;
-    }
-    return NO_ERROR;
-}
-
-sp<Buffer> LayerBitmap::allocate(uint32_t reqUsage)
-{
-    Mutex::Autolock _l(mLock);
-    surface_info_t* info = mInfo;
-    mBuffer.clear(); // free buffer before allocating a new one
-    sp<Buffer> buffer = new Buffer(mWidth, mHeight, mFormat, reqUsage, mFlags);
-    status_t err = buffer->initCheck();
-    if (LIKELY(err == NO_ERROR)) {
-        info->flags  = surface_info_t::eBufferDirty;
-        info->status = NO_ERROR;
-    } else {
-        memset(info, 0, sizeof(surface_info_t));
-        info->status = NO_MEMORY;
-    }
-    mBuffer = buffer;
-    return buffer;
-}
-
-status_t LayerBitmap::free()
-{
-    mBuffer.clear();
-    mWidth = 0;
-    mHeight = 0;
-    return NO_ERROR;
-}
-
-
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/libs/surfaceflinger/Buffer.h b/libs/surfaceflinger/Buffer.h
new file mode 100644
index 0000000..79f4eeb
--- /dev/null
+++ b/libs/surfaceflinger/Buffer.h
@@ -0,0 +1,94 @@
+/*
+ * 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_BITMAP_H
+#define ANDROID_LAYER_BITMAP_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <hardware/gralloc.h>
+
+#include <utils/Atomic.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <ui/Surface.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include <private/ui/SharedBufferStack.h>
+#include <private/ui/SurfaceBuffer.h>
+
+class copybit_image_t;
+struct android_native_buffer_t;
+
+namespace android {
+
+// ===========================================================================
+// Buffer
+// ===========================================================================
+
+class NativeBuffer;
+
+class Buffer : public SurfaceBuffer
+{
+public:
+    enum {
+        DONT_CLEAR  = 0x00000001,
+        SECURE      = 0x00000004
+    };
+
+    Buffer();
+
+    // creates w * h buffer
+    Buffer(uint32_t w, uint32_t h, PixelFormat format,
+            uint32_t reqUsage, uint32_t flags = 0);
+
+    // return status
+    status_t initCheck() const;
+
+    uint32_t getWidth() const           { return width; }
+    uint32_t getHeight() const          { return height; }
+    uint32_t getStride() const          { return stride; }
+    uint32_t getUsage() const           { return usage; }
+    PixelFormat getPixelFormat() const  { return format; }
+    Rect getBounds() const              { return Rect(width, height); }
+    
+    status_t lock(GGLSurface* surface, uint32_t usage);
+    
+    android_native_buffer_t* getNativeBuffer() const;
+    
+    status_t reallocate(uint32_t w, uint32_t h, PixelFormat f,
+            uint32_t reqUsage, uint32_t flags);
+
+private:
+    friend class LightRefBase<Buffer>;
+    Buffer(const Buffer& rhs);
+    virtual ~Buffer();
+    Buffer& operator = (const Buffer& rhs);
+    const Buffer& operator = (const Buffer& rhs) const;
+
+    status_t initSize(uint32_t w, uint32_t h, PixelFormat format,
+            uint32_t reqUsage, uint32_t flags);
+
+    ssize_t     mInitCheck;
+    uint32_t    mVStride;
+};
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BITMAP_H
diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp
index cee8b64..19867a5 100644
--- a/libs/surfaceflinger/BufferAllocator.cpp
+++ b/libs/surfaceflinger/BufferAllocator.cpp
@@ -71,14 +71,23 @@
     result.append(buffer);
 }
 
+static inline uint32_t clamp(uint32_t c) {
+    return c>0 ? c : 1;
+}
+
 status_t BufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
         int usage, buffer_handle_t* handle, int32_t* stride)
 {
     Mutex::Autolock _l(mLock);
-    
+
+    // make sure to not allocate a 0 x 0 buffer
+    w = clamp(w);
+    h = clamp(h);
+
     // we have a h/w allocator and h/w buffer is requested
     status_t err = mAllocDev->alloc(mAllocDev,
             w, h, format, usage, handle, stride);
+
     LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
             w, h, format, usage, err, strerror(-err));
     
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 3f607f6..651e7cf 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -46,22 +46,25 @@
 static __attribute__((noinline))
 void checkGLErrors()
 {
-    GLenum error = glGetError();
-    if (error != GL_NO_ERROR)
+    do {
+        // there could be more than one error flag
+        GLenum error = glGetError();
+        if (error == GL_NO_ERROR)
+            break;
         LOGE("GL error 0x%04x", int(error));
+    } while(true);
 }
 
 static __attribute__((noinline))
 void checkEGLErrors(const char* token)
 {
     EGLint error = eglGetError();
-    // GLESonGL seems to be returning 0 when there is no errors?
-    if (error && error != EGL_SUCCESS)
-        LOGE("%s error 0x%04x (%s)",
+    if (error && error != EGL_SUCCESS) {
+        LOGE("%s: EGL error 0x%04x (%s)",
                 token, int(error), EGLUtils::strerror(error));
+    }
 }
 
-
 /*
  * Initialize the display to the specified values.
  *
@@ -158,7 +161,6 @@
      */
 
     surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
-    checkEGLErrors("eglCreateWindowSurface");
 
     if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
         if (dummy == EGL_BUFFER_PRESERVED) {
@@ -212,8 +214,6 @@
      */
     
     context = eglCreateContext(display, config, NULL, NULL);
-    //checkEGLErrors("eglCreateContext");
-    
     
     /*
      * Gather OpenGL ES extensions
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 6f92515..ecb6b32 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -28,9 +28,9 @@
 #include <ui/PixelFormat.h>
 #include <ui/Surface.h>
 
+#include "Buffer.h"
 #include "clz.h"
 #include "Layer.h"
-#include "LayerBitmap.h"
 #include "SurfaceFlinger.h"
 #include "DisplayHardware/DisplayHardware.h"
 
@@ -47,26 +47,29 @@
 
 // ---------------------------------------------------------------------------
 
-Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& c, int32_t i)
-    :   LayerBaseClient(flinger, display, c, i),
+Layer::Layer(SurfaceFlinger* flinger, DisplayID display, 
+        const sp<Client>& c, int32_t i)
+    :   LayerBaseClient(flinger, display, c, i), lcblk(NULL),
         mSecure(false),
-        mFrontBufferIndex(1),
-        mNeedsBlending(true),
-        mResizeTransactionDone(false)
+        mNeedsBlending(true)
 {
     // no OpenGL operation is possible here, since we might not be
     // in the OpenGL thread.
+    lcblk = new SharedBufferServer(c->ctrlblk, i, NUM_BUFFERS);
+    mFrontBufferIndex = lcblk->getFrontBuffer();
 }
 
 Layer::~Layer()
 {
     destroy();
     // the actual buffers will be destroyed here
+    delete lcblk;
+
 }
 
 void Layer::destroy()
 {
-    for (int i=0 ; i<NUM_BUFFERS ; i++) {
+    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
         if (mTextures[i].name != -1U) {
             glDeleteTextures(1, &mTextures[i].name);
             mTextures[i].name = -1U;
@@ -76,19 +79,11 @@
             eglDestroyImageKHR(dpy, mTextures[i].image);
             mTextures[i].image = EGL_NO_IMAGE_KHR;
         }
-        mBuffers[i].free();
+        mBuffers[i].clear();
     }
     mSurface.clear();
 }
 
-void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags)
-{
-    LayerBase::initStates(w,h,flags);
-
-    if (flags & ISurfaceComposer::eDestroyBackbuffer)
-        lcblk->flags |= eNoCopyBack;
-}
-
 sp<LayerBaseClient::Surface> Layer::createSurface() const
 {
     return mSurface;
@@ -112,13 +107,14 @@
     if (flags & ISurfaceComposer::eSecure)
         bufferFlags |= Buffer::SECURE;
 
+    mFormat = format;
+    mWidth = w;
+    mHeight = h;
     mSecure = (bufferFlags & Buffer::SECURE) ? true : false;
     mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
-    for (int i=0 ; i<2 ; i++) {
-        err = mBuffers[i].init(lcblk->surface + i, w, h, format, bufferFlags);
-        if (err != NO_ERROR) {
-            return err;
-        }
+    mBufferFlags = bufferFlags;
+    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
+        mBuffers[i] = new Buffer();
     }
     mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
     return NO_ERROR;
@@ -126,7 +122,8 @@
 
 void Layer::reloadTexture(const Region& dirty)
 {
-    const sp<Buffer>& buffer(frontBuffer().getBuffer());
+    Mutex::Autolock _l(mLock);
+    sp<Buffer> buffer(getFrontBuffer());
     if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) {
         int index = mFrontBufferIndex;
         if (LIKELY(!mTextures[index].dirty)) {
@@ -202,195 +199,113 @@
     const int index = (mFlags & DisplayHardware::DIRECT_TEXTURE) ? 
             mFrontBufferIndex : 0;
     GLuint textureName = mTextures[index].name;
-
     if (UNLIKELY(textureName == -1LU)) {
-        LOGW("Layer %p doesn't have a texture", this);
+        //LOGW("Layer %p doesn't have a texture", this);
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. this happens frequently with
         // SurfaceView.
         clearWithOpenGL(clip);
         return;
     }
+
     drawWithOpenGL(clip, mTextures[index]);
 }
 
-sp<SurfaceBuffer> Layer::peekBuffer(int usage)
+sp<SurfaceBuffer> Layer::requestBuffer(int index, int usage)
 {
     /*
-     * This is called from the client's Surface::lock(), after it locked
-     * the surface successfully. We're therefore guaranteed that the
-     * back-buffer is not in use by ourselves.
-     * Of course, we need to validate all this, which is not trivial.
-     *
-     * FIXME: A resize could happen at any time here. What to do about this?
-     *  - resize() form post()
-     *  - resize() from doTransaction()
-     *  
-     *  We'll probably need an internal lock for this.
-     *     
+     * This is called from the client's Surface::dequeue(). This can happen
+     * at any time, especially while we're in the middle of using the
+     * buffer 'index' as our front buffer.
      * 
-     * TODO: We need to make sure that post() doesn't swap
-     *       the buffers under us.
+     * Make sure the buffer we're resizing is not the front buffer and has been
+     * dequeued. Once this condition is asserted, we are guaranteed that this
+     * buffer cannot become the front buffer under our feet, since we're called
+     * from Surface::dequeue()
      */
+    status_t err = lcblk->assertReallocate(index);
+    LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
 
-    // it's okay to read swapState for the purpose of figuring out the 
-    // backbuffer index, which cannot change (since the app has locked it).
-    const uint32_t state = lcblk->swapState;
-    const int32_t backBufferIndex = layer_cblk_t::backBuffer(state);
+    Mutex::Autolock _l(mLock);
+    uint32_t w = mWidth;
+    uint32_t h = mHeight;
     
-    // get rid of the EGL image, since we shouldn't need it anymore
-    // (note that we're in a different thread than where it is being used)
-    if (mTextures[backBufferIndex].image != EGL_NO_IMAGE_KHR) {
-        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
-        eglDestroyImageKHR(dpy, mTextures[backBufferIndex].image);
-        mTextures[backBufferIndex].image = EGL_NO_IMAGE_KHR;
-    }
-    
-    LayerBitmap& layerBitmap(mBuffers[backBufferIndex]);
-    sp<SurfaceBuffer> buffer = layerBitmap.allocate(usage);
-    
-    LOGD_IF(DEBUG_RESIZE,
-            "Layer::getBuffer(this=%p), index=%d, (%d,%d), (%d,%d)",
-            this, backBufferIndex,
-            layerBitmap.getWidth(),
-            layerBitmap.getHeight(),
-            layerBitmap.getBuffer()->getWidth(),
-            layerBitmap.getBuffer()->getHeight());
-
-    if (UNLIKELY(buffer == 0)) {
-        // XXX: what to do, what to do?
+    sp<Buffer>& buffer(mBuffers[index]);
+    if (buffer->getStrongCount() == 1) {
+        err = buffer->reallocate(w, h, mFormat, usage, mBufferFlags);
     } else {
+        // here we have to reallocate a new buffer because we could have a
+        // client in our process with a reference to it (eg: status bar),
+        // and we can't release the handle under its feet.
+        buffer.clear();
+        buffer = new Buffer(w, h, mFormat, usage, mBufferFlags);
+        err = buffer->initCheck();
+    }
+
+    if (err || buffer->handle == 0) {
+        LOGE_IF(err || buffer->handle == 0,
+                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
+                this, index, w, h, strerror(-err));
+    } else {
+        LOGD_IF(DEBUG_RESIZE,
+                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d",
+                this, index, w, h);
+    }
+
+    if (err == NO_ERROR && buffer->handle != 0) {
         // texture is now dirty...
-        mTextures[backBufferIndex].dirty = true;
-        // ... so it the visible region (because we consider the surface's
-        // buffer size for visibility calculations)
-        forceVisibilityTransaction();
-        mFlinger->setTransactionFlags(eTraversalNeeded);
+        mTextures[index].dirty = true;
     }
     return buffer;
 }
 
-void Layer::scheduleBroadcast()
-{
-    sp<Client> ourClient(client.promote());
-    if (ourClient != 0) {
-        mFlinger->scheduleBroadcast(ourClient);
-    }
-}
-
 uint32_t Layer::doTransaction(uint32_t flags)
 {
     const Layer::State& front(drawingState());
     const Layer::State& temp(currentState());
 
-    // the test front.{w|h} != temp.{w|h} is not enough because it is possible
-    // that the size changed back to its previous value before the buffer
-    // was resized (in the eLocked case below), in which case, we still
-    // need to execute the code below so the clients have a chance to be
-    // release. resize() deals with the fact that the size can be the same.
-
-    /*
-     *  Various states we could be in...
-
-         resize = state & eResizeRequested;
-         if (backbufferChanged) {
-             if (resize == 0) {
-                 // ERROR, the resized buffer doesn't have its resize flag set
-             } else if (resize == mask) {
-                 // ERROR one of the buffer has already been resized
-             } else if (resize == mask ^ eResizeRequested) {
-                 // ERROR, the resized buffer doesn't have its resize flag set
-             } else if (resize == eResizeRequested) {
-                 // OK, Normal case, proceed with resize
-             }
-         } else {
-             if (resize == 0) {
-                 // OK, nothing special, do nothing
-             } else if (resize == mask) {
-                 // restarted transaction, do nothing
-             } else if (resize == mask ^ eResizeRequested) {
-                 // restarted transaction, do nothing
-             } else if (resize == eResizeRequested) {
-                 // OK, size reset to previous value, proceed with resize
-             }
-         }
-     */
-
     // Index of the back buffer
     const bool backbufferChanged = (front.w != temp.w) || (front.h != temp.h);
-    const uint32_t state = lcblk->swapState;
-    const int32_t clientBackBufferIndex = layer_cblk_t::backBuffer(state);
-    const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
-    uint32_t resizeFlags = state & eResizeRequested;
 
-    if (UNLIKELY(backbufferChanged && (resizeFlags != eResizeRequested))) {
-        LOGE(   "backbuffer size changed, but both resize flags are not set! "
-                "(layer=%p), state=%08x, requested (%dx%d), drawing (%d,%d), "
-                "index=%d, (%dx%d), (%dx%d)",
-                this,  state,
-                int(temp.w), int(temp.h),
-                int(drawingState().w), int(drawingState().h),
-                int(clientBackBufferIndex),
-                int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
-                int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
-        // if we get there we're pretty screwed. the only reasonable
-        // thing to do is to pretend we should do the resize since
-        // backbufferChanged is set (this also will give a chance to
-        // client to get unblocked)
-        resizeFlags = eResizeRequested;
-    }
-
-    if (resizeFlags == eResizeRequested)  {
-        // NOTE: asserting that clientBackBufferIndex!=mFrontBufferIndex
-        // here, would be wrong and misleading because by this point
-        // mFrontBufferIndex has not been updated yet.
-
+    if (backbufferChanged) {
+        // the size changed, we need to ask our client to request a new buffer
         LOGD_IF(DEBUG_RESIZE,
-                    "resize (layer=%p), state=%08x, "
-                    "requested (%dx%d), "
-                    "drawing (%d,%d), "
-                    "index=%d, (%dx%d), (%dx%d)",
-                    this,  state,
-                    int(temp.w), int(temp.h),
+                    "resize (layer=%p), requested (%dx%d), "
+                    "drawing (%d,%d), (%dx%d), (%dx%d)",
+                    this, int(temp.w), int(temp.h),
                     int(drawingState().w), int(drawingState().h),
-                    int(clientBackBufferIndex),
-                    int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
-                    int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
+                    int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()),
+                    int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight()));
 
-        if (state & eLocked) {
-            // if the buffer is locked, we can't resize anything because
-            // - the backbuffer is currently in use by the user
-            // - the front buffer is being shown
-            // We just act as if the transaction didn't happen and we
-            // reschedule it later...
-            flags |= eRestartTransaction;
-        } else {
-            // This buffer needs to be resized
-            status_t err =
-                resize(clientBackBufferIndex, temp.w, temp.h, "transaction");
-            if (err == NO_ERROR) {
-                const uint32_t mask = clientBackBufferIndex ?
-                        eResizeBuffer1 : eResizeBuffer0;
-                android_atomic_and(~mask, &(lcblk->swapState));
-                // since a buffer became available, we can let the client go...
-                scheduleBroadcast();
-                mResizeTransactionDone = true;
+        // record the new size, form this point on, when the client request a
+        // buffer, it'll get the new size.
+        setDrawingSize(temp.w, temp.h);
 
-                // we're being resized and there is a freeze display request,
-                // acquire a freeze lock, so that the screen stays put
-                // until we've redrawn at the new size; this is to avoid
-                // glitches upon orientation changes.
-                if (mFlinger->hasFreezeRequest()) {
-                    // if the surface is hidden, don't try to acquire the
-                    // freeze lock, since hidden surfaces may never redraw
-                    if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
-                        mFreezeLock = mFlinger->getFreezeLock();
-                    }
-                }
+        // all buffers need reallocation
+        lcblk->reallocate();
+
+        // recompute the visible region
+        // FIXME: ideally we would do that only when we have received
+        // a buffer of the right size
+        flags |= Layer::eVisibleRegion;
+        this->contentDirty = true;
+        
+#if 0 
+        // FIXME: handle freeze lock
+        // we're being resized and there is a freeze display request,
+        // acquire a freeze lock, so that the screen stays put
+        // until we've redrawn at the new size; this is to avoid
+        // glitches upon orientation changes.
+        if (mFlinger->hasFreezeRequest()) {
+            // if the surface is hidden, don't try to acquire the
+            // freeze lock, since hidden surfaces may never redraw
+            if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
+                mFreezeLock = mFlinger->getFreezeLock();
             }
         }
+#endif
     }
-    
+
     if (temp.sequence != front.sequence) {
         if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
             // this surface is now hidden, so it shouldn't hold a freeze lock
@@ -402,65 +317,10 @@
     return LayerBase::doTransaction(flags);
 }
 
-status_t Layer::resize(
-        int32_t clientBackBufferIndex,
-        uint32_t width, uint32_t height,
-        const char* what)
-{
-    /*
-     * handle resize (backbuffer and frontbuffer reallocation)
-     * this is called from post() or from doTransaction()
-     */
-
-    const LayerBitmap& clientBackBuffer(mBuffers[clientBackBufferIndex]);
-
-    // if the new (transaction) size is != from the the backbuffer
-    // then we need to reallocate the backbuffer
-    bool backbufferChanged = (clientBackBuffer.getWidth()  != width) ||
-                             (clientBackBuffer.getHeight() != height);
-
-    LOGD_IF(!backbufferChanged,
-            "(%s) eResizeRequested (layer=%p), but size not changed: "
-            "requested (%dx%d), drawing (%d,%d), current (%d,%d),"
-            "state=%08lx, index=%d, (%dx%d), (%dx%d)",
-            what, this,
-            int(width), int(height),
-            int(drawingState().w), int(drawingState().h),
-            int(currentState().w), int(currentState().h),
-            long(lcblk->swapState),
-            int(clientBackBufferIndex),
-            int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
-            int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
-
-    // this can happen when changing the size back and forth quickly
-    status_t err = NO_ERROR;
-    if (backbufferChanged) {
-
-        LOGD_IF(DEBUG_RESIZE,
-                "resize (layer=%p), requested (%dx%d), "
-                "index=%d, (%dx%d), (%dx%d)",
-                this, int(width), int(height), int(clientBackBufferIndex),
-                int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
-                int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
-
-        err = mBuffers[clientBackBufferIndex].setSize(width, height);
-        if (UNLIKELY(err != NO_ERROR)) {
-            // This really should never happen
-            LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s",
-                    clientBackBufferIndex, width, height, err, strerror(err));
-            // couldn't reallocate the surface
-            android_atomic_write(eInvalidSurface, &lcblk->swapState);
-        }
-    }
-    return err;
-}
-
-void Layer::setSizeChanged(uint32_t w, uint32_t h)
-{
-    LOGD_IF(DEBUG_RESIZE,
-            "setSizeChanged w=%d, h=%d (old: w=%d, h=%d)",
-            w, h, mCurrentState.w, mCurrentState.h);
-    android_atomic_or(eResizeRequested, &(lcblk->swapState));
+void Layer::setDrawingSize(uint32_t w, uint32_t h) {
+    Mutex::Autolock _l(mLock);
+    mWidth = w;
+    mHeight = h;
 }
 
 // ----------------------------------------------------------------------------
@@ -469,139 +329,26 @@
 
 void Layer::lockPageFlip(bool& recomputeVisibleRegions)
 {
-    uint32_t state = android_atomic_or(eBusy, &(lcblk->swapState));
-    // preemptively block the client, because he might set
-    // eFlipRequested at any time and want to use this buffer
-    // for the next frame. This will be unset below if it
-    // turns out we didn't need it.
-
-    uint32_t mask = eInvalidSurface | eFlipRequested | eResizeRequested;
-    if (!(state & mask))
-        return;
-
-    if (UNLIKELY(state & eInvalidSurface)) {
-        // if eInvalidSurface is set, this means the surface
-        // became invalid during a transaction (NO_MEMORY for instance)
-        scheduleBroadcast();
+    ssize_t buf = lcblk->retireAndLock();
+    if (buf < NO_ERROR) {
+        //LOGW("nothing to retire (%s)", strerror(-buf));
+        // NOTE: here the buffer is locked because we will used 
+        // for composition later in the loop
         return;
     }
-
-    if (UNLIKELY(state & eFlipRequested)) {
-        uint32_t oldState;
-        mPostedDirtyRegion = post(&oldState, recomputeVisibleRegions);
-        if (oldState & eNextFlipPending) {
-            // Process another round (we know at least a buffer
-            // is ready for that client).
-            mFlinger->signalEvent();
-        }
-    }
-}
-
-Region Layer::post(uint32_t* previousSate, bool& recomputeVisibleRegions)
-{
-    // atomically swap buffers and (re)set eFlipRequested
-    int32_t oldValue, newValue;
-    layer_cblk_t * const lcblk = this->lcblk;
-    do {
-        oldValue = lcblk->swapState;
-            // get the current value
-
-        LOG_ASSERT(oldValue&eFlipRequested,
-            "eFlipRequested not set, yet we're flipping! (state=0x%08lx)",
-            long(oldValue));
-
-        newValue = (oldValue ^ eIndex);
-            // swap buffers
-
-        newValue &= ~(eFlipRequested | eNextFlipPending);
-            // clear eFlipRequested and eNextFlipPending
-
-        if (oldValue & eNextFlipPending)
-            newValue |= eFlipRequested;
-            // if eNextFlipPending is set (second buffer already has something
-            // in it) we need to reset eFlipRequested because the client
-            // might never do it
-
-    } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
-    *previousSate = oldValue;
     
-    const int32_t index = (newValue & eIndex) ^ 1;
-    mFrontBufferIndex = index;
+    // we retired a buffer, which becomes the new front buffer
+    mFrontBufferIndex = buf;
 
-    /* NOTE: it's safe to set this flag here because this is only touched
-     * from LayerBitmap::allocate(), which by construction cannot happen
-     * while we're in post().
-     */
-    lcblk->surface[index].flags &= ~surface_info_t::eBufferDirty;
+    // get the dirty region
+    sp<Buffer> newFrontBuffer(getBuffer(buf));
+    const Region dirty(lcblk->getDirtyRegion(buf));
+    mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
 
-    // ... post the new front-buffer
-    Region dirty(lcblk->region + index);
-    dirty.andSelf(frontBuffer().getBounds());
+    // FIXME: signal an event if we have more buffers waiting
+    // mFlinger->signalEvent();
 
-    //LOGD("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n",
-    //    oldValue, newValue, mFrontBufferIndex);
-    //dirty.dump("dirty");
-
-    if (UNLIKELY(oldValue & eResizeRequested)) {
-
-        LOGD_IF(DEBUG_RESIZE,
-                     "post (layer=%p), state=%08x, "
-                     "index=%d, (%dx%d), (%dx%d)",
-                     this,  newValue,
-                     int(1-index),
-                     int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
-                     int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
-
-        // here, we just posted the surface and we have resolved
-        // the front/back buffer indices. The client is blocked, so
-        // it cannot start using the new backbuffer.
-
-        // If the backbuffer was resized in THIS round, we actually cannot
-        // resize the frontbuffer because it has *just* been drawn (and we
-        // would have nothing to draw). In this case we just skip the resize
-        // it'll happen after the next page flip or during the next
-        // transaction.
-
-        const uint32_t mask = (1-index) ? eResizeBuffer1 : eResizeBuffer0;
-        if (mResizeTransactionDone && (newValue & mask)) {
-            // Resize the layer's second buffer only if the transaction
-            // happened. It may not have happened yet if eResizeRequested
-            // was set immediately after the "transactionRequested" test,
-            // in which case the drawing state's size would be wrong.
-            mFreezeLock.clear();
-            const Layer::State& s(drawingState());
-            if (resize(1-index, s.w, s.h, "post") == NO_ERROR) {
-                do {
-                    oldValue = lcblk->swapState;
-                    if ((oldValue & eResizeRequested) == eResizeRequested) {
-                        // ugh, another resize was requested since we processed
-                        // the first buffer, don't free the client, and let
-                        // the next transaction handle everything.
-                        break;
-                    }
-                    newValue = oldValue & ~mask;
-                } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
-            }
-            mResizeTransactionDone = false;
-            recomputeVisibleRegions = true;
-            this->contentDirty = true;
-        }
-    }
-
-    reloadTexture(dirty);
-
-    return dirty;
-}
-
-Point Layer::getPhysicalSize() const
-{
-    sp<const Buffer> front(frontBuffer().getBuffer());
-    Point size(front->getWidth(), front->getHeight());
-    if ((size.x | size.y) == 0) {
-        // if we don't have a buffer yet, just use the state's size.
-        size = LayerBase::getPhysicalSize();
-    }
-    return size;
+    reloadTexture( mPostedDirtyRegion );
 }
 
 void Layer::unlockPageFlip(
@@ -622,21 +369,15 @@
         // is in screen space as well).
         dirtyRegion.andSelf(visibleRegionScreen);
         outDirtyRegion.orSelf(dirtyRegion);
-
-        // client could be blocked, so signal them so they get a
-        // chance to reevaluate their condition.
-        scheduleBroadcast();
     }
 }
 
 void Layer::finishPageFlip()
 {
-    if (LIKELY(!(lcblk->swapState & eInvalidSurface))) {
-        LOGE_IF(!(lcblk->swapState & eBusy),
-                "layer %p wasn't locked!", this);
-        android_atomic_and(~eBusy, &(lcblk->swapState));
-    }
-    scheduleBroadcast();
+    status_t err = lcblk->unlock( mFrontBufferIndex );
+    LOGE_IF(err!=NO_ERROR, 
+            "layer %p, buffer=%d wasn't locked!",
+            this, mFrontBufferIndex);
 }
 
 // ---------------------------------------------------------------------------
@@ -651,12 +392,16 @@
 {
 }
 
-sp<SurfaceBuffer> Layer::SurfaceLayer::getBuffer(int usage)
+sp<SurfaceBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage)
 {
-    sp<SurfaceBuffer> buffer = 0;
+    sp<SurfaceBuffer> buffer;
     sp<Layer> owner(getOwner());
     if (owner != 0) {
-        buffer = owner->peekBuffer(usage);
+        LOGE_IF(uint32_t(index)>=NUM_BUFFERS,
+                "getBuffer() index (%d) out of range", index);
+        if (uint32_t(index) < NUM_BUFFERS) {
+            buffer = owner->requestBuffer(index, usage);
+        }
     }
     return buffer;
 }
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index add5d50..3b4489e 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -21,10 +21,6 @@
 #include <sys/types.h>
 
 #include <ui/PixelFormat.h>
-
-#include <private/ui/SharedState.h>
-#include <private/ui/LayerState.h>
-
 #include <pixelflinger/pixelflinger.h>
 
 #include <EGL/egl.h>
@@ -32,7 +28,7 @@
 #include <GLES/gl.h>
 #include <GLES/glext.h>
 
-#include "LayerBitmap.h"
+#include "Buffer.h"
 #include "LayerBase.h"
 #include "Transform.h"
 
@@ -41,12 +37,12 @@
 // ---------------------------------------------------------------------------
 
 class Client;
-class LayerBitmap;
 class FreezeLock;
+class Buffer;
 
 // ---------------------------------------------------------------------------
 
-const int NUM_BUFFERS = 2;
+const size_t NUM_BUFFERS = 2;
 
 class Layer : public LayerBaseClient
 {
@@ -56,23 +52,22 @@
     virtual char const* getTypeID() const { return typeID; }
     virtual uint32_t getTypeInfo() const { return typeInfo; }
 
+    
+    SharedBufferServer*     lcblk;
+
+    
                  Layer(SurfaceFlinger* flinger, DisplayID display,
                          const sp<Client>& client, int32_t i);
 
         virtual ~Layer();
 
-    inline PixelFormat pixelFormat() const {
-        return frontBuffer().getPixelFormat();
-    }
+    status_t setBuffers(uint32_t w, uint32_t h, 
+            PixelFormat format, uint32_t flags=0);
 
-    status_t setBuffers(    uint32_t w, uint32_t h,
-                            PixelFormat format, uint32_t flags=0);
+    void setDrawingSize(uint32_t w, uint32_t h);
 
     virtual void onDraw(const Region& clip) const;
-    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
-    virtual void setSizeChanged(uint32_t w, uint32_t h);
     virtual uint32_t doTransaction(uint32_t transactionFlags);
-    virtual Point getPhysicalSize() const;
     virtual void lockPageFlip(bool& recomputeVisibleRegions);
     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
     virtual void finishPageFlip();
@@ -80,42 +75,31 @@
     virtual bool isSecure() const           { return mSecure; }
     virtual sp<Surface> createSurface() const;
     virtual status_t ditch();
-
-    const LayerBitmap& getBuffer(int i) const { return mBuffers[i]; }
-          LayerBitmap& getBuffer(int i)       { return mBuffers[i]; }
-
+    
     // only for debugging
-    const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
+    inline sp<Buffer> getBuffer(int i) { return mBuffers[i]; }
+    // only for debugging
+    inline const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
+    // only for debugging
+    inline PixelFormat pixelFormat() const { return mFormat; }
 
 private:
-    inline const LayerBitmap&
-            frontBuffer() const { return getBuffer(mFrontBufferIndex); }
-    inline LayerBitmap&
-            frontBuffer()       { return getBuffer(mFrontBufferIndex); }
-    inline const LayerBitmap&
-            backBuffer() const  { return getBuffer(1-mFrontBufferIndex); }
-    inline LayerBitmap&
-            backBuffer()        { return getBuffer(1-mFrontBufferIndex); }
-
+    inline sp<Buffer> getFrontBuffer() {
+        return mBuffers[mFrontBufferIndex];
+    }
+ 
     void reloadTexture(const Region& dirty);
 
-    status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what);
-    Region post(uint32_t* oldState, bool& recomputeVisibleRegions);
-    sp<SurfaceBuffer> peekBuffer(int usage);
+    sp<SurfaceBuffer> requestBuffer(int index, int usage);
     void destroy();
-    void scheduleBroadcast();
 
-    
-    class SurfaceLayer : public LayerBaseClient::Surface
-    {
+    class SurfaceLayer : public LayerBaseClient::Surface {
     public:
-                SurfaceLayer(const sp<SurfaceFlinger>& flinger,
-                        SurfaceID id, const sp<Layer>& owner);
-                ~SurfaceLayer();
-
+        SurfaceLayer(const sp<SurfaceFlinger>& flinger,
+                SurfaceID id, const sp<Layer>& owner);
+        ~SurfaceLayer();
     private:
-        virtual sp<SurfaceBuffer> getBuffer(int usage);
-
+        virtual sp<SurfaceBuffer> requestBuffer(int index, int usage);
         sp<Layer> getOwner() const {
             return static_cast<Layer*>(Surface::getOwner().get());
         }
@@ -125,13 +109,20 @@
     sp<Surface>             mSurface;
 
             bool            mSecure;
-            LayerBitmap     mBuffers[NUM_BUFFERS];
-            Texture         mTextures[NUM_BUFFERS];
             int32_t         mFrontBufferIndex;
             bool            mNeedsBlending;
-            bool            mResizeTransactionDone;
             Region          mPostedDirtyRegion;
             sp<FreezeLock>  mFreezeLock;
+            PixelFormat     mFormat;
+            uint32_t        mBufferFlags;
+            
+            // protected by mLock
+            sp<Buffer>      mBuffers[NUM_BUFFERS];
+            Texture         mTextures[NUM_BUFFERS];
+            uint32_t        mWidth;
+            uint32_t        mHeight;
+            
+   mutable Mutex mLock;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index fd54e35..62e41b0 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -30,7 +30,6 @@
 
 #include "clz.h"
 #include "LayerBase.h"
-#include "LayerBlur.h"
 #include "SurfaceFlinger.h"
 #include "DisplayHardware/DisplayHardware.h"
 
@@ -127,9 +126,6 @@
     return android_atomic_or(flags, &mTransactionFlags);
 }
 
-void LayerBase::setSizeChanged(uint32_t w, uint32_t h) {
-}
-
 bool LayerBase::setPosition(int32_t x, int32_t y) {
     if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
         return false;
@@ -149,7 +145,6 @@
 bool LayerBase::setSize(uint32_t w, uint32_t h) {
     if (mCurrentState.w == w && mCurrentState.h == h)
         return false;
-    setSizeChanged(w, h);
     mCurrentState.w = w;
     mCurrentState.h = h;
     requestTransaction();
@@ -219,21 +214,14 @@
     return flags;
 }
 
-Point LayerBase::getPhysicalSize() const
-{
-    const Layer::State& front(drawingState());
-    return Point(front.w, front.h);
-}
-
 void LayerBase::validateVisibility(const Transform& planeTransform)
 {
     const Layer::State& s(drawingState());
     const Transform tr(planeTransform * s.transform);
     const bool transformed = tr.transformed();
    
-    const Point size(getPhysicalSize());
-    uint32_t w = size.x;
-    uint32_t h = size.y;    
+    uint32_t w = s.w;
+    uint32_t h = s.h;    
     tr.transform(mVertices[0], 0, 0);
     tr.transform(mVertices[1], 0, h);
     tr.transform(mVertices[2], w, h);
@@ -354,11 +342,13 @@
     return textureName;
 }
 
-void LayerBase::clearWithOpenGL(const Region& clip) const
+void LayerBase::clearWithOpenGL(const Region& clip, GLclampx red,
+                                GLclampx green, GLclampx blue,
+                                GLclampx alpha) const
 {
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     const uint32_t fbHeight = hw.getHeight();
-    glColor4x(0,0,0,0);
+    glColor4x(red,green,blue,alpha);
     glDisable(GL_TEXTURE_2D);
     glDisable(GL_BLEND);
     glDisable(GL_DITHER);
@@ -377,6 +367,11 @@
     }
 }
 
+void LayerBase::clearWithOpenGL(const Region& clip) const
+{
+    clearWithOpenGL(clip,0,0,0,0);
+}
+
 void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
 {
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
@@ -391,7 +386,8 @@
     glEnable(GL_TEXTURE_2D);
 
     // Dithering...
-    if (s.flags & ISurfaceComposer::eLayerDither) {
+    bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
+    if (fast || s.flags & ISurfaceComposer::eLayerDither) {
         glEnable(GL_DITHER);
     } else {
         glDisable(GL_DITHER);
@@ -647,9 +643,7 @@
 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
         const sp<Client>& client, int32_t i)
     : LayerBase(flinger, display), client(client),
-      lcblk( client!=0 ? &(client->ctrlblk->layers[i]) : 0 ),
-      mIndex(i),
-      mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
+      mIndex(i), mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
 {
 }
 
@@ -658,11 +652,8 @@
     sp<Client> client(this->client.promote());
     if (client != 0) {
         client->bindLayer(this, mIndex);
-        // Initialize this layer's control block
-        memset(this->lcblk, 0, sizeof(layer_cblk_t));
-        this->lcblk->identity = mIdentity;
-        Region::writeEmpty(&(this->lcblk->region[0]), sizeof(flat_region_t));
-        Region::writeEmpty(&(this->lcblk->region[1]), sizeof(flat_region_t));
+        // Initialize this layer's identity
+        client->ctrlblk->setIdentity(mIndex, mIdentity);
     }
 }
 
@@ -751,7 +742,7 @@
     return BnSurface::onTransact(code, data, reply, flags);
 }
 
-sp<SurfaceBuffer> LayerBaseClient::Surface::getBuffer(int) 
+sp<SurfaceBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) 
 {
     return NULL; 
 }
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 7791941..78bb4bf 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -23,6 +23,7 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
+#include <private/ui/SharedBufferStack.h>
 #include <private/ui/LayerState.h>
 
 #include <utils/RefBase.h>
@@ -137,11 +138,6 @@
     virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
     
     /**
-     * setSizeChanged - called when the *current* state's size is changed.
-     */
-    virtual void setSizeChanged(uint32_t w, uint32_t h);
-    
-    /**
      * doTransaction - process the transaction. This is a good place to figure
      * out which attributes of the surface have changed.
      */
@@ -161,13 +157,6 @@
     virtual void setCoveredRegion(const Region& coveredRegion);
     
     /**
-     * getPhysicalSize - returns the physical size of the drawing state of
-     * the surface. If the surface is backed by a bitmap, this is the size of
-     * the bitmap (as opposed to the size of the drawing state).
-     */
-    virtual Point getPhysicalSize() const;
-
-    /**
      * validateVisibility - cache a bunch of things
      */
     virtual void validateVisibility(const Transform& globalTransform);
@@ -251,7 +240,9 @@
               uint32_t      transform;
               bool          dirty;
           };
-          
+
+          void clearWithOpenGL(const Region& clip, GLclampx r, GLclampx g,
+                               GLclampx b, GLclampx alpha) const;
           void clearWithOpenGL(const Region& clip) const;
           void drawWithOpenGL(const Region& clip, const Texture& texture) const;
           void loadTexture(Texture* texture, GLint textureName, 
@@ -306,8 +297,8 @@
     virtual ~LayerBaseClient();
     virtual void onFirstRef();
 
-    wp<Client>          client;
-    layer_cblk_t*       const lcblk;
+    wp<Client>              client;
+//    SharedBufferServer*     lcblk;
 
     inline  uint32_t    getIdentity() const { return mIdentity; }
     inline  int32_t     clientIndex() const { return mIndex; }
@@ -334,7 +325,7 @@
         sp<LayerBaseClient> getOwner() const;
 
     private:
-        virtual sp<SurfaceBuffer> getBuffer(int usage);
+        virtual sp<SurfaceBuffer> requestBuffer(int index, int usage);
         virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); 
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
deleted file mode 100644
index 87e8f42..0000000
--- a/libs/surfaceflinger/LayerBitmap.h
+++ /dev/null
@@ -1,134 +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_BITMAP_H
-#define ANDROID_LAYER_BITMAP_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <hardware/gralloc.h>
-
-#include <utils/Atomic.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/Rect.h>
-#include <ui/Surface.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include <private/ui/SharedState.h>
-#include <private/ui/SurfaceBuffer.h>
-
-class copybit_image_t;
-struct android_native_buffer_t;
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-class IMemory;
-class LayerBitmap;
-
-// ===========================================================================
-// Buffer
-// ===========================================================================
-
-class NativeBuffer;
-
-class Buffer : public SurfaceBuffer
-{
-public:
-    enum {
-        DONT_CLEAR  = 0x00000001,
-        SECURE      = 0x00000004
-    };
-
-    // creates w * h buffer
-    Buffer(uint32_t w, uint32_t h, PixelFormat format,
-            uint32_t reqUsage, uint32_t flags = 0);
-
-    // return status
-    status_t initCheck() const;
-
-    uint32_t getWidth() const           { return width; }
-    uint32_t getHeight() const          { return height; }
-    uint32_t getStride() const          { return stride; }
-    uint32_t getUsage() const           { return usage; }
-    PixelFormat getPixelFormat() const  { return format; }
-    Rect getBounds() const              { return Rect(width, height); }
-    
-    status_t lock(GGLSurface* surface, uint32_t usage);
-    
-    android_native_buffer_t* getNativeBuffer() const;
-    
-private:
-    friend class LightRefBase<Buffer>;
-    Buffer(const Buffer& rhs);
-    virtual ~Buffer();
-    Buffer& operator = (const Buffer& rhs);
-    const Buffer& operator = (const Buffer& rhs) const;
-
-    status_t initSize(uint32_t w, uint32_t h, uint32_t reqUsage);
-
-    ssize_t                 mInitCheck;
-    uint32_t                mFlags;
-    uint32_t                mVStride;
-};
-
-// ===========================================================================
-// LayerBitmap
-// ===========================================================================
-
-class LayerBitmap
-{
-public:
-    enum {
-        DONT_CLEAR  = Buffer::DONT_CLEAR,
-        SECURE      = Buffer::SECURE
-    };
-    LayerBitmap();
-    ~LayerBitmap();
-
-    status_t init(surface_info_t* info,
-            uint32_t w, uint32_t h, PixelFormat format, uint32_t flags = 0);
-
-    status_t setSize(uint32_t w, uint32_t h);
-
-    sp<Buffer> allocate(uint32_t reqUsage);
-    status_t free();
-    
-    sp<const Buffer>  getBuffer() const { return mBuffer; }
-    sp<Buffer>        getBuffer()       { return mBuffer; }
-    
-    uint32_t getWidth() const           { return mWidth; }
-    uint32_t getHeight() const          { return mHeight; }
-    PixelFormat getPixelFormat() const  { return mBuffer->getPixelFormat(); }
-    Rect getBounds() const              { return mBuffer->getBounds(); }
-    
-private:
-    surface_info_t* mInfo;
-    sp<Buffer>      mBuffer;
-    uint32_t        mWidth;
-    uint32_t        mHeight;
-    PixelFormat     mFormat;
-    uint32_t        mFlags;
-    // protects setSize() and allocate()
-    mutable Mutex   mLock;
-};
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BITMAP_H
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index bd6d472..433b48e 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -28,6 +28,7 @@
 
 #include <hardware/copybit.h>
 
+#include "Buffer.h"
 #include "BufferAllocator.h"
 #include "LayerBuffer.h"
 #include "SurfaceFlinger.h"
@@ -58,7 +59,7 @@
 void LayerBuffer::onFirstRef()
 {
     LayerBaseClient::onFirstRef();
-    mSurface = new SurfaceBuffer(mFlinger, clientIndex(),
+    mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(),
             const_cast<LayerBuffer *>(this));
 }
 
@@ -181,21 +182,21 @@
 }
 
 // ============================================================================
-// LayerBuffer::SurfaceBuffer
+// LayerBuffer::SurfaceLayerBuffer
 // ============================================================================
 
-LayerBuffer::SurfaceBuffer::SurfaceBuffer(const sp<SurfaceFlinger>& flinger,
+LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
         SurfaceID id, const sp<LayerBuffer>& owner)
     : LayerBaseClient::Surface(flinger, id, owner->getIdentity(), owner)
 {
 }
 
-LayerBuffer::SurfaceBuffer::~SurfaceBuffer()
+LayerBuffer::SurfaceLayerBuffer::~SurfaceLayerBuffer()
 {
     unregisterBuffers();
 }
 
-status_t LayerBuffer::SurfaceBuffer::registerBuffers(
+status_t LayerBuffer::SurfaceLayerBuffer::registerBuffers(
         const ISurface::BufferHeap& buffers)
 {
     sp<LayerBuffer> owner(getOwner());
@@ -204,21 +205,21 @@
     return NO_INIT;
 }
 
-void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset)
+void LayerBuffer::SurfaceLayerBuffer::postBuffer(ssize_t offset)
 {
     sp<LayerBuffer> owner(getOwner());
     if (owner != 0)
         owner->postBuffer(offset);
 }
 
-void LayerBuffer::SurfaceBuffer::unregisterBuffers()
+void LayerBuffer::SurfaceLayerBuffer::unregisterBuffers()
 {
     sp<LayerBuffer> owner(getOwner());
     if (owner != 0)
         owner->unregisterBuffers();
 }
 
-sp<OverlayRef> LayerBuffer::SurfaceBuffer::createOverlay(
+sp<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay(
         uint32_t w, uint32_t h, int32_t format) {
     sp<OverlayRef> result;
     sp<LayerBuffer> owner(getOwner());
@@ -462,8 +463,8 @@
                 const int tmp_h = floorf(src_height * yscale);
                 
                 if (mTempBitmap==0 || 
-                        mTempBitmap->getWidth() < tmp_w || 
-                        mTempBitmap->getHeight() < tmp_h) {
+                        mTempBitmap->getWidth() < size_t(tmp_w) || 
+                        mTempBitmap->getHeight() < size_t(tmp_h)) {
                     mTempBitmap.clear();
                     mTempBitmap = new android::Buffer(
                             tmp_w, tmp_h, src.img.format,
@@ -600,7 +601,11 @@
 
 void LayerBuffer::OverlaySource::onDraw(const Region& clip) const
 {
-    mLayer.clearWithOpenGL(clip);
+    GLclampx color = 0x000018; //dark blue
+    GLclampx red = 0;
+    GLclampx green = 0;
+    GLclampx blue = 0x1818;
+    mLayer.clearWithOpenGL(clip, red, green, blue, 0);
 }
 
 void LayerBuffer::OverlaySource::onTransaction(uint32_t flags)
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 8057219..e539f68 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -24,7 +24,6 @@
 #include <private/ui/LayerState.h>
 
 #include "LayerBase.h"
-#include "LayerBitmap.h"
 
 struct copybit_device_t;
 
@@ -32,9 +31,12 @@
 
 // ---------------------------------------------------------------------------
 
+class Buffer;
 class Region;
 class OverlayRef;
 
+// ---------------------------------------------------------------------------
+
 class LayerBuffer : public LayerBaseClient
 {
     class Source : public LightRefBase<Source> {
@@ -179,12 +181,12 @@
     };
 
 
-    class SurfaceBuffer : public LayerBaseClient::Surface
+    class SurfaceLayerBuffer : public LayerBaseClient::Surface
     {
     public:
-                SurfaceBuffer(const sp<SurfaceFlinger>& flinger,
+        SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
                         SurfaceID id, const sp<LayerBuffer>& owner);
-        virtual ~SurfaceBuffer();
+        virtual ~SurfaceLayerBuffer();
 
         virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
         virtual void postBuffer(ssize_t offset);
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
index f613767..8ba0a9d 100644
--- a/libs/surfaceflinger/LayerDim.cpp
+++ b/libs/surfaceflinger/LayerDim.cpp
@@ -21,6 +21,7 @@
 #include <utils/Errors.h>
 #include <utils/Log.h>
 
+#include "Buffer.h"
 #include "BufferAllocator.h"
 #include "LayerDim.h"
 #include "SurfaceFlinger.h"
diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h
index 33bd49d..d4672a1 100644
--- a/libs/surfaceflinger/LayerDim.h
+++ b/libs/surfaceflinger/LayerDim.h
@@ -24,12 +24,11 @@
 #include <EGL/eglext.h>
 
 #include "LayerBase.h"
-#include "LayerBitmap.h"
-
-namespace android {
 
 // ---------------------------------------------------------------------------
 
+namespace android {
+
 class LayerDim : public LayerBaseClient
 {
     static bool sUseTexture;
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index a72294a..b368db6 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -44,12 +44,12 @@
 #include <GLES/gl.h>
 
 #include "clz.h"
+#include "Buffer.h"
 #include "BufferAllocator.h"
 #include "Layer.h"
 #include "LayerBlur.h"
 #include "LayerBuffer.h"
 #include "LayerDim.h"
-#include "LayerBitmap.h"
 #include "SurfaceFlinger.h"
 
 #include "DisplayHardware/DisplayHardware.h"
@@ -173,12 +173,12 @@
     :   BnSurfaceComposer(), Thread(false),
         mTransactionFlags(0),
         mTransactionCount(0),
+        mResizeTransationPending(false),
         mLayersRemoved(false),
         mBootTime(systemTime()),
         mHardwareTest("android.permission.HARDWARE_TEST"),
         mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
         mDump("android.permission.DUMP"),
-        mLastScheduledBroadcast(NULL),
         mVisibleRegionsDirty(false),
         mDeferReleaseConsole(false),
         mFreezeDisplay(false),
@@ -497,13 +497,11 @@
 
         // release the clients before we flip ('cause flip might block)
         unlockClients();
-        executeScheduledBroadcasts();
 
         postFramebuffer();
     } else {
         // pretend we did the post
         unlockClients();
-        executeScheduledBroadcasts();
         usleep(16667); // 60 fps period
     }
     return true;
@@ -573,8 +571,10 @@
     // do this without lock held
     const size_t count = ditchedLayers.size();
     for (size_t i=0 ; i<count ; i++) {
-        //LOGD("ditching layer %p", ditchedLayers[i].get());
-        ditchedLayers[i]->ditch();
+        if (ditchedLayers[i] != 0) {
+            //LOGD("ditching layer %p", ditchedLayers[i].get());
+            ditchedLayers[i]->ditch();
+        }
     }
 }
 
@@ -771,7 +771,8 @@
 void SurfaceFlinger::commitTransaction()
 {
     mDrawingState = mCurrentState;
-    mTransactionCV.signal();
+    mResizeTransationPending = false;
+    mTransactionCV.broadcast();
 }
 
 void SurfaceFlinger::handlePageFlip()
@@ -908,37 +909,6 @@
     }
 }
 
-void SurfaceFlinger::scheduleBroadcast(const sp<Client>& client)
-{
-    if (mLastScheduledBroadcast != client) {
-        mLastScheduledBroadcast = client;
-        mScheduledBroadcasts.add(client);
-    }
-}
-
-void SurfaceFlinger::executeScheduledBroadcasts()
-{
-    SortedVector< wp<Client> >& list(mScheduledBroadcasts);
-    size_t count = list.size();
-    while (count--) {
-        sp<Client> client = list[count].promote();
-        if (client != 0) {
-            per_client_cblk_t* const cblk = client->ctrlblk;
-            if (cblk->lock.tryLock() == NO_ERROR) {
-                cblk->cv.broadcast();
-                list.removeAt(count);
-                cblk->lock.unlock();
-            } else {
-                // schedule another round
-                LOGW("executeScheduledBroadcasts() skipped, "
-                        "contention on the client. We'll try again later...");
-                signalDelayedEvent(ms2ns(4));
-            }
-        }
-    }
-    mLastScheduledBroadcast = 0;
-}
-
 void SurfaceFlinger::debugFlashRegions()
 {
      const DisplayHardware& hw(graphicPlane(0).displayHardware());
@@ -1082,6 +1052,8 @@
 
 status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
 {
+    if (layer == 0)
+        return BAD_VALUE;
     ssize_t i = mCurrentState.layersSortedByZ.add(
                 layer, &LayerBase::compareCurrentStateZ);
     sp<LayerBaseClient> lbc = LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
@@ -1125,18 +1097,10 @@
     mLayersRemoved = false;
     
     // free resources associated with disconnected clients
-    SortedVector< wp<Client> >& scheduledBroadcasts(mScheduledBroadcasts);
     Vector< sp<Client> >& disconnectedClients(mDisconnectedClients);
     const size_t count = disconnectedClients.size();
     for (size_t i=0 ; i<count ; i++) {
         sp<Client> client = disconnectedClients[i];
-        // if this client is the scheduled broadcast list,
-        // remove it from there (and we don't need to signal it
-        // since it is dead).
-        int32_t index = scheduledBroadcasts.indexOf(client);
-        if (index >= 0) {
-            scheduledBroadcasts.removeItemsAt(index);
-        }
         mTokens.release(client->cid);
     }
     disconnectedClients.clear();
@@ -1169,6 +1133,13 @@
 {
     if (android_atomic_dec(&mTransactionCount) == 1) {
         signalEvent();
+
+        // if there is a transaction with a resize, wait for it to 
+        // take effect before returning.
+        Mutex::Autolock _l(mStateLock);
+        while (mResizeTransationPending) {
+            mTransactionCV.wait(mStateLock);
+        }
     }
 }
 
@@ -1420,8 +1391,10 @@
                 }
             }
             if (what & eSizeChanged) {
-                if (layer->setSize(s.w, s.h))
+                if (layer->setSize(s.w, s.h)) {
                     flags |= eTraversalNeeded;
+                    mResizeTransationPending = true;
+                }
             }
             if (what & eAlphaChanged) {
                 if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
@@ -1539,28 +1512,27 @@
                         "id=0x%08x, client=0x%08x, identity=%u\n",
                         lbc->clientIndex(), client.get() ? client->cid : 0,
                         lbc->getIdentity());
+
+                result.append(buffer);
+                buffer[0] = 0;
             }
-            result.append(buffer);
-            buffer[0] = 0;
             /*** Layer ***/
             sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get());
             if (l != 0) {
-                const LayerBitmap& buf0(l->getBuffer(0));
-                const LayerBitmap& buf1(l->getBuffer(1));
+                result.append( l->lcblk->dump("      ") );
+                sp<const Buffer> buf0(l->getBuffer(0));
+                sp<const Buffer> buf1(l->getBuffer(1));
                 snprintf(buffer, SIZE,
                         "      "
                         "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
-                        " freezeLock=%p, swapState=0x%08x\n",
+                        " freezeLock=%p\n",
                         l->pixelFormat(),
-                        buf0.getWidth(), buf0.getHeight(), 
-                        buf0.getBuffer()->getStride(),
-                        buf1.getWidth(), buf1.getHeight(), 
-                        buf1.getBuffer()->getStride(),
-                        l->getFreezeLock().get(),
-                        l->lcblk->swapState);
+                        buf0->getWidth(), buf0->getHeight(), buf0->getStride(),
+                        buf1->getWidth(), buf1->getHeight(), buf1->getStride(),
+                        l->getFreezeLock().get());
+                result.append(buffer);
+                buffer[0] = 0;
             }
-            result.append(buffer);
-            buffer[0] = 0;
             s.transparentRegion.dump(result, "transparentRegion");
             layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
             layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
@@ -1653,8 +1625,12 @@
                 const DisplayHardware& hw(graphicPlane(0).displayHardware());
                 mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
                 signalEvent();
+                return NO_ERROR;
             }
-            return NO_ERROR;
+            case 1005:{ // force transaction
+                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
+                return NO_ERROR;
+            }
             case 1007: // set mFreezeCount
                 mFreezeCount = data.readInt32();
                 return NO_ERROR;
@@ -1684,21 +1660,20 @@
     : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
 {
     const int pgsize = getpagesize();
-    const int cblksize = ((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
+    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
 
     mCblkHeap = new MemoryHeapBase(cblksize, 0,
             "SurfaceFlinger Client control-block");
 
-    ctrlblk = static_cast<per_client_cblk_t *>(mCblkHeap->getBase());
+    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
     if (ctrlblk) { // construct the shared structure in-place.
-        new(ctrlblk) per_client_cblk_t;
+        new(ctrlblk) SharedClient;
     }
 }
 
 Client::~Client() {
     if (ctrlblk) {
-        const int pgsize = getpagesize();
-        ctrlblk->~per_client_cblk_t();  // destroy our shared-structure.
+        ctrlblk->~SharedClient();  // destroy our shared-structure.
     }
 }
 
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 69e2f2e..f207f85 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -34,7 +34,7 @@
 #include <ui/ISurfaceComposer.h>
 #include <ui/ISurfaceFlingerClient.h>
 
-#include <private/ui/SharedState.h>
+#include <private/ui/SharedBufferStack.h>
 #include <private/ui/LayerState.h>
 
 #include "Barrier.h"
@@ -87,7 +87,7 @@
     }
     
     // pointer to this client's control block
-    per_client_cblk_t*      ctrlblk;
+    SharedClient*           ctrlblk;
     ClientID                cid;
 
     
@@ -268,8 +268,6 @@
             bool        lockPageFlip(const LayerVector& currentLayers);
             void        unlockPageFlip(const LayerVector& currentLayers);
             void        handleRepaint();
-            void        scheduleBroadcast(const sp<Client>& client);
-            void        executeScheduledBroadcasts();
             void        postFramebuffer();
             void        composeSurfaces(const Region& dirty);
             void        unlockClients();
@@ -313,6 +311,7 @@
     volatile    int32_t                 mTransactionFlags;
     volatile    int32_t                 mTransactionCount;
                 Condition               mTransactionCV;
+                bool                    mResizeTransationPending;
                 
                 // protected by mStateLock (but we could use another lock)
                 Tokenizer                               mTokens;
@@ -337,8 +336,6 @@
                 Region                      mDirtyRegionRemovedLayer;
                 Region                      mInvalidRegion;
                 Region                      mWormholeRegion;
-                wp<Client>                  mLastScheduledBroadcast;
-                SortedVector< wp<Client> >  mScheduledBroadcasts;
                 bool                        mVisibleRegionsDirty;
                 bool                        mDeferReleaseConsole;
                 bool                        mFreezeDisplay;
diff --git a/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.cpp b/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.cpp
deleted file mode 100644
index 2de628b..0000000
--- a/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.cpp
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-#include <binder/IBinder.h>
-#include <binder/MemoryDealer.h>
-#include <binder/MemoryBase.h>
-#include <binder/MemoryHeapPmem.h>
-#include <binder/MemoryHeapBase.h>
-#include <binder/IPCThreadState.h>
-#include <utils/StopWatch.h>
-
-#include <ui/ISurfaceComposer.h>
-
-#include "VRamHeap.h"
-#include "GPUHardware.h"
-
-#if HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-#include "GPUHardware/GPUHardware.h"
-
-
-/* 
- * Manage the GPU. This implementation is very specific to the G1.
- * There are no abstraction here. 
- * 
- * All this code will soon go-away and be replaced by a new architecture
- * for managing graphics accelerators.
- * 
- * In the meantime, it is conceptually possible to instantiate a
- * GPUHardwareInterface for another GPU (see GPUFactory at the bottom
- * of this file); practically... doubtful.
- * 
- */
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class GPUClientHeap;
-class GPUAreaHeap;
-
-class GPUHardware : public GPUHardwareInterface, public IBinder::DeathRecipient
-{
-public:
-    static const int GPU_RESERVED_SIZE;
-    static const int GPUR_SIZE;
-
-            GPUHardware();
-    virtual ~GPUHardware();
-    
-    virtual void revoke(int pid);
-    virtual sp<MemoryDealer> request(int pid);
-    virtual status_t request(int pid, 
-            const sp<IGPUCallback>& callback,
-            ISurfaceComposer::gpu_info_t* gpu);
-
-    virtual status_t friendlyRevoke();
-    virtual void unconditionalRevoke();
-    
-    virtual pid_t getOwner() const { return mOwner; }
-
-    // used for debugging only...
-    virtual sp<SimpleBestFitAllocator> getAllocator() const;
-
-private:
-    
-    
-    enum {
-        NO_OWNER = -1,
-    };
-        
-    struct GPUArea {
-        sp<GPUAreaHeap>     heap;
-        sp<MemoryHeapPmem>  clientHeap;
-        sp<IMemory> map();
-    };
-    
-    struct Client {
-        pid_t       pid;
-        GPUArea     smi;
-        GPUArea     ebi;
-        GPUArea     reg;
-        void createClientHeaps();
-        void revokeAllHeaps();
-    };
-    
-    Client& getClientLocked(pid_t pid);
-    status_t requestLocked(int pid);
-    void releaseLocked();
-    void takeBackGPULocked();
-    void registerCallbackLocked(const sp<IGPUCallback>& callback,
-            Client& client);
-
-    virtual void binderDied(const wp<IBinder>& who);
-
-    mutable Mutex           mLock;
-    sp<GPUAreaHeap>         mSMIHeap;
-    sp<GPUAreaHeap>         mEBIHeap;
-    sp<GPUAreaHeap>         mREGHeap;
-
-    KeyedVector<pid_t, Client> mClients;
-    DefaultKeyedVector< wp<IBinder>, pid_t > mRegisteredClients;
-    
-    pid_t                   mOwner;
-
-    sp<MemoryDealer>        mCurrentAllocator;
-    sp<IGPUCallback>        mCallback;
-    
-    sp<SimpleBestFitAllocator>  mAllocator;
-
-    Condition               mCondition;
-};
-
-// size reserved for GPU surfaces
-// 1200 KB fits exactly:
-//  - two 320*480 16-bits double-buffered surfaces
-//  - one 320*480 32-bits double-buffered surface
-//  - one 320*240 16-bits double-buffered, 4x anti-aliased surface
-const int GPUHardware::GPU_RESERVED_SIZE  = 1200 * 1024;
-const int GPUHardware::GPUR_SIZE          = 1 * 1024 * 1024;
-
-// ---------------------------------------------------------------------------
-
-/* 
- * GPUHandle is a special IMemory given to the client. It represents their
- * handle to the GPU. Once they give it up, they loose GPU access, or if
- * they explicitly revoke their access through the binder code 1000.
- * In both cases, this triggers a callback to revoke()
- * first, and then actually powers down the chip.
- * 
- * In the case of a misbehaving app, GPUHardware can ask for an immediate
- * release of the GPU to the target process which should answer by calling
- * code 1000 on GPUHandle. If it doesn't in a timely manner, the GPU will
- * be revoked from under their feet.
- * 
- * We should never hold a strong reference on GPUHandle. In practice this
- * shouldn't be a big issue though because clients should use code 1000 and
- * not rely on the dtor being called.
- * 
- */
-
-class GPUClientHeap : public MemoryHeapPmem
-{
-public:
-    GPUClientHeap(const wp<GPUHardware>& gpu, 
-            const sp<MemoryHeapBase>& heap)
-        :  MemoryHeapPmem(heap), mGPU(gpu) { }
-protected:
-    wp<GPUHardware> mGPU;
-};
-
-class GPUAreaHeap : public MemoryHeapBase
-{
-public:
-    GPUAreaHeap(const wp<GPUHardware>& gpu,
-            const char* const vram, size_t size=0, size_t reserved=0)
-    : MemoryHeapBase(vram, size), mGPU(gpu) { 
-        if (base() != MAP_FAILED) {
-            if (reserved == 0)
-                reserved = virtualSize();
-            mAllocator = new SimpleBestFitAllocator(reserved);
-        }
-    }
-    virtual sp<MemoryHeapPmem> createClientHeap() {
-        sp<MemoryHeapBase> parentHeap(this);
-        return new GPUClientHeap(mGPU, parentHeap);
-    }
-    virtual const sp<SimpleBestFitAllocator>& getAllocator() const {
-        return mAllocator; 
-    }
-private:
-    sp<SimpleBestFitAllocator>  mAllocator;
-protected:
-    wp<GPUHardware> mGPU;
-};
-
-class GPURegisterHeap : public GPUAreaHeap
-{
-public:
-    GPURegisterHeap(const sp<GPUHardware>& gpu)
-        : GPUAreaHeap(gpu, "/dev/hw3d", GPUHardware::GPUR_SIZE) { }
-    virtual sp<MemoryHeapPmem> createClientHeap() {
-        sp<MemoryHeapBase> parentHeap(this);
-        return new MemoryHeapRegs(mGPU, parentHeap);
-    }
-private:
-    class MemoryHeapRegs : public GPUClientHeap  {
-    public:
-        MemoryHeapRegs(const wp<GPUHardware>& gpu, 
-             const sp<MemoryHeapBase>& heap)
-            : GPUClientHeap(gpu, heap) { }
-        sp<MemoryHeapPmem::MemoryPmem> createMemory(size_t offset, size_t size);
-        virtual void revoke();
-    private:
-        class GPUHandle : public MemoryHeapPmem::MemoryPmem {
-        public:
-            GPUHandle(const sp<GPUHardware>& gpu,
-                    const sp<MemoryHeapPmem>& heap)
-                : MemoryHeapPmem::MemoryPmem(heap), 
-                  mGPU(gpu), mOwner(gpu->getOwner()) { }
-            virtual ~GPUHandle();
-            virtual sp<IMemoryHeap> getMemory(
-                    ssize_t* offset, size_t* size) const;
-            virtual void revoke() { };
-            virtual status_t onTransact(
-                    uint32_t code, const Parcel& data, 
-                    Parcel* reply, uint32_t flags);
-        private:
-            void revokeNotification();
-            wp<GPUHardware> mGPU;
-            pid_t mOwner;
-        };
-    };
-};
-
-GPURegisterHeap::MemoryHeapRegs::GPUHandle::~GPUHandle() { 
-    //LOGD("GPUHandle %p released, revoking GPU", this);
-    revokeNotification(); 
-}
-void GPURegisterHeap::MemoryHeapRegs::GPUHandle::revokeNotification()  {
-    sp<GPUHardware> hw(mGPU.promote());
-    if (hw != 0) {
-        hw->revoke(mOwner);
-    }
-}
-sp<IMemoryHeap> GPURegisterHeap::MemoryHeapRegs::GPUHandle::getMemory(
-        ssize_t* offset, size_t* size) const
-{
-    sp<MemoryHeapPmem> heap = getHeap();
-    if (offset) *offset = 0;
-    if (size)   *size = heap !=0 ? heap->virtualSize() : 0;
-    return heap;
-}
-status_t GPURegisterHeap::MemoryHeapRegs::GPUHandle::onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    status_t err = BnMemory::onTransact(code, data, reply, flags);
-    if (err == UNKNOWN_TRANSACTION && code == 1000) {
-        int callingPid = IPCThreadState::self()->getCallingPid();
-        //LOGD("pid %d voluntarily revoking gpu", callingPid);
-        if (callingPid == mOwner) {
-            revokeNotification();
-            // we've revoked the GPU, don't do it again later when we
-            // are destroyed.
-            mGPU.clear();
-        } else {
-            LOGW("%d revoking someone else's gpu? (owner=%d)",
-                    callingPid, mOwner);            
-        }
-        err = NO_ERROR;
-    }
-    return err;
-}
-
-// ---------------------------------------------------------------------------
-
-
-sp<MemoryHeapPmem::MemoryPmem> GPURegisterHeap::MemoryHeapRegs::createMemory(
-        size_t offset, size_t size)
-{
-    sp<GPUHandle> memory;
-    sp<GPUHardware> gpu = mGPU.promote();
-    if (heapID()>0 && gpu!=0) {
-#if HAVE_ANDROID_OS
-        /* this is where the GPU is powered on and the registers are mapped
-         * in the client */
-        //LOGD("ioctl(HW3D_GRANT_GPU)");
-        int err = ioctl(heapID(), HW3D_GRANT_GPU, base());
-        if (err) {
-            // it can happen if the master heap has been closed already
-            // in which case the GPU already is revoked (app crash for
-            // instance).
-            LOGW("HW3D_GRANT_GPU failed (%s), mFD=%d, base=%p",
-                    strerror(errno), heapID(), base());
-        }
-        memory = new GPUHandle(gpu, this);
-#endif
-    }
-    return memory;
-}
-
-void GPURegisterHeap::MemoryHeapRegs::revoke() 
-{
-    MemoryHeapPmem::revoke();
-#if HAVE_ANDROID_OS
-    if (heapID() > 0) {
-        //LOGD("ioctl(HW3D_REVOKE_GPU)");
-        int err = ioctl(heapID(), HW3D_REVOKE_GPU, base());
-        LOGE_IF(err, "HW3D_REVOKE_GPU failed (%s), mFD=%d, base=%p",
-                strerror(errno), heapID(), base());
-    }
-#endif
-}
-
-/*****************************************************************************/
-
-GPUHardware::GPUHardware()
-    : mOwner(NO_OWNER)
-{
-}
-
-GPUHardware::~GPUHardware()
-{
-}
-
-status_t GPUHardware::requestLocked(int pid)
-{
-    const int self_pid = getpid();
-    if (pid == self_pid) {
-        // can't use GPU from surfaceflinger's process
-        return PERMISSION_DENIED;
-    }
-
-    if (mOwner != pid) {
-        if (mREGHeap != 0) {
-            if (mOwner != NO_OWNER) {
-                // someone already has the gpu.
-                takeBackGPULocked();
-                releaseLocked();
-            }
-        } else {
-            // first time, initialize the stuff.
-            if (mSMIHeap == 0)
-                mSMIHeap = new GPUAreaHeap(this, "/dev/pmem_gpu0");
-            if (mEBIHeap == 0)
-                mEBIHeap = new GPUAreaHeap(this, 
-                        "/dev/pmem_gpu1", 0, GPU_RESERVED_SIZE);
-            mREGHeap = new GPURegisterHeap(this);
-            mAllocator = mEBIHeap->getAllocator();
-            if (mAllocator == NULL) {
-                // something went terribly wrong.
-                mSMIHeap.clear();
-                mEBIHeap.clear();
-                mREGHeap.clear();
-                return INVALID_OPERATION;
-            }
-        }
-        Client& client = getClientLocked(pid);
-        mCurrentAllocator = new MemoryDealer(client.ebi.clientHeap, mAllocator);
-        mOwner = pid;
-    }
-    return NO_ERROR;
-}
-
-sp<MemoryDealer> GPUHardware::request(int pid)
-{
-    sp<MemoryDealer> dealer;
-    Mutex::Autolock _l(mLock);
-    Client* client;
-    LOGD("pid %d requesting gpu surface (current owner = %d)", pid, mOwner);
-    if (requestLocked(pid) == NO_ERROR) {
-        dealer = mCurrentAllocator;
-        LOGD_IF(dealer!=0, "gpu surface granted to pid %d", mOwner);
-    }
-    return dealer;
-}
-
-status_t GPUHardware::request(int pid, const sp<IGPUCallback>& callback,
-        ISurfaceComposer::gpu_info_t* gpu)
-{
-    if (callback == 0)
-        return BAD_VALUE;
-
-    sp<IMemory> gpuHandle;
-    LOGD("pid %d requesting gpu core (owner = %d)", pid, mOwner);
-    Mutex::Autolock _l(mLock);
-    status_t err = requestLocked(pid);
-    if (err == NO_ERROR) {
-        // it's guaranteed to be there, be construction
-        Client& client = mClients.editValueFor(pid);
-        registerCallbackLocked(callback, client);
-        gpu->count = 2;
-        gpu->regions[0].region = client.smi.map();
-        gpu->regions[1].region = client.ebi.map();
-        gpu->regs              = client.reg.map();
-        gpu->regions[0].reserved = 0;
-        gpu->regions[1].reserved = GPU_RESERVED_SIZE;
-        if (gpu->regs != 0) {
-            //LOGD("gpu core granted to pid %d, handle base=%p",
-            //        mOwner, gpu->regs->pointer());
-        }
-        mCallback = callback;
-    } else {
-        LOGW("couldn't grant gpu core to pid %d", pid);
-    }
-    return err;
-}
-
-void GPUHardware::revoke(int pid)
-{
-    Mutex::Autolock _l(mLock);
-    if (mOwner > 0) {
-        if (pid != mOwner) {
-            LOGW("GPU owned by %d, revoke from %d", mOwner, pid);
-            return;
-        }
-        //LOGD("revoke pid=%d, owner=%d", pid, mOwner);
-        // mOwner could be <0 if the same process acquired the GPU
-        // several times without releasing it first.
-        mCondition.signal();
-        releaseLocked();
-    }
-}
-
-status_t GPUHardware::friendlyRevoke()
-{
-    Mutex::Autolock _l(mLock);
-    //LOGD("friendlyRevoke owner=%d", mOwner);
-    takeBackGPULocked();
-    releaseLocked();
-    return NO_ERROR;
-}
-
-void GPUHardware::takeBackGPULocked()
-{
-    sp<IGPUCallback> callback = mCallback;
-    mCallback.clear();
-    if (callback != 0) {
-        callback->gpuLost(); // one-way
-        mCondition.waitRelative(mLock, ms2ns(250));
-    }
-}
-
-void GPUHardware::releaseLocked()
-{
-    //LOGD("revoking gpu from pid %d", mOwner);
-    if (mOwner != NO_OWNER) {
-        // this may fail because the client might have died, and have
-        // been removed from the list.
-        ssize_t index = mClients.indexOfKey(mOwner);
-        if (index >= 0) {
-            Client& client(mClients.editValueAt(index));
-            client.revokeAllHeaps();
-        }
-        mOwner = NO_OWNER;
-        mCurrentAllocator.clear();
-        mCallback.clear();
-    }
-}
-
-GPUHardware::Client& GPUHardware::getClientLocked(pid_t pid)
-{
-    ssize_t index = mClients.indexOfKey(pid);
-    if (index < 0) {
-        Client client;
-        client.pid = pid;
-        client.smi.heap = mSMIHeap;
-        client.ebi.heap = mEBIHeap;
-        client.reg.heap = mREGHeap;
-        index = mClients.add(pid, client);
-    }
-    Client& client(mClients.editValueAt(index));
-    client.createClientHeaps();
-    return client;
-}
-
-// ----------------------------------------------------------------------------
-// for debugging / testing ...
-
-sp<SimpleBestFitAllocator> GPUHardware::getAllocator() const {
-    Mutex::Autolock _l(mLock);
-    return mAllocator;
-}
-
-void GPUHardware::unconditionalRevoke()
-{
-    Mutex::Autolock _l(mLock);
-    releaseLocked();
-}
-
-// ---------------------------------------------------------------------------
-
-sp<IMemory> GPUHardware::GPUArea::map() {
-    sp<IMemory> memory;
-    if (clientHeap != 0 && heap != 0) {
-        memory = clientHeap->mapMemory(0, heap->virtualSize());
-    }
-    return memory;
-}
-
-void GPUHardware::Client::createClientHeaps() 
-{
-    if (smi.clientHeap == 0)
-        smi.clientHeap = smi.heap->createClientHeap();
-    if (ebi.clientHeap == 0)
-        ebi.clientHeap = ebi.heap->createClientHeap();
-    if (reg.clientHeap == 0)
-        reg.clientHeap = reg.heap->createClientHeap();
-}
-
-void GPUHardware::Client::revokeAllHeaps() 
-{
-    if (smi.clientHeap != 0)
-        smi.clientHeap->revoke();
-    if (ebi.clientHeap != 0)
-        ebi.clientHeap->revoke();
-    if (reg.clientHeap != 0)
-        reg.clientHeap->revoke();
-}
-
-void GPUHardware::registerCallbackLocked(const sp<IGPUCallback>& callback,
-        Client& client)
-{
-    sp<IBinder> binder = callback->asBinder();
-    if (mRegisteredClients.add(binder, client.pid) >= 0) {
-        binder->linkToDeath(this);
-    }
-}
-
-void GPUHardware::binderDied(const wp<IBinder>& who)
-{
-    Mutex::Autolock _l(mLock);
-    pid_t pid = mRegisteredClients.valueFor(who);
-    if (pid != 0) {
-        ssize_t index = mClients.indexOfKey(pid);
-        if (index >= 0) {
-            //LOGD("*** removing client at %d", index);
-            Client& client(mClients.editValueAt(index));
-            client.revokeAllHeaps(); // not really needed in theory
-            mClients.removeItemsAt(index);
-            if (mClients.size() == 0) {
-                //LOGD("*** was last client closing everything");
-                mCallback.clear();
-                mAllocator.clear();
-                mCurrentAllocator.clear();
-                mSMIHeap.clear();
-                mREGHeap.clear();
-                
-                // NOTE: we cannot clear the EBI heap because surfaceflinger
-                // itself may be using it, since this is where surfaces
-                // are allocated. if we're in the middle of compositing 
-                // a surface (even if its process just died), we cannot
-                // rip the heap under our feet.
-                
-                mOwner = NO_OWNER;
-            }
-        }
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-sp<GPUHardwareInterface> GPUFactory::getGPU()
-{
-    sp<GPUHardwareInterface> gpu;
-    if (access("/dev/hw3d", F_OK) == 0) {
-        gpu = new GPUHardware();
-    }
-    return gpu;
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
diff --git a/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.h b/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.h
deleted file mode 100644
index 3354528..0000000
--- a/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_GPU_HARDWARE_H
-#define ANDROID_GPU_HARDWARE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <utils/KeyedVector.h>
-
-#include <ui/ISurfaceComposer.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class IGPUCallback;
-
-class GPUHardwareInterface : public virtual RefBase
-{
-public:
-    virtual void                revoke(int pid) = 0;
-    virtual sp<MemoryDealer>    request(int pid) = 0;
-    virtual status_t            request(int pid, const sp<IGPUCallback>& callback,
-            ISurfaceComposer::gpu_info_t* gpu) = 0;
-
-    virtual status_t            friendlyRevoke() = 0;
-    
-    // used for debugging only...
-    virtual sp<SimpleBestFitAllocator> getAllocator() const  = 0;
-    virtual pid_t getOwner() const = 0;
-    virtual void unconditionalRevoke() = 0;
-};
-
-// ---------------------------------------------------------------------------
-
-class GPUFactory
-{    
-public:
-    // the gpu factory
-    static sp<GPUHardwareInterface> getGPU();
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_GPU_HARDWARE_H
diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp
deleted file mode 100644
index 41c42d1..0000000
--- a/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/StopWatch.h>
-
-#include "BlurFilter.h"
-#include "LayerBase.h"
-#include "LayerOrientationAnim.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-#include "OrientationAnimation.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80;
-const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim";
-
-// ---------------------------------------------------------------------------
-
-// Animation...
-const float DURATION = ms2ns(200);
-const float BOUNCES_PER_SECOND = 0.5f;
-//const float BOUNCES_AMPLITUDE = 1.0f/16.0f;
-const float BOUNCES_AMPLITUDE = 0;
-const float DIM_TARGET = 0.40f;
-//#define INTERPOLATED_TIME(_t)   ((_t)*(_t))
-#define INTERPOLATED_TIME(_t)   (_t)
-
-// ---------------------------------------------------------------------------
-
-LayerOrientationAnim::LayerOrientationAnim(
-        SurfaceFlinger* flinger, DisplayID display, 
-        OrientationAnimation* anim, 
-        const sp<Buffer>& bitmapIn,
-        const sp<Buffer>& bitmapOut)
-    : LayerOrientationAnimBase(flinger, display), mAnim(anim), 
-      mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), 
-      mTextureName(-1), mTextureNameIn(-1)
-{
-    // blur that texture. 
-    mStartTime = systemTime();
-    mFinishTime = 0;
-    mOrientationCompleted = false;
-    mFirstRedraw = false;
-    mLastNormalizedTime = 0;
-    mNeedsBlending = false;
-    mAlphaInLerp.set(1.0f, DIM_TARGET);
-    mAlphaOutLerp.set(0.5f, 1.0f);
-}
-
-LayerOrientationAnim::~LayerOrientationAnim()
-{
-    if (mTextureName != -1U) {
-        glDeleteTextures(1, &mTextureName);
-    }
-    if (mTextureNameIn != -1U) {
-        glDeleteTextures(1, &mTextureNameIn);
-    }
-}
-
-bool LayerOrientationAnim::needsBlending() const 
-{
-    return mNeedsBlending; 
-}
-
-Point LayerOrientationAnim::getPhysicalSize() const
-{
-    const GraphicPlane& plane(graphicPlane(0));
-    const DisplayHardware& hw(plane.displayHardware());
-    return Point(hw.getWidth(), hw.getHeight());
-}
-
-void LayerOrientationAnim::validateVisibility(const Transform&)
-{
-    const Layer::State& s(drawingState());
-    const Transform tr(s.transform);
-    const Point size(getPhysicalSize());
-    uint32_t w = size.x;
-    uint32_t h = size.y;
-    mTransformedBounds = tr.makeBounds(w, h);
-    mLeft = tr.tx();
-    mTop  = tr.ty();
-    transparentRegionScreen.clear();
-    mTransformed = true;
-}
-
-void LayerOrientationAnim::onOrientationCompleted()
-{
-    mFinishTime = systemTime();
-    mOrientationCompleted = true;
-    mFirstRedraw = true;
-    mNeedsBlending = true;
-    mFlinger->invalidateLayerVisibility(this);
-}
-
-void LayerOrientationAnim::onDraw(const Region& clip) const
-{
-    const nsecs_t now = systemTime();
-    float alphaIn, alphaOut;
-    
-    if (mOrientationCompleted) {
-        if (mFirstRedraw) {
-            mFirstRedraw = false;
-            
-            // make a copy of what's on screen
-            copybit_image_t image;
-            mBitmapOut->getBitmapSurface(&image);
-            const DisplayHardware& hw(graphicPlane(0).displayHardware());
-            hw.copyBackToImage(image);
-
-            // and erase the screen for this round
-            glDisable(GL_BLEND);
-            glDisable(GL_DITHER);
-            glDisable(GL_SCISSOR_TEST);
-            glClearColor(0,0,0,0);
-            glClear(GL_COLOR_BUFFER_BIT);
-            
-            // FIXME: code below is gross
-            mNeedsBlending = false;
-            LayerOrientationAnim* self(const_cast<LayerOrientationAnim*>(this));
-            mFlinger->invalidateLayerVisibility(self);
-        }
-
-        // make sure pick-up where we left off
-        const float duration = DURATION * mLastNormalizedTime;
-        const float normalizedTime = (float(now - mFinishTime) / duration);
-        if (normalizedTime <= 1.0f) {
-            const float interpolatedTime = INTERPOLATED_TIME(normalizedTime);
-            alphaIn = mAlphaInLerp.getOut();
-            alphaOut = mAlphaOutLerp(interpolatedTime);
-        } else {
-            mAnim->onAnimationFinished();
-            alphaIn = mAlphaInLerp.getOut();
-            alphaOut = mAlphaOutLerp.getOut();
-        }
-    } else {
-        const float normalizedTime = float(now - mStartTime) / DURATION;
-        if (normalizedTime <= 1.0f) {
-            mLastNormalizedTime = normalizedTime;
-            const float interpolatedTime = INTERPOLATED_TIME(normalizedTime);
-            alphaIn = mAlphaInLerp(interpolatedTime);
-            alphaOut = 0.0f;
-        } else {
-            mLastNormalizedTime = 1.0f;
-            const float to_seconds = DURATION / seconds(1);
-            alphaIn = mAlphaInLerp.getOut();
-            if (BOUNCES_AMPLITUDE > 0.0f) {
-                const float phi = BOUNCES_PER_SECOND * 
-                        (((normalizedTime - 1.0f) * to_seconds)*M_PI*2);
-                if (alphaIn > 1.0f) alphaIn = 1.0f;
-                else if (alphaIn < 0.0f) alphaIn = 0.0f;
-                alphaIn += BOUNCES_AMPLITUDE * (1.0f - cosf(phi));
-            }
-            alphaOut = 0.0f;
-        }
-        mAlphaOutLerp.setIn(alphaIn);
-    }
-    drawScaled(1.0f, alphaIn, alphaOut);
-}
-
-void LayerOrientationAnim::drawScaled(float scale, float alphaIn, float alphaOut) const
-{
-    copybit_image_t dst;
-    const GraphicPlane& plane(graphicPlane(0));
-    const DisplayHardware& hw(plane.displayHardware());
-    //hw.getDisplaySurface(&dst);
-
-    // clear screen
-    // TODO: with update on demand, we may be able 
-    // to not erase the screen at all during the animation 
-    if (!mOrientationCompleted) {
-        if (scale==1.0f && (alphaIn>=1.0f || alphaOut>=1.0f)) {
-            // we don't need to erase the screen in that case
-        } else {
-            glDisable(GL_BLEND);
-            glDisable(GL_DITHER);
-            glDisable(GL_SCISSOR_TEST);
-            glClearColor(0,0,0,0);
-            glClear(GL_COLOR_BUFFER_BIT);
-        }
-    }
-    
-    copybit_image_t src;
-    mBitmapIn->getBitmapSurface(&src);
-
-    copybit_image_t srcOut;
-    mBitmapOut->getBitmapSurface(&srcOut);
-
-    const int w = dst.w*scale; 
-    const int h = dst.h*scale; 
-    const int xc = uint32_t(dst.w-w)/2;
-    const int yc = uint32_t(dst.h-h)/2;
-    const copybit_rect_t drect = { xc, yc, xc+w, yc+h }; 
-    const copybit_rect_t srect = { 0, 0, src.w, src.h };
-    const Region reg(Rect( drect.l, drect.t, drect.r, drect.b ));
-
-    GGLSurface t;
-    t.version = sizeof(GGLSurface);
-    t.width  = src.w;
-    t.height = src.h;
-    t.stride = src.w;
-    t.vstride= src.h;
-    t.format = src.format;
-    t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
-
-    Transform tr;
-    tr.set(scale,0,0,scale);
-    tr.set(xc, yc);
-    
-    // FIXME: we should not access mVertices and mDrawingState like that,
-    // but since we control the animation, we know it's going to work okay.
-    // eventually we'd need a more formal way of doing things like this.
-    LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
-    tr.transform(self.mVertices[0], 0, 0);
-    tr.transform(self.mVertices[1], 0, src.h);
-    tr.transform(self.mVertices[2], src.w, src.h);
-    tr.transform(self.mVertices[3], src.w, 0);
-    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
-        // Too slow to do this in software
-        self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
-    }
-
-    if (alphaIn > 0.0f) {
-        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
-        if (UNLIKELY(mTextureNameIn == -1LU)) {
-            mTextureNameIn = createTexture();
-            GLuint w=0, h=0;
-            const Region dirty(Rect(t.width, t.height));
-            loadTexture(dirty, mTextureNameIn, t, w, h);
-        }
-        self.mDrawingState.alpha = int(alphaIn*255);
-        drawWithOpenGL(reg, mTextureNameIn, t);
-    }
-
-    if (alphaOut > 0.0f) {
-        t.data = (GGLubyte*)(intptr_t(srcOut.base) + srcOut.offset);
-        if (UNLIKELY(mTextureName == -1LU)) {
-            mTextureName = createTexture();
-            GLuint w=0, h=0;
-            const Region dirty(Rect(t.width, t.height));
-            loadTexture(dirty, mTextureName, t, w, h);
-        }
-        self.mDrawingState.alpha = int(alphaOut*255);
-        drawWithOpenGL(reg, mTextureName, t);
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnim.h b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h
deleted file mode 100644
index a1a2654..0000000
--- a/libs/surfaceflinger/purgatory/LayerOrientationAnim.h
+++ /dev/null
@@ -1,112 +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_ORIENTATION_ANIM_H
-#define ANDROID_LAYER_ORIENTATION_ANIM_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/threads.h>
-#include <binder/Parcel.h>
-
-#include "LayerBase.h"
-#include "LayerBitmap.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-class OrientationAnimation;
-
-
-class LayerOrientationAnimBase : public LayerBase
-{
-public:
-    LayerOrientationAnimBase(SurfaceFlinger* flinger, DisplayID display)
-        : LayerBase(flinger, display) {
-    }
-    virtual void onOrientationCompleted() = 0;
-};
-
-// ---------------------------------------------------------------------------
-
-class LayerOrientationAnim : public LayerOrientationAnimBase
-{
-public:    
-    static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
-    
-                LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display,
-                        OrientationAnimation* anim, 
-                        const sp<Buffer>& bitmapIn,
-                        const sp<Buffer>& bitmapOut);
-        virtual ~LayerOrientationAnim();
-
-            void onOrientationCompleted();
-
-    virtual void onDraw(const Region& clip) const;
-    virtual Point getPhysicalSize() const;
-    virtual void validateVisibility(const Transform& globalTransform);
-    virtual bool needsBlending() const;
-    virtual bool isSecure() const       { return false; }
-private:
-    void drawScaled(float scale, float alphaIn, float alphaOut) const;
-
-    class Lerp {
-        float in;
-        float outMinusIn;
-    public:
-        Lerp() : in(0), outMinusIn(0) { }
-        Lerp(float in, float out) : in(in), outMinusIn(out-in) { }
-        float getIn() const { return in; };
-        float getOut() const { return in + outMinusIn; }
-        void set(float in, float out) { 
-            this->in = in; 
-            this->outMinusIn = out-in; 
-        }
-        void setIn(float in) { 
-            this->in = in; 
-        }
-        void setOut(float out) { 
-            this->outMinusIn = out - this->in; 
-        }
-        float operator()(float t) const { 
-            return outMinusIn*t + in; 
-        }
-    };
-    
-    OrientationAnimation* mAnim;
-    sp<Buffer> mBitmapIn;
-    sp<Buffer> mBitmapOut;
-    nsecs_t mStartTime;
-    nsecs_t mFinishTime;
-    bool mOrientationCompleted;
-    mutable bool mFirstRedraw;
-    mutable float mLastNormalizedTime;
-    mutable GLuint  mTextureName;
-    mutable GLuint  mTextureNameIn;
-    mutable bool mNeedsBlending;
-    
-    mutable Lerp mAlphaInLerp;
-    mutable Lerp mAlphaOutLerp;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_ORIENTATION_ANIM_H
diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp
deleted file mode 100644
index dc6b632..0000000
--- a/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include "LayerBase.h"
-#include "LayerOrientationAnim.h"
-#include "LayerOrientationAnimRotate.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-#include "OrientationAnimation.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-const uint32_t LayerOrientationAnimRotate::typeInfo = LayerBase::typeInfo | 0x100;
-const char* const LayerOrientationAnimRotate::typeID = "LayerOrientationAnimRotate";
-
-// ---------------------------------------------------------------------------
-
-const float ROTATION = M_PI * 0.5f;
-const float ROTATION_FACTOR = 1.0f; // 1.0 or 2.0
-const float DURATION = ms2ns(200);
-const float BOUNCES_PER_SECOND = 0.8;
-const float BOUNCES_AMPLITUDE = (5.0f/180.f) * M_PI;
-
-LayerOrientationAnimRotate::LayerOrientationAnimRotate(
-        SurfaceFlinger* flinger, DisplayID display, 
-        OrientationAnimation* anim, 
-        const sp<Buffer>& bitmapIn,
-        const sp<Buffer>& bitmapOut)
-    : LayerOrientationAnimBase(flinger, display), mAnim(anim), 
-      mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), 
-      mTextureName(-1), mTextureNameIn(-1)
-{
-    mStartTime = systemTime();
-    mFinishTime = 0;
-    mOrientationCompleted = false;
-    mFirstRedraw = false;
-    mLastNormalizedTime = 0;
-    mLastAngle = 0;
-    mLastScale = 0;
-    mNeedsBlending = false;
-    const GraphicPlane& plane(graphicPlane(0));
-    mOriginalTargetOrientation = plane.getOrientation(); 
-}
-
-LayerOrientationAnimRotate::~LayerOrientationAnimRotate()
-{
-    if (mTextureName != -1U) {
-        glDeleteTextures(1, &mTextureName);
-    }
-    if (mTextureNameIn != -1U) {
-        glDeleteTextures(1, &mTextureNameIn);
-    }
-}
-
-bool LayerOrientationAnimRotate::needsBlending() const 
-{
-    return mNeedsBlending; 
-}
-
-Point LayerOrientationAnimRotate::getPhysicalSize() const
-{
-    const GraphicPlane& plane(graphicPlane(0));
-    const DisplayHardware& hw(plane.displayHardware());
-    return Point(hw.getWidth(), hw.getHeight());
-}
-
-void LayerOrientationAnimRotate::validateVisibility(const Transform&)
-{
-    const Layer::State& s(drawingState());
-    const Transform tr(s.transform);
-    const Point size(getPhysicalSize());
-    uint32_t w = size.x;
-    uint32_t h = size.y;
-    mTransformedBounds = tr.makeBounds(w, h);
-    mLeft = tr.tx();
-    mTop  = tr.ty();
-    transparentRegionScreen.clear();
-    mTransformed = true;
-}
-
-void LayerOrientationAnimRotate::onOrientationCompleted()
-{
-    mFinishTime = systemTime();
-    mOrientationCompleted = true;
-    mFirstRedraw = true;
-    mNeedsBlending = true;
-    mFlinger->invalidateLayerVisibility(this);
-}
-
-void LayerOrientationAnimRotate::onDraw(const Region& clip) const
-{
-    // Animation...
-
-    const nsecs_t now = systemTime();
-    float angle, scale, alpha;
-    
-    if (mOrientationCompleted) {
-        if (mFirstRedraw) {
-            // make a copy of what's on screen
-            copybit_image_t image;
-            mBitmapIn->getBitmapSurface(&image);
-            const DisplayHardware& hw(graphicPlane(0).displayHardware());
-            hw.copyBackToImage(image);
-            
-            // FIXME: code below is gross
-            mFirstRedraw = false; 
-            mNeedsBlending = false;
-            LayerOrientationAnimRotate* self(const_cast<LayerOrientationAnimRotate*>(this));
-            mFlinger->invalidateLayerVisibility(self);
-        }
-
-        // make sure pick-up where we left off
-        const float duration = DURATION * mLastNormalizedTime;
-        const float normalizedTime = (float(now - mFinishTime) / duration);
-        if (normalizedTime <= 1.0f) {
-            const float squaredTime = normalizedTime*normalizedTime;
-            angle = (ROTATION*ROTATION_FACTOR - mLastAngle)*squaredTime + mLastAngle;
-            scale = (1.0f - mLastScale)*squaredTime + mLastScale;
-            alpha = normalizedTime;
-        } else {
-            mAnim->onAnimationFinished();
-            angle = ROTATION;
-            alpha = 1.0f;
-            scale = 1.0f;
-        }
-    } else {
-        // FIXME: works only for portrait framebuffers
-        const Point size(getPhysicalSize());
-        const float TARGET_SCALE = size.x * (1.0f / size.y);
-        const float normalizedTime = float(now - mStartTime) / DURATION;
-        if (normalizedTime <= 1.0f) {
-            mLastNormalizedTime = normalizedTime;
-            const float squaredTime = normalizedTime*normalizedTime;
-            angle = ROTATION * squaredTime;
-            scale = (TARGET_SCALE - 1.0f)*squaredTime + 1.0f;
-            alpha = 0;
-        } else {
-            mLastNormalizedTime = 1.0f;
-            angle = ROTATION;
-            if (BOUNCES_AMPLITUDE) {
-                const float to_seconds = DURATION / seconds(1);
-                const float phi = BOUNCES_PER_SECOND * 
-                (((normalizedTime - 1.0f) * to_seconds)*M_PI*2);
-                angle += BOUNCES_AMPLITUDE * sinf(phi);
-            }
-            scale = TARGET_SCALE;
-            alpha = 0;
-        }
-        mLastAngle = angle;
-        mLastScale = scale;
-    }
-    drawScaled(angle, scale, alpha);
-}
-
-void LayerOrientationAnimRotate::drawScaled(float f, float s, float alpha) const
-{
-    copybit_image_t dst;
-    const GraphicPlane& plane(graphicPlane(0));
-    const DisplayHardware& hw(plane.displayHardware());
-    //hw.getDisplaySurface(&dst);
-
-    // clear screen
-    // TODO: with update on demand, we may be able 
-    // to not erase the screen at all during the animation 
-    glDisable(GL_BLEND);
-    glDisable(GL_DITHER);
-    glDisable(GL_SCISSOR_TEST);
-    glClearColor(0,0,0,0);
-    glClear(GL_COLOR_BUFFER_BIT);
-    
-    const int w = dst.w; 
-    const int h = dst.h; 
-
-    copybit_image_t src;
-    mBitmapIn->getBitmapSurface(&src);
-    const copybit_rect_t srect = { 0, 0, src.w, src.h };
-
-
-    GGLSurface t;
-    t.version = sizeof(GGLSurface);
-    t.width  = src.w;
-    t.height = src.h;
-    t.stride = src.w;
-    t.vstride= src.h;
-    t.format = src.format;
-    t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
-
-    if (!mOriginalTargetOrientation) {
-        f = -f;
-    }
-
-    Transform tr;
-    tr.set(f, w*0.5f, h*0.5f);
-    tr.scale(s, w*0.5f, h*0.5f);
-
-    // FIXME: we should not access mVertices and mDrawingState like that,
-    // but since we control the animation, we know it's going to work okay.
-    // eventually we'd need a more formal way of doing things like this.
-    LayerOrientationAnimRotate& self(const_cast<LayerOrientationAnimRotate&>(*this));
-    tr.transform(self.mVertices[0], 0, 0);
-    tr.transform(self.mVertices[1], 0, src.h);
-    tr.transform(self.mVertices[2], src.w, src.h);
-    tr.transform(self.mVertices[3], src.w, 0);
-
-    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
-        // Too slow to do this in software
-        self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
-    }
-
-    if (UNLIKELY(mTextureName == -1LU)) {
-        mTextureName = createTexture();
-        GLuint w=0, h=0;
-        const Region dirty(Rect(t.width, t.height));
-        loadTexture(dirty, mTextureName, t, w, h);
-    }
-    self.mDrawingState.alpha = 255; //-int(alpha*255);
-    const Region clip(Rect( srect.l, srect.t, srect.r, srect.b ));
-    drawWithOpenGL(clip, mTextureName, t);
-    
-    if (alpha > 0) {
-        const float sign = (!mOriginalTargetOrientation) ? 1.0f : -1.0f;
-        tr.set(f + sign*(M_PI * 0.5f * ROTATION_FACTOR), w*0.5f, h*0.5f);
-        tr.scale(s, w*0.5f, h*0.5f);
-        tr.transform(self.mVertices[0], 0, 0);
-        tr.transform(self.mVertices[1], 0, src.h);
-        tr.transform(self.mVertices[2], src.w, src.h);
-        tr.transform(self.mVertices[3], src.w, 0);
-
-        copybit_image_t src;
-        mBitmapIn->getBitmapSurface(&src);
-        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
-        if (UNLIKELY(mTextureNameIn == -1LU)) {
-            mTextureNameIn = createTexture();
-            GLuint w=0, h=0;
-            const Region dirty(Rect(t.width, t.height));
-            loadTexture(dirty, mTextureNameIn, t, w, h);
-        }
-        self.mDrawingState.alpha = int(alpha*255);
-        const Region clip(Rect( srect.l, srect.t, srect.r, srect.b ));
-        drawWithOpenGL(clip, mTextureNameIn, t);
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h
deleted file mode 100644
index a88eec0..0000000
--- a/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h
+++ /dev/null
@@ -1,77 +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_ORIENTATION_ANIM_ROTATE_H
-#define ANDROID_LAYER_ORIENTATION_ANIM_ROTATE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/threads.h>
-#include <binder/Parcel.h>
-
-#include "LayerBase.h"
-#include "LayerBitmap.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-class OrientationAnimation;
-
-class LayerOrientationAnimRotate : public LayerOrientationAnimBase
-{
-public:    
-    static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
-    
-    LayerOrientationAnimRotate(SurfaceFlinger* flinger, DisplayID display,
-                        OrientationAnimation* anim, 
-                        const sp<Buffer>& bitmapIn,
-                        const sp<Buffer>& bitmapOut);
-        virtual ~LayerOrientationAnimRotate();
-
-            void onOrientationCompleted();
-
-    virtual void onDraw(const Region& clip) const;
-    virtual Point getPhysicalSize() const;
-    virtual void validateVisibility(const Transform& globalTransform);
-    virtual bool needsBlending() const;
-    virtual bool isSecure() const       { return false; }
-private:
-    void drawScaled(float angle, float scale, float alpha) const;
-    
-    OrientationAnimation* mAnim;
-    sp<Buffer> mBitmapIn;
-    sp<Buffer> mBitmapOut;
-    nsecs_t mStartTime;
-    nsecs_t mFinishTime;
-    bool mOrientationCompleted;
-    int mOriginalTargetOrientation;
-    mutable bool mFirstRedraw;
-    mutable float mLastNormalizedTime;
-    mutable float mLastAngle;
-    mutable float mLastScale;
-    mutable GLuint  mTextureName;
-    mutable GLuint  mTextureNameIn;
-    mutable bool mNeedsBlending;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_ORIENTATION_ANIM_ROTATE_H
diff --git a/libs/surfaceflinger/purgatory/OrientationAnimation.cpp b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp
deleted file mode 100644
index a6c9c28..0000000
--- a/libs/surfaceflinger/purgatory/OrientationAnimation.cpp
+++ /dev/null
@@ -1,150 +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 <stdint.h>
-#include <sys/types.h>
-#include <limits.h>
-
-#include "LayerOrientationAnim.h"
-#include "LayerOrientationAnimRotate.h"
-#include "OrientationAnimation.h"
-#include "SurfaceFlinger.h"
-
-#include "DisplayHardware/DisplayHardware.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-OrientationAnimation::OrientationAnimation(const sp<SurfaceFlinger>& flinger)
-    : mFlinger(flinger), mLayerOrientationAnim(NULL), mState(DONE)
-{
-}
-
-OrientationAnimation::~OrientationAnimation()
-{
-}
-
-void OrientationAnimation::onOrientationChanged(uint32_t type)
-{
-    if (mState == DONE) {
-        mType = type;
-        if (!(type & ISurfaceComposer::eOrientationAnimationDisable)) {
-            mState = PREPARE;
-        }
-    }
-}
-
-void OrientationAnimation::onAnimationFinished()
-{
-    if (mState != DONE)
-        mState = FINISH;
-}
-
-bool OrientationAnimation::run_impl()
-{
-    bool skip_frame;
-    switch (mState) {
-        default:
-        case DONE:
-            skip_frame = done();
-            break;
-        case PREPARE:
-            skip_frame = prepare();
-            break;
-        case PHASE1:
-            skip_frame = phase1();
-            break;
-        case PHASE2:
-            skip_frame = phase2();
-            break;
-        case FINISH:
-            skip_frame = finished();
-            break;
-    }
-    return skip_frame;
-}
-
-bool OrientationAnimation::done()
-{
-    return done_impl();
-}
-
-bool OrientationAnimation::prepare()
-{
-    mState = PHASE1;
-    
-    const GraphicPlane& plane(mFlinger->graphicPlane(0));
-    const DisplayHardware& hw(plane.displayHardware());
-    const uint32_t w = hw.getWidth();
-    const uint32_t h = hw.getHeight();
-
-    sp<Buffer> bitmap = new Buffer(w, h, hw.getFormat());
-    sp<Buffer> bitmapIn = new Buffer(w, h, hw.getFormat());
-
-    copybit_image_t front;
-    bitmap->getBitmapSurface(&front);
-    hw.copyFrontToImage(front); // FIXME: we need an extension to do this
-
-    sp<LayerOrientationAnimBase> l;
-    
-    if (mType & 0x80) {
-        l = new LayerOrientationAnimRotate(
-                mFlinger.get(), 0, this, bitmap, bitmapIn);
-    } else {
-        l = new LayerOrientationAnim(
-                mFlinger.get(), 0, this, bitmap, bitmapIn);
-    }
-
-    l->initStates(w, h, 0);
-    l->setLayer(INT_MAX-1);
-    mFlinger->addLayer(l);
-    mLayerOrientationAnim = l;
-    return true;
-}
-
-bool OrientationAnimation::phase1()
-{
-    if (mFlinger->isFrozen() == false) {
-        // start phase 2
-        mState = PHASE2;
-        mLayerOrientationAnim->onOrientationCompleted();
-        mLayerOrientationAnim->invalidate();
-        return true;
-        
-    }
-    mLayerOrientationAnim->invalidate();
-    return false;
-}
-
-bool OrientationAnimation::phase2()
-{
-    // do the 2nd phase of the animation
-    mLayerOrientationAnim->invalidate();
-    return false;
-}
-
-bool OrientationAnimation::finished()
-{
-    mState = DONE;
-    mFlinger->removeLayer(mLayerOrientationAnim);
-    mLayerOrientationAnim.clear();
-    return true;
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/purgatory/OrientationAnimation.h b/libs/surfaceflinger/purgatory/OrientationAnimation.h
deleted file mode 100644
index 8ba6621..0000000
--- a/libs/surfaceflinger/purgatory/OrientationAnimation.h
+++ /dev/null
@@ -1,84 +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_ORIENTATION_ANIMATION_H
-#define ANDROID_ORIENTATION_ANIMATION_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "SurfaceFlinger.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class SurfaceFlinger;
-class MemoryDealer;
-class LayerOrientationAnim;
-
-class OrientationAnimation
-{
-public:    
-                 OrientationAnimation(const sp<SurfaceFlinger>& flinger);
-        virtual ~OrientationAnimation();
-
-   void onOrientationChanged(uint32_t type);
-   void onAnimationFinished();
-   inline bool run() {
-       if (LIKELY(mState == DONE))
-           return done_impl();
-       return run_impl();
-   }
-
-private:
-    enum {
-        DONE = 0,
-        PREPARE,
-        PHASE1,
-        PHASE2,
-        FINISH
-    };
-
-    bool run_impl();
-    inline bool done_impl() {
-        if (mFlinger->isFrozen()) {
-            // we are not allowed to draw, but pause a bit to make sure
-            // apps don't end up using the whole CPU, if they depend on
-            // surfaceflinger for synchronization.
-            usleep(8333); // 8.3ms ~ 120fps
-            return true;
-        }
-        return false;
-    }
-    
-    bool done();    
-    bool prepare();
-    bool phase1();
-    bool phase2();
-    bool finished();
-
-    sp<SurfaceFlinger> mFlinger;
-    sp< LayerOrientationAnimBase > mLayerOrientationAnim;
-    int mState;
-    uint32_t mType;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_ORIENTATION_ANIMATION_H
diff --git a/libs/surfaceflinger/purgatory/VRamHeap.cpp b/libs/surfaceflinger/purgatory/VRamHeap.cpp
deleted file mode 100644
index f3ed790..0000000
--- a/libs/surfaceflinger/purgatory/VRamHeap.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-#include <utils/MemoryDealer.h>
-#include <utils/MemoryBase.h>
-#include <utils/MemoryHeapPmem.h>
-#include <utils/MemoryHeapBase.h>
-
-#include "GPUHardware/GPUHardware.h"
-#include "SurfaceFlinger.h"
-#include "VRamHeap.h"
-
-#if HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-/*
- * Amount of memory we reserve for surface, per client in PMEM
- * (PMEM is used for 2D acceleration)
- * 8 MB of address space per client should be enough.
- */
-static const int PMEM_SIZE = int(8 * 1024 * 1024);
-
-int SurfaceHeapManager::global_pmem_heap = 0;
-
-// ---------------------------------------------------------------------------
-
-SurfaceHeapManager::SurfaceHeapManager(const sp<SurfaceFlinger>& flinger, 
-        size_t clientHeapSize)
-    : mFlinger(flinger), mClientHeapSize(clientHeapSize)
-{
-    SurfaceHeapManager::global_pmem_heap = 1;
-}
-
-SurfaceHeapManager::~SurfaceHeapManager()
-{
-}
-
-void SurfaceHeapManager::onFirstRef()
-{
-    if (global_pmem_heap) {
-        const char* device = "/dev/pmem";
-        mPMemHeap = new PMemHeap(device, PMEM_SIZE);
-        if (mPMemHeap->base() == MAP_FAILED) {
-            mPMemHeap.clear();
-            global_pmem_heap = 0;
-        }
-    }
-}
-
-sp<MemoryDealer> SurfaceHeapManager::createHeap(
-        uint32_t flags,
-        pid_t client_pid,
-        const sp<MemoryDealer>& defaultAllocator)
-{
-    sp<MemoryDealer> dealer; 
-
-    if (flags & ISurfaceComposer::eGPU) {
-        // don't grant GPU memory if GPU is disabled
-        char value[PROPERTY_VALUE_MAX];
-        property_get("debug.egl.hw", value, "1");
-        if (atoi(value) == 0) {
-            flags &= ~ISurfaceComposer::eGPU;
-        }
-    }
-
-    if (flags & ISurfaceComposer::eGPU) {
-        // FIXME: this is msm7201A specific, where gpu surfaces may not be secure
-        if (!(flags & ISurfaceComposer::eSecure)) {
-            // if GPU doesn't work, we try eHardware
-            flags |= ISurfaceComposer::eHardware;
-            // asked for GPU memory, try that first
-            dealer = mFlinger->getGPU()->request(client_pid);
-        }
-    }
-
-    if (dealer == NULL) {
-        if (defaultAllocator != NULL)
-            // if a default allocator is given, use that
-            dealer = defaultAllocator;
-    }
-    
-    if (dealer == NULL) {
-        // always try h/w accelerated memory first
-        if (global_pmem_heap) {
-            const sp<PMemHeap>& heap(mPMemHeap);
-            if (dealer == NULL && heap != NULL) {
-                dealer = new MemoryDealer( 
-                        heap->createClientHeap(),
-                        heap->getAllocator());
-            }
-        }
-    }
-
-    if (dealer == NULL) {
-        // return the ashmem allocator (software rendering)
-        dealer = new MemoryDealer(mClientHeapSize, 0, "SFNativeHeap");
-    }
-    return dealer;
-}
-
-sp<SimpleBestFitAllocator> SurfaceHeapManager::getAllocator(int type) const 
-{
-    Mutex::Autolock _l(mLock);
-    sp<SimpleBestFitAllocator> allocator;
-
-    // this is only used for debugging
-    switch (type) {
-        case NATIVE_MEMORY_TYPE_PMEM:
-            if (mPMemHeap != 0) {
-                allocator = mPMemHeap->getAllocator();
-            }
-            break;
-    }
-    return allocator;
-}
-
-// ---------------------------------------------------------------------------
-
-PMemHeap::PMemHeap(const char* const device, size_t size, size_t reserved)
-    : MemoryHeapBase(device, size)
-{
-    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
-    if (base() != MAP_FAILED) {
-        //LOGD("%s, %u bytes", device, virtualSize());
-        if (reserved == 0)
-            reserved = virtualSize();
-        mAllocator = new SimpleBestFitAllocator(reserved);
-    }
-}
-
-PMemHeap::~PMemHeap() {
-    //LOGD("%s, %p, mFD=%d", __PRETTY_FUNCTION__, this, heapID());
-}
-
-sp<MemoryHeapPmem> PMemHeap::createClientHeap() {
-    sp<MemoryHeapBase> parentHeap(this);
-    return new MemoryHeapPmem(parentHeap);
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/surfaceflinger/purgatory/VRamHeap.h b/libs/surfaceflinger/purgatory/VRamHeap.h
deleted file mode 100644
index 9140167..0000000
--- a/libs/surfaceflinger/purgatory/VRamHeap.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_VRAM_HEAP_H
-#define ANDROID_VRAM_HEAP_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/MemoryDealer.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class PMemHeap;
-class MemoryHeapPmem;
-class SurfaceFlinger; 
-
-// ---------------------------------------------------------------------------
-
-class SurfaceHeapManager  : public RefBase
-{
-public:
-    SurfaceHeapManager(const sp<SurfaceFlinger>& flinger, size_t clientHeapSize);
-    virtual ~SurfaceHeapManager();
-    virtual void onFirstRef();
-    /* use ISurfaceComposer flags eGPU|eHArdware|eSecure */
-    sp<MemoryDealer> createHeap(uint32_t flags=0, pid_t client_pid = 0,
-            const sp<MemoryDealer>& defaultAllocator = 0);
-    
-    // used for debugging only...
-    sp<SimpleBestFitAllocator> getAllocator(int type) const;
-
-private:
-    sp<PMemHeap> getHeap(int type) const;
-
-    sp<SurfaceFlinger> mFlinger;
-    mutable Mutex   mLock;
-    size_t          mClientHeapSize;
-    sp<PMemHeap>    mPMemHeap;
-    static int global_pmem_heap;
-};
-
-// ---------------------------------------------------------------------------
-
-class PMemHeap : public MemoryHeapBase
-{
-public:
-                PMemHeap(const char* const vram,
-                        size_t size=0, size_t reserved=0);
-    virtual     ~PMemHeap();
-    
-    virtual const sp<SimpleBestFitAllocator>& getAllocator() const {
-        return mAllocator; 
-    }
-    virtual sp<MemoryHeapPmem> createClientHeap();
-    
-private:
-    sp<SimpleBestFitAllocator>  mAllocator;
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_VRAM_HEAP_H
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 93c7263..348dd68 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -23,7 +23,9 @@
 	PixelFormat.cpp \
 	Rect.cpp \
 	Region.cpp \
+	SharedBufferStack.cpp \
 	Surface.cpp \
+	SurfaceBuffer.cpp \
 	SurfaceComposerClient.cpp \
 	SurfaceFlingerSynchro.cpp 
 
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index 60c177b..e39a357 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -781,12 +781,21 @@
         if(strcmp(mDevices[i]->path.string(), deviceName) == 0) {
             //LOGD("remove device %d: %s\n", i, deviceName);
             device_t* device = mDevices[i];
-            int count = mFDCount - i - 1;
+            
+            LOGI("Removed device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
+                 device->path.string(), device->name.string(), device->id,
+                 mNumDevicesById, mFDCount, mFDs[i].fd, device->classes);
+         
+            // Clear this device's entry.
             int index = (device->id&ID_MASK);
             mDevicesById[index].device = NULL;
+            
+            // Close the file descriptor and compact the fd array.
             close(mFDs[i].fd);
+            int count = mFDCount - i - 1;
             memmove(mDevices + i, mDevices + i + 1, sizeof(mDevices[0]) * count);
             memmove(mFDs + i, mFDs + i + 1, sizeof(mFDs[0]) * count);
+            mFDCount--;
 
 #ifdef EV_SW
             for (int j=0; j<EV_SW; j++) {
@@ -799,8 +808,6 @@
             device->next = mClosingDevices;
             mClosingDevices = device;
 
-            mFDCount--;
-
             uint32_t publicID;
             if (device->id == mFirstKeyboardId) {
                 LOGW("built-in keyboard device %s (id=%d) is closing! the apps will not like this",
@@ -817,7 +824,7 @@
             return 0;
         }
     }
-    LOGE("remote device: %s not found\n", deviceName);
+    LOGE("remove device: %s not found\n", deviceName);
     return -1;
 }
 
@@ -832,7 +839,7 @@
     int event_pos = 0;
     struct inotify_event *event;
 
-LOGD("EventHub::read_notify nfd: %d\n", nfd);
+    LOGV("EventHub::read_notify nfd: %d\n", nfd);
     res = read(nfd, event_buf, sizeof(event_buf));
     if(res < (int)sizeof(*event)) {
         if(errno == EINTR)
diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp
index b78e8b5..a2dbe7f 100644
--- a/libs/ui/ISurface.cpp
+++ b/libs/ui/ISurface.cpp
@@ -71,12 +71,13 @@
     {
     }
 
-    virtual sp<SurfaceBuffer> getBuffer(int usage)
+    virtual sp<SurfaceBuffer> requestBuffer(int bufferIdx, int usage)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        data.writeInt32(bufferIdx);
         data.writeInt32(usage);
-        remote()->transact(GET_BUFFER, data, &reply);
+        remote()->transact(REQUEST_BUFFER, data, &reply);
         sp<SurfaceBuffer> buffer = new SurfaceBuffer(reply);
         return buffer;
     }
@@ -134,10 +135,11 @@
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
     switch(code) {
-        case GET_BUFFER: {
+        case REQUEST_BUFFER: {
             CHECK_INTERFACE(ISurface, data, reply);
+            int bufferIdx = data.readInt32();
             int usage = data.readInt32();
-            sp<SurfaceBuffer> buffer(getBuffer(usage));
+            sp<SurfaceBuffer> buffer(requestBuffer(bufferIdx, usage));
             return SurfaceBuffer::writeToParcel(reply, buffer.get());
         }
         case REGISTER_BUFFERS: {
diff --git a/libs/ui/SharedBufferStack.cpp b/libs/ui/SharedBufferStack.cpp
new file mode 100644
index 0000000..5995af5
--- /dev/null
+++ b/libs/ui/SharedBufferStack.cpp
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SharedBufferStack"
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+
+#include <private/ui/SharedBufferStack.h>
+
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+#define DEBUG_ATOMICS 0
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+SharedClient::SharedClient()
+    : lock(Mutex::SHARED)
+{
+}
+
+SharedClient::~SharedClient() {
+}
+
+
+// these functions are used by the clients
+status_t SharedClient::validate(size_t i) const {
+    if (uint32_t(i) >= uint32_t(NUM_LAYERS_MAX))
+        return BAD_INDEX;
+    return surfaces[i].status;
+}
+
+uint32_t SharedClient::getIdentity(size_t token) const {
+    return uint32_t(surfaces[token].identity);
+}
+
+status_t SharedClient::setIdentity(size_t token, uint32_t identity) {
+    if (token >= NUM_LAYERS_MAX)
+        return BAD_INDEX;
+    surfaces[token].identity = identity;
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+
+SharedBufferStack::SharedBufferStack()
+    : inUse(-1), identity(-1), status(NO_ERROR)
+{
+}
+
+status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
+{
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return BAD_INDEX;
+
+    // in the current implementation we only send a single rectangle
+    const Rect bounds(dirty.getBounds());
+    FlatRegion& reg(dirtyRegion[buffer]);
+    reg.count = 1;
+    reg.rects[0] = uint16_t(bounds.left);
+    reg.rects[1] = uint16_t(bounds.top);
+    reg.rects[2] = uint16_t(bounds.right);
+    reg.rects[3] = uint16_t(bounds.bottom);
+    return NO_ERROR;
+}
+
+Region SharedBufferStack::getDirtyRegion(int buffer) const
+{
+    Region res;
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return res;
+
+    const FlatRegion& reg(dirtyRegion[buffer]);
+    res.set(Rect(reg.rects[0], reg.rects[1], reg.rects[2], reg.rects[3]));
+    return res;
+}
+
+// ----------------------------------------------------------------------------
+
+SharedBufferBase::SharedBufferBase(SharedClient* sharedClient,
+        int surface, int num)
+    : mSharedClient(sharedClient), 
+      mSharedStack(sharedClient->surfaces + surface),
+      mNumBuffers(num)
+{
+}
+
+SharedBufferBase::~SharedBufferBase()
+{
+}
+
+uint32_t SharedBufferBase::getIdentity()
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.identity;
+}
+
+size_t SharedBufferBase::getFrontBuffer() const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return size_t( stack.head );
+}
+
+String8 SharedBufferBase::dump(char const* prefix) const
+{
+    const size_t SIZE = 1024;
+    char buffer[SIZE];
+    String8 result;
+    SharedBufferStack& stack( *mSharedStack );
+    snprintf(buffer, SIZE, 
+            "%s[ head=%2d, available=%2d, queued=%2d ] "
+            "reallocMask=%08x, inUse=%2d, identity=%d, status=%d\n",
+            prefix, stack.head, stack.available, stack.queued, 
+            stack.reallocMask, stack.inUse, stack.identity, stack.status);
+    result.append(buffer);
+    return result;
+}
+
+
+// ============================================================================
+// conditions and updates
+// ============================================================================
+
+SharedBufferClient::DequeueCondition::DequeueCondition(
+        SharedBufferClient* sbc) : ConditionBase(sbc)  { 
+}
+bool SharedBufferClient::DequeueCondition::operator()() {
+    return stack.available > 0;
+}
+
+SharedBufferClient::LockCondition::LockCondition(
+        SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) { 
+}
+bool SharedBufferClient::LockCondition::operator()() {
+    return (buf != stack.head || 
+            (stack.queued > 0 && stack.inUse != buf));
+}
+
+SharedBufferServer::ReallocateCondition::ReallocateCondition(
+        SharedBufferBase* sbb, int buf) : ConditionBase(sbb), buf(buf) { 
+}
+bool SharedBufferServer::ReallocateCondition::operator()() {
+    // TODO: we should also check that buf has been dequeued
+    return (buf != stack.head);
+}
+
+// ----------------------------------------------------------------------------
+
+SharedBufferClient::QueueUpdate::QueueUpdate(SharedBufferBase* sbb)
+    : UpdateBase(sbb) {    
+}
+ssize_t SharedBufferClient::QueueUpdate::operator()() {
+    android_atomic_inc(&stack.queued);
+    return NO_ERROR;
+}
+
+SharedBufferClient::UndoDequeueUpdate::UndoDequeueUpdate(SharedBufferBase* sbb)
+    : UpdateBase(sbb) {    
+}
+ssize_t SharedBufferClient::UndoDequeueUpdate::operator()() {
+    android_atomic_inc(&stack.available);
+    return NO_ERROR;
+}
+
+SharedBufferServer::UnlockUpdate::UnlockUpdate(
+        SharedBufferBase* sbb, int lockedBuffer)
+    : UpdateBase(sbb), lockedBuffer(lockedBuffer) {
+}
+ssize_t SharedBufferServer::UnlockUpdate::operator()() {
+    if (stack.inUse != lockedBuffer) {
+        LOGE("unlocking %d, but currently locked buffer is %d",
+                lockedBuffer, stack.inUse);
+        return BAD_VALUE;
+    }
+    android_atomic_write(-1, &stack.inUse);
+    return NO_ERROR;
+}
+
+SharedBufferServer::RetireUpdate::RetireUpdate(
+        SharedBufferBase* sbb, int numBuffers)
+    : UpdateBase(sbb), numBuffers(numBuffers) {
+}
+ssize_t SharedBufferServer::RetireUpdate::operator()() {
+    // head is only written in this function, which is single-thread.
+    int32_t head = stack.head;
+
+    // Preventively lock the current buffer before updating queued.
+    android_atomic_write(head, &stack.inUse);
+
+    // Decrement the number of queued buffers 
+    int32_t queued;
+    do {
+        queued = stack.queued;
+        if (queued == 0) {
+            return NOT_ENOUGH_DATA;
+        }
+    } while (android_atomic_cmpxchg(queued, queued-1, &stack.queued));
+    
+    // update the head pointer
+    head = ((head+1 >= numBuffers) ? 0 : head+1);
+
+    // lock the buffer before advancing head, which automatically unlocks
+    // the buffer we preventively locked upon entering this function
+    android_atomic_write(head, &stack.inUse);
+
+    // advance head
+    android_atomic_write(head, &stack.head);
+    
+    // now that head has moved, we can increment the number of available buffers
+    android_atomic_inc(&stack.available);
+    return head;
+}
+
+// ============================================================================
+
+SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
+        int surface, int num)
+    : SharedBufferBase(sharedClient, surface, num), tail(0)
+{
+}
+
+ssize_t SharedBufferClient::dequeue()
+{
+    //LOGD("[%d] about to dequeue a buffer",
+    //        mSharedStack->identity);
+    DequeueCondition condition(this);
+    status_t err = waitForCondition(condition);
+    if (err != NO_ERROR)
+        return ssize_t(err);
+
+
+    SharedBufferStack& stack( *mSharedStack );
+    // NOTE: 'stack.available' is part of the conditions, however
+    // decrementing it, never changes any conditions, so we don't need
+    // to do this as part of an update.
+    if (android_atomic_dec(&stack.available) == 0) {
+        LOGW("dequeue probably called from multiple threads!");
+    }
+
+    int dequeued = tail;
+    tail = ((tail+1 >= mNumBuffers) ? 0 : tail+1);
+    LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail=%d, %s",
+            dequeued, tail, dump("").string());
+    return dequeued;
+}
+
+status_t SharedBufferClient::undoDequeue(int buf)
+{
+    UndoDequeueUpdate update(this);
+    status_t err = updateCondition( update );
+    return err;
+}
+
+status_t SharedBufferClient::lock(int buf)
+{
+    LockCondition condition(this, buf);
+    status_t err = waitForCondition(condition);    
+    return err;
+}
+
+status_t SharedBufferClient::queue(int buf)
+{
+    QueueUpdate update(this);
+    status_t err = updateCondition( update );
+    LOGD_IF(DEBUG_ATOMICS, "queued=%d, %s", buf, dump("").string());
+    return err;
+}
+
+bool SharedBufferClient::needNewBuffer(int buffer) const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    const uint32_t mask = 1<<buffer;
+    return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0;
+}
+
+status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg)
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.setDirtyRegion(buffer, reg);
+}
+
+// ----------------------------------------------------------------------------
+
+SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
+        int surface, int num)
+    : SharedBufferBase(sharedClient, surface, num)
+{
+    mSharedStack->head = num-1;
+    mSharedStack->available = num;
+    mSharedStack->queued = 0;
+    mSharedStack->reallocMask = 0;
+    memset(mSharedStack->dirtyRegion, 0, sizeof(mSharedStack->dirtyRegion));
+}
+
+ssize_t SharedBufferServer::retireAndLock()
+{
+    RetireUpdate update(this, mNumBuffers);
+    ssize_t buf = updateCondition( update );
+    LOGD_IF(DEBUG_ATOMICS, "retire=%d, %s", int(buf), dump("").string());
+    return buf;
+}
+
+status_t SharedBufferServer::unlock(int buffer)
+{
+    UnlockUpdate update(this, buffer);
+    status_t err = updateCondition( update );
+    return err;
+}
+
+status_t SharedBufferServer::reallocate()
+{
+    SharedBufferStack& stack( *mSharedStack );
+    uint32_t mask = (1<<mNumBuffers)-1;
+    android_atomic_or(mask, &stack.reallocMask); 
+    return NO_ERROR;
+}
+
+status_t SharedBufferServer::assertReallocate(int buffer)
+{
+    ReallocateCondition condition(this, buffer);
+    status_t err = waitForCondition(condition);
+    return err;
+}
+
+Region SharedBufferServer::getDirtyRegion(int buffer) const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.getDirtyRegion(buffer);
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index 474308a..c3fbea2 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -25,6 +25,7 @@
 
 #include <utils/Errors.h>
 #include <utils/threads.h>
+#include <utils/CallStack.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IMemory.h>
 #include <utils/Log.h>
@@ -38,102 +39,12 @@
 
 #include <pixelflinger/pixelflinger.h>
 
-#include <private/ui/SharedState.h>
+#include <private/ui/SharedBufferStack.h>
 #include <private/ui/LayerState.h>
 #include <private/ui/SurfaceBuffer.h>
 
 namespace android {
 
-// ============================================================================
-//  SurfaceBuffer
-// ============================================================================
-
-SurfaceBuffer::SurfaceBuffer() 
-    : BASE(), mOwner(false), mBufferMapper(BufferMapper::get())
-{
-    width  = 
-    height = 
-    stride = 
-    format = 
-    usage  = 0;
-    handle = NULL;
-}
-
-SurfaceBuffer::SurfaceBuffer(const Parcel& data) 
-    : BASE(), mOwner(true), mBufferMapper(BufferMapper::get())
-{
-    // we own the handle in this case
-    width  = data.readInt32();
-    if (width < 0) {
-        width = height = stride = format = usage = 0;
-        handle = 0;
-    } else {
-        height = data.readInt32();
-        stride = data.readInt32();
-        format = data.readInt32();
-        usage  = data.readInt32();
-        handle = data.readNativeHandle();
-    }
-}
-
-SurfaceBuffer::~SurfaceBuffer()
-{
-    if (handle && mOwner) {
-        native_handle_close(handle);
-        native_handle_delete(const_cast<native_handle*>(handle));
-    }
-}
-
-status_t SurfaceBuffer::lock(uint32_t usage, void** vaddr)
-{
-    const Rect lockBounds(width, height);
-    status_t res = lock(usage, lockBounds, vaddr);
-    return res;
-}
-
-status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
-{
-    if (rect.left < 0 || rect.right  > this->width || 
-        rect.top  < 0 || rect.bottom > this->height) {
-        LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
-                rect.left, rect.top, rect.right, rect.bottom, 
-                this->width, this->height);
-        return BAD_VALUE;
-    }
-    status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
-    return res;
-}
-
-status_t SurfaceBuffer::unlock()
-{
-    status_t res = getBufferMapper().unlock(handle);
-    return res;
-}
-
-status_t SurfaceBuffer::writeToParcel(Parcel* reply, 
-        android_native_buffer_t const* buffer)
-{
-    if (buffer == NULL)
-        return BAD_VALUE;
-
-    if (buffer->width < 0 || buffer->height < 0)
-        return BAD_VALUE;
-
-    status_t err = NO_ERROR;
-    if (buffer->handle == NULL) {
-        // this buffer doesn't have a handle
-        reply->writeInt32(NO_MEMORY);
-    } else {
-        reply->writeInt32(buffer->width);
-        reply->writeInt32(buffer->height);
-        reply->writeInt32(buffer->stride);
-        reply->writeInt32(buffer->format);
-        reply->writeInt32(buffer->usage);
-        err = reply->writeNativeHandle(buffer->handle);
-    }
-    return err;
-}
-
 // ----------------------------------------------------------------------
 
 static status_t copyBlt(
@@ -324,7 +235,7 @@
     return client->setFreezeTint(mToken, tint);
 }
 
-status_t SurfaceControl::validate(per_client_cblk_t const* cblk) const
+status_t SurfaceControl::validate(SharedClient const* cblk) const
 {
     if (mToken<0 || mClient==0) {
         LOGE("invalid token (%d, identity=%u) or client (%p)", 
@@ -341,9 +252,10 @@
                 mToken, mIdentity, err, strerror(-err));
         return err;
     }
-    if (mIdentity != uint32_t(cblk->layers[mToken].identity)) {
+    uint32_t identity = cblk->getIdentity(mToken);
+    if (mIdentity != identity) {
         LOGE("using an invalid surface id=%d, identity=%u should be %d",
-                mToken, mIdentity, cblk->layers[mToken].identity);
+                mToken, mIdentity, identity);
         return NO_INIT;
     }
     return NO_ERROR;
@@ -398,14 +310,17 @@
     : mClient(surface->mClient), mSurface(surface->mSurface),
       mToken(surface->mToken), mIdentity(surface->mIdentity),
       mFormat(surface->mFormat), mFlags(surface->mFlags),
-      mBufferMapper(BufferMapper::get()),
+      mBufferMapper(BufferMapper::get()), mSharedBufferClient(NULL),
       mWidth(surface->mWidth), mHeight(surface->mHeight)
 {
+    mSharedBufferClient = new SharedBufferClient(
+            mClient->mControl, mToken, 2);
+
     init();
 }
 
 Surface::Surface(const Parcel& parcel)
-    :  mBufferMapper(BufferMapper::get())
+    :  mBufferMapper(BufferMapper::get()), mSharedBufferClient(NULL)
 {
     sp<IBinder> clientBinder = parcel.readStrongBinder();
     mSurface    = interface_cast<ISurface>(parcel.readStrongBinder());
@@ -416,9 +331,14 @@
     mFormat     = parcel.readInt32();
     mFlags      = parcel.readInt32();
 
-    if (clientBinder != NULL)
+    // FIXME: what does that mean if clientBinder is NULL here?
+    if (clientBinder != NULL) {
         mClient = SurfaceComposerClient::clientForConnection(clientBinder);
 
+        mSharedBufferClient = new SharedBufferClient(
+                mClient->mControl, mToken, 2);
+    }
+
     init();
 }
 
@@ -442,6 +362,7 @@
     // be default we request a hardware surface
     mUsage = GRALLOC_USAGE_HW_RENDER;
     mUsageChanged = true;
+    mNeedFullUpdate = false;
 }
 
 Surface::~Surface()
@@ -458,6 +379,7 @@
     // happen without delay, since these resources are quite heavy.
     mClient.clear();
     mSurface.clear();
+    delete mSharedBufferClient;
     IPCThreadState::self()->flushCommands();
 }
 
@@ -473,7 +395,7 @@
     return mToken>=0 && mClient!=0;
 }
 
-status_t Surface::validate(per_client_cblk_t const* cblk) const
+status_t Surface::validate(SharedClient const* cblk) const
 {
     sp<SurfaceComposerClient> client(getClient());
     if (mToken<0 || mClient==0) {
@@ -491,9 +413,10 @@
                 mToken, mIdentity, err, strerror(-err));
         return err;
     }
-    if (mIdentity != uint32_t(cblk->layers[mToken].identity)) {
+    uint32_t identity = cblk->getIdentity(mToken);
+    if (mIdentity != identity) {
         LOGE("using an invalid surface id=%d, identity=%u should be %d",
-                mToken, mIdentity, cblk->layers[mToken].identity);
+                mToken, mIdentity, identity);
         return NO_INIT;
     }
     return NO_ERROR;
@@ -511,42 +434,36 @@
 
 // ----------------------------------------------------------------------------
 
-int Surface::setSwapInterval(android_native_window_t* window, int interval)
-{
+int Surface::setSwapInterval(android_native_window_t* window, int interval) {
     return 0;
 }
 
 int Surface::dequeueBuffer(android_native_window_t* window, 
-        android_native_buffer_t** buffer)
-{
+        android_native_buffer_t** buffer) {
     Surface* self = getSelf(window);
     return self->dequeueBuffer(buffer);
 }
 
 int Surface::lockBuffer(android_native_window_t* window, 
-        android_native_buffer_t* buffer)
-{
+        android_native_buffer_t* buffer) {
     Surface* self = getSelf(window);
     return self->lockBuffer(buffer);
 }
 
 int Surface::queueBuffer(android_native_window_t* window, 
-        android_native_buffer_t* buffer)
-{
+        android_native_buffer_t* buffer) {
     Surface* self = getSelf(window);
     return self->queueBuffer(buffer);
 }
 
 int Surface::query(android_native_window_t* window, 
-        int what, int* value)
-{
+        int what, int* value) {
     Surface* self = getSelf(window);
     return self->query(what, value);
 }
 
 int Surface::perform(android_native_window_t* window, 
-        int operation, ...)
-{
+        int operation, ...) {
     va_list args;
     va_start(args, operation);
     Surface* self = getSelf(window);
@@ -557,8 +474,7 @@
 
 // ----------------------------------------------------------------------------
 
-status_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer)
-{
+status_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer) {
     android_native_buffer_t* out;
     status_t err = dequeueBuffer(&out);
     if (err == NO_ERROR) {
@@ -567,70 +483,49 @@
     return err;
 }
 
-status_t Surface::lockBuffer(const sp<SurfaceBuffer>& buffer)
-{
-    return lockBuffer(buffer.get());
-}
-
-status_t Surface::queueBuffer(const sp<SurfaceBuffer>& buffer)
-{
-    return queueBuffer(buffer.get());
-}
-
 // ----------------------------------------------------------------------------
 
+
 int Surface::dequeueBuffer(android_native_buffer_t** buffer)
 {
-    // FIXME: dequeueBuffer() needs proper implementation
-
-    Mutex::Autolock _l(mSurfaceLock);
-
     sp<SurfaceComposerClient> client(getClient());
-    per_client_cblk_t* const cblk = client->mControl;
-    status_t err = validate(cblk);
+    status_t err = validate(client->mControl);
     if (err != NO_ERROR)
         return err;
 
-    SurfaceID index(mToken); 
-    
-    int32_t backIdx = cblk->lock_layer(size_t(index),
-            per_client_cblk_t::BLOCKING);
-
-    if (backIdx < 0)
-        return status_t(backIdx); 
-
-    mBackbufferIndex = backIdx;
-    layer_cblk_t* const lcblk = &(cblk->layers[index]);
-    volatile const surface_info_t* const back = lcblk->surface + backIdx;
-
-    const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
-
-    if (backBuffer==0 &&
-            !((back->flags & surface_info_t::eNeedNewBuffer) || mUsageChanged)) {
-        LOGW("dequeueBuffer: backbuffer is null, but eNeedNewBuffer "
-                "is not set, fetching a buffer anyways...");
+    ssize_t bufIdx = mSharedBufferClient->dequeue();
+    if (bufIdx < 0) {
+        LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
+        return bufIdx;
     }
-
-    if ((back->flags & surface_info_t::eNeedNewBuffer) ||mUsageChanged ||
-            backBuffer==0) 
-    {
-        mUsageChanged = false;
-        err = getBufferLocked(backIdx, mUsage);
+    
+    // FIXME: in case of failure below, we need to undo the dequeue
+    
+    uint32_t usage;
+    const bool usageChanged = getUsage(&usage);
+    const sp<SurfaceBuffer>& backBuffer(mBuffers[bufIdx]);
+    if ((backBuffer == 0) || usageChanged || 
+            mSharedBufferClient->needNewBuffer(bufIdx)) {
+        err = getBufferLocked(bufIdx, usage);
+        LOGE_IF(err, "getBufferLocked(%ld, %08x) failed (%s)",
+                bufIdx, usage, strerror(-err));
         if (err == NO_ERROR) {
             // reset the width/height with the what we get from the buffer
-            const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
             mWidth  = uint32_t(backBuffer->width);
             mHeight = uint32_t(backBuffer->height);
         }
     }
 
+    // if we still don't have a buffer here, we probably ran out of memory
+    if (!err && backBuffer==0) {
+        err = NO_MEMORY;
+    }
+
     if (err == NO_ERROR) {
-        if (backBuffer != 0) {
-            mDirtyRegion.set(backBuffer->width, backBuffer->height);
-            *buffer = backBuffer.get();
-        } else {
-            err = NO_MEMORY;
-        }
+        mDirtyRegion.set(backBuffer->width, backBuffer->height);
+        *buffer = backBuffer.get();
+    } else {
+        mSharedBufferClient->undoDequeue(bufIdx);
     }
 
     return err;
@@ -638,25 +533,21 @@
 
 int Surface::lockBuffer(android_native_buffer_t* buffer)
 {
-    Mutex::Autolock _l(mSurfaceLock);
-
     sp<SurfaceComposerClient> client(getClient());
-    per_client_cblk_t* const cblk = client->mControl;
-    status_t err = validate(cblk);
+    status_t err = validate(client->mControl);
     if (err != NO_ERROR)
         return err;
 
-    // FIXME: lockBuffer() needs proper implementation
-    return 0;
+    int32_t bufIdx = SurfaceBuffer::getSelf(buffer)->getIndex();
+    err = mSharedBufferClient->lock(bufIdx);
+    LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
+    return err;
 }
 
 int Surface::queueBuffer(android_native_buffer_t* buffer)
 {   
-    Mutex::Autolock _l(mSurfaceLock);
-
     sp<SurfaceComposerClient> client(getClient());
-    per_client_cblk_t* const cblk = client->mControl;
-    status_t err = validate(cblk);
+    status_t err = validate(client->mControl);
     if (err != NO_ERROR)
         return err;
 
@@ -664,30 +555,30 @@
         mDirtyRegion.set(mSwapRectangle);
     }
     
-    // transmit the dirty region
-    SurfaceID index(mToken); 
-    layer_cblk_t* const lcblk = &(cblk->layers[index]);
-    _send_dirty_region(lcblk, mDirtyRegion);
+    int32_t bufIdx = SurfaceBuffer::getSelf(buffer)->getIndex();
+    mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
+    err = mSharedBufferClient->queue(bufIdx);
+    LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
 
-    uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
-    if (!(newstate & eNextFlipPending))
+    if (err == NO_ERROR) {
+        // FIXME: can we avoid this IPC if we know there is one pending?
         client->signalServer();
-
-    return NO_ERROR;
+    }
+    return err;
 }
 
 int Surface::query(int what, int* value)
 {
     switch (what) {
-        case NATIVE_WINDOW_WIDTH:
-            *value = int(mWidth);
-            return NO_ERROR;
-        case NATIVE_WINDOW_HEIGHT:
-            *value = int(mHeight);
-            return NO_ERROR;
-        case NATIVE_WINDOW_FORMAT:
-            *value = int(mFormat);
-            return NO_ERROR;
+    case NATIVE_WINDOW_WIDTH:
+        *value = int(mWidth);
+        return NO_ERROR;
+    case NATIVE_WINDOW_HEIGHT:
+        *value = int(mHeight);
+        return NO_ERROR;
+    case NATIVE_WINDOW_FORMAT:
+        *value = int(mFormat);
+        return NO_ERROR;
     }
     return BAD_VALUE;
 }
@@ -715,6 +606,17 @@
     }
 }
 
+bool Surface::getUsage(uint32_t* usage)
+{
+    Mutex::Autolock _l(mSurfaceLock);
+    *usage = mUsage;
+    if (mUsageChanged) {
+        mUsageChanged = false;
+        return true;
+    }
+    return false;
+}
+
 // ----------------------------------------------------------------------------
 
 status_t Surface::lock(SurfaceInfo* info, bool blocking) {
@@ -723,43 +625,55 @@
 
 status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 
 {
+    if (mApiLock.tryLock() != NO_ERROR) {
+        LOGE("calling Surface::lock() from different threads!");
+        CallStack stack;
+        stack.update();
+        stack.dump("Surface::lock called from different threads");
+        return WOULD_BLOCK;
+    }
+    
     // we're intending to do software rendering from this point
     setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
 
     sp<SurfaceBuffer> backBuffer;
     status_t err = dequeueBuffer(&backBuffer);
+    LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
     if (err == NO_ERROR) {
-        err = lockBuffer(backBuffer);
+        err = lockBuffer(backBuffer.get());
+        LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
+                backBuffer->getIndex(), strerror(-err));
         if (err == NO_ERROR) {
             // we handle copy-back here...
-            
+
             const Rect bounds(backBuffer->width, backBuffer->height);
             Region scratch(bounds);
             Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
 
-            sp<SurfaceComposerClient> client(getClient());
-            per_client_cblk_t* const cblk = client->mControl;
-            layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]);
-            volatile const surface_info_t* const back = lcblk->surface + mBackbufferIndex;
-            if (back->flags & surface_info_t::eBufferDirty) {
-                // content is meaningless in this case and the whole surface
-                // needs to be redrawn.
+            if (mNeedFullUpdate) {
+                // reset newDirtyRegion to bounds when a buffer is reallocated
+                // it would be better if this information was associated with
+                // the buffer and made available to outside of Surface.
+                // This will do for now though.
+                mNeedFullUpdate = false;
                 newDirtyRegion.set(bounds);
             } else {
                 newDirtyRegion.andSelf(bounds);
-                const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]);
-                if (frontBuffer !=0 &&
-                    backBuffer->width  == frontBuffer->width && 
-                    backBuffer->height == frontBuffer->height &&
-                    !(lcblk->flags & eNoCopyBack)) 
-                {
-                    const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
-                    if (!copyback.isEmpty() && frontBuffer!=0) {
-                        // copy front to back
-                        copyBlt(backBuffer, frontBuffer, copyback);
-                    }
+            }
+
+            const sp<SurfaceBuffer>& frontBuffer(mPostedBuffer);
+            if (frontBuffer !=0 &&
+                backBuffer->width  == frontBuffer->width && 
+                backBuffer->height == frontBuffer->height &&
+                !(mFlags & ISurfaceComposer::eDestroyBackbuffer)) 
+            {
+                const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
+                if (!copyback.isEmpty() && frontBuffer!=0) {
+                    // copy front to back
+                    copyBlt(backBuffer, frontBuffer, copyback);
                 }
             }
+
             mDirtyRegion = newDirtyRegion;
             mOldDirtyRegion = newDirtyRegion;
 
@@ -768,8 +682,8 @@
                     GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                     newDirtyRegion.bounds(), &vaddr);
             
-            LOGW_IF(res, "failed locking buffer %d (%p)", 
-                    mBackbufferIndex, backBuffer->handle);
+            LOGW_IF(res, "failed locking buffer (handle = %p)", 
+                    backBuffer->handle);
 
             mLockedBuffer = backBuffer;
             other->w      = backBuffer->width;
@@ -780,36 +694,29 @@
             other->bits   = vaddr;
         }
     }
+    mApiLock.unlock();
     return err;
 }
     
 status_t Surface::unlockAndPost() 
 {
-    if (mLockedBuffer == 0)
+    if (mLockedBuffer == 0) {
+        LOGE("unlockAndPost failed, no locked buffer");
         return BAD_VALUE;
+    }
 
-    status_t res = mLockedBuffer->unlock();
-    LOGW_IF(res, "failed unlocking buffer %d (%p)",
-            mBackbufferIndex, mLockedBuffer->handle);
+    status_t err = mLockedBuffer->unlock();
+    LOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle);
     
-    status_t err = queueBuffer(mLockedBuffer);
+    err = queueBuffer(mLockedBuffer.get());
+    LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
+            mLockedBuffer->getIndex(), strerror(-err));
+
+    mPostedBuffer = mLockedBuffer;
     mLockedBuffer = 0;
     return err;
 }
 
-void Surface::_send_dirty_region(
-        layer_cblk_t* lcblk, const Region& dirty)
-{
-    const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
-    flat_region_t* flat_region = lcblk->region + index;
-    status_t err = dirty.write(flat_region, sizeof(flat_region_t));
-    if (err < NO_ERROR) {
-        // region doesn't fit, use the bounds
-        const Region reg(dirty.bounds());
-        reg.write(flat_region, sizeof(flat_region_t));
-    }
-}
-
 void Surface::setSwapRectangle(const Rect& r) {
     Mutex::Autolock _l(mSurfaceLock);
     mSwapRectangle = r;
@@ -829,15 +736,22 @@
         currentBuffer.clear();
     }
 
-    sp<SurfaceBuffer> buffer = s->getBuffer(usage);
-    LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL");
+    sp<SurfaceBuffer> buffer = s->requestBuffer(index, usage);
+    LOGE_IF(buffer==0,
+            "ISurface::getBuffer(%d, %08x) returned NULL",
+            index, usage);
     if (buffer != 0) { // this should never happen by construction
+        LOGE_IF(buffer->handle == NULL, 
+                "requestBuffer(%d, %08x) returned a buffer with a null handle",
+                index, usage);
         if (buffer->handle != NULL) { 
             err = getBufferMapper().registerBuffer(buffer->handle);
             LOGW_IF(err, "registerBuffer(...) failed %d (%s)",
                     err, strerror(-err));
             if (err == NO_ERROR) {
                 currentBuffer = buffer;
+                currentBuffer->setIndex(index);
+                mNeedFullUpdate = true;
             }
         }
     }
diff --git a/libs/ui/SurfaceBuffer.cpp b/libs/ui/SurfaceBuffer.cpp
new file mode 100644
index 0000000..0510bc1
--- /dev/null
+++ b/libs/ui/SurfaceBuffer.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SurfaceBuffer"
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <binder/Parcel.h>
+
+#include <ui/BufferMapper.h>
+#include <ui/Rect.h>
+#include <private/ui/SurfaceBuffer.h>
+
+namespace android {
+
+// ============================================================================
+//  SurfaceBuffer
+// ============================================================================
+
+SurfaceBuffer::SurfaceBuffer() 
+    : BASE(), mOwner(false), mBufferMapper(BufferMapper::get()), mIndex(-1)
+{
+    width  = 
+    height = 
+    stride = 
+    format = 
+    usage  = 0;
+    handle = NULL;
+}
+
+SurfaceBuffer::SurfaceBuffer(const Parcel& data) 
+    : BASE(), mOwner(true), mBufferMapper(BufferMapper::get())
+{
+    // we own the handle in this case
+    width  = data.readInt32();
+    if (width < 0) {
+        width = height = stride = format = usage = 0;
+        handle = 0;
+    } else {
+        height = data.readInt32();
+        stride = data.readInt32();
+        format = data.readInt32();
+        usage  = data.readInt32();
+        handle = data.readNativeHandle();
+    }
+}
+
+SurfaceBuffer::~SurfaceBuffer()
+{
+    if (handle && mOwner) {
+        native_handle_close(handle);
+        native_handle_delete(const_cast<native_handle*>(handle));
+    }
+}
+
+status_t SurfaceBuffer::lock(uint32_t usage, void** vaddr)
+{
+    const Rect lockBounds(width, height);
+    status_t res = lock(usage, lockBounds, vaddr);
+    return res;
+}
+
+status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
+{
+    if (rect.left < 0 || rect.right  > this->width || 
+        rect.top  < 0 || rect.bottom > this->height) {
+        LOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
+                rect.left, rect.top, rect.right, rect.bottom, 
+                this->width, this->height);
+        return BAD_VALUE;
+    }
+    status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
+    return res;
+}
+
+status_t SurfaceBuffer::unlock()
+{
+    status_t res = getBufferMapper().unlock(handle);
+    return res;
+}
+
+status_t SurfaceBuffer::writeToParcel(Parcel* reply, 
+        android_native_buffer_t const* buffer)
+{
+    if (buffer == NULL)
+        return BAD_VALUE;
+
+    if (buffer->width < 0 || buffer->height < 0)
+        return BAD_VALUE;
+
+    status_t err = NO_ERROR;
+    if (buffer->handle == NULL) {
+        // this buffer doesn't have a handle
+        reply->writeInt32(NO_MEMORY);
+    } else {
+        reply->writeInt32(buffer->width);
+        reply->writeInt32(buffer->height);
+        reply->writeInt32(buffer->stride);
+        reply->writeInt32(buffer->format);
+        reply->writeInt32(buffer->usage);
+        err = reply->writeNativeHandle(buffer->handle);
+    }
+    return err;
+}
+
+
+void SurfaceBuffer::setIndex(int index) {
+    mIndex = index;
+}
+
+int SurfaceBuffer::getIndex() const {
+    return mIndex;
+}
+
+
+}; // namespace android
+
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
index d2cef78..8401cb6 100644
--- a/libs/ui/SurfaceComposerClient.cpp
+++ b/libs/ui/SurfaceComposerClient.cpp
@@ -40,8 +40,8 @@
 #include <ui/SurfaceComposerClient.h>
 #include <ui/Rect.h>
 
-#include <private/ui/SharedState.h>
 #include <private/ui/LayerState.h>
+#include <private/ui/SharedBufferStack.h>
 #include <private/ui/SurfaceFlingerSynchro.h>
 
 #define VERBOSE(...)	((void)0)
@@ -103,169 +103,6 @@
 
 // ---------------------------------------------------------------------------
 
-// these functions are used by the clients
-status_t per_client_cblk_t::validate(size_t i) const {
-    if (uint32_t(i) >= NUM_LAYERS_MAX)
-        return BAD_INDEX;
-    if (layers[i].swapState & eInvalidSurface)
-        return NO_MEMORY;
-    return NO_ERROR;
-}
-
-int32_t per_client_cblk_t::lock_layer(size_t i, uint32_t flags)
-{
-    int32_t index;
-    uint32_t state;
-    int timeout = 0;
-    status_t result;
-    layer_cblk_t * const layer = layers + i;
-    const bool blocking = flags & BLOCKING;
-    const bool inspect  = flags & INSPECT;
-
-    do {
-        state = layer->swapState;
-
-        if (UNLIKELY((state&(eFlipRequested|eNextFlipPending)) == eNextFlipPending)) {
-            LOGE("eNextFlipPending set but eFlipRequested not set, "
-                 "layer=%d (lcblk=%p), state=%08x",
-                 int(i), layer, int(state));
-            return INVALID_OPERATION;
-        }
-
-        if (UNLIKELY(state&eLocked)) {
-            LOGE("eLocked set when entering lock_layer(), "
-                 "layer=%d (lcblk=%p), state=%08x",
-                 int(i), layer, int(state));
-            return WOULD_BLOCK;
-        }
-
-
-	    if (state & (eFlipRequested | eNextFlipPending | eResizeRequested
-                        | eInvalidSurface))
-        {
-	        int32_t resizeIndex;
-	        Mutex::Autolock _l(lock);
-	            // might block for a very short amount of time
-	            // will never cause the server to block (trylock())
-
-	        goto start_loop_here;
-
-	        // We block the client if:
-	        // eNextFlipPending:  we've used both buffers already, so we need to
-	        //                    wait for one to become availlable.
-	        // eResizeRequested:  the buffer we're going to acquire is being
-	        //                    resized. Block until it is done.
-	        // eFlipRequested && eBusy: the buffer we're going to acquire is
-	        //                    currently in use by the server.
-	        // eInvalidSurface:   this is a special case, we don't block in this
-	        //                    case, we just return an error.
-
-	        while((state & (eNextFlipPending|eInvalidSurface)) ||
-	              (state & ((resizeIndex) ? eResizeBuffer1 : eResizeBuffer0)) ||
-	              ((state & (eFlipRequested|eBusy)) == (eFlipRequested|eBusy)) )
-	        {
-	            if (state & eInvalidSurface)
-	                return NO_MEMORY;
-
-	            if (!blocking)
-	                return WOULD_BLOCK;
-
-                timeout = 0;
-                result = cv.waitRelative(lock, seconds(1));
-	            if (__builtin_expect(result!=NO_ERROR, false)) {
-                    const int newState = layer->swapState;
-                    LOGW(   "lock_layer timed out (is the CPU pegged?) "
-                            "layer=%d, lcblk=%p, state=%08x (was %08x)",
-                            int(i), layer, newState, int(state));
-                    timeout = newState != int(state);
-                }
-
-	        start_loop_here:
-	            state = layer->swapState;
-	            resizeIndex = (state&eIndex) ^ ((state&eFlipRequested)>>1);
-	        }
-
-            LOGW_IF(timeout,
-                    "lock_layer() timed out but didn't appear to need "
-                    "to be locked and we recovered "
-                    "(layer=%d, lcblk=%p, state=%08x)",
-                    int(i), layer, int(state));
-	    }
-
-	    // eFlipRequested is not set and cannot be set by another thread: it's
-	    // safe to use the first buffer without synchronization.
-
-        // Choose the index depending on eFlipRequested.
-        // When it's set, choose the 'other' buffer.
-        index = (state&eIndex) ^ ((state&eFlipRequested)>>1);
-
-	    // make sure this buffer is valid
-        status_t err = layer->surface[index].status;
-	    if (err < 0) {
-	        return err;
-	    }
-
-        if (inspect) {
-            // we just want to inspect this layer. don't lock it.
-            goto done;
-        }
-
-	    // last thing before we're done, we need to atomically lock the state
-    } while (android_atomic_cmpxchg(state, state|eLocked, &(layer->swapState)));
-
-    VERBOSE("locked layer=%d (lcblk=%p), buffer=%d, state=0x%08x",
-         int(i), layer, int(index), int(state));
-
-    // store the index of the locked buffer (for client use only)
-    layer->flags &= ~eBufferIndex;
-    layer->flags |= ((index << eBufferIndexShift) & eBufferIndex);
-
-done:
-    return index;
-}
-
-uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i)
-{
-    // atomically set eFlipRequested and clear eLocked and optionally
-    // set eNextFlipPending if eFlipRequested was already set
-
-    layer_cblk_t * const layer = layers + i;
-    int32_t oldvalue, newvalue;
-    do {
-        oldvalue = layer->swapState;
-            // get current value
-
-        newvalue = oldvalue & ~eLocked;
-            // clear eLocked
-
-        newvalue |= eFlipRequested;
-            // set eFlipRequested
-
-        if (oldvalue & eFlipRequested)
-            newvalue |= eNextFlipPending;
-            // if eFlipRequested was already set, set eNextFlipPending
-
-    } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState)));
-
-    VERBOSE("request pageflip for layer=%d, buffer=%d, state=0x%08x",
-            int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift),
-            int(newvalue));
-
-    // from this point, the server can kick in at any time and use the first
-    // buffer, so we cannot use it anymore, and we must use the 'other'
-    // buffer instead (or wait if it is not available yet, see lock_layer).
-
-    return newvalue;
-}
-
-void per_client_cblk_t::unlock_layer(size_t i)
-{
-    layer_cblk_t * const layer = layers + i;
-    android_atomic_and(~eLocked, &layer->swapState);
-}
-
-// ---------------------------------------------------------------------------
-
 static inline int compare_type( const layer_state_t& lhs,
                                 const layer_state_t& rhs) {
     if (lhs.surface < rhs.surface)  return -1;
@@ -315,7 +152,7 @@
 
     mControlMemory = mClient->getControlBlock();
     mSignalServer = new SurfaceFlingerSynchro(sm);
-    mControl = static_cast<per_client_cblk_t *>(mControlMemory->getBase());
+    mControl = static_cast<SharedClient *>(mControlMemory->getBase());
 }
 
 SurfaceComposerClient::~SurfaceComposerClient()
@@ -539,18 +376,17 @@
 
     const size_t N = clients.size();
     VERBOSE("closeGlobalTransaction (%ld clients)", N);
-    if (N == 1) {
-        clients[0]->closeTransaction();
-    } else {
-        const sp<ISurfaceComposer>& sm(_get_surface_manager());
-        sm->openGlobalTransaction();
-        for (size_t i=0; i<N; i++) {
-            clients[i]->closeTransaction();
-        }
-        sm->closeGlobalTransaction();
+
+    const sp<ISurfaceComposer>& sm(_get_surface_manager());
+    sm->openGlobalTransaction();
+    for (size_t i=0; i<N; i++) {
+        clients[i]->closeTransaction();
     }
+    sm->closeGlobalTransaction();
+
 }
 
+
 status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
 {
     const sp<ISurfaceComposer>& sm(_get_surface_manager());
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 0831f4a..f80843d 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -3284,7 +3284,16 @@
                     break;
                 }
                 if (c == '\'' && (quoted == 0 || quoted == '\'')) {
-                    break;
+                    /*
+                     * In practice, when people write ' instead of \'
+                     * in a string, they are doing it by accident
+                     * instead of really meaning to use ' as a quoting
+                     * character.  Warn them so they don't lose it.
+                     */
+                    if (outErrorMsg) {
+                        *outErrorMsg = "Apostrophe not preceded by \\";
+                    }
+                    return false;
                 }
             }
             p++;
diff --git a/opengl/tests/gl2_basic/Android.mk b/opengl/tests/gl2_basic/Android.mk
new file mode 100644
index 0000000..a642eaf
--- /dev/null
+++ b/opengl/tests/gl2_basic/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	gl2_basic.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv2 \
+    libui
+
+LOCAL_MODULE:= test-opengl-gl2_basic
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
new file mode 100644
index 0000000..705794a
--- /dev/null
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -0,0 +1,85 @@
+/*
+ * 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 <stdio.h>
+#include <time.h>
+#include <sched.h>
+#include <sys/resource.h>
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <utils/Timers.h>
+
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/EGLUtils.h>
+
+using namespace android;
+
+static void printGLString(const char *name, GLenum s)
+{
+     const char *v = (const char *)glGetString(s);
+     if (v)
+         printf("GL %s = %s\n", name, v);
+     else
+         printf("GL %s = (null)\n", name);
+}
+
+int main(int argc, char** argv)
+{
+    EGLint s_configAttribs[] = {
+         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+         EGL_RED_SIZE,       5,
+         EGL_GREEN_SIZE,     6,
+         EGL_BLUE_SIZE,      5,
+         EGL_NONE
+     };
+
+     EGLint numConfigs = -1;
+     EGLint majorVersion;
+     EGLint minorVersion;
+     EGLConfig config;
+     EGLContext context;
+     EGLSurface surface;
+     EGLint w, h;
+
+     EGLDisplay dpy;
+
+     EGLNativeWindowType window = 0;
+     window = android_createDisplaySurface();
+
+     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+     eglInitialize(dpy, &majorVersion, &minorVersion);
+     EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
+     surface = eglCreateWindowSurface(dpy, config, window, NULL);
+
+    EGLint gl2_0Attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+
+     context = eglCreateContext(dpy, config, NULL, gl2_0Attribs);
+     eglMakeCurrent(dpy, surface, surface, context);
+     eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+     eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+     GLint dim = w<h ? w : h;
+
+     printGLString("Version", GL_VERSION);
+     printGLString("Vendor", GL_VENDOR);
+     printGLString("Renderer", GL_RENDERER);
+     printGLString("Extensions", GL_EXTENSIONS);
+
+     return 0;
+}