update surfaceflinger, libui and libagl to the new gralloc api

- Currently the lock/unlock path is naive and is done for each drawing operation (glDrawElements and glDrawArrays). this should be improved eventually.
- factor all the lock/unlock code in SurfaceBuffer.
- fixed "showupdate" so it works even when we don't have preserving eglSwapBuffers().
- improved the situation with the dirty-region and fixed a problem that caused GL apps to not update.
- make use of LightRefBase() where needed, instead of duplicating its implementation
- add LightRefBase::getStrongCount()
- renamed EGLNativeWindowSurface.cpp to FramebufferNativeWindow.cpp

- disabled copybits test, since it clashes with the new gralloc api

- Camera/Video will be fixed later when we rework the overlay apis
diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h
index ff90033..5f084be 100644
--- a/include/ui/BufferMapper.h
+++ b/include/ui/BufferMapper.h
@@ -20,10 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/CallStack.h>
-#include <utils/threads.h>
 #include <utils/Singleton.h>
-#include <utils/KeyedVector.h>
 
 #include <hardware/gralloc.h>
 
@@ -40,9 +37,14 @@
 {
 public:
     static inline BufferMapper& get() { return getInstance(); }
-    status_t map(buffer_handle_t handle, void** addr, const void* id);
-    status_t unmap(buffer_handle_t handle, const void* id);
-    status_t lock(buffer_handle_t handle, int usage, const Rect& bounds);
+
+    status_t registerBuffer(buffer_handle_t handle);
+
+    status_t unregisterBuffer(buffer_handle_t handle);
+    
+    status_t lock(buffer_handle_t handle,
+            int usage, const Rect& bounds, void** vaddr);
+
     status_t unlock(buffer_handle_t handle);
     
     // dumps information about the mapping of this handle
@@ -51,16 +53,7 @@
 private:
     friend class Singleton<BufferMapper>;
     BufferMapper();
-    mutable Mutex mLock;
     gralloc_module_t const *mAllocMod;
-    
-    void logMapLocked(buffer_handle_t handle, const void* id);
-    void logUnmapLocked(buffer_handle_t handle, const void* id);
-    struct map_info_t {
-        const void* id;
-        CallStack stack;
-    };
-    KeyedVector<buffer_handle_t, Vector<map_info_t> > mMapInfo;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/include/ui/EGLDisplaySurface.h b/include/ui/EGLDisplaySurface.h
deleted file mode 100644
index a8b5853..0000000
--- a/include/ui/EGLDisplaySurface.h
+++ /dev/null
@@ -1,86 +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_EGL_DISPLAY_SURFACE_H
-#define ANDROID_EGL_DISPLAY_SURFACE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Timers.h>
-
-#include <ui/EGLNativeSurface.h>
-
-#include <pixelflinger/pixelflinger.h>
-#include <linux/fb.h>
-
-#include <EGL/egl.h>
-
-struct copybit_device_t;
-struct copybit_image_t;
-
-// ---------------------------------------------------------------------------
-namespace android {
-// ---------------------------------------------------------------------------
-
-class Region;
-class Rect;
-
-class EGLDisplaySurface : public EGLNativeSurface<EGLDisplaySurface>
-{
-public:
-    EGLDisplaySurface();
-    ~EGLDisplaySurface();
-    
-    int32_t getPageFlipCount() const;
-    void    copyFrontToBack(const Region& copyback);
-    void    copyFrontToImage(const copybit_image_t& dst);
-    void    copyBackToImage(const copybit_image_t& dst);
-    
-    void        setSwapRectangle(int l, int t, int w, int h);
-
-private:
-    static void         hook_incRef(NativeWindowType window);
-    static void         hook_decRef(NativeWindowType window);
-    static uint32_t     hook_swapBuffers(NativeWindowType window);
-     
-            uint32_t    swapBuffers();
-
-            status_t    mapFrameBuffer();
-
-            enum {
-                PAGE_FLIP = 0x00000001
-            };
-    GGLSurface          mFb[2];
-    int                 mIndex;
-    uint32_t            mFlags;
-    size_t              mSize;
-    fb_var_screeninfo   mInfo;
-    fb_fix_screeninfo   mFinfo;
-    int32_t             mPageFlipCount;
-    nsecs_t             mTime;
-    int32_t             mSwapCount;
-    nsecs_t             mSleep;
-    uint32_t            mFeatureFlags;
-    copybit_device_t*   mBlitEngine;
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-// ---------------------------------------------------------------------------
-
-#endif // ANDROID_EGL_DISPLAY_SURFACE_H
-
diff --git a/include/ui/EGLNativeWindowSurface.h b/include/ui/FramebufferNativeWindow.h
similarity index 83%
rename from include/ui/EGLNativeWindowSurface.h
rename to include/ui/FramebufferNativeWindow.h
index 4b25655..1d49cca 100644
--- a/include/ui/EGLNativeWindowSurface.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_EGL_NATIVE_WINDOW_SURFACE_H
-#define ANDROID_EGL_NATIVE_WINDOW_SURFACE_H
+#ifndef ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H
+#define ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -76,32 +76,18 @@
 
     framebuffer_device_t const * getDevice() const { return fbDev; } 
 
+    void setSwapRectangle(const Rect& dirty);
+
 private:
     friend class LightRefBase<FramebufferNativeWindow>;    
     ~FramebufferNativeWindow(); // this class cannot be overloaded
     static void connect(android_native_window_t* window);
     static void disconnect(android_native_window_t* window);
     static int setSwapInterval(android_native_window_t* window, int interval);
-    static int setSwapRectangle(android_native_window_t* window,
-            int l, int t, int w, int h);
     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);
     static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
     
-
-    static inline FramebufferNativeWindow* getSelf(
-            android_native_window_t* window) {
-        FramebufferNativeWindow* self = 
-            static_cast<FramebufferNativeWindow*>(window);
-            return self;
-    }
-
-    static inline FramebufferNativeWindow* getSelf(
-            android_native_base_t* window) {
-        return getSelf(reinterpret_cast<android_native_window_t*>(window));
-    }
-
-    
     framebuffer_device_t* fbDev;
     alloc_device_t* grDev;
 
@@ -121,5 +107,5 @@
 }; // namespace android
 // ---------------------------------------------------------------------------
 
-#endif // ANDROID_EGL_NATIVE_WINDOW_SURFACE_H
+#endif // ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H
 
diff --git a/include/ui/Region.h b/include/ui/Region.h
index 7689673..5efeff7 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -57,6 +57,7 @@
 
             void        clear();
             void        set(const Rect& r);
+            void        set(uint32_t w, uint32_t h);
         
             Region&     orSelf(const Rect& rhs);
             Region&     andSelf(const Rect& rhs);
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
index 16d2edb..6eb06ae 100644
--- a/include/ui/Surface.h
+++ b/include/ui/Surface.h
@@ -34,7 +34,9 @@
 
 // ---------------------------------------------------------------------------
 
+class BufferMapper;
 class Rect;
+class Surface;
 class SurfaceComposerClient;
 struct per_client_cblk_t;
 struct layer_cblk_t;
@@ -52,6 +54,10 @@
         return handle;
     }
     
+    status_t lock(uint32_t usage);
+    status_t lock(uint32_t usage, const Rect& rect);
+    status_t unlock();
+
 protected:
             SurfaceBuffer();
             SurfaceBuffer(const Parcel& reply);
@@ -59,7 +65,11 @@
     buffer_handle_t handle;
     bool mOwner;
 
+    inline const BufferMapper& getBufferMapper() const { return mBufferMapper; }
+    inline BufferMapper& getBufferMapper() { return mBufferMapper; }
+    
 private:
+    friend class Surface;
     friend class BpSurface;
     friend class BnSurface;
     friend class LightRefBase<SurfaceBuffer>;    
@@ -72,6 +82,8 @@
     
     static int getHandle(android_native_buffer_t const * base, 
             buffer_handle_t* handle);
+    
+    BufferMapper& mBufferMapper;
 };
 
 // ---------------------------------------------------------------------------
@@ -191,9 +203,8 @@
     status_t    lock(SurfaceInfo* info, Region* dirty, bool blocking = true);
     status_t    unlockAndPost();
 
-    // setSwapRectangle() is mainly used by EGL
+    // setSwapRectangle() is intended to be used by GL ES clients
     void        setSwapRectangle(const Rect& r);
-    const Rect& swapRectangle() const;
 
 private:
     // can't be copied
@@ -216,22 +227,14 @@
     const sp<ISurface>& getISurface() const { return mSurface; }
 
     status_t getBufferLocked(int index);
-    
-    
-    
-    Region dirtyRegion() const;
-    void setDirtyRegion(const Region& region) const;
-
    
            status_t validate(per_client_cblk_t const* cblk) const;
     static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty);
 
+    inline const BufferMapper& getBufferMapper() const { return mBufferMapper; }
+    inline BufferMapper& getBufferMapper() { return mBufferMapper; }
     
-    static void connect(android_native_window_t* window);
-    static void disconnect(android_native_window_t* window);
     static int setSwapInterval(android_native_window_t* window, int interval);
-    static int setSwapRectangle(android_native_window_t* window,
-            int l, int t, int w, int h);
     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);
     static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
@@ -239,21 +242,27 @@
     int dequeueBuffer(android_native_buffer_t** buffer);
     int lockBuffer(android_native_buffer_t* buffer);
     int queueBuffer(android_native_buffer_t* buffer);
-    
+
+    status_t dequeueBuffer(sp<SurfaceBuffer>* buffer);
+    status_t lockBuffer(const sp<SurfaceBuffer>& buffer);
+    status_t queueBuffer(const sp<SurfaceBuffer>& buffer);
+
     
     alloc_device_t*             mAllocDevice;
     sp<SurfaceComposerClient>   mClient;
     sp<ISurface>                mSurface;
     sp<SurfaceBuffer>           mBuffers[2];
-    android_native_buffer_t*    mLockedBuffer;
+    sp<SurfaceBuffer>           mLockedBuffer;
     SurfaceID                   mToken;
     uint32_t                    mIdentity;
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
     mutable Region              mDirtyRegion;
-    mutable Rect                mSwapRectangle;
+    mutable Region              mOldDirtyRegion;
     mutable uint8_t             mBackbufferIndex;
     mutable Mutex               mSurfaceLock;
+    Rect                        mSwapRectangle;
+    BufferMapper&               mBufferMapper;
 };
 
 }; // namespace android
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
index cbda0fd..bd7f28c 100644
--- a/include/utils/RefBase.h
+++ b/include/utils/RefBase.h
@@ -156,6 +156,10 @@
             delete static_cast<const T*>(this);
         }
     }
+    //! DEBUGGING ONLY: Get current strong ref count.
+    inline int32_t getStrongCount() const {
+        return mCount;
+    }
     
 protected:
     inline ~LightRefBase() { }
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index 2b360d6..639a82e 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -14,10 +14,7 @@
     LayerBlur.cpp \
     LayerBitmap.cpp \
     LayerDim.cpp \
-    LayerOrientationAnim.cpp \
-    LayerOrientationAnimRotate.cpp \
     MessageQueue.cpp \
-    OrientationAnimation.cpp \
     SurfaceFlinger.cpp \
     Tokenizer.cpp \
     Transform.cpp
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/libs/surfaceflinger/BootAnimation.cpp
index ee36b67..b45fe34 100644
--- a/libs/surfaceflinger/BootAnimation.cpp
+++ b/libs/surfaceflinger/BootAnimation.cpp
@@ -32,7 +32,7 @@
 #include <ui/DisplayInfo.h>
 #include <ui/ISurfaceComposer.h>
 #include <ui/ISurfaceFlingerClient.h>
-#include <ui/EGLNativeWindowSurface.h>
+#include <ui/FramebufferNativeWindow.h>
 
 #include <core/SkBitmap.h>
 #include <images/SkImageDecoder.h>
diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp
index fec7c87..cee8b64 100644
--- a/libs/surfaceflinger/BufferAllocator.cpp
+++ b/libs/surfaceflinger/BufferAllocator.cpp
@@ -16,20 +16,14 @@
 */
 
 #include <sys/mman.h>
-#include <utils/CallStack.h>
 #include <cutils/ashmem.h>
 #include <cutils/log.h>
 
 #include <utils/Singleton.h>
 #include <utils/String8.h>
 
-#include <ui/BufferMapper.h>
-
 #include "BufferAllocator.h"
 
-// FIXME: ANDROID_GRALLOC_DEBUG must only be used with *our* gralloc
-#define ANDROID_GRALLOC_DEBUG 1
-
 
 namespace android {
 // ---------------------------------------------------------------------------
@@ -67,8 +61,8 @@
     const size_t c = list.size();
     for (size_t i=0 ; i<c ; i++) {
         const alloc_rec_t& rec(list.valueAt(i));
-        snprintf(buffer, SIZE, "%10p: %10p | %7.2f KB | %4u x %4u | %2d | 0x%08x\n",
-            list.keyAt(i), rec.vaddr, rec.size/1024.0f,
+        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u x %4u | %2d | 0x%08x\n",
+            list.keyAt(i), rec.size/1024.0f, 
             rec.w, rec.h, rec.format, rec.usage);
         result.append(buffer);
         total += rec.size;
@@ -108,23 +102,9 @@
 {
     Mutex::Autolock _l(mLock);
 
-#if ANDROID_GRALLOC_DEBUG
-    void* base = (void*)(handle->data[2]);
-#endif
-
     status_t err = mAllocDev->free(mAllocDev, handle);
     LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err));
     
-#if ANDROID_GRALLOC_DEBUG
-    if (base) {
-        LOGD("freeing mapped handle %p from:", handle);
-        CallStack s;
-        s.update();
-        s.dump("");
-        BufferMapper::get().dump(handle);
-    }
-#endif
-
     if (err == NO_ERROR) {
         Mutex::Autolock _l(sLock);
         KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
@@ -134,37 +114,5 @@
     return err;
 }
 
-status_t BufferAllocator::map(buffer_handle_t handle, void** addr)
-{
-    Mutex::Autolock _l(mLock);
-    status_t err = BufferMapper::get().map(handle, addr, this);
-    if (err == NO_ERROR) {
-        Mutex::Autolock _l(sLock);
-        KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
-        ssize_t idx = list.indexOfKey(handle);
-        if (idx >= 0)
-            list.editValueAt(idx).vaddr = addr;
-    }
-
-    return err;
-}
-
-status_t BufferAllocator::unmap(buffer_handle_t handle)
-{
-    Mutex::Autolock _l(mLock);
-    gralloc_module_t* mod = (gralloc_module_t*)mAllocDev->common.module;
-    status_t err = BufferMapper::get().unmap(handle, this);
-    if (err == NO_ERROR) {
-        Mutex::Autolock _l(sLock);
-        KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
-        ssize_t idx = list.indexOfKey(handle);
-        if (idx >= 0)
-            list.editValueAt(idx).vaddr = 0;
-    }
-
-    return err;
-}
-
-
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/libs/surfaceflinger/BufferAllocator.h b/libs/surfaceflinger/BufferAllocator.h
index 0b69b8e..a279ded 100644
--- a/libs/surfaceflinger/BufferAllocator.h
+++ b/libs/surfaceflinger/BufferAllocator.h
@@ -67,10 +67,6 @@
 
     status_t free(buffer_handle_t handle);
 
-    status_t map(buffer_handle_t handle, void** addr);
-    
-    status_t unmap(buffer_handle_t handle);
-    
     void dump(String8& res) const;
 
 private:
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 1f7211c..83ebd7a 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -25,7 +25,7 @@
 #include <utils/Log.h>
 
 #include <ui/PixelFormat.h>
-#include <ui/EGLNativeWindowSurface.h>
+#include <ui/FramebufferNativeWindow.h>
 
 #include <GLES/gl.h>
 #include <EGL/egl.h>
@@ -313,8 +313,7 @@
     } 
 
     const Rect& b(newDirty.bounds());
-    mNativeWindow->android_native_window_t::setSwapRectangle(
-            mNativeWindow.get(), b.left, b.top, b.width(), b.height());
+    mNativeWindow->setSwapRectangle(b);
 
     mPageFlipCount++;
     eglSwapBuffers(dpy, surface);
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 8a7d467..7625931 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -69,8 +69,6 @@
 {
     for (int i=0 ; i<NUM_BUFFERS ; i++) {
         if (mTextures[i].name != -1U) {
-            // FIXME: this was originally to work-around a bug in the
-            // adreno driver. this should be fixed now.
             glDeleteTextures(1, &mTextures[i].name);
             mTextures[i].name = -1U;
         }
@@ -142,8 +140,8 @@
 
 void Layer::reloadTexture(const Region& dirty)
 {
-    const sp<const Buffer>& buffer(frontBuffer().getBuffer());
-     if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) {
+    const sp<Buffer>& buffer(frontBuffer().getBuffer());
+    if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) {
         int index = mFrontBufferIndex;
         if (LIKELY(!mTextures[index].dirty)) {
             glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
@@ -197,12 +195,16 @@
         }
     } else {
         GGLSurface t;
-        if (LIKELY(buffer->getBitmapSurface(&t) == NO_ERROR)) {
+        status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY);
+        LOGE_IF(res, "error %d (%s) locking buffer %p",
+                res, strerror(res), buffer.get());
+        if (res == NO_ERROR) {
             if (UNLIKELY(mTextures[0].name == -1U)) {
                 mTextures[0].name = createTexture();
             }
             loadTexture(dirty, mTextures[0].name, t, 
                     mTextures[0].width, mTextures[0].height);
+            buffer->unlock();
         }
     }
 }
@@ -225,8 +227,7 @@
 
     GGLSurface t;
     sp<const Buffer> buffer(frontBuffer().getBuffer());
-    buffer->getBitmapSurface(&t);
-    drawWithOpenGL(clip, textureName, t);
+    drawWithOpenGL(clip, textureName, buffer);
 }
 
 sp<SurfaceBuffer> Layer::peekBuffer()
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index ef5a959..cc9c586 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -377,12 +377,14 @@
 }
 
 void LayerBase::drawWithOpenGL(const Region& clip,
-        GLint textureName, const GGLSurface& t, int transform) const
+        GLint textureName, const sp<const Buffer>& buffer, int transform) const
 {
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     const uint32_t fbHeight = hw.getHeight();
     const State& s(drawingState());
-
+    const uint32_t width = buffer->width;
+    const uint32_t height = buffer->height;
+    
     // bind our texture
     validateTexture(textureName);
     glEnable(GL_TEXTURE_2D);
@@ -457,14 +459,14 @@
 
             if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
                 // find the smallest power-of-two that will accommodate our surface
-                GLuint tw = 1 << (31 - clz(t.width));
-                GLuint th = 1 << (31 - clz(t.height));
-                if (tw < t.width)  tw <<= 1;
-                if (th < t.height) th <<= 1;
+                GLuint tw = 1 << (31 - clz(width));
+                GLuint th = 1 << (31 - clz(height));
+                if (tw < width)  tw <<= 1;
+                if (th < height) th <<= 1;
                 // this divide should be relatively fast because it's
                 // a power-of-two (optimized path in libgcc)
-                GLfloat ws = GLfloat(t.width) /tw;
-                GLfloat hs = GLfloat(t.height)/th;
+                GLfloat ws = GLfloat(width) /tw;
+                GLfloat hs = GLfloat(height)/th;
                 glScalef(ws, hs, 1.0f);
             }
 
@@ -489,15 +491,15 @@
         Region::iterator iterator(clip);
         if (iterator) {
             Rect r;
-            GLint crop[4] = { 0, t.height, t.width, -t.height };
+            GLint crop[4] = { 0, height, width, -height };
             glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
             int x = tx();
             int y = ty();
-            y = fbHeight - (y + t.height);
+            y = fbHeight - (y + height);
             while (iterator.iterate(&r)) {
                 const GLint sy = fbHeight - (r.top + r.height());
                 glScissor(r.left, sy, r.width(), r.height());
-                glDrawTexiOES(x, y, 0, t.width, t.height);
+                glDrawTexiOES(x, y, 0, width, height);
             }
         }
     }
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index c177c2a..509dedd 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -40,6 +40,7 @@
 class GraphicPlane;
 class Client;
 class SurfaceBuffer;
+class Buffer;
 
 // ---------------------------------------------------------------------------
 
@@ -239,7 +240,7 @@
     
           void drawWithOpenGL(const Region& clip,
                   GLint textureName,
-                  const GGLSurface& surface,
+                  const sp<const Buffer>& buffer,
                   int transform = 0) const;
 
           void clearWithOpenGL(const Region& clip) const;
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
index d633a2d..38d4bcf 100644
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -52,10 +52,7 @@
 Buffer::~Buffer()
 {
     if (handle) {
-        BufferAllocator& allocator = BufferAllocator::get();
-        if (usage & BufferAllocator::USAGE_SW_READ_MASK) {
-            allocator.unmap(handle);
-        }
+        BufferAllocator& allocator(BufferAllocator::get());
         allocator.free(handle);
     }
 }
@@ -107,9 +104,6 @@
     err = allocator.alloc(w, h, format, usage, &handle, &stride);
     
     if (err == NO_ERROR) {
-        if (usage & BufferAllocator::USAGE_SW_READ_MASK) {
-            err = allocator.map(handle, &bits);
-        }
         if (err == NO_ERROR) {
             width  = w;
             height = h;
@@ -120,31 +114,22 @@
     return err;
 }
 
-status_t Buffer::getBitmapSurface(copybit_image_t* img) const
+status_t Buffer::lock(GGLSurface* sur, uint32_t usage) 
 {
-    img->w = stride  ?: width;
-    img->h = mVStride ?: height;
-    img->format = format;
-    
-    // FIXME: this should use a native_handle
-    img->offset = 0;    
-    img->base = bits;
-    img->fd = getHandle()->data[0];
-    
-    return NO_ERROR;
+    status_t res = SurfaceBuffer::lock(usage);
+    if (res == NO_ERROR && sur) {
+        sur->version = sizeof(GGLSurface);
+        sur->width = width;
+        sur->height = height;
+        sur->stride = stride;
+        sur->format = format;
+        sur->vstride = mVStride;
+        sur->data = static_cast<GGLubyte*>(bits);
+    }
+    return res;
 }
 
-status_t Buffer::getBitmapSurface(GGLSurface* sur) const
-{
-    sur->version = sizeof(GGLSurface);
-    sur->width = width;
-    sur->height = height;
-    sur->stride = stride;
-    sur->format = format;
-    sur->vstride = mVStride;
-    sur->data = static_cast<GGLubyte*>(bits);
-    return NO_ERROR;
-}
+
 
 // ===========================================================================
 // LayerBitmap
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
index e673755..6e136a2 100644
--- a/libs/surfaceflinger/LayerBitmap.h
+++ b/libs/surfaceflinger/LayerBitmap.h
@@ -73,9 +73,8 @@
     PixelFormat getPixelFormat() const  { return format; }
     Rect getBounds() const              { return Rect(width, height); }
     
-    status_t getBitmapSurface(copybit_image_t* img) const;
-    status_t getBitmapSurface(GGLSurface* surface) const;
-
+    status_t lock(GGLSurface* surface, uint32_t usage);
+    
     android_native_buffer_t* getNativeBuffer() const;
     
 private:
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 9339b87..8be91c9 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -380,37 +380,37 @@
 
 void LayerBuffer::BufferSource::onDraw(const Region& clip) const 
 {
-    sp<Buffer> buffer(getBuffer());
+    // FIXME: we should get a native buffer here 
+    /*
+    sp<Buffer> ourBbuffer(getBuffer());
     if (UNLIKELY(buffer == 0))  {
         // nothing to do, we don't have a buffer
         mLayer.clearWithOpenGL(clip);
         return;
     }
 
-    status_t err = NO_ERROR;
-    NativeBuffer src(buffer->getBuffer());
-    const Rect& transformedBounds = mLayer.getTransformedBounds();
-
     // FIXME: We should model this after the overlay stuff
-    
     if (UNLIKELY(mTextureName == -1LU)) {
         mTextureName = mLayer.createTexture();
     }
-    GLuint w = 0;
-    GLuint h = 0;
-    GGLSurface t;
-    t.version = sizeof(GGLSurface);
-    t.width  = src.crop.r;
-    t.height = src.crop.b;
-    t.stride = src.img.w;
-    t.vstride= src.img.h;
-    t.format = src.img.format;
-    t.data = (GGLubyte*)(intptr_t(src.img.base) + src.img.offset);
-    const Region dirty(Rect(t.width, t.height));
 
     // FIXME: Use EGLImage extension for this
-    mLayer.loadTexture(dirty, mTextureName, t, w, h);
-    mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform);
+    
+    
+    
+    GGLSurface t;
+    status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_RARELY);
+    if (res == NO_ERROR) {
+        GLuint w = 0;
+        GLuint h = 0;
+        const Region dirty(Rect(buffer->width, buffer->height));
+        mLayer.loadTexture(dirty, mTextureName, t, w, h);
+        buffer->unlock();
+    }
+    if (res == NO_ERROR) {
+        mLayer.drawWithOpenGL(clip, mTextureName, buffer, mBufferHeap.transform);
+    }
+    */
 }
 
 
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 6b42158..5fd979e 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -50,8 +50,6 @@
 #include "LayerBuffer.h"
 #include "LayerDim.h"
 #include "LayerBitmap.h"
-#include "LayerOrientationAnim.h"
-#include "OrientationAnimation.h"
 #include "SurfaceFlinger.h"
 
 #include "DisplayHardware/DisplayHardware.h"
@@ -206,7 +204,6 @@
 SurfaceFlinger::~SurfaceFlinger()
 {
     glDeleteTextures(1, &mWormholeTexName);
-    delete mOrientationAnimation;
 }
 
 overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
@@ -399,8 +396,6 @@
      *  We're now ready to accept clients...
      */
 
-    mOrientationAnimation = new OrientationAnimation(this);
-    
     // the boot animation!
     if (mDebugNoBootAnimation == false)
         mBootAnimation = new BootAnimation(this);
@@ -513,16 +508,17 @@
 
 void SurfaceFlinger::postFramebuffer()
 {
-    const bool skip = mOrientationAnimation->run();
-    if (UNLIKELY(skip)) {
+    if (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;
     }
 
     if (!mInvalidRegion.isEmpty()) {
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
-
         hw.flip(mInvalidRegion);
-
         mInvalidRegion.clear();
     }
 }
@@ -616,7 +612,6 @@
             mVisibleRegionsDirty = true;
             mDirtyRegion.set(hw.bounds());
             mFreezeDisplayTime = 0;
-            mOrientationAnimation->onOrientationChanged(type);
         }
 
         if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
@@ -893,19 +888,26 @@
 
 void SurfaceFlinger::debugFlashRegions()
 {
-    if (UNLIKELY(!mDirtyRegion.isRect())) {
-        // TODO: do this only if we don't have preserving
-        // swapBuffer. If we don't have update-on-demand,
-        // redraw everything.
-        composeSurfaces(Region(mDirtyRegion.bounds()));
-    }
-
+     const DisplayHardware& hw(graphicPlane(0).displayHardware());
+     const uint32_t flags = hw.getFlags();
+     if (!(flags & DisplayHardware::BUFFER_PRESERVED)) {
+         const Region repaint((flags & DisplayHardware::UPDATE_ON_DEMAND) ?
+                 mDirtyRegion.bounds() : hw.bounds());
+         composeSurfaces(repaint);
+     }
+    
     glDisable(GL_TEXTURE_2D);
     glDisable(GL_BLEND);
     glDisable(GL_DITHER);
     glDisable(GL_SCISSOR_TEST);
 
-    glColor4x(0x10000, 0, 0x10000, 0x10000);
+    static int toggle = 0;
+    toggle = 1 - toggle;
+    if (toggle) {
+        glColor4x(0x10000, 0, 0x10000, 0x10000);
+    } else {
+        glColor4x(0x10000, 0x10000, 0, 0x10000);
+    }
 
     Rect r;
     Region::iterator iterator(mDirtyRegion);
@@ -919,8 +921,7 @@
         glVertexPointer(2, GL_FLOAT, 0, vertices);
         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
-
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    
     hw.flip(mDirtyRegion.merge(mInvalidRegion));
     mInvalidRegion.clear();
 
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 319f80e..d5e5252 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -55,8 +55,6 @@
 class FreezeLock;
 class Layer;
 class LayerBuffer;
-class LayerOrientationAnim;
-class OrientationAnimation;
 
 typedef int32_t ClientID;
 
@@ -335,8 +333,6 @@
                 bool                        mFreezeDisplay;
                 int32_t                     mFreezeCount;
                 nsecs_t                     mFreezeDisplayTime;
-                friend class OrientationAnimation;
-                OrientationAnimation*       mOrientationAnimation;
 
                 // don't use a lock for these, we don't care
                 int                         mDebugRegion;
diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp
similarity index 100%
rename from libs/surfaceflinger/LayerOrientationAnim.cpp
rename to libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp
diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h
similarity index 100%
rename from libs/surfaceflinger/LayerOrientationAnim.h
rename to libs/surfaceflinger/purgatory/LayerOrientationAnim.h
diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp
similarity index 100%
rename from libs/surfaceflinger/LayerOrientationAnimRotate.cpp
rename to libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp
diff --git a/libs/surfaceflinger/LayerOrientationAnimRotate.h b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h
similarity index 100%
rename from libs/surfaceflinger/LayerOrientationAnimRotate.h
rename to libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h
diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp
similarity index 100%
rename from libs/surfaceflinger/OrientationAnimation.cpp
rename to libs/surfaceflinger/purgatory/OrientationAnimation.cpp
diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/purgatory/OrientationAnimation.h
similarity index 100%
rename from libs/surfaceflinger/OrientationAnimation.h
rename to libs/surfaceflinger/purgatory/OrientationAnimation.h
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 577dd4b..d44d2f9 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -5,9 +5,9 @@
 	BufferMapper.cpp \
 	Camera.cpp \
 	CameraParameters.cpp \
-	EGLNativeWindowSurface.cpp \
 	EventHub.cpp \
 	EventRecurrence.cpp \
+	FramebufferNativeWindow.cpp \
 	KeyLayoutMap.cpp \
 	KeyCharacterMap.cpp \
 	ICamera.cpp \
diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp
index 85a029b..1a75c5d 100644
--- a/libs/ui/BufferMapper.cpp
+++ b/libs/ui/BufferMapper.cpp
@@ -17,14 +17,9 @@
 #define LOG_TAG "BufferMapper"
 
 #include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
 #include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 
 #include <utils/Errors.h>
-#include <utils/threads.h>
 #include <utils/Log.h>
 
 #include <ui/BufferMapper.h>
@@ -34,12 +29,6 @@
 
 #include <hardware/gralloc.h>
 
-// ---------------------------------------------------------------------------
-// enable mapping debugging
-#define DEBUG_MAPPINGS           0
-// never remove mappings from the list
-#define DEBUG_MAPPINGS_KEEP_ALL  0
-// ---------------------------------------------------------------------------
 
 namespace android {
 // ---------------------------------------------------------------------------
@@ -57,34 +46,27 @@
     }
 }
 
-status_t BufferMapper::map(buffer_handle_t handle, void** addr, const void* id)
+status_t BufferMapper::registerBuffer(buffer_handle_t handle)
 {
-    Mutex::Autolock _l(mLock);
-    status_t err = mAllocMod->map(mAllocMod, handle, addr);
-    LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
-#if DEBUG_MAPPINGS
-    if (err == NO_ERROR)
-        logMapLocked(handle, id);
-#endif
+    status_t err = mAllocMod->registerBuffer(mAllocMod, handle);
+    LOGW_IF(err, "registerBuffer(%p) failed %d (%s)",
+            handle, err, strerror(-err));
     return err;
 }
 
-status_t BufferMapper::unmap(buffer_handle_t handle, const void* id)
+status_t BufferMapper::unregisterBuffer(buffer_handle_t handle)
 {
-    Mutex::Autolock _l(mLock);
-    status_t err = mAllocMod->unmap(mAllocMod, handle);
-    LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err));
-#if DEBUG_MAPPINGS
-    if (err == NO_ERROR)
-        logUnmapLocked(handle, id);
-#endif
+    status_t err = mAllocMod->unregisterBuffer(mAllocMod, handle);
+    LOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)",
+            handle, err, strerror(-err));
     return err;
 }
 
-status_t BufferMapper::lock(buffer_handle_t handle, int usage, const Rect& bounds)
+status_t BufferMapper::lock(buffer_handle_t handle, 
+        int usage, const Rect& bounds, void** vaddr)
 {
     status_t err = mAllocMod->lock(mAllocMod, handle, usage,
-            bounds.left, bounds.top, bounds.width(), bounds.height());
+            bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr);
     LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
     return err;
 }
@@ -96,65 +78,5 @@
     return err;
 }
 
-void BufferMapper::logMapLocked(buffer_handle_t handle, const void* id)
-{
-    CallStack stack;
-    stack.update(2);
-    
-    map_info_t info;
-    info.id = id;
-    info.stack = stack;
-    
-    ssize_t index = mMapInfo.indexOfKey(handle);
-    if (index >= 0) {
-        Vector<map_info_t>& infos = mMapInfo.editValueAt(index);
-        infos.add(info);
-    } else {
-        Vector<map_info_t> infos;
-        infos.add(info);
-        mMapInfo.add(handle, infos);
-    }
-}
-
-void BufferMapper::logUnmapLocked(buffer_handle_t handle, const void* id)
-{    
-    ssize_t index = mMapInfo.indexOfKey(handle);
-    if (index < 0) {
-        LOGE("unmapping %p which doesn't exist in our map!", handle);
-        return;
-    }
-    
-    Vector<map_info_t>& infos = mMapInfo.editValueAt(index);
-    ssize_t count = infos.size();
-    for (int i=0 ; i<count ; ) {
-        if (infos[i].id == id) {
-            infos.removeAt(i);
-            --count;
-        } else {
-            ++i;
-        }
-    }
-    if (count == 0) {
-        mMapInfo.removeItemsAt(index, 1);
-    }
-}
-
-void BufferMapper::dump(buffer_handle_t handle)
-{
-    Mutex::Autolock _l(mLock);
-    ssize_t index = mMapInfo.indexOfKey(handle);
-    if (index < 0) {
-        LOGD("handle %p is not mapped through BufferMapper", handle);
-        return;
-    }
-    
-    const Vector<map_info_t>& infos = mMapInfo.valueAt(index);
-    ssize_t count = infos.size();
-    for (int i=0 ; i<count ; i++) {
-        LOGD("#%d", i);
-        infos[i].stack.dump();
-    }
-}
-
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/FramebufferNativeWindow.cpp
similarity index 81%
rename from libs/ui/EGLNativeWindowSurface.cpp
rename to libs/ui/FramebufferNativeWindow.cpp
index 5d9d6a4..407d6f4 100644
--- a/libs/ui/EGLNativeWindowSurface.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -15,7 +15,7 @@
 ** limitations under the License.
 */
 
-#define LOG_TAG "EGLNativeWindowSurface"
+#define LOG_TAG "FramebufferNativeWindow"
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -28,7 +28,7 @@
 
 #include <ui/SurfaceComposerClient.h>
 #include <ui/Rect.h>
-#include <ui/EGLNativeWindowSurface.h>
+#include <ui/FramebufferNativeWindow.h>
 
 #include <EGL/egl.h>
 
@@ -87,13 +87,6 @@
 
         LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s",
                 fbDev->width, fbDev->height, strerror(-err));
-
-        gralloc_module_t* m = 
-            reinterpret_cast<gralloc_module_t*>(grDev->common.module);
-
-        // FIXME: do we actually need to map the framebuffer?
-        m->map(m, buffers[0]->handle, &buffers[0]->bits);
-        m->map(m, buffers[1]->handle, &buffers[1]->bits);
     }
 
     uint32_t flags = fbDev->flags & SURFACE_FLAG_MAPPED;
@@ -125,10 +118,7 @@
     const_cast<int&>(android_native_window_t::maxSwapInterval) = 
         fbDev->maxSwapInterval;
 
-    android_native_window_t::connect = connect;
-    android_native_window_t::disconnect = disconnect;
     android_native_window_t::setSwapInterval = setSwapInterval;
-    android_native_window_t::setSwapRectangle = setSwapRectangle;
     android_native_window_t::dequeueBuffer = dequeueBuffer;
     android_native_window_t::lockBuffer = lockBuffer;
     android_native_window_t::queueBuffer = queueBuffer;
@@ -137,10 +127,6 @@
 FramebufferNativeWindow::~FramebufferNativeWindow() {
     grDev->free(grDev, buffers[0]->handle);
     grDev->free(grDev, buffers[1]->handle);
-    gralloc_module_t* m = 
-        reinterpret_cast<gralloc_module_t*>(grDev->common.module);
-    m->unmap(m, buffers[0]->handle);
-    m->unmap(m, buffers[1]->handle);
     gralloc_close(grDev);
     framebuffer_close(fbDev);
 }
@@ -160,13 +146,10 @@
     return fb->setSwapInterval(fb, interval);
 }
 
-int FramebufferNativeWindow::setSwapRectangle(android_native_window_t* window,
-        int l, int t, int w, int h)
+void FramebufferNativeWindow::setSwapRectangle(const Rect& dirty)
 {
-    FramebufferNativeWindow* self = getSelf(window);
-    Mutex::Autolock _l(self->mutex);
-    self->mDirty = Rect(l, t, l+w, t+h); 
-    return 0;
+    Mutex::Autolock _l(mutex);
+    mDirty = dirty; 
 }
 
 int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, 
@@ -201,16 +184,8 @@
     while (self->front == buffer) {
         self->mCondition.wait(self->mutex);
     }
-        
-    gralloc_module_t* m = 
-        reinterpret_cast<gralloc_module_t*>(self->grDev->common.module);
-    const Rect& dirty(self->mDirty);
 
-    buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle;
-    int res = m->lock(m, handle, GRALLOC_USAGE_HW_FB,
-            dirty.left, dirty.right, dirty.width(), dirty.height());
-    
-    return res;
+    return NO_ERROR;
 }
 
 int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, 
@@ -219,13 +194,8 @@
     FramebufferNativeWindow* self = getSelf(window);
     Mutex::Autolock _l(self->mutex);
     framebuffer_device_t* fb = self->fbDev;
-    gralloc_module_t* m = 
-        reinterpret_cast<gralloc_module_t*>(self->grDev->common.module);
-
     buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle;
-    m->unlock(m, handle);
     int res = fb->post(fb, handle);
-
     self->front = static_cast<NativeBuffer*>(buffer);
     self->mNumFreeBuffers++;
     self->mCondition.broadcast();
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 26e694a..30da911 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -88,6 +88,13 @@
     mRegion.setRect(ir);
 }
 
+void Region::set(uint32_t w, uint32_t h)
+{
+    SkIRect ir;
+    ir.set(0, 0, w, h);
+    mRegion.setRect(ir);
+}
+
 // ----------------------------------------------------------------------------
 
 Region& Region::orSelf(const Rect& r)
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index fb105b3..68fd963 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -31,7 +31,6 @@
 
 #include <ui/DisplayInfo.h>
 #include <ui/BufferMapper.h>
-#include <ui/EGLNativeWindowSurface.h>
 #include <ui/ISurface.h>
 #include <ui/Surface.h>
 #include <ui/SurfaceComposerClient.h>
@@ -53,7 +52,7 @@
 ANDROID_SINGLETON_STATIC_INSTANCE( SurfaceBuffer )
 
 SurfaceBuffer::SurfaceBuffer() 
-    : BASE(), handle(0), mOwner(false)
+    : BASE(), handle(0), mOwner(false), mBufferMapper(BufferMapper::get())
 {
     width  = 
     height = 
@@ -64,7 +63,7 @@
 }
 
 SurfaceBuffer::SurfaceBuffer(const Parcel& data) 
-    : BASE(), handle(0), mOwner(true)
+    : BASE(), handle(0), mOwner(true), mBufferMapper(BufferMapper::get())
 {
     // we own the handle in this case
     width  = data.readInt32();
@@ -91,6 +90,26 @@
     return 0;
 }
 
+status_t SurfaceBuffer::lock(uint32_t usage)
+{
+    const Rect lockBounds(width, height);
+    status_t res = lock(usage, lockBounds);
+    return res;
+}
+
+status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect)
+{
+    status_t res = getBufferMapper().lock(handle, usage, rect, &bits);
+    return res;
+}
+
+status_t SurfaceBuffer::unlock()
+{
+    status_t res = getBufferMapper().unlock(handle);
+    bits = NULL;
+    return res;
+}
+
 status_t SurfaceBuffer::writeToParcel(Parcel* reply, 
         android_native_buffer_t const* buffer)
 {
@@ -110,9 +129,17 @@
 
 // ----------------------------------------------------------------------
 
-static void copyBlt(const android_native_buffer_t* dst,
-        const android_native_buffer_t* src, const Region& reg)
+static void copyBlt(
+        const sp<SurfaceBuffer>& dst, 
+        const sp<SurfaceBuffer>& src, 
+        const Region& reg)
 {
+    src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds());
+    uint8_t const * const src_bits = (uint8_t const *)src->bits;
+
+    dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds());
+    uint8_t* const dst_bits = (uint8_t*)dst->bits;
+    
     Region::iterator iterator(reg);
     if (iterator) {
         // NOTE: dst and src must be the same format
@@ -120,29 +147,29 @@
         const size_t bpp = bytesPerPixel(src->format);
         const size_t dbpr = dst->stride * bpp;
         const size_t sbpr = src->stride * bpp;
+
         while (iterator.iterate(&r)) {
-            ssize_t h = r.bottom - r.top;
-            if (h) {
-                size_t size = (r.right - r.left) * bpp;
-                uint8_t* s = (GGLubyte*)src->bits + 
-                        (r.left + src->stride * r.top) * bpp;
-                uint8_t* d = (GGLubyte*)dst->bits +
-                        (r.left + dst->stride * r.top) * bpp;
-                if (dbpr==sbpr && size==sbpr) {
-                    size *= h;
-                    h = 1;
-                }
-                do {
-                    memcpy(d, s, size);
-                    d += dbpr;
-                    s += sbpr;
-                } while (--h > 0);
+            ssize_t h = r.height();
+            if (h <= 0) continue;
+            size_t size = r.width() * bpp;
+            uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
+            uint8_t       * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
+            if (dbpr==sbpr && size==sbpr) {
+                size *= h;
+                h = 1;
             }
+            do {
+                memcpy(d, s, size);
+                d += dbpr;
+                s += sbpr;
+            } while (--h > 0);
         }
     }
+    
+    src->unlock();
+    dst->unlock();
 }
 
-
 // ============================================================================
 //  SurfaceControl
 // ============================================================================
@@ -347,12 +374,14 @@
 Surface::Surface(const sp<SurfaceControl>& surface)
     : mClient(surface->mClient), mSurface(surface->mSurface),
       mToken(surface->mToken), mIdentity(surface->mIdentity),
-      mFormat(surface->mFormat), mFlags(surface->mFlags)
+      mFormat(surface->mFormat), mFlags(surface->mFlags),
+      mBufferMapper(BufferMapper::get())
 {
     init();
 }
 
 Surface::Surface(const Parcel& parcel)
+    :  mBufferMapper(BufferMapper::get())
 {
     sp<IBinder> clientBinder = parcel.readStrongBinder();
     mSurface    = interface_cast<ISurface>(parcel.readStrongBinder());
@@ -369,16 +398,11 @@
 
 void Surface::init()
 {
-    android_native_window_t::connect          = connect;
-    android_native_window_t::disconnect       = disconnect;
     android_native_window_t::setSwapInterval  = setSwapInterval;
-    android_native_window_t::setSwapRectangle = setSwapRectangle;
     android_native_window_t::dequeueBuffer    = dequeueBuffer;
     android_native_window_t::lockBuffer       = lockBuffer;
     android_native_window_t::queueBuffer      = queueBuffer;
-
     mSwapRectangle.makeInvalid();
-
     DisplayInfo dinfo;
     SurfaceComposerClient::getDisplayInfo(0, &dinfo);
     const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi;
@@ -396,7 +420,7 @@
     // its buffers in this process.
     for (int i=0 ; i<2 ; i++) {
         if (mBuffers[i] != 0) {
-            BufferMapper::get().unmap(mBuffers[i]->getHandle(), this);
+            getBufferMapper().unregisterBuffer(mBuffers[i]->getHandle());
         }
     }
 
@@ -443,22 +467,6 @@
 
 // ----------------------------------------------------------------------------
 
-int Surface::setSwapRectangle(android_native_window_t* window,
-        int l, int t, int w, int h)
-{
-    Surface* self = getSelf(window);
-    self->setSwapRectangle(Rect(l, t, l+w, t+h));
-    return 0;
-}
-
-void Surface::connect(android_native_window_t* window)
-{
-}
-
-void Surface::disconnect(android_native_window_t* window)
-{
-}
-
 int Surface::setSwapInterval(android_native_window_t* window, int interval)
 {
     return 0;
@@ -487,6 +495,26 @@
 
 // ----------------------------------------------------------------------------
 
+status_t Surface::dequeueBuffer(sp<SurfaceBuffer>* buffer)
+{
+    android_native_buffer_t* out;
+    status_t err = dequeueBuffer(&out);
+    *buffer = SurfaceBuffer::getSelf(out);
+    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
@@ -515,8 +543,9 @@
     }
 
     const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
+    mDirtyRegion.set(backBuffer->width, backBuffer->height);
     *buffer = backBuffer.get();
-
+  
     return NO_ERROR;
 }
 
@@ -542,11 +571,14 @@
     if (err != NO_ERROR)
         return err;
 
+    if (mSwapRectangle.isValid()) {
+        mDirtyRegion.set(mSwapRectangle);
+    }
+    
     // transmit the dirty region
-    const Region dirty(swapRectangle());
     SurfaceID index(mToken); 
     layer_cblk_t* const lcblk = &(cblk->layers[index]);
-    _send_dirty_region(lcblk, dirty);
+    _send_dirty_region(lcblk, mDirtyRegion);
 
     uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
     if (!(newstate & eNextFlipPending))
@@ -561,27 +593,20 @@
     return Surface::lock(info, NULL, blocking);
 }
 
-status_t Surface::lock(SurfaceInfo* other, Region* dirty, bool blocking) 
+status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 
 {
     // FIXME: needs some locking here
-    android_native_buffer_t* backBuffer;
+    
+    sp<SurfaceBuffer> backBuffer;
     status_t err = dequeueBuffer(&backBuffer);
     if (err == NO_ERROR) {
         err = lockBuffer(backBuffer);
         if (err == NO_ERROR) {
-            backBuffer->common.incRef(&backBuffer->common);
-            mLockedBuffer = backBuffer;
-            other->w      = backBuffer->width;
-            other->h      = backBuffer->height;
-            other->s      = backBuffer->stride;
-            other->usage  = backBuffer->usage;
-            other->format = backBuffer->format;
-            other->bits   = backBuffer->bits;
-
             // we handle copy-back here...
             
             const Rect bounds(backBuffer->width, backBuffer->height);
-            Region newDirtyRegion;
+            Region scratch(bounds);
+            Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
 
             per_client_cblk_t* const cblk = mClient->mControl;
             layer_cblk_t* const lcblk = &(cblk->layers[SurfaceID(mToken)]);
@@ -590,43 +615,34 @@
                 // content is meaningless in this case and the whole surface
                 // needs to be redrawn.
                 newDirtyRegion.set(bounds);
-                if (dirty) {
-                    *dirty = newDirtyRegion;
-                }
-            } else 
-            {
-                if (dirty) {
-                    dirty->andSelf(Region(bounds));
-                    newDirtyRegion = *dirty;
-                } else {
-                    newDirtyRegion.set(bounds);
-                }
-                Region copyback;
+            } else {
+                newDirtyRegion.andSelf(bounds);
                 if (!(lcblk->flags & eNoCopyBack)) {
-                    const Region previousDirtyRegion(dirtyRegion());
-                    copyback = previousDirtyRegion.subtract(newDirtyRegion);
-                }
-                const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]);
-                if (!copyback.isEmpty() && frontBuffer!=0) {
-                    // copy front to back
-                    copyBlt(backBuffer, frontBuffer.get(), copyback);
+                    const sp<SurfaceBuffer>& frontBuffer(mBuffers[1-mBackbufferIndex]);
+                    const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
+                    if (!copyback.isEmpty() && frontBuffer!=0) {
+                        // copy front to back
+                        copyBlt(backBuffer, frontBuffer, copyback);
+                    }
                 }
             }
-            setDirtyRegion(newDirtyRegion);
+            mDirtyRegion = newDirtyRegion;
+            mOldDirtyRegion = newDirtyRegion;
 
-
-            Rect lockBounds(backBuffer->width, backBuffer->height);
-            if (dirty) {
-                lockBounds = dirty->bounds();
-            }
-            buffer_handle_t handle;
-            backBuffer->getHandle(backBuffer, &handle);
-            status_t res = BufferMapper::get().lock(handle,
-                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, 
-                    lockBounds);
+            status_t res = backBuffer->lock(
+                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                    newDirtyRegion.bounds());
+            
             LOGW_IF(res, "failed locking buffer %d (%p)", 
-                    mBackbufferIndex, handle);
-            setSwapRectangle(lockBounds);
+                    mBackbufferIndex, backBuffer->handle);
+
+            mLockedBuffer = backBuffer;
+            other->w      = backBuffer->width;
+            other->h      = backBuffer->height;
+            other->s      = backBuffer->stride;
+            other->usage  = backBuffer->usage;
+            other->format = backBuffer->format;
+            other->bits   = backBuffer->bits;
         }
     }
     return err;
@@ -639,16 +655,12 @@
     if (mLockedBuffer == 0)
         return BAD_VALUE;
 
-    buffer_handle_t handle;
-    mLockedBuffer->getHandle(mLockedBuffer, &handle);
-    status_t res = BufferMapper::get().unlock(handle);
+    status_t res = mLockedBuffer->unlock();
     LOGW_IF(res, "failed unlocking buffer %d (%p)",
-            mBackbufferIndex, handle);
-
-    const Rect dirty(dirtyRegion().bounds());
-    setSwapRectangle(dirty);
+            mBackbufferIndex, mLockedBuffer->handle);
+    
     status_t err = queueBuffer(mLockedBuffer);
-    mLockedBuffer->common.decRef(&mLockedBuffer->common);
+    mLockedBuffer->bits = NULL;
     mLockedBuffer = 0;
     return err;
 }
@@ -666,15 +678,6 @@
     }
 }
 
-Region Surface::dirtyRegion() const  {
-    return mDirtyRegion; 
-}
-void Surface::setDirtyRegion(const Region& region) const {
-    mDirtyRegion = region;
-}
-const Rect& Surface::swapRectangle() const {
-    return mSwapRectangle;
-}
 void Surface::setSwapRectangle(const Rect& r) {
     mSwapRectangle = r;
 }
@@ -687,10 +690,10 @@
     if (buffer != 0) {
         sp<SurfaceBuffer>& currentBuffer(mBuffers[index]);
         if (currentBuffer != 0) {
-            BufferMapper::get().unmap(currentBuffer->getHandle(), this);
+            getBufferMapper().unregisterBuffer(currentBuffer->getHandle());
             currentBuffer.clear();
         }
-        err = BufferMapper::get().map(buffer->getHandle(), &buffer->bits, this);
+        err = getBufferMapper().registerBuffer(buffer->getHandle());
         LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
         if (err == NO_ERROR) {
             currentBuffer = buffer;
diff --git a/opengl/include/EGL/android_natives.h b/opengl/include/EGL/android_natives.h
index e3c3b86..329705b 100644
--- a/opengl/include/EGL/android_natives.h
+++ b/opengl/include/EGL/android_natives.h
@@ -96,18 +96,6 @@
     /* Some storage reserved for the OEM's driver. */
     intptr_t    oem[4];
         
-    /*
-     * hook called by EGL when the native surface is made current 
-     * (eglMakeCurrent()). This hook can be NULL.
-     */
-    void    (*connect)(struct android_native_window_t* window);
-
-    /*
-     * hook called by EGL when the native surface in not current any-longer.
-     * This hook can be NULL.
-     */
-    void    (*disconnect)(struct android_native_window_t* window);
-
 
     /*
      * Set the swap interval for this surface.
@@ -117,20 +105,10 @@
     int     (*setSwapInterval)(struct android_native_window_t* window,
                 int interval);
     
-
-    /*
-     * FIXME: needs documentation for setSwapRectangle
-     * tentative: rect used during queueBuffer to indicate which part of
-     * the screen needs updating.
-     */
-    int     (*setSwapRectangle)(struct android_native_window_t* window,
-            int left, int top, int width, int height);
-    
-    
     /*
      * hook called by EGL to acquire a buffer. After this call, the buffer
      * is not locked, so its content cannot be modified.
-     * this call may block if no buffers are availlable.
+     * this call may block if no buffers are available.
      * 
      * Returns 0 on success or -errno on error.
      */
@@ -179,7 +157,7 @@
     int stride;
     int format;
     int usage;
-    void* bits;     // non-zero if buffer is mmaped
+    void* bits;     // non-zero if buffer is locked for sw usage
 
     void* reserved[2];
 
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
index f927de9..9eb99f0 100644
--- a/opengl/libagl/TextureObjectManager.cpp
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -23,7 +23,7 @@
 // ----------------------------------------------------------------------------
 
 EGLTextureObject::EGLTextureObject()
-    : mCount(0), mSize(0)
+    : mSize(0)
 {
     init();
 }
@@ -56,6 +56,7 @@
 #ifdef LIBAGL_USE_GRALLOC_COPYBITS
     copybits_fd = -1;
 #endif // LIBAGL_USE_GRALLOC_COPYBITS
+    buffer = 0;
 }
 
 void EGLTextureObject::copyParameters(const sp<EGLTextureObject>& old)
@@ -126,6 +127,7 @@
     }
     surface = *s;
     internalformat = 0;
+    buffer = 0;
 
     // we should keep the crop_rect, but it's delicate because
     // the new size of the surface could make it invalid.
@@ -144,6 +146,20 @@
     return NO_ERROR;
 }
 
+status_t EGLTextureObject::setImage(android_native_buffer_t* native_buffer)
+{
+    GGLSurface sur;
+    sur.version = sizeof(GGLSurface);
+    sur.width = native_buffer->width;
+    sur.height= native_buffer->height;
+    sur.stride= native_buffer->stride;
+    sur.format= native_buffer->format;
+    sur.data  = 0;
+    setSurface(&sur);
+    buffer = native_buffer;
+    return NO_ERROR;
+}
+
 status_t EGLTextureObject::reallocate(
         GLint level, int w, int h, int s,
         int format, int compressedFormat, int bpr)
@@ -227,7 +243,7 @@
 // ----------------------------------------------------------------------------
 
 EGLSurfaceManager::EGLSurfaceManager()
-    : TokenManager(), mCount(0)
+    : TokenManager()
 {
 }
 
diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h
index 497528c..29d5037 100644
--- a/opengl/libagl/TextureObjectManager.h
+++ b/opengl/libagl/TextureObjectManager.h
@@ -30,6 +30,7 @@
 #include <private/pixelflinger/ggl_context.h>
 
 #include <GLES/gl.h>
+#include <EGL/android_natives.h>
 
 #include "Tokenizer.h"
 #include "TokenManager.h"
@@ -39,22 +40,20 @@
 
 // ----------------------------------------------------------------------------
 
-class EGLTextureObject
+class EGLTextureObject : public LightRefBase<EGLTextureObject>
 {
 public:
                     EGLTextureObject();
                    ~EGLTextureObject();
 
-    // protocol for sp<>
-    inline  void        incStrong(const void* id) const;
-    inline  void        decStrong(const void* id) const;
-    inline  uint32_t    getStrongCount() const;
+    status_t    setSurface(GGLSurface const* s);
+    status_t    setImage(android_native_buffer_t* buffer);
+    void        setImageBits(void* vaddr) { surface.data = (GGLubyte*)vaddr; }
 
-    status_t            setSurface(GGLSurface const* s);
     status_t            reallocate(GLint level,
                             int w, int h, int s,
                             int format, int compressedFormat, int bpr);
-    inline  size_t      size() const;
+    inline  size_t      size() const { return mSize; }
     const GGLSurface&   mip(int lod) const;
     GGLSurface&         editMip(int lod);
     bool                hasMipmaps() const { return mMipmaps!=0; }
@@ -65,7 +64,6 @@
         status_t        allocateMipmaps();
             void        freeMipmaps();
             void        init();
-    mutable int32_t     mCount;
     size_t              mSize;
     GGLSurface          *mMipmaps;
     int                 mNumExtraLod;
@@ -84,36 +82,19 @@
 #ifdef LIBAGL_USE_GRALLOC_COPYBITS
     int                 copybits_fd;
 #endif // LIBAGL_USE_GRALLOC_COPYBITS
+    android_native_buffer_t* buffer;
 };
 
-void EGLTextureObject::incStrong(const void* id) const {
-    android_atomic_inc(&mCount);
-}
-void EGLTextureObject::decStrong(const void* id) const {
-    if (android_atomic_dec(&mCount) == 1) {
-        delete this;
-    }
-}
-uint32_t EGLTextureObject::getStrongCount() const {
-    return mCount;
-}
-size_t EGLTextureObject::size() const {
-    return mSize;
-}
-
 // ----------------------------------------------------------------------------
 
-class EGLSurfaceManager : public TokenManager
+class EGLSurfaceManager :
+    public LightRefBase<EGLSurfaceManager>,
+    public TokenManager
 {
 public:
                 EGLSurfaceManager();
                 ~EGLSurfaceManager();
 
-    // protocol for sp<>
-    inline  void    incStrong(const void* id) const;
-    inline  void    decStrong(const void* id) const;
-    typedef void    weakref_type;
-
     sp<EGLTextureObject>    createTexture(GLuint name);
     sp<EGLTextureObject>    removeTexture(GLuint name);
     sp<EGLTextureObject>    replaceTexture(GLuint name);
@@ -121,21 +102,10 @@
     sp<EGLTextureObject>    texture(GLuint name);
 
 private:
-    mutable int32_t                             mCount;
     mutable Mutex                               mLock;
     KeyedVector< GLuint, sp<EGLTextureObject> > mTextures;
 };
 
-void EGLSurfaceManager::incStrong(const void* id) const {
-    android_atomic_inc(&mCount);
-}
-void EGLSurfaceManager::decStrong(const void* id) const {
-    if (android_atomic_dec(&mCount) == 1) {
-        delete this;
-    }
-}
-
-
 // ----------------------------------------------------------------------------
 }; // namespace android
 
diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp
index eefe614..6d2cc91 100644
--- a/opengl/libagl/array.cpp
+++ b/opengl/libagl/array.cpp
@@ -1371,9 +1371,18 @@
     if ((c->cull.enable) && (c->cull.cullFace == GL_FRONT_AND_BACK))
         return; // all triangles are culled
 
+
     validate_arrays(c, mode);
+
+    const uint32_t enables = c->rasterizer.state.enables;
+    if (enables & GGL_ENABLE_TMUS)
+        ogles_lock_textures(c);
+
     drawArraysPrims[mode](c, first, count);
 
+    if (enables & GGL_ENABLE_TMUS)
+        ogles_unlock_textures(c);
+
 #if VC_CACHE_STATISTICS
     c->vc.total = count;
     c->vc.dump_stats(mode);
@@ -1425,8 +1434,16 @@
         indices = c->arrays.element_array_buffer->data + uintptr_t(indices);
     }
 
-    drawElementsPrims[mode](c, count, indices);
+    const uint32_t enables = c->rasterizer.state.enables;
+    if (enables & GGL_ENABLE_TMUS)
+        ogles_lock_textures(c);
 
+    drawElementsPrims[mode](c, count, indices);
+    
+    if (enables & GGL_ENABLE_TMUS)
+        ogles_unlock_textures(c);
+
+    
 #if VC_CACHE_STATISTICS
     c->vc.total = count;
     c->vc.dump_stats(mode);
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 9384e18da..04ca431 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -212,8 +212,11 @@
     virtual     EGLint      getRefreshRate() const;
     virtual     EGLint      getSwapBehavior() const;
 private:
+    status_t lock(android_native_buffer_t* buf, int usage);
+    status_t unlock(android_native_buffer_t* buf);
     android_native_window_t*   nativeWindow;
     android_native_buffer_t*   buffer;
+    gralloc_module_t const*    module;
     int width;
     int height;
 };
@@ -222,8 +225,13 @@
         EGLConfig config,
         int32_t depthFormat,
         android_native_window_t* window)
-    : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0)
+    : egl_surface_t(dpy, config, depthFormat), 
+    nativeWindow(window), buffer(0), module(0)
 {
+    hw_module_t const* pModule;
+    hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule);
+    module = reinterpret_cast<gralloc_module_t const*>(pModule);
+
     nativeWindow->common.incRef(&nativeWindow->common);
 
     nativeWindow->dequeueBuffer(nativeWindow, &buffer);
@@ -246,13 +254,44 @@
     buffer->common.incRef(&buffer->common);
     nativeWindow->lockBuffer(nativeWindow, buffer);
 
-    // FIXME: we need to gralloc lock the buffer
+    // Lock the buffer
+    lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
+    
     // FIXME: we need to handle the copy-back if needed, but
     // for now we're a "non preserving" implementation.
 }
 
+status_t egl_window_surface_v2_t::lock(
+        android_native_buffer_t* buf, int usage)
+{
+    int err;
+    buffer_handle_t bufferHandle;
+    err = buf->getHandle(buf, &bufferHandle);
+    if (err < 0)
+        return err;
+
+    err = module->lock(module, bufferHandle, 
+            usage, 0, 0, buf->width, buf->height, &buf->bits);
+    return err;
+}
+
+status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf)
+{
+    int err;
+    buffer_handle_t bufferHandle;
+    err = buf->getHandle(buf, &bufferHandle);
+    if (err < 0)
+        return err;
+
+    err = module->unlock(module, bufferHandle);
+    buf->bits = NULL;
+    return err;
+}
+
+
 egl_window_surface_v2_t::~egl_window_surface_v2_t() {
     if (buffer) {
+        unlock(buffer);
         buffer->common.decRef(&buffer->common);
     }
     nativeWindow->common.decRef(&nativeWindow->common);
@@ -269,6 +308,7 @@
     //mDisplaySurface->copyFrontToBack(copyback);
 
     
+    unlock(buffer);
     nativeWindow->queueBuffer(nativeWindow, buffer);
     buffer->common.decRef(&buffer->common); buffer = 0;
 
@@ -278,6 +318,7 @@
     // TODO: lockBuffer should rather be executed when the very first
     // direct rendering occurs.
     nativeWindow->lockBuffer(nativeWindow, buffer);
+    lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
 
     
     if ((width != buffer->width) || (height != buffer->height)) {
@@ -1690,20 +1731,6 @@
 
     if (native_buffer->common.version != sizeof(android_native_buffer_t))
         return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-
-    hw_module_t const* pModule;
-    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
-        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-    buffer_handle_t bufferHandle;
-    gralloc_module_t const* module =
-        reinterpret_cast<gralloc_module_t const*>(pModule);
-    if (native_buffer->getHandle(native_buffer, &bufferHandle) < 0)
-        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-    int err = module->map(module, bufferHandle, &native_buffer->bits);
-    if (err < 0) {
-        LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
-        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-    }
     
     native_buffer->common.incRef(&native_buffer->common);
     return (EGLImageKHR)native_buffer;
@@ -1723,18 +1750,6 @@
     if (native_buffer->common.version != sizeof(android_native_buffer_t))
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
 
-    hw_module_t const* pModule;
-    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule) == 0) {
-        buffer_handle_t bufferHandle;
-        gralloc_module_t const* module =
-            reinterpret_cast<gralloc_module_t const*>(pModule);
-        int err = native_buffer->getHandle(native_buffer, &bufferHandle);
-        if (err == 0) {
-            int err = module->unmap(module, bufferHandle);
-            LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err));
-        }
-    }
-
     native_buffer->common.decRef(&native_buffer->common);
 
     return EGL_TRUE;
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 9dca133..f2d8da3 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -103,7 +103,7 @@
     }
 }
 
-void ogles_validate_texture_impl(ogles_context_t* c)
+void ogles_validate_texture(ogles_context_t* c)
 {
     for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
         if (c->rasterizer.state.texture[i].enable)
@@ -117,6 +117,67 @@
     c->textures.tmu[tmu].dirty = flags;
 }
 
+/*
+ * If the active textures are EGLImage, they need to be locked before
+ * they can be used. 
+ * 
+ * FIXME: code below is far from being optimal
+ * 
+ */
+
+void ogles_lock_textures(ogles_context_t* c)
+{
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (c->rasterizer.state.texture[i].enable) {
+            texture_unit_t& u(c->textures.tmu[i]);
+            android_native_buffer_t* native_buffer = u.texture->buffer;
+            if (native_buffer) {
+                c->rasterizer.procs.activeTexture(c, i);
+                hw_module_t const* pModule;
+                if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
+                    continue;
+
+                gralloc_module_t const* module =
+                    reinterpret_cast<gralloc_module_t const*>(pModule);
+                buffer_handle_t bufferHandle;
+                native_buffer->getHandle(native_buffer, &bufferHandle);
+                int err = module->lock(module, bufferHandle,
+                        GRALLOC_USAGE_SW_READ_OFTEN,
+                        0, 0, native_buffer->width, native_buffer->height,
+                        &native_buffer->bits);
+
+                u.texture->setImageBits(native_buffer->bits);
+                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
+            }
+        }
+    }
+}
+
+void ogles_unlock_textures(ogles_context_t* c)
+{
+    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
+        if (c->rasterizer.state.texture[i].enable) {
+            texture_unit_t& u(c->textures.tmu[i]);
+            android_native_buffer_t* native_buffer = u.texture->buffer;
+            if (native_buffer) {
+                c->rasterizer.procs.activeTexture(c, i);
+                hw_module_t const* pModule;
+                if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
+                    continue;
+
+                gralloc_module_t const* module =
+                    reinterpret_cast<gralloc_module_t const*>(pModule);
+                buffer_handle_t bufferHandle;
+                native_buffer->getHandle(native_buffer, &bufferHandle);
+                module->unlock(module, bufferHandle);
+                u.texture->setImageBits(NULL);
+                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
+            }
+        }
+    }
+    c->rasterizer.procs.activeTexture(c, c->textures.active);
+}
+
 // ----------------------------------------------------------------------------
 #if 0
 #pragma mark -
@@ -592,6 +653,8 @@
 static void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
         ogles_context_t* c)
 {
+    ogles_lock_textures(c);
+    
     const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
     y = gglIntToFixed(cbSurface.height) - (y + h);
     w >>= FIXED_BITS;
@@ -650,6 +713,8 @@
             gglFixedToIntRound(y),
             gglFixedToIntRound(x)+w,
             gglFixedToIntRound(y)+h);
+
+    ogles_unlock_textures(c);
 }
 
 static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
@@ -724,6 +789,8 @@
                 goto slow_case;
             }
 
+            ogles_lock_textures(c);
+
             c->rasterizer.procs.texCoord2i(c, s0, t0);
             const uint32_t enables = c->rasterizer.state.enables;
             if (ggl_unlikely(enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)))
@@ -734,6 +801,9 @@
             c->rasterizer.procs.disable(c, GGL_AA);
             c->rasterizer.procs.shadeModel(c, GL_FLAT);
             c->rasterizer.procs.recti(c, x, y, x+w, y+h);
+            
+            ogles_unlock_textures(c);
+
             return;
         }
     }
@@ -1460,23 +1530,9 @@
         return;
     }
 
-    if (native_buffer->bits == NULL) {
-        // this buffer cannot be used with this implementation
-        ogles_error(c, GL_INVALID_VALUE);
-        return;
-    }
-
-    GGLSurface sur;
-    sur.version = sizeof(GGLSurface);
-    sur.width = native_buffer->width;
-    sur.height= native_buffer->height;
-    sur.stride= native_buffer->stride;
-    sur.format= native_buffer->format;
-    sur.data  = (GGLubyte*)native_buffer->bits;
-
     // bind it to the texture unit
     sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
-    tex->setSurface(&sur);
+    tex->setImage(native_buffer);
 
     /*
      * Here an implementation can retrieve the buffer_handle_t of this buffer
diff --git a/opengl/libagl/texture.h b/opengl/libagl/texture.h
index 5c57948..98f7550 100644
--- a/opengl/libagl/texture.h
+++ b/opengl/libagl/texture.h
@@ -32,13 +32,9 @@
 
 void ogles_init_texture(ogles_context_t* c);
 void ogles_uninit_texture(ogles_context_t* c);
-void ogles_validate_texture_impl(ogles_context_t* c);
-
-inline void ogles_validate_texture(ogles_context_t* c) {
-    if (c->rasterizer.state.enables & GGL_ENABLE_TMUS)
-        ogles_validate_texture_impl(c);
-}
-
+void ogles_validate_texture(ogles_context_t* c);
+void ogles_lock_textures(ogles_context_t* c);
+void ogles_unlock_textures(ogles_context_t* c);
 
 }; // namespace android
 
diff --git a/opengl/tests/copybits/Android.mk b/opengl/tests/copybits/Android.mk
index d5ded42..2876a1e 100644
--- a/opengl/tests/copybits/Android.mk
+++ b/opengl/tests/copybits/Android.mk
@@ -14,5 +14,5 @@
 
 LOCAL_MODULE_TAGS := tests
 
-include $(BUILD_EXECUTABLE)
+##include $(BUILD_EXECUTABLE)