am d47cdbb7: am 3bb5e4d3: Merge "Tweak style of recent apps dialog title." into froyo

Merge commit 'd47cdbb7ea97a6ed3b428d913fa45883904d0ba8' into kraken

* commit 'd47cdbb7ea97a6ed3b428d913fa45883904d0ba8':
  Tweak style of recent apps dialog title.
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 00bd54e..53c77da 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -16,6 +16,7 @@
 ** limitations under the License.
 */
 
+//#define LOG_NDEBUG 0
 #define LOG_TAG "CameraService"
 #include <utils/Log.h>
 
@@ -247,7 +248,7 @@
 status_t CameraService::Client::checkPid()
 {
     int callingPid = getCallingPid();
-    if (mClientPid == callingPid) return NO_ERROR;
+    if (mClientPid == callingPid || callingPid == getpid()) return NO_ERROR;
     LOGW("Attempt to use locked camera (client %p) from different process "
         " (old pid %d, new pid %d)",
         getCameraClient()->asBinder().get(), mClientPid, callingPid);
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 9b5a1e0..dc53d6a 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -58,7 +58,7 @@
 // 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_BUFFER_MAX  = 16;
 const unsigned int NUM_DISPLAY_MAX = 4;
 
 // ----------------------------------------------------------------------------
@@ -69,7 +69,11 @@
 
 // ----------------------------------------------------------------------------
 
-// should be 128 bytes (32 longs)
+// 4 * (11 + 7 + (1 + 2*NUM_RECT_MAX) * NUM_BUFFER_MAX) * NUM_LAYERS_MAX
+// 4 * (11 + 7 + (1 + 2*7)*16) * 31
+// 1032 * 31
+// = ~27 KiB (31992)
+
 class SharedBufferStack
 {
     friend class SharedClient;
@@ -78,21 +82,31 @@
     friend class SharedBufferServer;
 
 public:
-    struct FlatRegion { // 12 bytes
-        static const unsigned int NUM_RECT_MAX = 1;
-        uint32_t    count;
-        uint16_t    rects[4*NUM_RECT_MAX];
-    };
-    
     struct Statistics { // 4 longs
         typedef int32_t usecs_t;
         usecs_t  totalTime;
         usecs_t  reserved[3];
     };
+
+    struct SmallRect {
+        uint16_t l, t, r, b;
+    };
+
+    struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
+        static const unsigned int NUM_RECT_MAX = 6;
+        uint32_t    count;
+        SmallRect   rects[NUM_RECT_MAX];
+    };
+    
+    struct BufferData {
+        FlatRegion dirtyRegion;
+        SmallRect  crop;
+    };
     
     SharedBufferStack();
     void init(int32_t identity);
     status_t setDirtyRegion(int buffer, const Region& reg);
+    status_t setCrop(int buffer, const Rect& reg);
     Region getDirtyRegion(int buffer) const;
 
     // these attributes are part of the conditions/updates
@@ -106,9 +120,10 @@
     volatile int32_t reallocMask;
 
     int32_t     identity;       // surface's identity (const)
-    int32_t     reserved32[9];
+    int32_t     reserved32[6];
     Statistics  stats;
-    FlatRegion  dirtyRegion[NUM_BUFFER_MAX];    // 12*4=48 bytes
+    int32_t     reserved;
+    BufferData  buffers[NUM_BUFFER_MAX];     // 960 bytes
 };
 
 // ----------------------------------------------------------------------------
@@ -152,6 +167,7 @@
     SharedBufferStack* const mSharedStack;
     const int mNumBuffers;
     const int mIdentity;
+    int32_t computeTail() const;
 
     friend struct Update;
     friend struct QueueUpdate;
@@ -160,61 +176,22 @@
         SharedBufferStack& stack;
         inline ConditionBase(SharedBufferBase* sbc) 
             : stack(*sbc->mSharedStack) { }
+        virtual ~ConditionBase() { };
+        virtual bool operator()() const = 0;
+        virtual const char* name() const = 0;
     };
+    status_t waitForCondition(const ConditionBase& condition);
 
     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) 
-{
-    const SharedBufferStack& stack( *mSharedStack );
-    SharedClient& client( *mSharedClient );
-    const nsecs_t TIMEOUT = s2ns(1);
-    Mutex::Autolock _l(client.lock);
-    while ((condition()==false) &&
-            (stack.identity == mIdentity) &&
-            (stack.status == NO_ERROR))
-    {
-        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(),
-                        stack.identity);
-                    break;
-                } else {
-                    LOGW("waitForCondition(%s) timed out "
-                        "(identity=%d, status=%d). "
-                        "CPU may be pegged. trying again.", T::name(),
-                        stack.identity, stack.status);
-                }
-            } else {
-                LOGE("waitForCondition(%s) error (%s) ",
-                        T::name(), strerror(-err));
-                return err;
-            }
-        }
-    }
-    return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
-}
-
-
-template <typename T>
 status_t SharedBufferBase::updateCondition(T update) {
     SharedClient& client( *mSharedClient );
     Mutex::Autolock _l(client.lock);
@@ -238,13 +215,12 @@
     status_t queue(int buf);
     bool needNewBuffer(int buffer) const;
     status_t setDirtyRegion(int buffer, const Region& reg);
+    status_t setCrop(int buffer, const Rect& reg);
     
 private:
     friend struct Condition;
     friend struct DequeueCondition;
     friend struct LockCondition;
-    
-    int32_t computeTail() const;
 
     struct QueueUpdate : public UpdateBase {
         inline QueueUpdate(SharedBufferBase* sbb);
@@ -260,18 +236,19 @@
 
     struct DequeueCondition : public ConditionBase {
         inline DequeueCondition(SharedBufferClient* sbc);
-        inline bool operator()();
-        static inline const char* name() { return "DequeueCondition"; }
+        inline bool operator()() const;
+        inline const char* name() const { return "DequeueCondition"; }
     };
 
     struct LockCondition : public ConditionBase {
         int buf;
         inline LockCondition(SharedBufferClient* sbc, int buf);
-        inline bool operator()();
-        static inline const char* name() { return "LockCondition"; }
+        inline bool operator()() const;
+        inline const char* name() const { return "LockCondition"; }
     };
 
     int32_t tail;
+    int32_t undoDequeueTail;
     // statistics...
     nsecs_t mDequeueTime[NUM_BUFFER_MAX];
 };
@@ -318,8 +295,8 @@
     struct ReallocateCondition : public ConditionBase {
         int buf;
         inline ReallocateCondition(SharedBufferBase* sbb, int buf);
-        inline bool operator()();
-        static inline const char* name() { return "ReallocateCondition"; }
+        inline bool operator()() const;
+        inline const char* name() const { return "ReallocateCondition"; }
     };
 };
 
@@ -349,8 +326,7 @@
 
 // ---------------------------------------------------------------------------
 
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 4096)
-COMPILE_TIME_ASSERT(sizeof(SharedBufferStack) == 128)
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768)
 COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
 
 // ---------------------------------------------------------------------------
diff --git a/include/surfaceflinger/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceFlingerClient.h
index d257645..c96432f 100644
--- a/include/surfaceflinger/ISurfaceFlingerClient.h
+++ b/include/surfaceflinger/ISurfaceFlingerClient.h
@@ -59,6 +59,9 @@
     
     virtual sp<IMemoryHeap> getControlBlock() const = 0;
 
+    /*
+     * Requires ACCESS_SURFACE_FLINGER permission
+     */
     virtual sp<ISurface> createSurface( surface_data_t* data,
                                         int pid, 
                                         const String8& name,
@@ -68,8 +71,14 @@
                                         PixelFormat format,
                                         uint32_t flags) = 0;
                                     
+    /*
+     * Requires ACCESS_SURFACE_FLINGER permission
+     */
     virtual status_t    destroySurface(SurfaceID sid) = 0;
 
+    /*
+     * Requires ACCESS_SURFACE_FLINGER permission
+     */
     virtual status_t    setState(int32_t count, const layer_state_t* states) = 0;
 };
 
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 0279d84..7ab3a00 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -30,6 +30,8 @@
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/ISurfaceFlingerClient.h>
 
+#define ANDROID_VIEW_SURFACE_JNI_ID    "mNativeSurface"
+
 namespace android {
 
 // ---------------------------------------------------------------------------
@@ -163,38 +165,36 @@
     // setSwapRectangle() is intended to be used by GL ES clients
     void        setSwapRectangle(const Rect& r);
 
+
 private:
-    // can't be copied
-    Surface& operator = (Surface& rhs);
-    Surface(const Surface& rhs);
-
-    Surface(const sp<SurfaceControl>& control);
-    void init();
-     ~Surface();
-  
-    friend class SurfaceComposerClient;
-    friend class SurfaceControl;
-
-    
+    /*
+     * Android frameworks friends
+     * (eventually this should go away and be replaced by proper APIs)
+     */
     // camera and camcorder need access to the ISurface binder interface for preview
     friend class Camera;
     friend class MediaRecorder;
-    // mediaplayer needs access to ISurface for display
+    // MediaPlayer needs access to ISurface for display
     friend class MediaPlayer;
     friend class IOMX;
     // this is just to be able to write some unit tests
     friend class Test;
 
-    sp<SurfaceComposerClient> getClient() const;
-    sp<ISurface> getISurface() const;
+private:
+    friend class SurfaceComposerClient;
+    friend class SurfaceControl;
 
-    status_t getBufferLocked(int index, int usage);
-   
-           status_t validate() const;
+    // can't be copied
+    Surface& operator = (Surface& rhs);
+    Surface(const Surface& rhs);
 
-    inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
-    inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
-    
+    Surface(const sp<SurfaceControl>& control);
+    ~Surface();
+
+
+    /*
+     *  android_native_window_t hooks
+     */
     static int setSwapInterval(android_native_window_t* window, int interval);
     static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
     static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
@@ -208,15 +208,29 @@
     int query(int what, int* value);
     int perform(int operation, va_list args);
 
-    status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
-
     void dispatch_setUsage(va_list args);
     int  dispatch_connect(va_list args);
     int  dispatch_disconnect(va_list args);
+    int  dispatch_crop(va_list args);
     
     void setUsage(uint32_t reqUsage);
     int  connect(int api);
     int  disconnect(int api);
+    int  crop(Rect const* rect);
+
+    /*
+     *  private stuff...
+     */
+    void init();
+    status_t validate() const;
+    sp<SurfaceComposerClient> getClient() const;
+    sp<ISurface> getISurface() const;
+
+    inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
+    inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
+
+    status_t getBufferLocked(int index, int usage);
+    int getBufferIndex(const sp<GraphicBuffer>& buffer) const;
 
     uint32_t getUsage() const;
     int      getConnectedApi() const;
@@ -235,6 +249,7 @@
     Rect                        mSwapRectangle;
     uint32_t                    mUsage;
     int                         mConnected;
+    Rect                        mNextBufferCrop;
     
     // protected by mSurfaceLock. These are also used from lock/unlock
     // but in that case, they must be called form the same thread.
@@ -245,7 +260,7 @@
     sp<GraphicBuffer>           mLockedBuffer;
     sp<GraphicBuffer>           mPostedBuffer;
     mutable Region              mOldDirtyRegion;
-    bool                        mNeedFullUpdate;
+    bool                        mReserved;
 
     // query() must be called from dequeueBuffer() thread
     uint32_t                    mWidth;
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 741d763..54b8236 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -73,9 +73,9 @@
     struct alloc_rec_t {
         uint32_t w;
         uint32_t h;
+        uint32_t s;
         PixelFormat format;
         uint32_t usage;
-        void* vaddr;
         size_t size;
     };
     
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 773fd93..471c3c7 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -41,6 +41,14 @@
 
 struct android_native_buffer_t;
 
+typedef struct android_native_rect_t
+{
+    int32_t left;
+    int32_t top;
+    int32_t right;
+    int32_t bottom;
+} android_native_rect_t;
+
 // ---------------------------------------------------------------------------
 
 typedef struct android_native_base_t
@@ -63,15 +71,16 @@
 /* attributes queriable with query() */
 enum {
     NATIVE_WINDOW_WIDTH     = 0,
-    NATIVE_WINDOW_HEIGHT    = 1,
-    NATIVE_WINDOW_FORMAT    = 2,
+    NATIVE_WINDOW_HEIGHT,
+    NATIVE_WINDOW_FORMAT,
 };
 
 /* valid operations for the (*perform)() hook */
 enum {
     NATIVE_WINDOW_SET_USAGE  = 0,
-    NATIVE_WINDOW_CONNECT    = 1,
-    NATIVE_WINDOW_DISCONNECT = 2
+    NATIVE_WINDOW_CONNECT,
+    NATIVE_WINDOW_DISCONNECT,
+    NATIVE_WINDOW_SET_CROP,
 };
 
 /* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -125,7 +134,7 @@
      * 
      * Returns 0 on success or -errno on error.
      */
-    int     (*dequeueBuffer)(struct android_native_window_t* window, 
+    int     (*dequeueBuffer)(struct android_native_window_t* window,
                 struct android_native_buffer_t** buffer);
 
     /*
@@ -171,6 +180,7 @@
      *     NATIVE_WINDOW_SET_USAGE
      *     NATIVE_WINDOW_CONNECT
      *     NATIVE_WINDOW_DISCONNECT
+     *     NATIVE_WINDOW_SET_CROP
      *  
      */
     
@@ -221,6 +231,24 @@
     return window->perform(window, NATIVE_WINDOW_DISCONNECT, api);
 }
 
+/*
+ * native_window_set_crop(..., crop) sets which region of the next queued
+ * buffers needs to be considered.
+ * A buffer's crop region is scaled to match the surface's size.
+ *
+ * The specified crop region applies to all buffers queued after it is called.
+ *
+ * if 'crop' is NULL, subsequently queued buffers won't be cropped.
+ *
+ * An error is returned if for instance the crop region is invalid,
+ * out of the buffer's bound or if the window is invalid.
+ */
+static inline int native_window_set_crop(
+        android_native_window_t* window,
+        android_native_rect_t const * crop)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
+}
 
 // ---------------------------------------------------------------------------
 
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index b701ce7..c7d9ff1 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -933,6 +933,7 @@
         SCREENSIZE_SMALL = 0x01,
         SCREENSIZE_NORMAL = 0x02,
         SCREENSIZE_LARGE = 0x03,
+        SCREENSIZE_XLARGE = 0x04,
         
         // screenLayout bits for wide/long screen variation.
         MASK_SCREENLONG = 0x30,
@@ -1208,7 +1209,28 @@
             if (screenLayout || o.screenLayout) {
                 if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
                         && (requested->screenLayout & MASK_SCREENSIZE)) {
-                    return (screenLayout & MASK_SCREENSIZE);
+                    // A little backwards compatibility here: undefined is
+                    // considered equivalent to normal.  But only if the
+                    // requested size is at least normal; otherwise, small
+                    // is better than the default.
+                    int mySL = (screenLayout & MASK_SCREENSIZE);
+                    int oSL = (o.screenLayout & MASK_SCREENSIZE);
+                    int fixedMySL = mySL;
+                    int fixedOSL = oSL;
+                    if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
+                        if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
+                        if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
+                    }
+                    // For screen size, the best match is the one that is
+                    // closest to the requested screen size, but not over
+                    // (the not over part is dealt with in match() below).
+                    if (fixedMySL == fixedOSL) {
+                        // If the two are the same, but 'this' is actually
+                        // undefined, then the other is really a better match.
+                        if (mySL == 0) return false;
+                        return true;
+                    }
+                    return fixedMySL >= fixedOSL;
                 }
                 if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
                         && (requested->screenLayout & MASK_SCREENLONG)) {
@@ -1370,8 +1392,11 @@
         if (screenConfig != 0) {
             const int screenSize = screenLayout&MASK_SCREENSIZE;
             const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
-            if (setScreenSize != 0 && screenSize != 0
-                    && screenSize != setScreenSize) {
+            // Any screen sizes for larger screens than the setting do not
+            // match.
+            if ((setScreenSize != 0 && screenSize != 0
+                    && screenSize > setScreenSize) ||
+                    (setScreenSize == 0 && screenSize != 0)) {
                 return false;
             }
             
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index ea68352..d979f00 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -266,9 +266,6 @@
     if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) {
         mFlags |= NPOT_EXTENSION;
     }
-    if (strstr(gl_extensions, "GL_OES_draw_texture")) {
-        mFlags |= DRAW_TEXTURE_EXTENSION;
-    }
 #ifdef EGL_ANDROID_image_native_buffer
     if (strstr( gl_extensions, "GL_OES_EGL_image") &&
         (strstr(egl_extensions, "EGL_KHR_image_base") || 
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index df046af..897a6ed 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -46,7 +46,6 @@
         DIRECT_TEXTURE          = 0x00000002,
         COPY_BITS_EXTENSION     = 0x00000008,
         NPOT_EXTENSION          = 0x00000100,
-        DRAW_TEXTURE_EXTENSION  = 0x00000200,
         BUFFER_PRESERVED        = 0x00010000,
         PARTIAL_UPDATES         = 0x00020000,   // video driver feature
         SLOW_CONFIG             = 0x00040000,   // software
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 0a3254d..566428f 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -47,11 +47,6 @@
 
 // ---------------------------------------------------------------------------
 
-const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
-const char* const Layer::typeID = "Layer";
-
-// ---------------------------------------------------------------------------
-
 Layer::Layer(SurfaceFlinger* flinger, DisplayID display, 
         const sp<Client>& c, int32_t i)
     :   LayerBaseClient(flinger, display, c, i),
@@ -540,9 +535,15 @@
         mFlinger->signalEvent();
     }
 
-    if (!mPostedDirtyRegion.isEmpty()) {
-        reloadTexture( mPostedDirtyRegion );
-    }
+    /* a buffer was posted, so we need to call reloadTexture(), which
+     * will update our internal data structures (eg: EGLImageKHR or
+     * texture names). we need to do this even if mPostedDirtyRegion is
+     * empty -- it's orthogonal to the fact that a new buffer was posted,
+     * for instance, a degenerate case could be that the user did an empty
+     * update but repainted the buffer with appropriate content (after a
+     * resize for instance).
+     */
+    reloadTexture( mPostedDirtyRegion );
 }
 
 void Layer::unlockPageFlip(
@@ -566,7 +567,7 @@
     }
     if (visibleRegionScreen.isEmpty()) {
         // an invisible layer should not hold a freeze-lock
-        // (because it may never be updated and thereore never release it)
+        // (because it may never be updated and therefore never release it)
         mFreezeLock.clear();
     }
 }
@@ -579,6 +580,38 @@
             this, mFrontBufferIndex);
 }
 
+
+void Layer::dump(String8& result, char* buffer, size_t SIZE) const
+{
+    LayerBaseClient::dump(result, buffer, SIZE);
+
+    SharedBufferStack::Statistics stats = lcblk->getStats();
+    result.append( lcblk->dump("      ") );
+    sp<const GraphicBuffer> buf0(getBuffer(0));
+    sp<const GraphicBuffer> buf1(getBuffer(1));
+    uint32_t w0=0, h0=0, s0=0;
+    uint32_t w1=0, h1=0, s1=0;
+    if (buf0 != 0) {
+        w0 = buf0->getWidth();
+        h0 = buf0->getHeight();
+        s0 = buf0->getStride();
+    }
+    if (buf1 != 0) {
+        w1 = buf1->getWidth();
+        h1 = buf1->getHeight();
+        s1 = buf1->getStride();
+    }
+    snprintf(buffer, SIZE,
+            "      "
+            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
+            " freezeLock=%p, dq-q-time=%u us\n",
+            pixelFormat(),
+            w0, h0, s0, w1, h1, s1,
+            getFreezeLock().get(), stats.totalTime);
+
+    result.append(buffer);
+}
+
 // ---------------------------------------------------------------------------
 
 Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index 743afb4..98e30d7 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -46,11 +46,6 @@
 class Layer : public LayerBaseClient
 {
 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; }
-    
                  Layer(SurfaceFlinger* flinger, DisplayID display,
                          const sp<Client>& client, int32_t i);
 
@@ -73,7 +68,7 @@
     virtual status_t ditch();
     
     // only for debugging
-    inline sp<GraphicBuffer> getBuffer(int i) { return mBuffers[i]; }
+    inline sp<GraphicBuffer> getBuffer(int i) const { return mBuffers[i]; }
     // only for debugging
     inline const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
     // only for debugging
@@ -81,6 +76,11 @@
     // only for debugging
     inline int getFrontBufferIndex() const { return mFrontBufferIndex; }
 
+    virtual const char* getTypeId() const { return "Layer"; }
+
+protected:
+    virtual void dump(String8& result, char* scratch, size_t size) const;
+
 private:
     inline sp<GraphicBuffer> getFrontBufferLocked() {
         return mBuffers[mFrontBufferIndex];
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index a8b735e..48b0e47 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -38,14 +38,6 @@
 
 // ---------------------------------------------------------------------------
 
-const uint32_t LayerBase::typeInfo = 1;
-const char* const LayerBase::typeID = "LayerBase";
-
-const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2;
-const char* const LayerBaseClient::typeID = "LayerBaseClient";
-
-// ---------------------------------------------------------------------------
-
 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
     : dpy(display), contentDirty(false),
       mFlinger(flinger),
@@ -54,7 +46,7 @@
       mOrientation(0),
       mLeft(0), mTop(0),
       mTransactionFlags(0),
-      mPremultipliedAlpha(true), mDebug(false),
+      mPremultipliedAlpha(true), mName("unnamed"), mDebug(false),
       mInvalidate(0)
 {
     const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
@@ -374,7 +366,7 @@
     Region::const_iterator it = clip.begin();
     Region::const_iterator const end = clip.end();
     glEnable(GL_SCISSOR_TEST);
-    glVertexPointer(2, GL_FIXED, 0, mVertices);
+    glVertexPointer(2, GL_FLOAT, 0, mVertices);
     while (it != end) {
         const Rect& r = *it++;
         const GLint sy = fbHeight - (r.top + r.height());
@@ -418,14 +410,14 @@
             env = GL_REPLACE;
             src = GL_SRC_ALPHA;
         }
-        const GGLfixed alpha = (s.alpha << 16)/255;
-        glColor4x(alpha, alpha, alpha, alpha);
+        const GLfloat alpha = s.alpha * (1.0f/255.0f);
+        glColor4f(alpha, alpha, alpha, alpha);
         glEnable(GL_BLEND);
         glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
     } else {
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
+        glColor4f(1, 1, 1, 1);
         if (needsBlending()) {
             GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
             glEnable(GL_BLEND);
@@ -437,13 +429,11 @@
 
     Region::const_iterator it = clip.begin();
     Region::const_iterator const end = clip.end();
-
-    //StopWatch watch("GL transformed");
-    const GLfixed texCoords[4][2] = {
-            { 0,        0 },
-            { 0,        0x10000 },
-            { 0x10000,  0x10000 },
-            { 0x10000,  0 }
+    const GLfloat texCoords[4][2] = {
+            { 0,  0 },
+            { 0,  1 },
+            { 1,  1 },
+            { 1,  0 }
     };
 
     glMatrixMode(GL_TEXTURE);
@@ -470,8 +460,8 @@
     }
 
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    glVertexPointer(2, GL_FIXED, 0, mVertices);
-    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+    glVertexPointer(2, GL_FLOAT, 0, mVertices);
+    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
 
     while (it != end) {
         const Rect& r = *it++;
@@ -683,6 +673,22 @@
     return err;
 }
 
+void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
+{
+    const Layer::State& s(drawingState());
+    snprintf(buffer, SIZE,
+            "+ %s %p\n"
+            "      "
+            "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
+            "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
+            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
+            getTypeId(), this, s.z, tx(), ty(), s.w, s.h,
+            needsBlending(), needsDithering(), contentDirty,
+            s.alpha, s.flags,
+            s.transform[0][0], s.transform[0][1],
+            s.transform[1][0], s.transform[1][1]);
+    result.append(buffer);
+}
 
 // ---------------------------------------------------------------------------
 
@@ -715,13 +721,13 @@
     delete lcblk;
 }
 
-int32_t LayerBaseClient::serverIndex() const 
+ssize_t LayerBaseClient::serverIndex() const
 {
     sp<Client> client(this->client.promote());
     if (client != 0) {
         return (client->cid<<16)|mIndex;
     }
-    return 0xFFFF0000 | mIndex;
+    return ssize_t(0xFFFF0000 | mIndex);
 }
 
 sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
@@ -750,6 +756,21 @@
     lcblk->setStatus(NO_INIT);
 }
 
+void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
+{
+    LayerBase::dump(result, buffer, SIZE);
+
+    sp<Client> client(this->client.promote());
+    snprintf(buffer, SIZE,
+            "      name=%s\n"
+            "      id=0x%08x, client=0x%08x, identity=%u\n",
+            getName().string(),
+            clientIndex(), client.get() ? client->cid : 0,
+            getIdentity());
+
+    result.append(buffer);
+}
+
 // ---------------------------------------------------------------------------
 
 LayerBaseClient::Surface::Surface(
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index 62ec839..219a53c 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -51,35 +51,9 @@
 
 class LayerBase : public RefBase
 {
-    // poor man's dynamic_cast below
-    template<typename T>
-    struct getTypeInfoOfAnyType {
-        static uint32_t get() { return T::typeInfo; }
-    };
-
-    template<typename T>
-    struct getTypeInfoOfAnyType<T*> {
-        static uint32_t get() { return getTypeInfoOfAnyType<T>::get(); }
-    };
-
 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; }
-    
-    template<typename T>
-    static T dynamicCast(LayerBase* base) {
-        uint32_t mostDerivedInfo = base->getTypeInfo();
-        uint32_t castToInfo = getTypeInfoOfAnyType<T>::get();
-        if ((mostDerivedInfo & castToInfo) == castToInfo)
-            return static_cast<T>(base);
-        return 0;
-    }
+            LayerBase(SurfaceFlinger* flinger, DisplayID display);
 
-    
-    LayerBase(SurfaceFlinger* flinger, DisplayID display);
-    
     DisplayID           dpy;
     mutable bool        contentDirty;
             Region      visibleRegionScreen;
@@ -125,6 +99,9 @@
 
             void invalidate();
 
+    virtual const char* getTypeId() const { return "LayerBase"; }
+    virtual ssize_t serverIndex() const { return -1; }
+
     /**
      * draw - performs some global clipping optimizations
      * and calls onDraw().
@@ -217,7 +194,10 @@
      *  current list */
     virtual void onRemoved() { };
     
-    
+    /** always call base class first */
+    virtual void dump(String8& result, char* scratch, size_t size) const;
+
+
     enum { // flags for doTransaction()
         eVisibleRegion      = 0x00000002,
     };
@@ -278,7 +258,7 @@
                 bool            mTransformed;
                 bool            mUseLinearFiltering;
                 int32_t         mOrientation;
-                GLfixed         mVertices[4][2];
+                GLfloat         mVertices[4][2];
                 Rect            mTransformedBounds;
                 int             mLeft;
                 int             mTop;
@@ -313,10 +293,6 @@
 {
 public:
     class Surface;
-   static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
 
     // lcblk is (almost) only accessed from the main SF thread, in the places
     // where it's not, a reference to Client must be held
@@ -331,14 +307,12 @@
 
     inline  uint32_t    getIdentity() const { return mIdentity; }
     inline  int32_t     clientIndex() const { return mIndex; }
-            int32_t     serverIndex() const;
-
    
             sp<Surface> getSurface();
     virtual sp<Surface> createSurface() const;
-    
-    virtual void onRemoved();
-
+    virtual ssize_t     serverIndex() const;
+    virtual void        onRemoved();
+    virtual const char* getTypeId() const { return "LayerBaseClient"; }
 
     class Surface : public BnSurface 
     {
@@ -373,8 +347,11 @@
 
     friend class Surface;
 
+protected:
+    virtual void dump(String8& result, char* scratch, size_t size) const;
+
 private:
-                int32_t         mIndex;
+    int32_t         mIndex;
     mutable     Mutex           mLock;
     mutable     wp<Surface>     mClientSurface;
     // only read
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index 5fd7904..2d77876 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -33,11 +33,6 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-const uint32_t LayerBlur::typeInfo = LayerBaseClient::typeInfo | 8;
-const char* const LayerBlur::typeID = "LayerBlur";
-
-// ---------------------------------------------------------------------------
-
 LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
         const sp<Client>& client, int32_t i)
     : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
@@ -206,8 +201,8 @@
 
         const State& s = drawingState();
         if (UNLIKELY(s.alpha < 0xFF)) {
-            const GGLfixed alpha = (s.alpha << 16)/255;
-            glColor4x(0, 0, 0, alpha);
+            const GLfloat alpha = s.alpha * (1.0f/255.0f);
+            glColor4f(0, 0, 0, alpha);
             glEnable(GL_BLEND);
             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
             glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@@ -225,38 +220,20 @@
         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
-        if (UNLIKELY(transformed()
-                || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) {
-            // This is a very rare scenario.
-            glMatrixMode(GL_TEXTURE);
-            glLoadIdentity();
-            glScalef(mWidthScale, mHeightScale, 1);
-            glTranslatef(-x, mYOffset - y, 0);
-            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-            glVertexPointer(2, GL_FIXED, 0, mVertices);
-            glTexCoordPointer(2, GL_FIXED, 0, mVertices);
-            while (it != end) {
-                const Rect& r = *it++;
-                const GLint sy = fbHeight - (r.top + r.height());
-                glScissor(r.left, sy, r.width(), r.height());
-                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
-            }       
-            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-        } else {
-            // NOTE: this is marginally faster with the software gl, because
-            // glReadPixels() reads the fb bottom-to-top, however we'll
-            // skip all the jaccobian computations.
-            Rect r;
-            GLint crop[4] = { 0, 0, w, h };
-            glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
-            y = fbHeight - (y + h);
-            while (it != end) {
-                const Rect& r = *it++;
-                const GLint sy = fbHeight - (r.top + r.height());
-                glScissor(r.left, sy, r.width(), r.height());
-                glDrawTexiOES(x, y, 0, w, h);
-            }
+        glMatrixMode(GL_TEXTURE);
+        glLoadIdentity();
+        glScalef(mWidthScale, mHeightScale, 1);
+        glTranslatef(-x, mYOffset - y, 0);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        glVertexPointer(2, GL_FLOAT, 0, mVertices);
+        glTexCoordPointer(2, GL_FLOAT, 0, mVertices);
+        while (it != end) {
+            const Rect& r = *it++;
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
         }
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
     }
 }
 
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
index 5b63dec..380f587 100644
--- a/libs/surfaceflinger/LayerBlur.h
+++ b/libs/surfaceflinger/LayerBlur.h
@@ -31,11 +31,6 @@
 class LayerBlur : public LayerBaseClient
 {
 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; }
-    
                 LayerBlur(SurfaceFlinger* flinger, DisplayID display,
                         const sp<Client>& client, int32_t i);
         virtual ~LayerBlur();
@@ -43,6 +38,7 @@
     virtual void onDraw(const Region& clip) const;
     virtual bool needsBlending() const  { return true; }
     virtual bool isSecure() const       { return false; }
+    virtual const char* getTypeId() const { return "LayerBlur"; }
 
     virtual uint32_t doTransaction(uint32_t flags);
     virtual void setVisibleRegion(const Region& visibleRegion);
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 5c21593..0041a0f 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -39,8 +39,6 @@
 
 // ---------------------------------------------------------------------------
 
-const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20;
-const char* const LayerBuffer::typeID = "LayerBuffer";
 gralloc_module_t const* LayerBuffer::sGrallocModule = 0;
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index b176623..243cc43 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -52,17 +52,13 @@
     };
 
 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; }
-
             LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
                     const sp<Client>& client, int32_t i);
         virtual ~LayerBuffer();
 
     virtual void onFirstRef();
     virtual bool needsBlending() const;
+    virtual const char* getTypeId() const { return "LayerBuffer"; }
 
     virtual sp<LayerBaseClient::Surface> createSurface() const;
     virtual status_t ditch();
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
index fd61e30..568fedb 100644
--- a/libs/surfaceflinger/LayerDim.cpp
+++ b/libs/surfaceflinger/LayerDim.cpp
@@ -30,9 +30,6 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
-const char* const LayerDim::typeID = "LayerDim";
-
 bool LayerDim::sUseTexture;
 GLuint LayerDim::sTexId;
 EGLImageKHR LayerDim::sImage;
diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h
index d4672a1..19a9990 100644
--- a/libs/surfaceflinger/LayerDim.h
+++ b/libs/surfaceflinger/LayerDim.h
@@ -37,11 +37,6 @@
     static int32_t sWidth;
     static int32_t sHeight;
 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; }
-    
                 LayerDim(SurfaceFlinger* flinger, DisplayID display,
                         const sp<Client>& client, int32_t i);
         virtual ~LayerDim();
@@ -49,6 +44,7 @@
     virtual void onDraw(const Region& clip) const;
     virtual bool needsBlending() const  { return true; }
     virtual bool isSecure() const       { return false; }
+    virtual const char* getTypeId() const { return "LayerDim"; }
 
     static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h);
 };
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 0722fda..62d829b 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -206,8 +206,8 @@
     property_get("debug.sf.showbackground", value, "0");
     mDebugBackground = atoi(value);
 
-    LOGI_IF(mDebugRegion,           "showupdates enabled");
-    LOGI_IF(mDebugBackground,       "showbackground enabled");
+    LOGI_IF(mDebugRegion,       "showupdates enabled");
+    LOGI_IF(mDebugBackground,   "showbackground enabled");
 }
 
 SurfaceFlinger::~SurfaceFlinger()
@@ -357,7 +357,6 @@
     dcblk->ydpi         = hw.getDpiY();
     dcblk->fps          = hw.getRefreshRate();
     dcblk->density      = hw.getDensity();
-    asm volatile ("":::"memory");
 
     // Initialize OpenGL|ES
     glActiveTexture(GL_TEXTURE0);
@@ -1079,15 +1078,15 @@
 
 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());
-    if (lbc != 0) {
-        mLayerMap.add(lbc->serverIndex(), lbc);
-    }
-    return NO_ERROR;
+    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
+}
+
+status_t SurfaceFlinger::addClientLayer_l(const sp<LayerBaseClient>& lbc)
+{
+    ssize_t serverIndex = lbc->serverIndex();
+    return mLayerMap.add(serverIndex, lbc);
 }
 
 status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
@@ -1095,10 +1094,9 @@
     ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
     if (index >= 0) {
         mLayersRemoved = true;
-        sp<LayerBaseClient> layer =
-            LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get());
-        if (layer != 0) {
-            mLayerMap.removeItem(layer->serverIndex());
+        ssize_t serverIndex = layerBase->serverIndex();
+        if (serverIndex >= 0) {
+            mLayerMap.removeItem(serverIndex);
         }
         return NO_ERROR;
     }
@@ -1298,7 +1296,7 @@
         format = PIXEL_FORMAT_RGBA_8888;
         break;
     case PIXEL_FORMAT_OPAQUE:
-        format = PIXEL_FORMAT_RGB_565;
+        format = PIXEL_FORMAT_RGBX_8888;
         break;
     }
 
@@ -1307,6 +1305,7 @@
     if (LIKELY(err == NO_ERROR)) {
         layer->initStates(w, h, flags);
         addLayer_l(layer);
+        addClientLayer_l(layer);
     } else {
         LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
         layer.clear();
@@ -1321,6 +1320,7 @@
     sp<LayerBlur> layer = new LayerBlur(this, display, client, id);
     layer->initStates(w, h, flags);
     addLayer_l(layer);
+    addClientLayer_l(layer);
     return layer;
 }
 
@@ -1331,6 +1331,7 @@
     sp<LayerDim> layer = new LayerDim(this, display, client, id);
     layer->initStates(w, h, flags);
     addLayer_l(layer);
+    addClientLayer_l(layer);
     return layer;
 }
 
@@ -1341,6 +1342,7 @@
     sp<LayerBuffer> layer = new LayerBuffer(this, display, client, id);
     layer->initStates(w, h, flags);
     addLayer_l(layer);
+    addClientLayer_l(layer);
     return layer;
 }
 
@@ -1512,83 +1514,17 @@
             result.append(buffer);
         }
 
-        size_t s = mClientsMap.size();
-        char name[64];
-        for (size_t i=0 ; i<s ; i++) {
-            sp<Client> client = mClientsMap.valueAt(i);
-            sprintf(name, "  Client (id=0x%08x)", client->cid);
-            client->dump(name);
-        }
         const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
         const size_t count = currentLayers.size();
         for (size_t i=0 ; i<count ; i++) {
-            /*** LayerBase ***/
-            const sp<LayerBase>& layer = currentLayers[i];
-            const Layer::State& s = layer->drawingState();
-            snprintf(buffer, SIZE,
-                    "+ %s %p\n"
-                    "      "
-                    "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
-                    "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
-                    "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
-                    layer->getTypeID(), layer.get(),
-                    s.z, layer->tx(), layer->ty(), s.w, s.h,
-                    layer->needsBlending(), layer->needsDithering(),
-                    layer->contentDirty,
-                    s.alpha, s.flags,
-                    s.transform[0][0], s.transform[0][1],
-                    s.transform[1][0], s.transform[1][1]);
-            result.append(buffer);
-            buffer[0] = 0;
-            /*** LayerBaseClient ***/
-            sp<LayerBaseClient> lbc =
-                LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
-            if (lbc != 0) {
-                sp<Client> client(lbc->client.promote());
-                snprintf(buffer, SIZE,
-                        "      name=%s\n", lbc->getName().string());
-                result.append(buffer);
-                snprintf(buffer, SIZE,
-                        "      id=0x%08x, client=0x%08x, identity=%u\n",
-                        lbc->clientIndex(), client.get() ? client->cid : 0,
-                        lbc->getIdentity());
-
-                result.append(buffer);
-                buffer[0] = 0;
-            }
-            /*** Layer ***/
-            sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get());
-            if (l != 0) {
-                SharedBufferStack::Statistics stats = l->lcblk->getStats();
-                result.append( l->lcblk->dump("      ") );
-                sp<const GraphicBuffer> buf0(l->getBuffer(0));
-                sp<const GraphicBuffer> buf1(l->getBuffer(1));
-                uint32_t w0=0, h0=0, s0=0;
-                uint32_t w1=0, h1=0, s1=0;
-                if (buf0 != 0) {
-                    w0 = buf0->getWidth();
-                    h0 = buf0->getHeight();
-                    s0 = buf0->getStride();
-                }
-                if (buf1 != 0) {
-                    w1 = buf1->getWidth();
-                    h1 = buf1->getHeight();
-                    s1 = buf1->getStride();
-                }
-                snprintf(buffer, SIZE,
-                        "      "
-                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
-                        " freezeLock=%p, dq-q-time=%u us\n",
-                        l->pixelFormat(),
-                        w0, h0, s0, w1, h1, s1,
-                        l->getFreezeLock().get(), stats.totalTime);
-                result.append(buffer);
-                buffer[0] = 0;
-            }
+            const sp<LayerBase>& layer(currentLayers[i]);
+            layer->dump(result, buffer, SIZE);
+            const Layer::State& s(layer->drawingState());
             s.transparentRegion.dump(result, "transparentRegion");
             layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
             layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
         }
+
         mWormholeRegion.dump(result, "WormholeRegion");
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         snprintf(buffer, SIZE,
@@ -1601,16 +1537,19 @@
                 "  last transaction time     : %f us\n",
                 mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
         result.append(buffer);
+
         if (inSwapBuffersDuration || !locked) {
             snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
                     inSwapBuffersDuration/1000.0);
             result.append(buffer);
         }
+
         if (inTransactionDuration || !locked) {
             snprintf(buffer, SIZE, "  transaction time: %f us\n",
                     inTransactionDuration/1000.0);
             result.append(buffer);
         }
+
         snprintf(buffer, SIZE, "  client count: %d\n", mClientsMap.size());
         result.append(buffer);
         const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
@@ -1773,10 +1712,6 @@
     return lbc;
 }
 
-void Client::dump(const char* what)
-{
-}
-
 // ---------------------------------------------------------------------------
 #if 0
 #pragma mark -
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index d75dc15..9c8de51 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -73,7 +73,6 @@
 
     inline  bool                    isValid(int32_t i) const;
     sp<LayerBaseClient>             getLayerUser(int32_t i) const;
-    void                            dump(const char* what);
     
     const Vector< wp<LayerBaseClient> >& getLayers() const { 
         return mLayers; 
@@ -281,6 +280,7 @@
             void        destroyConnection(ClientID cid);
             sp<LayerBaseClient> getLayerUser_l(SurfaceID index) const;
             status_t    addLayer_l(const sp<LayerBase>& layer);
+            status_t    addClientLayer_l(const sp<LayerBaseClient>& lbc);
             status_t    removeLayer_l(const sp<LayerBase>& layer);
             status_t    purgatorizeLayer_l(const sp<LayerBase>& layer);
             void        free_resources_l();
diff --git a/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp
index 175f989..5e27cc9 100644
--- a/libs/surfaceflinger/Transform.cpp
+++ b/libs/surfaceflinger/Transform.cpp
@@ -229,14 +229,13 @@
     return r;
 }
 
-void Transform::transform(fixed1616* point, int x, int y) const
+void Transform::transform(float* point, int x, int y) const
 {
-    const float toFixed = 65536.0f;
     const mat33& M(mMatrix);
     vec2 v(x, y);
     v = transform(v);
-    point[0] = v[0] * toFixed;
-    point[1] = v[1] * toFixed;
+    point[0] = v[0];
+    point[1] = v[1];
 }
 
 Rect Transform::makeBounds(int w, int h) const
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
index 2e5b893..20fa11a 100644
--- a/libs/surfaceflinger/Transform.h
+++ b/libs/surfaceflinger/Transform.h
@@ -37,8 +37,6 @@
            explicit Transform(uint32_t orientation);
                     ~Transform();
 
-            typedef int32_t fixed1616;
-
             // FIXME: must match OVERLAY_TRANSFORM_*, pull from hardware.h
             enum orientation_flags {
                 ROT_0   = 0x00000000,
@@ -76,7 +74,7 @@
 
             // transform data
             Rect    makeBounds(int w, int h) const;
-            void    transform(fixed1616* point, int x, int y) const;
+            void    transform(float* point, int x, int y) const;
             Region  transform(const Region& reg) const;
             Transform operator * (const Transform& rhs) const;
 
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index a17e8ac..21a40db 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -67,19 +67,47 @@
     identity = i;
 }
 
+status_t SharedBufferStack::setCrop(int buffer, const Rect& crop)
+{
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return BAD_INDEX;
+
+    buffers[buffer].crop.l = uint16_t(crop.left);
+    buffers[buffer].crop.t = uint16_t(crop.top);
+    buffers[buffer].crop.r = uint16_t(crop.right);
+    buffers[buffer].crop.b = uint16_t(crop.bottom);
+    return 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);
+    FlatRegion& reg(buffers[buffer].dirtyRegion);
+    if (dirty.isEmpty()) {
+        reg.count = 0;
+        return NO_ERROR;
+    }
+
+    size_t count;
+    Rect const* r = dirty.getArray(&count);
+    if (count > FlatRegion::NUM_RECT_MAX) {
+        const Rect bounds(dirty.getBounds());
+        reg.count = 1;
+        reg.rects[0].l = uint16_t(bounds.left);
+        reg.rects[0].t = uint16_t(bounds.top);
+        reg.rects[0].r = uint16_t(bounds.right);
+        reg.rects[0].b = uint16_t(bounds.bottom);
+    } else {
+        reg.count = count;
+        for (size_t i=0 ; i<count ; i++) {
+            reg.rects[i].l = uint16_t(r[i].left);
+            reg.rects[i].t = uint16_t(r[i].top);
+            reg.rects[i].r = uint16_t(r[i].right);
+            reg.rects[i].b = uint16_t(r[i].bottom);
+        }
+    }
     return NO_ERROR;
 }
 
@@ -89,8 +117,27 @@
     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]));
+    const FlatRegion& reg(buffers[buffer].dirtyRegion);
+    if (reg.count > FlatRegion::NUM_RECT_MAX)
+        return res;
+
+    if (reg.count == 1) {
+        const Rect r(
+                reg.rects[0].l,
+                reg.rects[0].t,
+                reg.rects[0].r,
+                reg.rects[0].b);
+        res.set(r);
+    } else {
+        for (size_t i=0 ; i<reg.count ; i++) {
+            const Rect r(
+                    reg.rects[i].l,
+                    reg.rects[i].t,
+                    reg.rects[i].r,
+                    reg.rects[i].b);
+            res.orSelf(r);
+        }
+    }
     return res;
 }
 
@@ -132,7 +179,7 @@
     char buffer[SIZE];
     String8 result;
     SharedBufferStack& stack( *mSharedStack );
-    int tail = (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
+    int tail = computeTail();
     snprintf(buffer, SIZE, 
             "%s[ head=%2d, available=%2d, queued=%2d, tail=%2d ] "
             "reallocMask=%08x, inUse=%2d, identity=%d, status=%d\n",
@@ -142,6 +189,48 @@
     return result;
 }
 
+int32_t SharedBufferBase::computeTail() const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
+}
+
+status_t SharedBufferBase::waitForCondition(const ConditionBase& condition)
+{
+    const SharedBufferStack& stack( *mSharedStack );
+    SharedClient& client( *mSharedClient );
+    const nsecs_t TIMEOUT = s2ns(1);
+    const int identity = mIdentity;
+
+    Mutex::Autolock _l(client.lock);
+    while ((condition()==false) &&
+            (stack.identity == identity) &&
+            (stack.status == NO_ERROR))
+    {
+        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." , condition.name(), stack.identity);
+                    break;
+                } else {
+                    LOGW("waitForCondition(%s) timed out "
+                        "(identity=%d, status=%d). "
+                        "CPU may be pegged. trying again.", condition.name(),
+                        stack.identity, stack.status);
+                }
+            } else {
+                LOGE("waitForCondition(%s) error (%s) ",
+                        condition.name(), strerror(-err));
+                return err;
+            }
+        }
+    }
+    return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
+}
 // ============================================================================
 // conditions and updates
 // ============================================================================
@@ -149,14 +238,14 @@
 SharedBufferClient::DequeueCondition::DequeueCondition(
         SharedBufferClient* sbc) : ConditionBase(sbc)  { 
 }
-bool SharedBufferClient::DequeueCondition::operator()() {
+bool SharedBufferClient::DequeueCondition::operator()() const {
     return stack.available > 0;
 }
 
 SharedBufferClient::LockCondition::LockCondition(
         SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) { 
 }
-bool SharedBufferClient::LockCondition::operator()() {
+bool SharedBufferClient::LockCondition::operator()() const {
     return (buf != stack.head || 
             (stack.queued > 0 && stack.inUse != buf));
 }
@@ -164,7 +253,7 @@
 SharedBufferServer::ReallocateCondition::ReallocateCondition(
         SharedBufferBase* sbb, int buf) : ConditionBase(sbb), buf(buf) { 
 }
-bool SharedBufferServer::ReallocateCondition::operator()() {
+bool SharedBufferServer::ReallocateCondition::operator()() const {
     // TODO: we should also check that buf has been dequeued
     return (buf != stack.head);
 }
@@ -250,37 +339,17 @@
 
 SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
         int surface, int num, int32_t identity)
-    : SharedBufferBase(sharedClient, surface, num, identity), tail(0)
+    : SharedBufferBase(sharedClient, surface, num, identity),
+      tail(0), undoDequeueTail(0)
 {
     tail = computeTail();
 }
 
-int32_t SharedBufferClient::computeTail() const
-{
-    SharedBufferStack& stack( *mSharedStack );
-    // we need to make sure we read available and head coherently,
-    // w.r.t RetireUpdate.
-    int32_t newTail;
-    int32_t avail;
-    int32_t head;
-    do {
-        avail = stack.available;
-        head = stack.head;
-    } while (stack.available != avail);
-    newTail = head - avail + 1;
-    if (newTail < 0) {
-        newTail += mNumBuffers;
-    } else if (newTail >= mNumBuffers) {
-        newTail -= mNumBuffers;
-    }
-    return newTail;
-}
-
 ssize_t SharedBufferClient::dequeue()
 {
     SharedBufferStack& stack( *mSharedStack );
 
-    if (stack.head == tail && stack.available == 2) {
+    if (stack.head == tail && stack.available == mNumBuffers) {
         LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
                 tail, stack.head, stack.available, stack.queued);
     }
@@ -303,6 +372,7 @@
 
     int dequeued = tail;
     tail = ((tail+1 >= mNumBuffers) ? 0 : tail+1);
+    undoDequeueTail = dequeued;
     LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail=%d, %s",
             dequeued, tail, dump("").string());
 
@@ -316,7 +386,7 @@
     UndoDequeueUpdate update(this);
     status_t err = updateCondition( update );
     if (err == NO_ERROR) {
-        tail = computeTail();
+        tail = undoDequeueTail;
     }
     return err;
 }
@@ -346,6 +416,12 @@
     return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0;
 }
 
+status_t SharedBufferClient::setCrop(int buffer, const Rect& crop)
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.setCrop(buffer, crop);
+}
+
 status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg)
 {
     SharedBufferStack& stack( *mSharedStack );
@@ -363,7 +439,7 @@
     mSharedStack->available = num;
     mSharedStack->queued = 0;
     mSharedStack->reallocMask = 0;
-    memset(mSharedStack->dirtyRegion, 0, sizeof(mSharedStack->dirtyRegion));
+    memset(mSharedStack->buffers, 0, sizeof(mSharedStack->buffers));
 }
 
 ssize_t SharedBufferServer::retireAndLock()
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 5dd75c3..eee4dae 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -17,8 +17,6 @@
 #define LOG_TAG "Surface"
 
 #include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -28,8 +26,6 @@
 #include <utils/CallStack.h>
 #include <utils/Log.h>
 
-#include <pixelflinger/pixelflinger.h>
-
 #include <binder/IPCThreadState.h>
 #include <binder/IMemory.h>
 
@@ -55,6 +51,8 @@
         const sp<GraphicBuffer>& src, 
         const Region& reg)
 {
+    // src and dst with, height and format must be identical. no verification
+    // is done here.
     status_t err;
     uint8_t const * src_bits = NULL;
     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
@@ -67,7 +65,6 @@
     Region::const_iterator head(reg.begin());
     Region::const_iterator tail(reg.end());
     if (head != tail && src_bits && dst_bits) {
-        // NOTE: dst and src must be the same format
         const size_t bpp = bytesPerPixel(src->format);
         const size_t dbpr = dst->stride * bpp;
         const size_t sbpr = src->stride * bpp;
@@ -354,7 +351,6 @@
     // be default we request a hardware surface
     mUsage = GRALLOC_USAGE_HW_RENDER;
     mConnected = 0;
-    mNeedFullUpdate = false;
 }
 
 Surface::~Surface()
@@ -467,18 +463,6 @@
 
 // ----------------------------------------------------------------------------
 
-status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer) {
-    android_native_buffer_t* out;
-    status_t err = dequeueBuffer(&out);
-    if (err == NO_ERROR) {
-        *buffer = GraphicBuffer::getSelf(out);
-    }
-    return err;
-}
-
-// ----------------------------------------------------------------------------
-
-
 int Surface::dequeueBuffer(android_native_buffer_t** buffer)
 {
     sp<SurfaceComposerClient> client(getClient());
@@ -495,9 +479,12 @@
     // below we make sure we AT LEAST have the usage flags we want
     const uint32_t usage(getUsage());
     const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
+
+    // Always call needNewBuffer(), since it clears the needed buffers flags
+    bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx);
     if (backBuffer == 0 || 
         ((uint32_t(backBuffer->usage) & usage) != usage) ||
-        mSharedBufferClient->needNewBuffer(bufIdx)) 
+        needNewBuffer)
     {
         err = getBufferLocked(bufIdx, usage);
         LOGE_IF(err, "getBufferLocked(%ld, %08x) failed (%s)",
@@ -531,7 +518,7 @@
     if (err != NO_ERROR)
         return err;
 
-    int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
+    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
     err = mSharedBufferClient->lock(bufIdx);
     LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
     return err;
@@ -548,7 +535,8 @@
         mDirtyRegion.set(mSwapRectangle);
     }
     
-    int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
+    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
+    mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
     mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
     err = mSharedBufferClient->queue(bufIdx);
     LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
@@ -578,6 +566,10 @@
 
 int Surface::perform(int operation, va_list args)
 {
+    status_t err = validate();
+    if (err != NO_ERROR)
+        return err;
+
     int res = NO_ERROR;
     switch (operation) {
     case NATIVE_WINDOW_SET_USAGE:
@@ -589,6 +581,9 @@
     case NATIVE_WINDOW_DISCONNECT:
         res = dispatch_disconnect( args );
         break;
+    case NATIVE_WINDOW_SET_CROP:
+        res = dispatch_crop( args );
+        break;
     default:
         res = NAME_NOT_FOUND;
         break;
@@ -608,6 +603,10 @@
     int api = va_arg(args, int);
     return disconnect( api );
 }
+int Surface::dispatch_crop(va_list args) {
+    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
+    return crop( reinterpret_cast<Rect const*>(rect) );
+}
 
 
 void Surface::setUsage(uint32_t reqUsage)
@@ -666,6 +665,14 @@
     return mConnected;
 }
 
+int Surface::crop(Rect const* rect)
+{
+    Mutex::Autolock _l(mSurfaceLock);
+    // TODO: validate rect size
+    mNextBufferCrop = *rect;
+    return NO_ERROR;
+}
+
 
 // ----------------------------------------------------------------------------
 
@@ -703,45 +710,47 @@
     // we're intending to do software rendering from this point
     setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
 
-    sp<GraphicBuffer> backBuffer;
-    status_t err = dequeueBuffer(&backBuffer);
+    android_native_buffer_t* out;
+    status_t err = dequeueBuffer(&out);
     LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
     if (err == NO_ERROR) {
+        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
         err = lockBuffer(backBuffer.get());
         LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
-                backBuffer->getIndex(), strerror(-err));
+                getBufferIndex(backBuffer), strerror(-err));
         if (err == NO_ERROR) {
-            // we handle copy-back here...
-
             const Rect bounds(backBuffer->width, backBuffer->height);
-            Region scratch(bounds);
+            const Region boundsRegion(bounds);
+            Region scratch(boundsRegion);
             Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
+            newDirtyRegion &= boundsRegion;
 
-            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);
-            }
-
+            // figure out if we can copy the frontbuffer back
             const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
-            if (frontBuffer !=0 &&
-                backBuffer->width  == frontBuffer->width && 
-                backBuffer->height == frontBuffer->height &&
-                !(mFlags & ISurfaceComposer::eDestroyBackbuffer)) 
-            {
+            const bool canCopyBack = (frontBuffer != 0 &&
+                    backBuffer->width  == frontBuffer->width &&
+                    backBuffer->height == frontBuffer->height &&
+                    backBuffer->format == frontBuffer->format &&
+                    !(mFlags & ISurfaceComposer::eDestroyBackbuffer));
+
+            // the dirty region we report to surfaceflinger is the one
+            // given by the user (as opposed to the one *we* return to the
+            // user).
+            mDirtyRegion = newDirtyRegion;
+
+            if (canCopyBack) {
+                // copy the area that is invalid and not repainted this round
                 const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
-                if (!copyback.isEmpty() && frontBuffer!=0) {
-                    // copy front to back
+                if (!copyback.isEmpty())
                     copyBlt(backBuffer, frontBuffer, copyback);
-                }
+            } else {
+                // if we can't copy-back anything, modify the user's dirty
+                // region to make sure they redraw the whole buffer
+                newDirtyRegion = boundsRegion;
             }
 
-            mDirtyRegion = newDirtyRegion;
+            // keep track of the are of the buffer that is "clean"
+            // (ie: that will be redrawn)
             mOldDirtyRegion = newDirtyRegion;
 
             void* vaddr;
@@ -777,7 +786,7 @@
     
     err = queueBuffer(mLockedBuffer.get());
     LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
-            mLockedBuffer->getIndex(), strerror(-err));
+            getBufferIndex(mLockedBuffer), strerror(-err));
 
     mPostedBuffer = mLockedBuffer;
     mLockedBuffer = 0;
@@ -789,6 +798,11 @@
     mSwapRectangle = r;
 }
 
+int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
+{
+    return buffer->getIndex();
+}
+
 status_t Surface::getBufferLocked(int index, int usage)
 {
     sp<ISurface> s(mSurface);
@@ -820,7 +834,6 @@
             if (err == NO_ERROR) {
                 currentBuffer = buffer;
                 currentBuffer->setIndex(index);
-                mNeedFullUpdate = true;
             }
         } else {
             err = err<0 ? err : NO_MEMORY;
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 6ae7e74..d51664d 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -15,6 +15,8 @@
 ** limitations under the License.
 */
 
+#define LOG_TAG "GraphicBufferAllocator"
+
 #include <cutils/log.h>
 
 #include <utils/Singleton.h>
@@ -61,9 +63,9 @@
     const size_t c = list.size();
     for (size_t i=0 ; i<c ; i++) {
         const alloc_rec_t& rec(list.valueAt(i));
-        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u x %4u | %2d | 0x%08x\n",
+        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n",
             list.keyAt(i), rec.size/1024.0f, 
-            rec.w, rec.h, rec.format, rec.usage);
+            rec.w, rec.s, rec.h, rec.format, rec.usage);
         result.append(buffer);
         total += rec.size;
     }
@@ -71,16 +73,13 @@
     result.append(buffer);
 }
 
-static inline uint32_t clamp(uint32_t c) {
-    return c>0 ? c : 1;
-}
-
 status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
         int usage, buffer_handle_t* handle, int32_t* stride)
 {
-    // make sure to not allocate a 0 x 0 buffer
-    w = clamp(w);
-    h = clamp(h);
+    // make sure to not allocate a N x 0 or 0 x N buffer, since this is
+    // allowed from an API stand-point allocate a 1x1 buffer instead.
+    if (!w || !h)
+        w = h = 1;
 
     // we have a h/w allocator and h/w buffer is requested
     status_t err; 
@@ -100,9 +99,9 @@
         alloc_rec_t rec;
         rec.w = w;
         rec.h = h;
+        rec.s = *stride;
         rec.format = format;
         rec.usage = usage;
-        rec.vaddr = 0;
         rec.size = h * stride[0] * bytesPerPixel(format);
         list.add(*handle, rec);
     } else {
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 7e0f881..a1401ad 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -4178,6 +4178,9 @@
                             case ResTable_config::SCREENSIZE_LARGE:
                                 printf(" (large)");
                                 break;
+                            case ResTable_config::SCREENSIZE_XLARGE:
+                                printf(" (xlarge)");
+                                break;
                         }
                         printf(" lng=%d",
                                 type->config.screenLayout&ResTable_config::MASK_SCREENLONG);
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 89b3e1f..e6cf792 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -239,7 +239,7 @@
 
 // ----------------------------------------------------------------------------
 
-egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
+static egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
 static egl_display_t gDisplay[NUM_DISPLAYS];
 static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t gEGLThreadLocalStorageKey = -1;
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index 1fba209..c8f529a 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -31,6 +31,7 @@
 
 struct egl_connection_t
 {
+    inline egl_connection_t() : dso(0) { }
     void *              dso;
     gl_hooks_t *        hooks[2];
     EGLint              major;
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index ce522c8..ce40b5d 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -85,7 +85,8 @@
 
     // TODO(oam): Test VPN when EFS is enabled (will do later)...
     public static String getProfilePath() {
-        return Environment.getDataDirectory().getPath() + PROFILES_PATH;
+        // This call will return the correct path if Encrypted FS is enabled or not.
+        return Environment.getSecureDataDirectory().getPath() + PROFILES_PATH;
     }
 
     /**