am ea5c0444: When apps switch between system and data partition the code and resource paths should also be updated based on which version is being picked up. update the code and resource paths when a path change is detected

Merge commit 'ea5c044412f6853d686e93b8bef07f4729b6ad26'

* commit 'ea5c044412f6853d686e93b8bef07f4729b6ad26':
  When apps switch between system and data partition the code and
diff --git a/camera/libcameraservice/Android.mk b/camera/libcameraservice/Android.mk
index 96cc512..be78a62 100644
--- a/camera/libcameraservice/Android.mk
+++ b/camera/libcameraservice/Android.mk
@@ -42,6 +42,7 @@
 LOCAL_SHARED_LIBRARIES:= \
     libui \
     libutils \
+    libbinder \
     libcutils \
     libmedia
 
diff --git a/camera/libcameraservice/CameraHardwareStub.h b/camera/libcameraservice/CameraHardwareStub.h
index 0d26d47..efae935 100644
--- a/camera/libcameraservice/CameraHardwareStub.h
+++ b/camera/libcameraservice/CameraHardwareStub.h
@@ -21,8 +21,8 @@
 #include "FakeCamera.h"
 #include <utils/threads.h>
 #include <ui/CameraHardwareInterface.h>
-#include <utils/MemoryBase.h>
-#include <utils/MemoryHeapBase.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
 #include <utils/threads.h>
 
 namespace android {
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index e4b6791..96389dd 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -20,12 +20,12 @@
 #define LOG_TAG "CameraService"
 #include <utils/Log.h>
 
-#include <utils/IServiceManager.h>
-#include <utils/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
 #include <utils/String16.h>
 #include <utils/Errors.h>
-#include <utils/MemoryBase.h>
-#include <utils/MemoryHeapBase.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
 #include <ui/ICameraService.h>
 
 #include <media/mediaplayer.h>
@@ -1160,12 +1160,6 @@
 }
 
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t CameraService::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/cmds/runtime/Android.mk b/cmds/runtime/Android.mk
index 521eb2b..6a72d10 100644
--- a/cmds/runtime/Android.mk
+++ b/cmds/runtime/Android.mk
@@ -10,6 +10,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libutils \
+	libbinder \
 	libandroid_runtime \
 	libcutils \
 	libui \
diff --git a/cmds/runtime/ServiceManager.cpp b/cmds/runtime/ServiceManager.cpp
index 758a95c..b2bef07 100644
--- a/cmds/runtime/ServiceManager.cpp
+++ b/cmds/runtime/ServiceManager.cpp
@@ -9,9 +9,9 @@
 
 #include <utils/Debug.h>
 #include <utils/Log.h>
-#include <utils/Parcel.h>
+#include <binder/Parcel.h>
 #include <utils/String8.h>
-#include <utils/ProcessState.h>
+#include <binder/ProcessState.h>
 
 #include <private/utils/Static.h>
 
diff --git a/cmds/runtime/ServiceManager.h b/cmds/runtime/ServiceManager.h
index d09cec8..090ca6d 100644
--- a/cmds/runtime/ServiceManager.h
+++ b/cmds/runtime/ServiceManager.h
@@ -4,7 +4,7 @@
 #ifndef ANDROID_SERVICE_MANAGER_H
 #define ANDROID_SERVICE_MANAGER_H
 
-#include <utils/IServiceManager.h>
+#include <binder/IServiceManager.h>
 #include <utils/KeyedVector.h>
 #include <utils/threads.h>
 
diff --git a/cmds/runtime/main_runtime.cpp b/cmds/runtime/main_runtime.cpp
index 476f38a..21e0e4d 100644
--- a/cmds/runtime/main_runtime.cpp
+++ b/cmds/runtime/main_runtime.cpp
@@ -7,9 +7,11 @@
 #include "ServiceManager.h"
 #include "SignalHandler.h"
 
-#include <utils.h>
-#include <utils/IPCThreadState.h>
-#include <utils/ProcessState.h>
+#include <utils/threads.h>
+#include <utils/Errors.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
 #include <utils/Log.h>  
 #include <cutils/zygote.h>
 
diff --git a/cmds/surfaceflinger/Android.mk b/cmds/surfaceflinger/Android.mk
index 37c3d94..bfa58a1 100644
--- a/cmds/surfaceflinger/Android.mk
+++ b/cmds/surfaceflinger/Android.mk
@@ -6,6 +6,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libsurfaceflinger \
+	libbinder \
 	libutils
 
 LOCAL_C_INCLUDES := \
diff --git a/cmds/surfaceflinger/main_surfaceflinger.cpp b/cmds/surfaceflinger/main_surfaceflinger.cpp
index 7c89578..d650721 100644
--- a/cmds/surfaceflinger/main_surfaceflinger.cpp
+++ b/cmds/surfaceflinger/main_surfaceflinger.cpp
@@ -1,6 +1,6 @@
-#include <utils/IPCThreadState.h>
-#include <utils/ProcessState.h>
-#include <utils/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
 #include <utils/Log.h>
 
 #include <SurfaceFlinger.h>
diff --git a/include/utils/Binder.h b/include/binder/Binder.h
similarity index 96%
rename from include/utils/Binder.h
rename to include/binder/Binder.h
index b5b8d98..47b2bb9 100644
--- a/include/utils/Binder.h
+++ b/include/binder/Binder.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_BINDER_H
 #define ANDROID_BINDER_H
 
-#include <utils/IBinder.h>
+#include <binder/IBinder.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -27,7 +27,7 @@
 public:
                         BBinder();
 
-    virtual String16    getInterfaceDescriptor() const;
+    virtual const String16& getInterfaceDescriptor() const;
     virtual bool        isBinderAlive() const;
     virtual status_t    pingBinder();
     virtual status_t    dump(int fd, const Vector<String16>& args);
@@ -71,6 +71,7 @@
 
             Extras*     mExtras;
             void*       mReserved0;
+    static  String16    sEmptyDescriptor;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/include/utils/BpBinder.h b/include/binder/BpBinder.h
similarity index 94%
rename from include/utils/BpBinder.h
rename to include/binder/BpBinder.h
index 7b96e29..7ef93aa 100644
--- a/include/utils/BpBinder.h
+++ b/include/binder/BpBinder.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_BPBINDER_H
 #define ANDROID_BPBINDER_H
 
-#include <utils/IBinder.h>
+#include <binder/IBinder.h>
 #include <utils/KeyedVector.h>
 #include <utils/threads.h>
 
@@ -31,7 +31,7 @@
 
     inline  int32_t     handle() const { return mHandle; }
 
-    virtual String16    getInterfaceDescriptor() const;
+    virtual const String16&    getInterfaceDescriptor() const;
     virtual bool        isBinderAlive() const;
     virtual status_t    pingBinder();
     virtual status_t    dump(int fd, const Vector<String16>& args);
@@ -106,6 +106,7 @@
     };
 
             void                reportOneDeath(const Obituary& obit);
+            bool                isDescriptorCached() const;
 
     mutable Mutex               mLock;
             volatile int32_t    mAlive;
@@ -113,6 +114,7 @@
             Vector<Obituary>*   mObituaries;
             ObjectManager       mObjects;
             Parcel*             mConstantData;
+    mutable String16            mDescriptorCache;
 };
 
 }; // namespace android
diff --git a/include/utils/IBinder.h b/include/binder/IBinder.h
similarity index 97%
rename from include/utils/IBinder.h
rename to include/binder/IBinder.h
index 7370330..884b5c1 100644
--- a/include/utils/IBinder.h
+++ b/include/binder/IBinder.h
@@ -56,7 +56,7 @@
         FLAG_ONEWAY             = 0x00000001
     };
 
-    inline                  IBinder() { }
+                          IBinder();
 
     /**
      * Check if this IBinder implements the interface named by
@@ -69,7 +69,7 @@
      * Return the canonical name of the interface provided by this IBinder
      * object.
      */
-    virtual String16        getInterfaceDescriptor() const = 0;
+    virtual const String16& getInterfaceDescriptor() const = 0;
 
     virtual bool            isBinderAlive() const = 0;
     virtual status_t        pingBinder() = 0;
@@ -147,7 +147,7 @@
     virtual BpBinder*       remoteBinder();
 
 protected:
-    inline virtual          ~IBinder() { }
+    virtual          ~IBinder();
 
 private:
 };
diff --git a/include/utils/IInterface.h b/include/binder/IInterface.h
similarity index 82%
rename from include/utils/IInterface.h
rename to include/binder/IInterface.h
index 959722a..273d922 100644
--- a/include/utils/IInterface.h
+++ b/include/binder/IInterface.h
@@ -18,7 +18,7 @@
 #ifndef ANDROID_IINTERFACE_H
 #define ANDROID_IINTERFACE_H
 
-#include <utils/Binder.h>
+#include <binder/Binder.h>
 
 namespace android {
 
@@ -27,10 +27,12 @@
 class IInterface : public virtual RefBase
 {
 public:
+            IInterface();
             sp<IBinder>         asBinder();
             sp<const IBinder>   asBinder() const;
-
+            
 protected:
+    virtual                     ~IInterface();
     virtual IBinder*            onAsBinder() = 0;
 };
 
@@ -49,7 +51,7 @@
 {
 public:
     virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
-    virtual String16            getInterfaceDescriptor() const;
+    virtual const String16&     getInterfaceDescriptor() const;
 
 protected:
     virtual IBinder*            onAsBinder();
@@ -72,11 +74,14 @@
 #define DECLARE_META_INTERFACE(INTERFACE)                               \
     static const String16 descriptor;                                   \
     static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj);        \
-    virtual String16 getInterfaceDescriptor() const;                    \
+    virtual const String16& getInterfaceDescriptor() const;             \
+    I##INTERFACE();                                                     \
+    virtual ~I##INTERFACE();                                            \
+
 
 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
     const String16 I##INTERFACE::descriptor(NAME);                      \
-    String16 I##INTERFACE::getInterfaceDescriptor() const {             \
+    const String16& I##INTERFACE::getInterfaceDescriptor() const {      \
         return I##INTERFACE::descriptor;                                \
     }                                                                   \
     sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)  \
@@ -92,9 +97,16 @@
         }                                                               \
         return intr;                                                    \
     }                                                                   \
+    I##INTERFACE::I##INTERFACE() { }                                    \
+    I##INTERFACE::~I##INTERFACE() { }                                   \
+
+
+#define CHECK_INTERFACE(interface, data, reply)                         \
+    if (!data.checkInterface(this)) { return PERMISSION_DENIED; }       \
+
 
 // ----------------------------------------------------------------------
-// No user-servicable parts after this...
+// No user-serviceable parts after this...
 
 template<typename INTERFACE>
 inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
@@ -105,7 +117,7 @@
 }
 
 template<typename INTERFACE>
-inline String16 BnInterface<INTERFACE>::getInterfaceDescriptor() const
+inline const String16& BnInterface<INTERFACE>::getInterfaceDescriptor() const
 {
     return INTERFACE::getInterfaceDescriptor();
 }
diff --git a/include/utils/IMemory.h b/include/binder/IMemory.h
similarity index 94%
rename from include/utils/IMemory.h
rename to include/binder/IMemory.h
index 35a3fd7..ae042cb 100644
--- a/include/utils/IMemory.h
+++ b/include/binder/IMemory.h
@@ -23,7 +23,7 @@
 
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
-#include <utils/IInterface.h>
+#include <binder/IInterface.h>
 
 namespace android {
 
@@ -59,6 +59,10 @@
             const Parcel& data,
             Parcel* reply,
             uint32_t flags = 0);
+    
+    BnMemoryHeap();
+protected:
+    virtual ~BnMemoryHeap();
 };
 
 // ----------------------------------------------------------------------------
@@ -85,6 +89,10 @@
             const Parcel& data,
             Parcel* reply,
             uint32_t flags = 0);
+
+    BnMemory();
+protected:
+    virtual ~BnMemory();
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/utils/IPCThreadState.h b/include/binder/IPCThreadState.h
similarity index 98%
rename from include/utils/IPCThreadState.h
rename to include/binder/IPCThreadState.h
index 0490fd3..78306b2 100644
--- a/include/utils/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -18,8 +18,8 @@
 #define ANDROID_IPC_THREAD_STATE_H
 
 #include <utils/Errors.h>
-#include <utils/Parcel.h>
-#include <utils/ProcessState.h>
+#include <binder/Parcel.h>
+#include <binder/ProcessState.h>
 #include <utils/Vector.h>
 
 #ifdef HAVE_WIN32_PROC
diff --git a/include/utils/IPermissionController.h b/include/binder/IPermissionController.h
similarity index 97%
rename from include/utils/IPermissionController.h
rename to include/binder/IPermissionController.h
index cb1dd34..f9d371b 100644
--- a/include/utils/IPermissionController.h
+++ b/include/binder/IPermissionController.h
@@ -18,7 +18,7 @@
 #ifndef ANDROID_IPERMISSION_CONTROLLER_H
 #define ANDROID_IPERMISSION_CONTROLLER_H
 
-#include <utils/IInterface.h>
+#include <binder/IInterface.h>
 
 namespace android {
 
diff --git a/include/utils/IServiceManager.h b/include/binder/IServiceManager.h
similarity index 94%
rename from include/utils/IServiceManager.h
rename to include/binder/IServiceManager.h
index e3d99fe..24e9e99 100644
--- a/include/utils/IServiceManager.h
+++ b/include/binder/IServiceManager.h
@@ -18,8 +18,8 @@
 #ifndef ANDROID_ISERVICE_MANAGER_H
 #define ANDROID_ISERVICE_MANAGER_H
 
-#include <utils/IInterface.h>
-#include <utils/IPermissionController.h>
+#include <binder/IInterface.h>
+#include <binder/IPermissionController.h>
 #include <utils/Vector.h>
 #include <utils/String16.h>
 
@@ -78,6 +78,8 @@
 bool checkCallingPermission(const String16& permission);
 bool checkCallingPermission(const String16& permission,
                             int32_t* outPid, int32_t* outUid);
+bool checkPermission(const String16& permission, pid_t pid, uid_t uid);
+
 
 // ----------------------------------------------------------------------
 
diff --git a/include/utils/MemoryBase.h b/include/binder/MemoryBase.h
similarity index 97%
rename from include/utils/MemoryBase.h
rename to include/binder/MemoryBase.h
index eb5a9d2..463e26d 100644
--- a/include/utils/MemoryBase.h
+++ b/include/binder/MemoryBase.h
@@ -20,7 +20,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 
-#include <utils/IMemory.h>
+#include <binder/IMemory.h>
 
 
 namespace android {
diff --git a/include/utils/MemoryDealer.h b/include/binder/MemoryDealer.h
similarity index 92%
rename from include/utils/MemoryDealer.h
rename to include/binder/MemoryDealer.h
index 454b627..6628f75 100644
--- a/include/utils/MemoryDealer.h
+++ b/include/binder/MemoryDealer.h
@@ -21,9 +21,9 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/IMemory.h>
+#include <binder/IMemory.h>
 #include <utils/threads.h>
-#include <utils/MemoryHeapBase.h>
+#include <binder/MemoryHeapBase.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -39,6 +39,10 @@
 public:
     // all values must be page-aligned
     virtual sp<IMemory> mapMemory(size_t offset, size_t size) = 0;
+
+    HeapInterface();
+protected:
+    virtual ~HeapInterface();
 };
 
 // ----------------------------------------------------------------------------
@@ -61,6 +65,10 @@
     virtual void        dump(const char* what, uint32_t flags = 0) const = 0;
     virtual void        dump(String8& res,
             const char* what, uint32_t flags = 0) const = 0;
+
+    AllocatorInterface();
+protected:
+    virtual ~AllocatorInterface();
 };
 
 // ----------------------------------------------------------------------------
@@ -71,6 +79,7 @@
 class SharedHeap : public HeapInterface, public MemoryHeapBase
 {
 public:
+                        SharedHeap();
                         SharedHeap(size_t size, uint32_t flags = 0, char const * name = NULL);
     virtual             ~SharedHeap();
     virtual sp<IMemory> mapMemory(size_t offset, size_t size);
@@ -117,13 +126,22 @@
             mFirst = mLast = newNode;
             newNode->prev = newNode->next = 0;
         } else {
-            insertBefore(mFirst, newNode);
+            newNode->prev = 0;
+            newNode->next = mFirst;
+            mFirst->prev = newNode;
+            mFirst = newNode;
         }
     }
     
     void insertTail(NODE* newNode) {
-        if (mLast == 0) insertBeginning(newNode);
-        else            insertAfter(mLast, newNode);
+        if (mLast == 0) {
+            insertHead(newNode);
+        } else {
+            newNode->prev = mLast;
+            newNode->next = 0;
+            mLast->next = newNode;
+            mLast = newNode;
+        }
     }
 
     NODE* remove(NODE* node) {
diff --git a/include/utils/MemoryHeapBase.h b/include/binder/MemoryHeapBase.h
similarity index 98%
rename from include/utils/MemoryHeapBase.h
rename to include/binder/MemoryHeapBase.h
index 574acf4..83c7283 100644
--- a/include/utils/MemoryHeapBase.h
+++ b/include/binder/MemoryHeapBase.h
@@ -20,7 +20,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 
-#include <utils/IMemory.h>
+#include <binder/IMemory.h>
 
 
 namespace android {
diff --git a/include/utils/MemoryHeapPmem.h b/include/binder/MemoryHeapPmem.h
similarity index 95%
rename from include/utils/MemoryHeapPmem.h
rename to include/binder/MemoryHeapPmem.h
index 60335ad..dbf26ff 100644
--- a/include/utils/MemoryHeapPmem.h
+++ b/include/binder/MemoryHeapPmem.h
@@ -20,9 +20,9 @@
 #include <stdlib.h>
 #include <stdint.h>
 
-#include <utils/MemoryDealer.h>
-#include <utils/MemoryHeapBase.h>
-#include <utils/IMemory.h>
+#include <binder/MemoryDealer.h>
+#include <binder/MemoryHeapBase.h>
+#include <binder/IMemory.h>
 #include <utils/SortedVector.h>
 
 namespace android {
diff --git a/include/utils/Parcel.h b/include/binder/Parcel.h
similarity index 98%
rename from include/utils/Parcel.h
rename to include/binder/Parcel.h
index af1490a..58c2d9a 100644
--- a/include/utils/Parcel.h
+++ b/include/binder/Parcel.h
@@ -57,7 +57,8 @@
 
     status_t            writeInterfaceToken(const String16& interface);
     bool                enforceInterface(const String16& interface) const;
-            
+    bool                checkInterface(IBinder*) const;    
+
     void                freeData();
 
     const size_t*       objects() const;
@@ -147,7 +148,7 @@
                                             release_func relFunc, void* relCookie);
     
     void                print(TextOutput& to, uint32_t flags = 0) const;
-    
+        
 private:
                         Parcel(const Parcel& o);
     Parcel&             operator=(const Parcel& o);
diff --git a/include/binder/Permission.h b/include/binder/Permission.h
new file mode 100644
index 0000000..9542d50
--- /dev/null
+++ b/include/binder/Permission.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BINDER_PERMISSION_H
+#define BINDER_PERMISSION_H
+
+#include <stdint.h>
+#include <unistd.h>
+
+#include <utils/SortedVector.h>
+#include <utils/String16.h>
+#include <utils/threads.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+/*
+ * Permission caches the result of the permission check for the given
+ * permission name and the provided uid/pid. It also handles a few
+ * known cases efficiently (caller is in the same process or is root).
+ * The package manager does something similar but lives in dalvik world
+ * and is therefore extremely slow to access.
+ */
+
+class Permission
+{
+public:
+            Permission(char const* name);
+            Permission(const String16& name);
+            Permission(const Permission& rhs);
+    virtual ~Permission();
+
+    bool operator < (const Permission& rhs) const;
+
+    // checks the current binder call's caller has access to this permission
+    bool checkCalling() const;
+    
+    // checks the specified pid/uid has access to this permission
+    bool check(pid_t pid, uid_t uid) const;
+    
+protected:
+    virtual bool doCheckPermission(pid_t pid, uid_t uid) const;
+
+private:
+    Permission& operator = (const Permission& rhs) const;
+    const String16 mPermissionName;
+    mutable SortedVector<uid_t> mGranted;
+    const pid_t mPid;
+    mutable Mutex mLock;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif /* BINDER_PERMISSION_H */
diff --git a/include/utils/ProcessState.h b/include/binder/ProcessState.h
similarity index 98%
rename from include/utils/ProcessState.h
rename to include/binder/ProcessState.h
index 39584f4..feeb3c3 100644
--- a/include/utils/ProcessState.h
+++ b/include/binder/ProcessState.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_PROCESS_STATE_H
 #define ANDROID_PROCESS_STATE_H
 
-#include <utils/IBinder.h>
+#include <binder/IBinder.h>
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
 #include <utils/String16.h>
diff --git a/include/private/binder/Static.h b/include/private/binder/Static.h
new file mode 100644
index 0000000..5b0f9fc
--- /dev/null
+++ b/include/private/binder/Static.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// All static variables go here, to control initialization and
+// destruction order in the library.
+
+#include <utils/threads.h>
+
+#include <binder/IBinder.h>
+#include <binder/IMemory.h>
+#include <binder/ProcessState.h>
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
+
+namespace android {
+
+// For ProcessState.cpp
+extern Mutex gProcessMutex;
+extern sp<ProcessState> gProcess;
+
+// For ServiceManager.cpp
+extern Mutex gDefaultServiceManagerLock;
+extern sp<IServiceManager> gDefaultServiceManager;
+extern sp<IPermissionController> gPermissionController;
+
+}   // namespace android
diff --git a/include/private/utils/binder_module.h b/include/private/binder/binder_module.h
similarity index 100%
rename from include/private/utils/binder_module.h
rename to include/private/binder/binder_module.h
diff --git a/include/private/opengles/gl_context.h b/include/private/opengles/gl_context.h
index a85f275..523aed0 100644
--- a/include/private/opengles/gl_context.h
+++ b/include/private/opengles/gl_context.h
@@ -26,6 +26,8 @@
 #endif
 
 #include <private/pixelflinger/ggl_context.h>
+#include <hardware/copybit.h>
+#include <hardware/gralloc.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
@@ -39,7 +41,7 @@
 class EGLBufferObjectManager;
 
 namespace gl {
- 
+
 struct ogles_context_t;
 struct matrixx_t;
 struct transform_t;
@@ -96,7 +98,7 @@
 
 struct vertex_t {
     enum {
-        // these constant matter for our clipping 
+        // these constant matter for our clipping
         CLIP_L          = 0x0001,   // clipping flags
         CLIP_R          = 0x0002,
         CLIP_B          = 0x0004,
@@ -106,7 +108,7 @@
 
         EYE             = 0x0040,
         RESERVED        = 0x0080,
-        
+
         USER_CLIP_0     = 0x0100,   // user clipping flags
         USER_CLIP_1     = 0x0200,
         USER_CLIP_2     = 0x0400,
@@ -121,7 +123,7 @@
         USER_CLIP_ALL   = 0x3F00,
         CLIP_ALL        = 0x3F3F,
     };
-    
+
     // the fields below are arranged to minimize d-cache usage
     // we group together, by cache-line, the fields most likely to be used
 
@@ -130,7 +132,7 @@
     vec4_t          eye;
     };
     vec4_t          clip;
-    
+
     uint32_t        flags;
     size_t          index;  // cache tag, and vertex index
     GLfixed         fog;
@@ -142,7 +144,7 @@
     vec4_t          color;
     vec4_t          texture[GGL_TEXTURE_UNIT_COUNT];
     uint32_t        reserved1[4];
-    
+
     inline void clear() {
         flags = index = locked = mru = 0;
     }
@@ -199,7 +201,7 @@
     GLenum          indicesType;
     buffer_t const* array_buffer;
     buffer_t const* element_array_buffer;
-    
+
     void (*compileElements)(ogles_context_t*, vertex_t*, GLint, GLsizei);
     void (*compileElement)(ogles_context_t*, vertex_t*, GLint);
 
@@ -410,7 +412,7 @@
     matrixx_t       matrix;
     uint32_t        flags;
     uint32_t        ops;
-    
+
     union {
         struct {
             void (*point2)(transform_t const* t, vec4_t*, vec4_t const*);
@@ -509,17 +511,17 @@
     GLint       x;
     GLint       y;
     GLsizei     w;
-    GLsizei     h; 
+    GLsizei     h;
     struct {
         GLint       x;
         GLint       y;
-    } surfaceport;  
+    } surfaceport;
     struct {
         GLint       x;
         GLint       y;
         GLsizei     w;
-        GLsizei     h; 
-    } scissor;  
+        GLsizei     h;
+    } scissor;
 };
 
 // ----------------------------------------------------------------------------
@@ -594,6 +596,14 @@
     void (*renderTriangle)(GL, vertex_t*, vertex_t*, vertex_t*);
 };
 
+struct copybits_context_t {
+    // A handle to the blit engine, if it exists, else NULL.
+    copybit_device_t*       blitEngine;
+    int32_t                 minScale;
+    int32_t                 maxScale;
+    buffer_handle_t         drawSurfaceBuffer;
+};
+
 struct ogles_context_t {
     context_t               rasterizer;
     array_machine_t         arrays         __attribute__((aligned(32)));
@@ -617,6 +627,14 @@
     uint32_t                transformTextures : 1;
     EGLSurfaceManager*      surfaceManager;
     EGLBufferObjectManager* bufferObjectManager;
+
+    // copybits is only used if LIBAGL_USE_GRALLOC_COPYBITS is
+    // defined, but it is always present because ogles_context_t is a public
+    // struct that is used by clients of libagl. We want the size and offsets
+    // to stay the same, whether or not LIBAGL_USE_GRALLOC_COPYBITS is defined.
+
+    copybits_context_t      copybits;
+
     GLenum                  error;
 
     static inline ogles_context_t* get() {
diff --git a/include/private/ui/RegionHelper.h b/include/private/ui/RegionHelper.h
new file mode 100644
index 0000000..926fddb
--- /dev/null
+++ b/include/private/ui/RegionHelper.h
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_PRIVATE_REGION_HELPER_H
+#define ANDROID_UI_PRIVATE_REGION_HELPER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+template<typename RECT>
+class region_operator
+{
+    typedef typename RECT::value_type TYPE;    
+    static const TYPE max_value = 0x7FFFFFF;
+
+public:
+    /* 
+     * Common boolean operations:
+     * value is computed as 0b101 op 0b110
+     *    other boolean operation are possible, simply compute
+     *    their corresponding value with the above formulae and use
+     *    it when instantiating a region_operator.
+     */
+    static const uint32_t LHS = 0x5;  // 0b101
+    static const uint32_t RHS = 0x6;  // 0b110
+    enum {
+        op_nand = LHS & ~RHS,
+        op_and  = LHS &  RHS,
+        op_or   = LHS |  RHS,
+        op_xor  = LHS ^  RHS
+    };
+
+    struct region {
+        RECT const* rects;
+        size_t count;
+        TYPE dx;
+        TYPE dy;
+        inline region(const region& rhs) 
+            : rects(rhs.rects), count(rhs.count), dx(rhs.dx), dy(rhs.dy) { }
+        inline region(RECT const* r, size_t c) 
+            : rects(r), count(c), dx(), dy() { }
+        inline region(RECT const* r, size_t c, TYPE dx, TYPE dy) 
+            : rects(r), count(c), dx(dx), dy(dy) { }
+    };
+
+    class region_rasterizer {
+        friend class region_operator;
+        virtual void operator()(const RECT& rect) = 0;
+    public:
+        virtual ~region_rasterizer() { };
+    };
+    
+    inline region_operator(int op, const region& lhs, const region& rhs) 
+        : op_mask(op), spanner(lhs, rhs) 
+    {
+    }
+
+    void operator()(region_rasterizer& rasterizer) {
+        RECT current;
+        do {
+            SpannerInner spannerInner(spanner.lhs, spanner.rhs);
+            int inside = spanner.next(current.top, current.bottom);
+            spannerInner.prepare(inside);
+            do {
+                TYPE left, right;
+                int inside = spannerInner.next(current.left, current.right);
+                if ((op_mask >> inside) & 1) {
+                    if (current.left < current.right && 
+                            current.top < current.bottom) {
+                        rasterizer(current);
+                    }
+                }
+            } while(!spannerInner.isDone());            
+        } while(!spanner.isDone());
+    }
+
+private:    
+    uint32_t op_mask;
+
+    class SpannerBase
+    {
+    public:
+        enum {
+            lhs_before_rhs   = 0,
+            lhs_after_rhs    = 1,
+            lhs_coincide_rhs = 2
+        };
+
+    protected:
+        TYPE lhs_head;
+        TYPE lhs_tail;
+        TYPE rhs_head;
+        TYPE rhs_tail;
+
+        inline int next(TYPE& head, TYPE& tail,
+                bool& more_lhs, bool& more_rhs) 
+        {
+            int inside;
+            more_lhs = false;
+            more_rhs = false;
+            if (lhs_head < rhs_head) {
+                inside = lhs_before_rhs;
+                head = lhs_head;
+                if (lhs_tail <= rhs_head) {
+                    tail = lhs_tail;
+                    more_lhs = true;
+                } else {
+                    lhs_head = rhs_head;
+                    tail = rhs_head;
+                }
+            } else if (rhs_head < lhs_head) {
+                inside = lhs_after_rhs;
+                head = rhs_head;
+                if (rhs_tail <= lhs_head) {
+                    tail = rhs_tail;
+                    more_rhs = true;
+                } else {
+                    rhs_head = lhs_head;
+                    tail = lhs_head;
+                }
+            } else {
+                inside = lhs_coincide_rhs;
+                head = lhs_head;
+                if (lhs_tail <= rhs_tail) {
+                    tail = rhs_head = lhs_tail;
+                    more_lhs = true;
+                }
+                if (rhs_tail <= lhs_tail) {
+                    tail = lhs_head = rhs_tail;
+                    more_rhs = true;
+                }
+            }
+            return inside;
+        }
+    };
+
+    class Spanner : protected SpannerBase 
+    {
+        friend class region_operator;
+        region lhs;
+        region rhs;
+
+    public:
+        inline Spanner(const region& lhs, const region& rhs)
+            : lhs(lhs), rhs(rhs) 
+        {
+            SpannerBase::lhs_head = lhs.rects->top      + lhs.dy;
+            SpannerBase::lhs_tail = lhs.rects->bottom   + lhs.dy;
+            SpannerBase::rhs_head = rhs.rects->top      + rhs.dy;
+            SpannerBase::rhs_tail = rhs.rects->bottom   + rhs.dy;
+        }
+
+        inline bool isDone() const {
+            return !rhs.count && !lhs.count;
+        }
+
+        inline int next(TYPE& top, TYPE& bottom) 
+        {
+            bool more_lhs = false;
+            bool more_rhs = false;
+            int inside = SpannerBase::next(top, bottom, more_lhs, more_rhs);
+            if (more_lhs) {
+                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
+            }
+            if (more_rhs) {
+                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
+            }
+            return inside;
+        }
+
+    private:
+        static inline 
+        void advance(region& reg, TYPE& aTop, TYPE& aBottom) {
+            // got to next span
+            size_t count = reg.count;
+            RECT const * rects = reg.rects;
+            RECT const * const end = rects + count;
+            const int top = rects->top;
+            while (rects != end && rects->top == top) {
+                rects++;
+                count--;
+            }
+            if (rects != end) {
+                aTop    = rects->top    + reg.dy;
+                aBottom = rects->bottom + reg.dy;
+            } else {
+                aTop    = max_value;
+                aBottom = max_value;
+            }
+            reg.rects = rects;
+            reg.count = count;
+        }
+    };
+
+    class SpannerInner : protected SpannerBase 
+    {
+        region lhs;
+        region rhs;
+        
+    public:
+        inline SpannerInner(const region& lhs, const region& rhs)
+            : lhs(lhs), rhs(rhs) 
+        {
+        }
+
+        inline void prepare(int inside) {
+            SpannerBase::lhs_head = lhs.rects->left  + lhs.dx;
+            SpannerBase::lhs_tail = lhs.rects->right + lhs.dx;
+            SpannerBase::rhs_head = rhs.rects->left  + rhs.dx;
+            SpannerBase::rhs_tail = rhs.rects->right + rhs.dx;
+            if (inside == SpannerBase::lhs_before_rhs) {
+                SpannerBase::rhs_head = max_value;
+                SpannerBase::rhs_tail = max_value;
+            } else if (inside == SpannerBase::lhs_after_rhs) {
+                SpannerBase::lhs_head = max_value;
+                SpannerBase::lhs_tail = max_value;
+            } else {
+                // use both spans
+            }
+        }
+
+        inline bool isDone() const {
+            return SpannerBase::lhs_head == max_value && 
+                   SpannerBase::rhs_head == max_value;
+        }
+
+        inline int next(TYPE& left, TYPE& right) 
+        {
+            bool more_lhs = false;
+            bool more_rhs = false;
+            int inside = SpannerBase::next(left, right, more_lhs, more_rhs);
+            if (more_lhs) {
+                advance(lhs, SpannerBase::lhs_head, SpannerBase::lhs_tail);
+            }
+            if (more_rhs) {
+                advance(rhs, SpannerBase::rhs_head, SpannerBase::rhs_tail);
+            }
+            return inside;
+        }
+
+    private:
+        static inline 
+        void advance(region& reg, TYPE& left, TYPE& right) {
+            if (reg.rects && reg.count) {
+                const int cur_span_top = reg.rects->top;
+                reg.rects++;
+                reg.count--;
+                if (!reg.count || reg.rects->top != cur_span_top) {
+                    left  = max_value;
+                    right = max_value;
+                } else {
+                    left  = reg.rects->left  + reg.dx;
+                    right = reg.rects->right + reg.dx;
+                }
+            }
+        }
+    };
+
+    Spanner spanner;
+};
+
+// ----------------------------------------------------------------------------
+};
+
+#endif /* ANDROID_UI_PRIVATE_REGION_HELPER_H */
diff --git a/include/private/ui/SharedState.h b/include/private/ui/SharedState.h
index 546d0ad..3bc7979 100644
--- a/include/private/ui/SharedState.h
+++ b/include/private/ui/SharedState.h
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <utils/Debug.h>
 #include <utils/threads.h>
 
 namespace android {
@@ -32,16 +33,12 @@
 
 struct surface_info_t { // 4 longs, 16 bytes
     enum {
-        eBufferDirty    = 0x01
+        eBufferDirty    = 0x01,
+        eNeedNewBuffer  = 0x02
     };
-    uint16_t    w;
-    uint16_t    h;
-    uint16_t    stride;
-    uint16_t    bpr;
-    uint16_t    reserved;
-    uint8_t     format;
+    uint8_t     reserved[11];
     uint8_t     flags;
-    ssize_t     bits_offset;
+    status_t    status;
 };
 
 // ---------------------------------------------------------------------------
@@ -110,8 +107,6 @@
         INSPECT  = 0x00000002
     };
 
-    per_client_cblk_t();
-
     // these functions are used by the clients
     status_t validate(size_t i) const;
     int32_t lock_layer(size_t i, uint32_t flags);
@@ -138,30 +133,19 @@
 
 struct surface_flinger_cblk_t   // 4KB max
 {
-    surface_flinger_cblk_t();
-    
     uint8_t         connected;
     uint8_t         reserved[3];
     uint32_t        pad[7];
- 
     display_cblk_t  displays[NUM_DISPLAY_MAX];
 };
 
 // ---------------------------------------------------------------------------
 
-template<bool> struct CTA;
-template<> struct CTA<true> { };
+COMPILE_TIME_ASSERT(sizeof(layer_cblk_t) == 128)
+COMPILE_TIME_ASSERT(sizeof(per_client_cblk_t) <= 4096)
+COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
 
-// compile-time assertions. just to avoid catastrophes.
-inline void compile_time_asserts() {
-    CTA<sizeof(layer_cblk_t) == 128> sizeof__layer_cblk_t__eq_128;
-    (void)sizeof__layer_cblk_t__eq_128; // we don't want a warning
-    CTA<sizeof(per_client_cblk_t) <= 4096> sizeof__per_client_cblk_t__le_4096;
-    (void)sizeof__per_client_cblk_t__le_4096;  // we don't want a warning
-    CTA<sizeof(surface_flinger_cblk_t) <= 4096> sizeof__surface_flinger_cblk_t__le_4096;
-    (void)sizeof__surface_flinger_cblk_t__le_4096;  // we don't want a warning
-}
-
+// ---------------------------------------------------------------------------
 }; // namespace android
 
 #endif // ANDROID_UI_SHARED_STATE_H
diff --git a/include/private/ui/SurfaceBuffer.h b/include/private/ui/SurfaceBuffer.h
new file mode 100644
index 0000000..bf68406
--- /dev/null
+++ b/include/private/ui/SurfaceBuffer.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_PRIVATE_SURFACE_BUFFER_H
+#define ANDROID_UI_PRIVATE_SURFACE_BUFFER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/RefBase.h>
+
+#include <private/ui/android_natives_priv.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class BufferMapper;
+class Parcel;
+class Rect;
+class Surface;
+class SurfaceBuffer;
+
+// ---------------------------------------------------------------------------
+
+class SurfaceBuffer 
+    : public EGLNativeBase<
+        android_native_buffer_t, 
+        SurfaceBuffer, 
+        LightRefBase<SurfaceBuffer> >
+{
+public:
+    status_t lock(uint32_t usage, void** vaddr);
+    status_t lock(uint32_t usage, const Rect& rect, void** vaddr);
+    status_t unlock();
+
+protected:
+            SurfaceBuffer();
+            SurfaceBuffer(const Parcel& reply);
+    virtual ~SurfaceBuffer();
+    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>;    
+
+    SurfaceBuffer& operator = (const SurfaceBuffer& rhs);
+    const SurfaceBuffer& operator = (const SurfaceBuffer& rhs) const;
+
+    static status_t writeToParcel(Parcel* reply, 
+            android_native_buffer_t const* buffer);
+    
+    BufferMapper& mBufferMapper;
+};
+
+}; // namespace android
+
+#endif // ANDROID_UI_PRIVATE_SURFACE_BUFFER_H
+
diff --git a/include/private/ui/SurfaceFlingerSynchro.h b/include/private/ui/SurfaceFlingerSynchro.h
index ff91b61..7386d33 100644
--- a/include/private/ui/SurfaceFlingerSynchro.h
+++ b/include/private/ui/SurfaceFlingerSynchro.h
@@ -21,7 +21,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <utils/Errors.h>
-#include <utils/threads.h>
 #include <ui/ISurfaceComposer.h>
 
 namespace android {
@@ -31,7 +30,6 @@
 class SurfaceFlingerSynchro
 {
 public:
-
                 // client constructor
                 SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger);
                 ~SurfaceFlingerSynchro();
@@ -40,34 +38,8 @@
     status_t    signal();
     
 private:
-    class Barrier {
-    public:
-        Barrier();
-        ~Barrier();
-        void open();
-        void close();
-        void waitAndClose();
-        status_t waitAndClose(nsecs_t timeout);
-    private:
-        enum { OPENED, CLOSED };
-        mutable     Mutex       lock;
-        mutable     Condition   cv;
-        volatile    int         state;
-    };
-
     friend class SurfaceFlinger;
-
-                // server constructor
-                SurfaceFlingerSynchro();
-                
-    void        open();
-    
-                // wait until there is some work to do
-    status_t    wait();
-    status_t    wait(nsecs_t timeout);
-    
     sp<ISurfaceComposer> mSurfaceComposer;
-    Barrier              mBarrier;
 };
 
 }; // namespace android
diff --git a/include/private/ui/android_natives_priv.h b/include/private/ui/android_natives_priv.h
new file mode 100644
index 0000000..ee843e9
--- /dev/null
+++ b/include/private/ui/android_natives_priv.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_ANDROID_NATIVES_PRIV_H
+#define ANDROID_ANDROID_NATIVES_PRIV_H
+
+#include <ui/egl/android_natives.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************/
+
+struct android_native_buffer_t
+{
+#ifdef __cplusplus
+    android_native_buffer_t() { 
+        common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
+        common.version = sizeof(android_native_buffer_t);
+        memset(common.reserved, 0, sizeof(common.reserved));
+    }
+#endif
+
+    struct android_native_base_t common;
+
+    int width;
+    int height;
+    int stride;
+    int format;
+    int usage;
+    
+    void* reserved[2];
+
+    buffer_handle_t handle;
+
+    void* reserved_proc[8];
+};
+
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*****************************************************************************/
+
+#endif /* ANDROID_ANDROID_NATIVES_PRIV_H */
diff --git a/include/private/utils/Static.h b/include/private/utils/Static.h
index f1439b7..d95ae0d 100644
--- a/include/private/utils/Static.h
+++ b/include/private/utils/Static.h
@@ -20,14 +20,6 @@
 #include <utils/threads.h>
 #include <utils/KeyedVector.h>
 
-#ifndef LIBUTILS_NATIVE
-#include <utils/IBinder.h>
-#include <utils/IMemory.h>
-#include <utils/ProcessState.h>
-#include <utils/IPermissionController.h>
-#include <utils/IServiceManager.h>
-#endif
-
 namespace android {
 // For TextStream.cpp
 extern Vector<int32_t> gTextBuffers;
@@ -40,19 +32,4 @@
 extern void initialize_string16();
 extern void terminate_string16();
 
-
-
-#ifndef LIBUTILS_NATIVE
-
-// For ProcessState.cpp
-extern Mutex gProcessMutex;
-extern sp<ProcessState> gProcess;
-
-// For ServiceManager.cpp
-extern Mutex gDefaultServiceManagerLock;
-extern sp<IServiceManager> gDefaultServiceManager;
-extern sp<IPermissionController> gPermissionController;
-
-#endif
-
 }   // namespace android
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
index 21cb73b..ed084ca 100644
--- a/include/tts/TtsEngine.h
+++ b/include/tts/TtsEngine.h
@@ -80,6 +80,8 @@
 class TtsEngine
 {
 public:
+    virtual ~TtsEngine() {}
+
     // Initialize the TTS engine and returns whether initialization succeeded.
     // @param synthDoneCBPtr synthesis callback function pointer
     // @return TTS_SUCCESS, or TTS_FAILURE
diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h
new file mode 100644
index 0000000..5f084be
--- /dev/null
+++ b/include/ui/BufferMapper.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_BUFFER_MAPPER_H
+#define ANDROID_UI_BUFFER_MAPPER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Singleton.h>
+
+#include <hardware/gralloc.h>
+
+
+struct gralloc_module_t;
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class Rect;
+
+class BufferMapper : public Singleton<BufferMapper>
+{
+public:
+    static inline BufferMapper& get() { return getInstance(); }
+
+    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
+    void dump(buffer_handle_t handle);
+
+private:
+    friend class Singleton<BufferMapper>;
+    BufferMapper();
+    gralloc_module_t const *mAllocMod;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_UI_BUFFER_MAPPER_H
+
diff --git a/include/ui/CameraHardwareInterface.h b/include/ui/CameraHardwareInterface.h
index 822b4a8..c703f5e 100644
--- a/include/ui/CameraHardwareInterface.h
+++ b/include/ui/CameraHardwareInterface.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
 #define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
 
-#include <utils/IMemory.h>
+#include <binder/IMemory.h>
 #include <utils/RefBase.h>
 #include <ui/CameraParameters.h>
 #include <ui/Overlay.h>
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/EGLNativeWindowSurface.h
deleted file mode 100644
index 3494234..0000000
--- a/include/ui/EGLNativeWindowSurface.h
+++ /dev/null
@@ -1,59 +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_NATIVE_WINDOW_SURFACE_H
-#define ANDROID_EGL_NATIVE_WINDOW_SURFACE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <ui/EGLNativeSurface.h>
-#include <EGL/egl.h>
-
-// ---------------------------------------------------------------------------
-namespace android {
-// ---------------------------------------------------------------------------
-
-class Surface;
-
-class EGLNativeWindowSurface : public EGLNativeSurface<EGLNativeWindowSurface>
-{
-public:
-    EGLNativeWindowSurface(const sp<Surface>& surface);
-    ~EGLNativeWindowSurface();
-
-    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);
-    static void         hook_connect(NativeWindowType window);
-    static void         hook_disconnect(NativeWindowType window);
-
-            uint32_t    swapBuffers();
-            void        connect();
-            void        disconnect();
-            
-            sp<Surface> mSurface;
-            bool        mConnected;
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-// ---------------------------------------------------------------------------
-
-#endif // ANDROID_EGL_NATIVE_WINDOW_SURFACE_H
-
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 3848d8c..e12c4f1 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -20,7 +20,10 @@
 
 #include <utils/String8.h>
 #include <utils/threads.h>
-#include <utils.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <utils/List.h>
+#include <utils/Errors.h>
 
 #include <linux/input.h>
 
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
new file mode 100644
index 0000000..e72357a
--- /dev/null
+++ b/include/ui/FramebufferNativeWindow.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H
+#define ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <EGL/egl.h>
+
+#include <utils/threads.h>
+#include <ui/Rect.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include <ui/egl/android_natives.h>
+
+
+extern "C" EGLNativeWindowType android_createDisplaySurface(void);
+
+// ---------------------------------------------------------------------------
+namespace android {
+// ---------------------------------------------------------------------------
+
+class Surface;
+class NativeBuffer;
+
+// ---------------------------------------------------------------------------
+
+class FramebufferNativeWindow 
+    : public EGLNativeBase<
+        android_native_window_t, 
+        FramebufferNativeWindow, 
+        LightRefBase<FramebufferNativeWindow> >
+{
+public:
+    FramebufferNativeWindow(); 
+
+    framebuffer_device_t const * getDevice() const { return fbDev; } 
+
+    bool isUpdateOnDemand() const { return mUpdateOnDemand; }
+    status_t setUpdateRectangle(const Rect& updateRect);
+    
+private:
+    friend class LightRefBase<FramebufferNativeWindow>;    
+    ~FramebufferNativeWindow(); // this class cannot be overloaded
+    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);
+    static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
+    
+    framebuffer_device_t* fbDev;
+    alloc_device_t* grDev;
+
+    sp<NativeBuffer> buffers[2];
+    sp<NativeBuffer> front;
+    
+    mutable Mutex mutex;
+    Condition mCondition;
+    int32_t mNumBuffers;
+    int32_t mNumFreeBuffers;
+    int32_t mBufferHead;
+    bool mUpdateOnDemand;
+};
+    
+// ---------------------------------------------------------------------------
+}; // namespace android
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_FRAMEBUFFER_NATIVE_WINDOW_H
+
diff --git a/include/ui/ICamera.h b/include/ui/ICamera.h
index 241fb63..1df7914 100644
--- a/include/ui/ICamera.h
+++ b/include/ui/ICamera.h
@@ -18,10 +18,10 @@
 #define ANDROID_HARDWARE_ICAMERA_H
 
 #include <utils/RefBase.h>
-#include <utils/IInterface.h>
-#include <utils/Parcel.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
 #include <ui/ISurface.h>
-#include <utils/IMemory.h>
+#include <binder/IMemory.h>
 #include <utils/String8.h>
 #include <ui/Camera.h>
 
diff --git a/include/ui/ICameraClient.h b/include/ui/ICameraClient.h
index 1001c71..236d0f6 100644
--- a/include/ui/ICameraClient.h
+++ b/include/ui/ICameraClient.h
@@ -18,9 +18,9 @@
 #define ANDROID_HARDWARE_ICAMERA_APP_H
 
 #include <utils/RefBase.h>
-#include <utils/IInterface.h>
-#include <utils/Parcel.h>
-#include <utils/IMemory.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
 #include <utils/Timers.h>
 
 namespace android {
diff --git a/include/ui/ICameraService.h b/include/ui/ICameraService.h
index c652c51..061681a 100644
--- a/include/ui/ICameraService.h
+++ b/include/ui/ICameraService.h
@@ -18,8 +18,8 @@
 #define ANDROID_HARDWARE_ICAMERASERVICE_H
 
 #include <utils/RefBase.h>
-#include <utils/IInterface.h>
-#include <utils/Parcel.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
 
 #include <ui/ICameraClient.h>
 #include <ui/ICamera.h>
diff --git a/include/ui/IOverlay.h b/include/ui/IOverlay.h
index 699b1b0..af3add1 100644
--- a/include/ui/IOverlay.h
+++ b/include/ui/IOverlay.h
@@ -21,7 +21,7 @@
 #include <sys/types.h>
 
 #include <utils/Errors.h>
-#include <utils/IInterface.h>
+#include <binder/IInterface.h>
 #include <utils/RefBase.h>
 #include <ui/PixelFormat.h>
 
diff --git a/include/ui/ISurface.h b/include/ui/ISurface.h
index 87b320f..adba45a 100644
--- a/include/ui/ISurface.h
+++ b/include/ui/ISurface.h
@@ -21,11 +21,12 @@
 #include <sys/types.h>
 
 #include <utils/Errors.h>
-#include <utils/IInterface.h>
+#include <binder/IInterface.h>
 #include <utils/RefBase.h>
 #include <ui/PixelFormat.h>
 
 #include <hardware/hardware.h>
+#include <hardware/gralloc.h>
 
 namespace android {
 
@@ -33,6 +34,7 @@
 
 class IMemoryHeap;
 class OverlayRef;
+class SurfaceBuffer;
 
 class ISurface : public IInterface
 {
@@ -42,11 +44,13 @@
         UNREGISTER_BUFFERS,
         POST_BUFFER, // one-way transaction
         CREATE_OVERLAY,
+        GET_BUFFER,
     };
 
 public: 
     DECLARE_META_INTERFACE(Surface);
 
+    virtual sp<SurfaceBuffer> getBuffer() = 0; 
     
     class BufferHeap {
     public:
@@ -78,9 +82,7 @@
     };
     
     virtual status_t registerBuffers(const BufferHeap& buffers) = 0;
-
     virtual void postBuffer(ssize_t offset) = 0; // one-way
-
     virtual void unregisterBuffers() = 0;
     
     virtual sp<OverlayRef> createOverlay(
diff --git a/include/ui/ISurfaceComposer.h b/include/ui/ISurfaceComposer.h
index 5c64b22..1788265 100644
--- a/include/ui/ISurfaceComposer.h
+++ b/include/ui/ISurfaceComposer.h
@@ -22,7 +22,7 @@
 
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
-#include <utils/IInterface.h>
+#include <binder/IInterface.h>
 
 #include <ui/PixelFormat.h>
 #include <ui/ISurfaceFlingerClient.h>
@@ -32,7 +32,6 @@
 // ----------------------------------------------------------------------------
 
 class DisplayInfo;
-class IGPUCallback;
 
 class ISurfaceComposer : public IInterface
 {
@@ -63,7 +62,6 @@
         eTransparentRegionChanged   = 0x00000020,
         eVisibilityChanged          = 0x00000040,
         eFreezeTintChanged          = 0x00000080,
-        eDestroyed                  = 0x00000100
     };
 
     enum {
@@ -94,7 +92,7 @@
     virtual sp<ISurfaceFlingerClient> createConnection() = 0;
 
     /* retrieve the control block */
-    virtual sp<IMemory> getCblk() const = 0;
+    virtual sp<IMemoryHeap> getCblk() const = 0;
 
     /* open/close transactions. recquires ACCESS_SURFACE_FLINGER permission */
     virtual void openGlobalTransaction() = 0;
@@ -112,37 +110,12 @@
      */
     virtual void bootFinished() = 0;
 
-    /* get access to the GPU. Access is relinquished when releasing regs */
-    struct gpu_info_t {
-        struct gpu_region_t {
-            sp<IMemory> region;
-            size_t reserved;
-        };
-        sp<IMemory>             regs;
-        size_t                  count;
-        gpu_region_t            regions[2];
-    };
-    virtual status_t requestGPU(
-            const sp<IGPUCallback>& callback,
-            gpu_info_t* gpu) = 0;
-
-    /* take the gpu back from any apps using it. They'll get a
-     * EGL_CONTEXT_LOST error */
-    virtual status_t revokeGPU() = 0;
-
     /* Signal surfaceflinger that there might be some work to do
      * This is an ASYNCHRONOUS call.
      */
     virtual void signal() const = 0;
 };
 
-class IGPUCallback : public IInterface
-{
-public:
-    DECLARE_META_INTERFACE(GPUCallback);
-    virtual void gpuLost() = 0; //one-way
-};
-
 // ----------------------------------------------------------------------------
 
 class BnSurfaceComposer : public BnInterface<ISurfaceComposer>
@@ -159,8 +132,6 @@
         SET_ORIENTATION,
         FREEZE_DISPLAY,
         UNFREEZE_DISPLAY,
-        REQUEST_GPU,
-        REVOKE_GPU,
         SIGNAL
     };
 
@@ -170,15 +141,6 @@
                                     uint32_t flags = 0);
 };
 
-class BnGPUCallback : public BnInterface<IGPUCallback>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
 // ----------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/include/ui/ISurfaceFlingerClient.h b/include/ui/ISurfaceFlingerClient.h
index 5b9361d..932a70a 100644
--- a/include/ui/ISurfaceFlingerClient.h
+++ b/include/ui/ISurfaceFlingerClient.h
@@ -21,7 +21,7 @@
 #include <sys/types.h>
 
 #include <utils/Errors.h>
-#include <utils/IInterface.h>
+#include <binder/IInterface.h>
 #include <utils/RefBase.h>
 
 #include <ui/ISurface.h>
@@ -52,12 +52,11 @@
     struct surface_data_t {
         int32_t             token;
         int32_t             identity;
-        sp<IMemoryHeap>     heap[2];
         status_t readFromParcel(const Parcel& parcel);
         status_t writeToParcel(Parcel* parcel) const;
     };
     
-    virtual void getControlBlocks(sp<IMemory>* ctl) const = 0;
+    virtual sp<IMemoryHeap> getControlBlock() const = 0;
 
     virtual sp<ISurface> createSurface( surface_data_t* data,
                                         int pid, 
diff --git a/include/ui/Overlay.h b/include/ui/Overlay.h
index 66514b4..9ba2f7b 100644
--- a/include/ui/Overlay.h
+++ b/include/ui/Overlay.h
@@ -21,7 +21,7 @@
 #include <sys/types.h>
 
 #include <utils/Errors.h>
-#include <utils/IInterface.h>
+#include <binder/IInterface.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index 14af823..6d87321b 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -84,6 +84,13 @@
 
 struct PixelFormatInfo
 {
+    enum {
+        INDEX_ALPHA   = 0,
+        INDEX_RED     = 1,
+        INDEX_GREEN   = 2,
+        INDEX_BLUE    = 3
+    };
+    
     enum { // components
         ALPHA               = 1,
         RGB                 = 2,
@@ -95,20 +102,33 @@
         Y_CB_CR_I           = 8,
     };
 
+    struct szinfo {
+        uint8_t h;
+        uint8_t l;
+    };
+    
     inline PixelFormatInfo() : version(sizeof(PixelFormatInfo)) { }
     size_t getScanlineSize(unsigned int width) const;
+    size_t getSize(size_t ci) const { 
+        return (ci <= 3) ? (cinfo[ci].h - cinfo[ci].l) : 0;
+    }
     size_t      version;
     PixelFormat format;
     size_t      bytesPerPixel;
     size_t      bitsPerPixel;
-    uint8_t     h_alpha;
-    uint8_t     l_alpha;
-    uint8_t     h_red;
-    uint8_t     l_red;
-    uint8_t     h_green;
-    uint8_t     l_green;
-    uint8_t     h_blue;
-    uint8_t     l_blue;
+    union {
+        szinfo      cinfo[4];
+        struct {
+            uint8_t     h_alpha;
+            uint8_t     l_alpha;    
+            uint8_t     h_red;
+            uint8_t     l_red;
+            uint8_t     h_green;
+            uint8_t     l_green;
+            uint8_t     h_blue;
+            uint8_t     l_blue;
+        };
+    };
     uint8_t     components;
     uint8_t     reserved0[3];
     uint32_t    reserved1;
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index da72944..a213c09 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -30,6 +30,8 @@
     int right;
     int bottom;
 
+    typedef int value_type;
+
     // we don't provide copy-ctor and operator= on purpose
     // because we want the compiler generated versions
 
@@ -46,7 +48,11 @@
     }
 
     void makeInvalid();
-    
+
+    inline void clear() {
+        left = top = right = bottom = 0;
+    }
+
     // a valid rectangle has a non negative width and height
     inline bool isValid() const {
         return (width()>=0) && (height()>=0);
diff --git a/include/ui/Region.h b/include/ui/Region.h
index 7689673..2bcad5b 100644
--- a/include/ui/Region.h
+++ b/include/ui/Region.h
@@ -21,14 +21,12 @@
 #include <sys/types.h>
 
 #include <utils/Vector.h>
-#include <utils/Parcel.h>
+#include <binder/Parcel.h>
 
 #include <ui/Rect.h>
 
 #include <hardware/copybit.h>
 
-#include <core/SkRegion.h>
-
 namespace android {
 // ---------------------------------------------------------------------------
 
@@ -40,7 +38,6 @@
 public:
                         Region();
                         Region(const Region& rhs);
-    explicit            Region(const SkRegion& rhs);
     explicit            Region(const Rect& rhs);
     explicit            Region(const Parcel& parcel);
     explicit            Region(const void* buffer);
@@ -48,65 +45,78 @@
                         
         Region& operator = (const Region& rhs);
 
-    inline  bool        isEmpty() const     { return mRegion.isEmpty(); }
-    inline  bool        isRect() const      { return mRegion.isRect(); }
+    inline  bool        isEmpty() const     { return mBounds.isEmpty();  }
+    inline  bool        isRect() const      { return mStorage.isEmpty(); }
 
-            Rect        bounds() const;
+    inline  Rect        getBounds() const   { return mBounds; }
+    inline  Rect        bounds() const      { return getBounds(); }
 
-            const SkRegion& toSkRegion() const;
-
+            // the region becomes its bounds
+            Region&     makeBoundsSelf();
+    
             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);
+            Region&     subtractSelf(const Rect& rhs);
 
             // boolean operators, applied on this
             Region&     orSelf(const Region& rhs);
             Region&     andSelf(const Region& rhs);
             Region&     subtractSelf(const Region& rhs);
 
+            // boolean operators
+    const   Region      merge(const Rect& rhs) const;
+    const   Region      intersect(const Rect& rhs) const;
+    const   Region      subtract(const Rect& rhs) const;
+
+            // boolean operators
+    const   Region      merge(const Region& rhs) const;
+    const   Region      intersect(const Region& rhs) const;
+    const   Region      subtract(const Region& rhs) const;
+
             // these translate rhs first
             Region&     translateSelf(int dx, int dy);
             Region&     orSelf(const Region& rhs, int dx, int dy);
             Region&     andSelf(const Region& rhs, int dx, int dy);
             Region&     subtractSelf(const Region& rhs, int dx, int dy);
 
-            // boolean operators
-            Region      merge(const Region& rhs) const;
-            Region      intersect(const Region& rhs) const;
-            Region      subtract(const Region& rhs) const;
-
             // these translate rhs first
-            Region      translate(int dx, int dy) const;
-            Region      merge(const Region& rhs, int dx, int dy) const;
-            Region      intersect(const Region& rhs, int dx, int dy) const;
-            Region      subtract(const Region& rhs, int dx, int dy) const;
+    const   Region      translate(int dx, int dy) const;
+    const   Region      merge(const Region& rhs, int dx, int dy) const;
+    const   Region      intersect(const Region& rhs, int dx, int dy) const;
+    const   Region      subtract(const Region& rhs, int dx, int dy) const;
 
     // convenience operators overloads
-    inline  Region      operator | (const Region& rhs) const;
-    inline  Region      operator & (const Region& rhs) const;
-    inline  Region      operator - (const Region& rhs) const;
-    inline  Region      operator + (const Point& pt) const;
+    inline  const Region      operator | (const Region& rhs) const;
+    inline  const Region      operator & (const Region& rhs) const;
+    inline  const Region      operator - (const Region& rhs) const;
+    inline  const Region      operator + (const Point& pt) const;
 
     inline  Region&     operator |= (const Region& rhs);
     inline  Region&     operator &= (const Region& rhs);
     inline  Region&     operator -= (const Region& rhs);
     inline  Region&     operator += (const Point& pt);
 
-    class iterator {
-        SkRegion::Iterator  mIt;
-    public:
-        iterator(const Region& r);
-        inline operator bool () const { return !done(); }
-        int iterate(Rect* rect);
-    private:
-        inline bool done() const {
-            return const_cast<SkRegion::Iterator&>(mIt).done();
-        }
-    };
+    
+    /* various ways to access the rectangle list */
+    
+    typedef Rect const* const_iterator;
+    
+            const_iterator begin() const;
+            const_iterator end() const;
 
-            size_t      rects(Vector<Rect>& rectList) const;
+    /* no user serviceable parts here... */
+            
+            size_t      getRects(Vector<Rect>& rectList) const;
+            Rect const* getArray(size_t* count) const;
+
+            
+            // add a rectangle to the internal list. This rectangle must
+            // be sorted in Y and X and must not make the region invalid.
+            void        addRectUnchecked(int l, int t, int r, int b);
 
             // flatten/unflatten a region to/from a Parcel
             status_t    write(Parcel& parcel) const;
@@ -123,20 +133,46 @@
     void        dump(const char* what, uint32_t flags=0) const;
 
 private:
-    SkRegion    mRegion;
+    class rasterizer;
+    friend class rasterizer;
+    
+    Region& operationSelf(const Rect& r, int op);
+    Region& operationSelf(const Region& r, int op);
+    Region& operationSelf(const Region& r, int dx, int dy, int op);
+    const Region operation(const Rect& rhs, int op) const;
+    const Region operation(const Region& rhs, int op) const;
+    const Region operation(const Region& rhs, int dx, int dy, int op) const;
+
+    static void boolean_operation(int op, Region& dst,
+            const Region& lhs, const Region& rhs, int dx, int dy);
+    static void boolean_operation(int op, Region& dst,
+            const Region& lhs, const Rect& rhs, int dx, int dy);
+
+    static void boolean_operation(int op, Region& dst,
+            const Region& lhs, const Region& rhs);
+    static void boolean_operation(int op, Region& dst,
+            const Region& lhs, const Rect& rhs);
+
+    static void translate(Region& reg, int dx, int dy);
+    static void translate(Region& dst, const Region& reg, int dx, int dy);
+
+    static bool validate(const Region& reg, const char* name);
+    
+    Rect            mBounds;
+    Vector<Rect>    mStorage;
 };
 
 
-Region Region::operator | (const Region& rhs) const {
+const Region Region::operator | (const Region& rhs) const {
     return merge(rhs);
 }
-Region Region::operator & (const Region& rhs) const {
+const Region Region::operator & (const Region& rhs) const {
     return intersect(rhs);
 }
-Region Region::operator - (const Region& rhs) const {
+const Region Region::operator - (const Region& rhs) const {
     return subtract(rhs);
 }
-Region Region::operator + (const Point& pt) const {
+const Region Region::operator + (const Point& pt) const {
     return translate(pt.x, pt.y);
 }
 
@@ -157,16 +193,23 @@
 // ---------------------------------------------------------------------------
 
 struct region_iterator : public copybit_region_t {
-    region_iterator(const Region& region) : i(region) {
+    region_iterator(const Region& region)
+        : b(region.begin()), e(region.end()) {
         this->next = iterate;
     }
 private:
     static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
-        return static_cast<const region_iterator*>(self)
-        ->i.iterate(reinterpret_cast<Rect*>(rect));
+        region_iterator const* me = static_cast<region_iterator const*>(self);
+        if (me->b != me->e) {
+            *reinterpret_cast<Rect*>(rect) = *me->b++;
+            return 1;
+        }
+        return 0;
     }
-    mutable Region::iterator i;
+    mutable Region::const_iterator b;
+    Region::const_iterator const e;
 };
+
 // ---------------------------------------------------------------------------
 }; // namespace android
 
diff --git a/include/ui/Surface.h b/include/ui/Surface.h
index 33953a9..8c4f63d 100644
--- a/include/ui/Surface.h
+++ b/include/ui/Surface.h
@@ -28,48 +28,40 @@
 #include <ui/Region.h>
 #include <ui/ISurfaceFlingerClient.h>
 
+#include <ui/egl/android_natives.h>
+
 namespace android {
 
 // ---------------------------------------------------------------------------
 
+class BufferMapper;
 class Rect;
+class Surface;
 class SurfaceComposerClient;
+struct per_client_cblk_t;
+struct layer_cblk_t;
 
-class Surface : public RefBase
+// ---------------------------------------------------------------------------
+
+class SurfaceControl : public RefBase
 {
-
 public:
-    struct SurfaceInfo {
-        uint32_t    w;
-        uint32_t    h;
-        uint32_t    bpr;
-        PixelFormat format;
-        void*       bits;
-        void*       base;
-        uint32_t    reserved[2];
-    };
-
-    bool        isValid() const { return this && mToken>=0 && mClient!=0; }
+    static bool isValid(const sp<SurfaceControl>& surface) {
+        return (surface != 0) && surface->isValid();
+    }
+    bool isValid() {
+        return mToken>=0 && mClient!=0;
+    }
+    static bool isSameSurface(
+            const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
+        
     SurfaceID   ID() const      { return mToken; }
-
-    status_t    lock(SurfaceInfo* info, bool blocking = true);
-    status_t    lock(SurfaceInfo* info, Region* dirty, bool blocking = true);
-    status_t    unlockAndPost();
-    status_t    unlock();
-
-    void*       heapBase(int i) const;
     uint32_t    getFlags() const { return mFlags; }
+    uint32_t    getIdentity() const { return mIdentity; }
 
-    // setSwapRectangle() is mainly used by EGL
-    void        setSwapRectangle(const Rect& r);
-    const Rect& swapRectangle() const;
-    status_t    nextBuffer(SurfaceInfo* info);
-
-    sp<Surface>         dup() const;
-    static sp<Surface>  readFromParcel(Parcel* parcel);
-    static status_t     writeToParcel(const sp<Surface>& surface, Parcel* parcel);
-    static bool         isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs);
-
+    // release surface data from java
+    void        clear();
+    
     status_t    setLayer(int32_t layer);
     status_t    setPosition(int32_t x, int32_t y);
     status_t    setSize(uint32_t w, uint32_t h);
@@ -83,8 +75,17 @@
     status_t    setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
     status_t    setFreezeTint(uint32_t tint);
 
-    uint32_t    getIdentity() const { return mIdentity; }
+    static status_t writeSurfaceToParcel(
+            const sp<SurfaceControl>& control, Parcel* parcel);
+
+    sp<Surface> getSurface() const;
+
 private:
+    // can't be copied
+    SurfaceControl& operator = (SurfaceControl& rhs);
+    SurfaceControl(const SurfaceControl& rhs);
+
+    
     friend class SurfaceComposerClient;
 
     // camera and camcorder need access to the ISurface binder interface for preview
@@ -92,43 +93,130 @@
     friend class MediaRecorder;
     // mediaplayer needs access to ISurface for display
     friend class MediaPlayer;
+    // for testing
+    friend class Test;
+    const sp<ISurface>& getISurface() const { return mSurface; }
+    
+
+    friend class Surface;
+
+    SurfaceControl(
+            const sp<SurfaceComposerClient>& client,
+            const sp<ISurface>& surface,
+            const ISurfaceFlingerClient::surface_data_t& data,
+            uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+
+    ~SurfaceControl();
+
+    status_t validate(per_client_cblk_t const* cblk) const;
+    void destroy();
+    
+    sp<SurfaceComposerClient>   mClient;
+    sp<ISurface>                mSurface;
+    SurfaceID                   mToken;
+    uint32_t                    mIdentity;
+    PixelFormat                 mFormat;
+    uint32_t                    mFlags;
+    mutable Mutex               mLock;
+    
+    mutable sp<Surface>         mSurfaceData;
+};
+    
+// ---------------------------------------------------------------------------
+
+class Surface 
+    : public EGLNativeBase<android_native_window_t, Surface, RefBase>
+{
+public:
+    struct SurfaceInfo {
+        uint32_t    w;
+        uint32_t    h;
+        uint32_t    s;
+        uint32_t    usage;
+        PixelFormat format;
+        void*       bits;
+        uint32_t    reserved[2];
+    };
+
+    Surface(const Parcel& data);
+
+    static bool isValid(const sp<Surface>& surface) {
+        return (surface != 0) && surface->isValid();
+    }
+    bool isValid() {
+        return mToken>=0 && mClient!=0;
+    }
+    static bool isSameSurface(
+            const sp<Surface>& lhs, const sp<Surface>& rhs);
+    SurfaceID   ID() const      { return mToken; }
+    uint32_t    getFlags() const { return mFlags; }
+    uint32_t    getIdentity() const { return mIdentity; }
+
+
+    status_t    lock(SurfaceInfo* info, bool blocking = true);
+    status_t    lock(SurfaceInfo* info, Region* dirty, bool blocking = true);
+    status_t    unlockAndPost();
+
+    // 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;
+
+    // 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
+    friend class MediaPlayer;
     friend class Test;
     const sp<ISurface>& getISurface() const { return mSurface; }
 
-    // can't be copied
-    Surface& operator = (Surface& rhs);
-    Surface(const Surface& rhs);
+    status_t getBufferLocked(int index);
+   
+           status_t validate(per_client_cblk_t const* cblk) const;
+    static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty);
 
-    Surface(const sp<SurfaceComposerClient>& client,
-            const sp<ISurface>& surface,
-            const ISurfaceFlingerClient::surface_data_t& data,
-            uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
-            bool owner = true);
+    inline const BufferMapper& getBufferMapper() const { return mBufferMapper; }
+    inline BufferMapper& getBufferMapper() { return mBufferMapper; }
+    
+    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);
+    static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
 
-    Surface(Surface const* rhs);
+    int dequeueBuffer(android_native_buffer_t** buffer);
+    int lockBuffer(android_native_buffer_t* buffer);
+    int queueBuffer(android_native_buffer_t* buffer);
 
-    ~Surface();
+    status_t dequeueBuffer(sp<SurfaceBuffer>* buffer);
+    status_t lockBuffer(const sp<SurfaceBuffer>& buffer);
+    status_t queueBuffer(const sp<SurfaceBuffer>& buffer);
 
-    Region dirtyRegion() const;
-    void setDirtyRegion(const Region& region) const;
-
-    // this locks protects calls to lockSurface() / unlockSurface()
-    // and is called by SurfaceComposerClient.
-    Mutex& getLock() const { return mSurfaceLock; }
-
+    
+    alloc_device_t*             mAllocDevice;
     sp<SurfaceComposerClient>   mClient;
     sp<ISurface>                mSurface;
-    sp<IMemoryHeap>             mHeap[2];
+    sp<SurfaceBuffer>           mBuffers[2];
+    sp<SurfaceBuffer>           mLockedBuffer;
     SurfaceID                   mToken;
     uint32_t                    mIdentity;
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
-    const bool                  mOwner;
-    mutable void*               mSurfaceHeapBase[2];
     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/ui/SurfaceComposerClient.h b/include/ui/SurfaceComposerClient.h
index 76a3b55..286f885 100644
--- a/include/ui/SurfaceComposerClient.h
+++ b/include/ui/SurfaceComposerClient.h
@@ -62,7 +62,7 @@
     // surface creation / destruction
 
     //! Create a surface
-    sp<Surface>   createSurface(
+    sp<SurfaceControl> createSurface(
             int pid,            //!< pid of the process the surfacec is for
             DisplayID display,  //!< Display to create this surface on
             uint32_t w,         //!< width in pixel
@@ -111,51 +111,35 @@
 
 private:
     friend class Surface;
+    friend class SurfaceControl;
     
     SurfaceComposerClient(const sp<ISurfaceComposer>& sm, 
             const sp<IBinder>& conn);
 
-    status_t    hide(Surface* surface);
-    status_t    show(Surface* surface, int32_t layer = -1);
-    status_t    freeze(Surface* surface);
-    status_t    unfreeze(Surface* surface);
-    status_t    setFlags(Surface* surface, uint32_t flags, uint32_t mask);
-    status_t    setTransparentRegionHint(Surface* surface, const Region& transparent);
-    status_t    setLayer(Surface* surface, int32_t layer);
-    status_t    setAlpha(Surface* surface, float alpha=1.0f);
-    status_t    setFreezeTint(Surface* surface, uint32_t tint);
-    status_t    setMatrix(Surface* surface, float dsdx, float dtdx, float dsdy, float dtdy);
-    status_t    setPosition(Surface* surface, int32_t x, int32_t y);
-    status_t    setSize(Surface* surface, uint32_t w, uint32_t h);
+    status_t    hide(SurfaceID id);
+    status_t    show(SurfaceID id, int32_t layer = -1);
+    status_t    freeze(SurfaceID id);
+    status_t    unfreeze(SurfaceID id);
+    status_t    setFlags(SurfaceID id, uint32_t flags, uint32_t mask);
+    status_t    setTransparentRegionHint(SurfaceID id, const Region& transparent);
+    status_t    setLayer(SurfaceID id, int32_t layer);
+    status_t    setAlpha(SurfaceID id, float alpha=1.0f);
+    status_t    setFreezeTint(SurfaceID id, uint32_t tint);
+    status_t    setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy);
+    status_t    setPosition(SurfaceID id, int32_t x, int32_t y);
+    status_t    setSize(SurfaceID id, uint32_t w, uint32_t h);
     
-    //! Unlock the surface, and specify the dirty region if any
-    status_t    unlockAndPostSurface(Surface* surface);
-    status_t    unlockSurface(Surface* surface);
-
-    status_t    lockSurface(Surface* surface,
-                            Surface::SurfaceInfo* info,
-                            Region* dirty,
-                            bool blocking = true);
-
-    status_t    nextBuffer(Surface* surface,
-                            Surface::SurfaceInfo* info);
+    void        signalServer();
 
     status_t    destroySurface(SurfaceID sid);
 
     void        _init(const sp<ISurfaceComposer>& sm,
                     const sp<ISurfaceFlingerClient>& conn);
-    void        _signal_server();
-    static void _send_dirty_region(layer_cblk_t* lcblk, const Region& dirty);
 
-    inline layer_state_t*   _get_state_l(const sp<Surface>& surface);
-    layer_state_t*          _lockLayerState(const sp<Surface>& surface);
+    inline layer_state_t*   _get_state_l(SurfaceID id);
+    layer_state_t*          _lockLayerState(SurfaceID id);
     inline void             _unlockLayerState();
 
-    status_t validateSurface(
-            per_client_cblk_t const* cblk, Surface const * surface);
-
-    void pinHeap(const sp<IMemoryHeap>& heap);
-
     mutable     Mutex                               mLock;
                 layer_state_t*                      mPrebuiltLayerState;
                 SortedVector<layer_state_t>         mStates;
@@ -165,11 +149,8 @@
                 // after assignment
                 status_t                    mStatus;
                 per_client_cblk_t*          mControl;
-                sp<IMemory>                 mControlMemory;
+                sp<IMemoryHeap>             mControlMemory;
                 sp<ISurfaceFlingerClient>   mClient;
-                sp<IMemoryHeap>             mSurfaceHeap;
-                uint8_t*                    mSurfaceHeapBase;
-                void*                       mGL;
                 SurfaceFlingerSynchro*      mSignalServer;
 };
 
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
new file mode 100644
index 0000000..0398ea7
--- /dev/null
+++ b/include/ui/egl/android_natives.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_ANDROID_NATIVES_H
+#define ANDROID_ANDROID_NATIVES_H
+
+#include <sys/types.h>
+#include <string.h>
+
+#include <hardware/gralloc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************************************************/
+
+#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \
+    (((unsigned)(a)<<24)|((unsigned)(b)<<16)|((unsigned)(c)<<8)|(unsigned)(d))
+
+#define ANDROID_NATIVE_WINDOW_MAGIC \
+    ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d')
+
+#define ANDROID_NATIVE_BUFFER_MAGIC \
+    ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r')
+
+// ---------------------------------------------------------------------------
+
+struct android_native_buffer_t;
+
+// ---------------------------------------------------------------------------
+
+struct android_native_base_t
+{
+    /* a magic value defined by the actual EGL native type */
+    int magic;
+    
+    /* the sizeof() of the actual EGL native type */
+    int version;
+
+    void* reserved[4];
+
+    /* reference-counting interface */
+    void (*incRef)(struct android_native_base_t* base);
+    void (*decRef)(struct android_native_base_t* base);
+};
+
+// ---------------------------------------------------------------------------
+
+struct android_native_window_t 
+{
+#ifdef __cplusplus
+    android_native_window_t()
+        : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
+    {
+        common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
+        common.version = sizeof(android_native_window_t);
+        memset(common.reserved, 0, sizeof(common.reserved));
+    }
+#endif
+    
+    struct android_native_base_t common;
+
+    /* flags describing some attributes of this surface or its updater */
+    const uint32_t flags;
+    
+    /* min swap interval supported by this updated */
+    const int   minSwapInterval;
+
+    /* max swap interval supported by this updated */
+    const int   maxSwapInterval;
+
+    /* horizontal and vertical resolution in DPI */
+    const float xdpi;
+    const float ydpi;
+
+    /* Some storage reserved for the OEM's driver. */
+    intptr_t    oem[4];
+        
+
+    /*
+     * Set the swap interval for this surface.
+     * 
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*setSwapInterval)(struct android_native_window_t* window,
+                int interval);
+    
+    /*
+     * 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 available.
+     * 
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*dequeueBuffer)(struct android_native_window_t* window, 
+                struct android_native_buffer_t** buffer);
+
+    /*
+     * hook called by EGL to lock a buffer. This MUST be called before modifying
+     * the content of a buffer. The buffer must have been acquired with 
+     * dequeueBuffer first.
+     * 
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*lockBuffer)(struct android_native_window_t* window,
+                struct android_native_buffer_t* buffer);
+   /*
+    * hook called by EGL when modifications to the render buffer are done. 
+    * This unlocks and post the buffer.
+    * 
+    * Buffers MUST be queued in the same order than they were dequeued.
+    * 
+    * Returns 0 on success or -errno on error.
+    */
+    int     (*queueBuffer)(struct android_native_window_t* window,
+                struct android_native_buffer_t* buffer);
+
+    
+    void* reserved_proc[5];
+};
+
+// ---------------------------------------------------------------------------
+
+/* FIXME: this is legacy for pixmaps */
+struct egl_native_pixmap_t
+{
+    int32_t     version;    /* must be 32 */
+    int32_t     width;
+    int32_t     height;
+    int32_t     stride;
+    uint8_t*    data;
+    uint8_t     format;
+    uint8_t     rfu[3];
+    union {
+        uint32_t    compressedFormat;
+        int32_t     vstride;
+    };
+    int32_t     reserved;
+};
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+
+#include <utils/RefBase.h>
+
+namespace android {
+
+/*
+ * This helper class turns an EGL android_native_xxx type into a C++
+ * reference-counted object; with proper type conversions.
+ */
+template <typename NATIVE_TYPE, typename TYPE, typename REF>
+class EGLNativeBase : public NATIVE_TYPE, public REF
+{
+protected:
+    typedef EGLNativeBase<NATIVE_TYPE, TYPE, REF> BASE;
+    EGLNativeBase() : NATIVE_TYPE(), REF() {
+        NATIVE_TYPE::common.incRef = incRef;
+        NATIVE_TYPE::common.decRef = decRef;
+    }
+    static inline TYPE* getSelf(NATIVE_TYPE* self) {
+        return static_cast<TYPE*>(self);
+    }
+    static inline TYPE const* getSelf(NATIVE_TYPE const* self) {
+        return static_cast<TYPE const *>(self);
+    }
+    static inline TYPE* getSelf(android_native_base_t* base) {
+        return getSelf(reinterpret_cast<NATIVE_TYPE*>(base));
+    }
+    static inline TYPE const * getSelf(android_native_base_t const* base) {
+        return getSelf(reinterpret_cast<NATIVE_TYPE const*>(base));
+    }
+    static void incRef(android_native_base_t* base) {
+        EGLNativeBase* self = getSelf(base);
+        self->incStrong(self);
+    }
+    static void decRef(android_native_base_t* base) {
+        EGLNativeBase* self = getSelf(base);
+        self->decStrong(self);
+    }
+};
+
+} // namespace android
+#endif // __cplusplus
+
+/*****************************************************************************/
+
+#endif /* ANDROID_ANDROID_NATIVES_H */
diff --git a/include/utils.h b/include/utils.h
deleted file mode 100644
index 30648b1..0000000
--- a/include/utils.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// Handy utility functions and portability code.  This file includes all
-// of the generally-useful headers in the "utils" directory.
-//
-#ifndef _LIBS_UTILS_H
-#define _LIBS_UTILS_H
-
-#include <utils/ported.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#include <utils/List.h>
-#include <utils/string_array.h>
-#include <utils/misc.h>
-#include <utils/Errors.h>
-
-#endif // _LIBS_UTILS_H
diff --git a/include/utils/Debug.h b/include/utils/Debug.h
index a662b9c..21d04bd 100644
--- a/include/utils/Debug.h
+++ b/include/utils/Debug.h
@@ -14,10 +14,6 @@
  * limitations under the License.
  */
 
-//
-// Debugging tools.  These should be able to be stripped
-// in release builds.
-//
 #ifndef ANDROID_DEBUG_H
 #define ANDROID_DEBUG_H
 
@@ -25,9 +21,30 @@
 #include <sys/types.h>
 
 namespace android {
+// ---------------------------------------------------------------------------
 
+#ifdef __cplusplus
 template<bool> struct CompileTimeAssert;
 template<> struct CompileTimeAssert<true> {};
+#define COMPILE_TIME_ASSERT(_exp) \
+    template class CompileTimeAssert< (_exp) >;
+#endif
+
+// ---------------------------------------------------------------------------
+
+#ifdef __cplusplus
+template<bool C, typename LSH, typename RHS> struct CompileTimeIfElse;
+template<typename LHS, typename RHS> 
+struct CompileTimeIfElse<true,  LHS, RHS> { typedef LHS TYPE; };
+template<typename LHS, typename RHS> 
+struct CompileTimeIfElse<false, LHS, RHS> { typedef RHS TYPE; };
+#endif
+
+// ---------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 const char* stringForIndent(int32_t indentLevel);
 
@@ -35,11 +52,17 @@
 
 void printTypeCode(uint32_t typeCode,
     debugPrintFunc func = 0, void* cookie = 0);
+
 void printHexData(int32_t indent, const void *buf, size_t length,
     size_t bytesPerLine=16, int32_t singleLineBytesCutoff=16,
     size_t alignment=0, bool cArrayStyle=false,
     debugPrintFunc func = 0, void* cookie = 0);
 
+#ifdef __cplusplus
+}
+#endif
+
+// ---------------------------------------------------------------------------
 }; // namespace android
 
 #endif // ANDROID_DEBUG_H
diff --git a/include/utils/KeyedVector.h b/include/utils/KeyedVector.h
index f4513ee..6bcdea4 100644
--- a/include/utils/KeyedVector.h
+++ b/include/utils/KeyedVector.h
@@ -164,7 +164,7 @@
 template<typename KEY, typename VALUE> inline
 ssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) {
     if (index<size()) {
-        mVector.editValueAt(index).value = item;
+        mVector.editItemAt(index).value = item;
         return index;
     }
     return BAD_INDEX;
diff --git a/include/utils/List.h b/include/utils/List.h
index 1a6be9a..403cd7f 100644
--- a/include/utils/List.h
+++ b/include/utils/List.h
@@ -22,147 +22,200 @@
 // construction, so if the compiler's auto-generated versions won't work for
 // you, define your own.
 //
-// The only class you want to use from here is "List".  Do not use classes
-// starting with "_" directly.
+// The only class you want to use from here is "List".
 //
 #ifndef _LIBS_UTILS_LIST_H
 #define _LIBS_UTILS_LIST_H
 
+#include <stddef.h>
+#include <stdint.h>
+
 namespace android {
 
 /*
- * One element in the list.
- */
-template<class T> class _ListNode {
-public:
-    typedef _ListNode<T> _Node;
-
-    _ListNode(const T& val) : mVal(val) {}
-    ~_ListNode(void) {}
-
-    T& getRef(void) { return mVal; }
-    void setVal(const T& val) { mVal = val; }
-
-    _Node* getPrev(void) const { return mpPrev; }
-    void setPrev(_Node* ptr) { mpPrev = ptr; }
-    _Node* getNext(void) const { return mpNext; }
-    void setNext(_Node* ptr) { mpNext = ptr; }
-
-private:
-    T           mVal;
-    _Node*      mpPrev;
-    _Node*      mpNext;
-};
-
-/*
- * Iterator for walking through the list.
- */
-template<class T, class Tref> class _ListIterator {
-public:
-    typedef _ListIterator<T,Tref> _Iter;
-    typedef _ListNode<T> _Node;
-
-    _ListIterator(void) {}
-    _ListIterator(_Node* ptr) : mpNode(ptr) {}
-    ~_ListIterator(void) {}
-
-    /*
-     * Dereference operator.  Used to get at the juicy insides.
-     */
-    Tref operator*() const { return mpNode->getRef(); }
-
-    /*
-     * Iterator comparison.
-     */
-    bool operator==(const _Iter& right) const { return mpNode == right.mpNode; }
-    bool operator!=(const _Iter& right) const { return mpNode != right.mpNode; }
-
-    /*
-     * Incr/decr, used to move through the list.
-     */
-    _Iter& operator++(void) {        // pre-increment
-        mpNode = mpNode->getNext();
-        return *this;
-    }
-    _Iter operator++(int) {          // post-increment
-        _Iter tmp = *this;
-        ++*this;
-        return tmp;
-    }
-    _Iter& operator--(void) {        // pre-increment
-        mpNode = mpNode->getPrev();
-        return *this;
-    }
-    _Iter operator--(int) {          // post-increment
-        _Iter tmp = *this;
-        --*this;
-        return tmp;
-    }
-
-    _Node* getNode(void) const { return mpNode; }
-
-private:
-    _Node*      mpNode;
-};
-
-
-/*
  * Doubly-linked list.  Instantiate with "List<MyClass> myList".
  *
  * Objects added to the list are copied using the assignment operator,
  * so this must be defined.
  */
-template<class T> class List {
-public:
-    typedef _ListNode<T> _Node;
+template<typename T> 
+class List 
+{
+protected:
+    /*
+     * One element in the list.
+     */
+    class _Node {
+    public:
+        explicit _Node(const T& val) : mVal(val) {}
+        ~_Node() {}
+        inline T& getRef() { return mVal; }
+        inline const T& getRef() const { return mVal; }
+        inline _Node* getPrev() const { return mpPrev; }
+        inline _Node* getNext() const { return mpNext; }
+        inline void setVal(const T& val) { mVal = val; }
+        inline void setPrev(_Node* ptr) { mpPrev = ptr; }
+        inline void setNext(_Node* ptr) { mpNext = ptr; }
+    private:
+        friend class List;
+        friend class _ListIterator;
+        T           mVal;
+        _Node*      mpPrev;
+        _Node*      mpNext;
+    };
 
-    List(void) {
+    /*
+     * Iterator for walking through the list.
+     */
+    
+    template <typename TYPE>
+    struct CONST_ITERATOR {
+        typedef _Node const * NodePtr;
+        typedef const TYPE Type;
+    };
+    
+    template <typename TYPE>
+    struct NON_CONST_ITERATOR {
+        typedef _Node* NodePtr;
+        typedef TYPE Type;
+    };
+    
+    template<
+        typename U,
+        template <class> class Constness
+    > 
+    class _ListIterator {
+        typedef _ListIterator<U, Constness>     _Iter;
+        typedef typename Constness<U>::NodePtr  _NodePtr;
+        typedef typename Constness<U>::Type     _Type;
+
+        explicit _ListIterator(_NodePtr ptr) : mpNode(ptr) {}
+
+    public:
+        _ListIterator() {}
+        _ListIterator(const _Iter& rhs) : mpNode(rhs.mpNode) {}
+        ~_ListIterator() {}
+        
+        // this will handle conversions from iterator to const_iterator
+        // (and also all convertible iterators)
+        // Here, in this implementation, the iterators can be converted
+        // if the nodes can be converted
+        template<typename V> explicit 
+        _ListIterator(const V& rhs) : mpNode(rhs.mpNode) {}
+        
+
+        /*
+         * Dereference operator.  Used to get at the juicy insides.
+         */
+        _Type& operator*() const { return mpNode->getRef(); }
+        _Type* operator->() const { return &(mpNode->getRef()); }
+
+        /*
+         * Iterator comparison.
+         */
+        inline bool operator==(const _Iter& right) const { 
+            return mpNode == right.mpNode; }
+        
+        inline bool operator!=(const _Iter& right) const { 
+            return mpNode != right.mpNode; }
+
+        /*
+         * handle comparisons between iterator and const_iterator
+         */
+        template<typename OTHER>
+        inline bool operator==(const OTHER& right) const { 
+            return mpNode == right.mpNode; }
+        
+        template<typename OTHER>
+        inline bool operator!=(const OTHER& right) const { 
+            return mpNode != right.mpNode; }
+
+        /*
+         * Incr/decr, used to move through the list.
+         */
+        inline _Iter& operator++() {     // pre-increment
+            mpNode = mpNode->getNext();
+            return *this;
+        }
+        const _Iter operator++(int) {    // post-increment
+            _Iter tmp(*this);
+            mpNode = mpNode->getNext();
+            return tmp;
+        }
+        inline _Iter& operator--() {     // pre-increment
+            mpNode = mpNode->getPrev();
+            return *this;
+        }
+        const _Iter operator--(int) {   // post-increment
+            _Iter tmp(*this);
+            mpNode = mpNode->getPrev();
+            return tmp;
+        }
+
+        inline _NodePtr getNode() const { return mpNode; }
+
+        _NodePtr mpNode;    /* should be private, but older gcc fails */
+    private:
+        friend class List;
+    };
+
+public:
+    List() {
         prep();
     }
     List(const List<T>& src) {      // copy-constructor
         prep();
         insert(begin(), src.begin(), src.end());
     }
-    virtual ~List(void) {
+    virtual ~List() {
         clear();
         delete[] (unsigned char*) mpMiddle;
     }
 
-    typedef _ListIterator<T,T&> iterator;
-    typedef _ListIterator<T, const T&> const_iterator;
+    typedef _ListIterator<T, NON_CONST_ITERATOR> iterator;
+    typedef _ListIterator<T, CONST_ITERATOR> const_iterator;
 
     List<T>& operator=(const List<T>& right);
 
     /* returns true if the list is empty */
-    bool empty(void) const { return mpMiddle->getNext() == mpMiddle; }
+    inline bool empty() const { return mpMiddle->getNext() == mpMiddle; }
 
     /* return #of elements in list */
-    unsigned int size(void) const {
-        return distance(begin(), end());
+    size_t size() const {
+        return size_t(distance(begin(), end()));
     }
 
     /*
      * Return the first element or one past the last element.  The
-     * _ListNode* we're returning is converted to an "iterator" by a
+     * _Node* we're returning is converted to an "iterator" by a
      * constructor in _ListIterator.
      */
-    iterator begin()                { return mpMiddle->getNext(); }
-    const_iterator begin() const    { return mpMiddle->getNext(); }
-    iterator end()                  { return mpMiddle; }
-    const_iterator end() const      { return mpMiddle; }
+    inline iterator begin() { 
+        return iterator(mpMiddle->getNext()); 
+    }
+    inline const_iterator begin() const { 
+        return const_iterator(const_cast<_Node const*>(mpMiddle->getNext())); 
+    }
+    inline iterator end() { 
+        return iterator(mpMiddle); 
+    }
+    inline const_iterator end() const { 
+        return const_iterator(const_cast<_Node const*>(mpMiddle)); 
+    }
 
     /* add the object to the head or tail of the list */
     void push_front(const T& val) { insert(begin(), val); }
     void push_back(const T& val) { insert(end(), val); }
 
     /* insert before the current node; returns iterator at new node */
-    iterator insert(iterator posn, const T& val) {
+    iterator insert(iterator posn, const T& val) 
+    {
         _Node* newNode = new _Node(val);        // alloc & copy-construct
         newNode->setNext(posn.getNode());
         newNode->setPrev(posn.getNode()->getPrev());
         posn.getNode()->getPrev()->setNext(newNode);
         posn.getNode()->setPrev(newNode);
-        return newNode;
+        return iterator(newNode);
     }
 
     /* insert a range of elements before the current node */
@@ -178,18 +231,18 @@
         pPrev->setNext(pNext);
         pNext->setPrev(pPrev);
         delete posn.getNode();
-        return pNext;
+        return iterator(pNext);
     }
 
     /* remove a range of elements */
     iterator erase(iterator first, iterator last) {
         while (first != last)
             erase(first++);     // don't erase than incr later!
-        return last;
+        return iterator(last);
     }
 
     /* remove all contents of the list */
-    void clear(void) {
+    void clear() {
         _Node* pCurrent = mpMiddle->getNext();
         _Node* pNext;
 
@@ -207,21 +260,20 @@
      * will be equal to "last".  The iterators must refer to the same
      * list.
      *
-     * (This is actually a generic iterator function.  It should be part
-     * of some other class, possibly an iterator base class.  It needs to
-     * know the difference between a list, which has to march through,
-     * and a vector, which can just do pointer math.)
+     * FIXME: This is actually a generic iterator function. It should be a 
+     * template function at the top-level with specializations for things like
+     * vector<>, which can just do pointer math). Here we limit it to
+     * _ListIterator of the same type but different constness.
      */
-    unsigned int distance(iterator first, iterator last) {
-        unsigned int count = 0;
-        while (first != last) {
-            ++first;
-            ++count;
-        }
-        return count;
-    }
-    unsigned int distance(const_iterator first, const_iterator last) const {
-        unsigned int count = 0;
+    template<
+        typename U,
+        template <class> class CL,
+        template <class> class CR
+    > 
+    ptrdiff_t distance(
+            _ListIterator<U, CL> first, _ListIterator<U, CR> last) const 
+    {
+        ptrdiff_t count = 0;
         while (first != last) {
             ++first;
             ++count;
@@ -231,12 +283,12 @@
 
 private:
     /*
-     * I want a _ListNode but don't need it to hold valid data.  More
+     * I want a _Node but don't need it to hold valid data.  More
      * to the point, I don't want T's constructor to fire, since it
      * might have side-effects or require arguments.  So, we do this
      * slightly uncouth storage alloc.
      */
-    void prep(void) {
+    void prep() {
         mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];
         mpMiddle->setPrev(mpMiddle);
         mpMiddle->setNext(mpMiddle);
diff --git a/include/utils/LogSocket.h b/include/utils/LogSocket.h
deleted file mode 100644
index 01fbfb5..0000000
--- a/include/utils/LogSocket.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* utils/LogSocket.h
-** 
-** Copyright 2008, The Android Open Source Project
-**
-** This file is dual licensed.  It may be redistributed and/or modified
-** under the terms of the Apache 2.0 License OR version 2 of the GNU
-** General Public License.
-*/
-
-#ifndef _UTILS_LOGSOCKET_H
-#define _UTILS_LOGSOCKET_H
-
-#define SOCKET_CLOSE_LOCAL 0
-
-void add_send_stats(int fd, int send);
-void add_recv_stats(int fd, int recv);
-void log_socket_close(int fd, short reason);
-void log_socket_connect(int fd, unsigned int ip, unsigned short port);
-
-#endif /* _UTILS_LOGSOCKET_H */
diff --git a/include/utils/Pipe.h b/include/utils/Pipe.h
deleted file mode 100644
index 6404168..0000000
--- a/include/utils/Pipe.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// FIFO I/O.
-//
-#ifndef _LIBS_UTILS_PIPE_H
-#define _LIBS_UTILS_PIPE_H
-
-#ifdef HAVE_ANDROID_OS
-#error DO NOT USE THIS FILE IN THE DEVICE BUILD
-#endif
-
-namespace android {
-
-/*
- * Simple anonymous unidirectional pipe.
- *
- * The primary goal is to create an implementation with minimal overhead
- * under Linux.  Making Windows, Mac OS X, and Linux all work the same way
- * is a secondary goal.  Part of this goal is to have something that can
- * be fed to a select() call, so that the application can sleep in the
- * kernel until something interesting happens.
- */
-class Pipe {
-public:
-    Pipe(void);
-    virtual ~Pipe(void);
-
-    /* Create the pipe */
-    bool create(void);
-
-    /* Create a read-only pipe, using the supplied handle as read handle */
-    bool createReader(unsigned long handle);
-    /* Create a write-only pipe, using the supplied handle as write handle */
-    bool createWriter(unsigned long handle);
-
-    /* Is this object ready to go? */
-    bool isCreated(void);
-
-    /*
-     * Read "count" bytes from the pipe.  Returns the amount of data read,
-     * or 0 if no data available and we're non-blocking.
-     * Returns -1 on error.
-     */
-    int read(void* buf, int count);
-
-    /*
-     * Write "count" bytes into the pipe.  Returns number of bytes written,
-     * or 0 if there's no room for more data and we're non-blocking.
-     * Returns -1 on error.
-     */
-    int write(const void* buf, int count);
-
-    /* Returns "true" if data is available to read */
-    bool readReady(void);
-
-    /* Enable or disable non-blocking I/O for reads */
-    bool setReadNonBlocking(bool val);
-    /* Enable or disable non-blocking I/O for writes.  Only works on Linux. */
-    bool setWriteNonBlocking(bool val);
-
-    /*
-     * Get the handle.  Only useful in some platform-specific situations.
-     */
-    unsigned long getReadHandle(void);
-    unsigned long getWriteHandle(void);
-
-    /*
-     * Modify inheritance, i.e. whether or not a child process will get
-     * copies of the descriptors.  Systems with fork+exec allow us to close
-     * the descriptors before launching the child process, but Win32
-     * doesn't allow it.
-     */
-    bool disallowReadInherit(void);
-    bool disallowWriteInherit(void);
-
-    /*
-     * Close one side or the other.  Useful in the parent after launching
-     * a child process.
-     */
-    bool closeRead(void);
-    bool closeWrite(void);
-
-private:
-    bool    mReadNonBlocking;
-    bool    mWriteNonBlocking;
-
-    unsigned long mReadHandle;
-    unsigned long mWriteHandle;
-};
-
-}; // android
-
-#endif // _LIBS_UTILS_PIPE_H
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/include/utils/Singleton.h b/include/utils/Singleton.h
new file mode 100644
index 0000000..bc7626a
--- /dev/null
+++ b/include/utils/Singleton.h
@@ -0,0 +1,69 @@
+/*
+ * 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_UTILS_SINGLETON_H
+#define ANDROID_UTILS_SINGLETON_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/threads.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+template <typename TYPE>
+class Singleton
+{
+public:
+    static TYPE& getInstance() {
+        Mutex::Autolock _l(sLock);
+        TYPE* instance = sInstance;
+        if (instance == 0) {
+            instance = new TYPE();
+            sInstance = instance;
+        }
+        return *instance;
+    }
+    
+protected:
+    ~Singleton() { };
+    Singleton() { };
+
+private:
+    Singleton(const Singleton&);
+    Singleton& operator = (const Singleton&);
+    static Mutex sLock;
+    static TYPE* sInstance;
+};
+
+/*
+ * use ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) in your implementation file
+ * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
+ * and avoid to have a copy of them in each compilation units Singleton<TYPE>
+ * is used.
+ */
+
+#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)             \
+    template class Singleton< TYPE >;                       \
+    template< class TYPE > Mutex Singleton< TYPE >::sLock;  \
+    template<> TYPE* Singleton< TYPE >::sInstance(0);
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_UTILS_SINGLETON_H
+
diff --git a/include/utils/Socket.h b/include/utils/Socket.h
deleted file mode 100644
index 8b7f406..0000000
--- a/include/utils/Socket.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// Socket class.  Modeled after Java classes.
-//
-#ifndef _RUNTIME_SOCKET_H
-#define _RUNTIME_SOCKET_H
-
-#include <utils/inet_address.h>
-#include <sys/types.h>
-
-namespace android {
-
-/*
- * Basic socket class, needed to abstract away the differences between
- * BSD sockets and WinSock.  This establishes a streaming network
- * connection (TCP/IP) to somebody.
- */
-class Socket {
-public:
-    Socket(void);
-    ~Socket(void);
-
-    // Create a connection to somewhere.
-    // Return 0 on success.
-    int connect(const char* host, int port);
-    int connect(const InetAddress* addr, int port);
-
-
-    // Close the socket.  Don't try to use this object again after
-    // calling this.  Returns false on failure.
-    bool close(void);
-
-    // If we created the socket without an address, we can use these
-    // to finish the connection.  Returns 0 on success.
-    int bind(const SocketAddress& bindPoint);
-    int connect(const SocketAddress& endPoint);
-
-    // Here we deviate from the traditional object-oriented fanciness
-    // and just provide read/write operators instead of getters for
-    // objects that abstract a stream.
-    //
-    // Standard read/write semantics.
-    int read(void* buf, ssize_t len) const;
-    int write(const void* buf, ssize_t len) const;
-
-    // This must be called once, at program startup.
-    static bool bootInit(void);
-    static void finalShutdown(void);
-
-private:
-    // Internal function that establishes a connection.
-    int doConnect(const InetSocketAddress& addr);
-
-    unsigned long   mSock;      // holds SOCKET or int
-
-    static bool     mBootInitialized;
-};
-
-
-// debug -- unit tests
-void TestSockets(void);
-
-}; // namespace android
-
-#endif // _RUNTIME_SOCKET_H
diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h
index c8a6153..8beec57 100644
--- a/include/utils/SortedVector.h
+++ b/include/utils/SortedVector.h
@@ -141,8 +141,7 @@
     : SortedVectorImpl(sizeof(TYPE),
                 ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)
                 |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)
-                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0)
-                |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
+                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0))
                 )
 {
 }
diff --git a/include/utils/StringArray.h b/include/utils/StringArray.h
new file mode 100644
index 0000000..c2445871
--- /dev/null
+++ b/include/utils/StringArray.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Sortable array of strings.  STL-ish, but STL-free.
+//  
+#ifndef _LIBS_UTILS_STRING_ARRAY_H
+#define _LIBS_UTILS_STRING_ARRAY_H
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace android {
+
+//
+// An expanding array of strings.  Add, get, sort, delete.
+//
+class StringArray {
+public:
+    StringArray();
+    virtual ~StringArray();
+
+    //
+    // Add a string.  A copy of the string is made.
+    //
+    bool push_back(const char* str);
+
+    //
+    // Delete an entry.
+    //
+    void erase(int idx);
+
+    //
+    // Sort the array.
+    //
+    void sort(int (*compare)(const void*, const void*));
+    
+    //
+    // Pass this to the sort routine to do an ascending alphabetical sort.
+    //
+    static int cmpAscendingAlpha(const void* pstr1, const void* pstr2);
+    
+    //
+    // Get the #of items in the array.
+    //
+    inline int size(void) const { return mCurrent; }
+
+    //
+    // Return entry N.
+    // [should use operator[] here]
+    //
+    const char* getEntry(int idx) const {
+        return (unsigned(idx) >= unsigned(mCurrent)) ? NULL : mArray[idx];
+    }
+
+    //
+    // Set entry N to specified string.
+    // [should use operator[] here]
+    //
+    void setEntry(int idx, const char* str);
+
+private:
+    int     mMax;
+    int     mCurrent;
+    char**  mArray;
+};
+
+}; // namespace android
+
+#endif // _LIBS_UTILS_STRING_ARRAY_H
diff --git a/include/utils/TextOutput.h b/include/utils/TextOutput.h
index d8d86ba..de2fbbe 100644
--- a/include/utils/TextOutput.h
+++ b/include/utils/TextOutput.h
@@ -28,8 +28,8 @@
 class TextOutput
 {
 public:
-                        TextOutput() { }
-    virtual             ~TextOutput() { }
+                        TextOutput();
+    virtual             ~TextOutput();
     
     virtual status_t    print(const char* txt, size_t len) = 0;
     virtual void        moveIndent(int delta) = 0;
diff --git a/include/utils/TimerProbe.h b/include/utils/TimerProbe.h
deleted file mode 100644
index f2e32b2..0000000
--- a/include/utils/TimerProbe.h
+++ /dev/null
@@ -1,72 +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_TIMER_PROBE_H
-#define ANDROID_TIMER_PROBE_H
-
-#if 0 && defined(HAVE_POSIX_CLOCKS)
-#define ENABLE_TIMER_PROBE 1
-#else
-#define ENABLE_TIMER_PROBE 0
-#endif
-
-#if ENABLE_TIMER_PROBE
-
-#include <time.h>
-#include <sys/time.h>
-#include <utils/Vector.h>
-
-#define TIMER_PROBE(tag) \
-    static int _timer_slot_; \
-    android::TimerProbe probe(tag, &_timer_slot_)
-#define TIMER_PROBE_END() probe.end()
-#else
-#define TIMER_PROBE(tag)
-#define TIMER_PROBE_END()
-#endif
-
-#if ENABLE_TIMER_PROBE
-namespace android {
-
-class TimerProbe {
-public:
-    TimerProbe(const char tag[], int* slot);
-    void end();
-    ~TimerProbe();
-private:
-    struct Bucket {
-        int mStart, mReal, mProcess, mThread, mCount;
-        const char* mTag;
-        int* mSlotPtr;
-        int mIndent;
-    };
-    static Vector<Bucket> gBuckets;
-    static TimerProbe* gExecuteChain;
-    static int gIndent;
-    static timespec gRealBase;
-    TimerProbe* mNext;
-    static uint32_t ElapsedTime(const timespec& start, const timespec& end);
-    void print(const timespec& r, const timespec& p, const timespec& t) const;
-    timespec mRealStart, mPStart, mTStart;
-    const char* mTag;
-    int mIndent;
-    int mBucket;
-};
-
-}; // namespace android
-
-#endif
-#endif
diff --git a/include/utils/Timers.h b/include/utils/Timers.h
index 9610399..9a9e07c 100644
--- a/include/utils/Timers.h
+++ b/include/utils/Timers.h
@@ -88,9 +88,6 @@
 nsecs_t systemTime(int clock);
 #endif // def __cplusplus
 
-// return the system-time according to the specified clock
-int sleepForInterval(long interval, struct timeval* pNextTick);
-
 #ifdef __cplusplus
 } // extern "C"
 #endif
@@ -108,15 +105,15 @@
  */
 class DurationTimer {
 public:
-    DurationTimer(void) {}
-    ~DurationTimer(void) {}
+    DurationTimer() {}
+    ~DurationTimer() {}
 
     // Start the timer.
-    void start(void);
+    void start();
     // Stop the timer.
-    void stop(void);
+    void stop();
     // Get the duration in microseconds.
-    long long durationUsecs(void) const;
+    long long durationUsecs() const;
 
     // Subtract two timevals.  Returns the difference (ptv1-ptv2) in
     // microseconds.
diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h
index c04c37f..2ff2749 100644
--- a/include/utils/TypeHelpers.h
+++ b/include/utils/TypeHelpers.h
@@ -29,35 +29,39 @@
 /*
  * Types traits
  */
-    
-template <typename T> struct trait_trivial_ctor  { enum { value = false }; };
-template <typename T> struct trait_trivial_dtor  { enum { value = false }; };
-template <typename T> struct trait_trivial_copy  { enum { value = false }; };
-template <typename T> struct trait_trivial_assign{ enum { value = false }; };
 
-template <typename T> struct trait_pointer     { enum { value = false }; };    
-template <typename T> struct trait_pointer<T*> { enum { value = true }; };
+template <typename T> struct trait_trivial_ctor { enum { value = false }; };
+template <typename T> struct trait_trivial_dtor { enum { value = false }; };
+template <typename T> struct trait_trivial_copy { enum { value = false }; };
+template <typename T> struct trait_trivial_move { enum { value = false }; };
+template <typename T> struct trait_pointer      { enum { value = false }; };    
+template <typename T> struct trait_pointer<T*>  { enum { value = true }; };
 
-#define ANDROID_BASIC_TYPES_TRAITS( T )                                       \
-    template<> struct trait_trivial_ctor< T >  { enum { value = true }; };    \
-    template<> struct trait_trivial_dtor< T >  { enum { value = true }; };    \
-    template<> struct trait_trivial_copy< T >  { enum { value = true }; };    \
-    template<> struct trait_trivial_assign< T >{ enum { value = true }; }; 
+// sp<> can be trivially moved
+template <typename T> class sp;
+template <typename T> struct trait_trivial_move< sp<T> >{
+    enum { value = true }; 
+};
 
-#define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign )                    \
-    template<> struct trait_trivial_ctor< T >  { enum { value = ctor }; };    \
-    template<> struct trait_trivial_dtor< T >  { enum { value = dtor }; };    \
-    template<> struct trait_trivial_copy< T >  { enum { value = copy }; };    \
-    template<> struct trait_trivial_assign< T >{ enum { value = assign }; }; 
+// wp<> can be trivially moved
+template <typename T> class wp;
+template <typename T> struct trait_trivial_move< wp<T> >{ 
+    enum { value = true }; 
+};
 
 template <typename TYPE>
 struct traits {
     enum {
+        // whether this type is a pointer
         is_pointer          = trait_pointer<TYPE>::value,
+        // whether this type's constructor is a no-op
         has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
+        // whether this type's destructor is a no-op
         has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
+        // whether this type type can be copy-constructed with memcpy
         has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
-        has_trivial_assign  = is_pointer || trait_trivial_assign<TYPE>::value   
+        // whether this type can be moved with memmove
+        has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value
     };
 };
 
@@ -65,37 +69,47 @@
 struct aggregate_traits {
     enum {
         is_pointer          = false,
-        has_trivial_ctor    = traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
-        has_trivial_dtor    = traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
-        has_trivial_copy    = traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
-        has_trivial_assign  = traits<T>::has_trivial_assign && traits<U>::has_trivial_assign
+        has_trivial_ctor    = 
+            traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
+        has_trivial_dtor    = 
+            traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
+        has_trivial_copy    = 
+            traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
+        has_trivial_move    = 
+            traits<T>::has_trivial_move && traits<U>::has_trivial_move
     };
 };
 
+#define ANDROID_BASIC_TYPES_TRAITS( T )                                     \
+    template<> struct trait_trivial_ctor< T >   { enum { value = true }; }; \
+    template<> struct trait_trivial_dtor< T >   { enum { value = true }; }; \
+    template<> struct trait_trivial_copy< T >   { enum { value = true }; }; \
+    template<> struct trait_trivial_move< T >   { enum { value = true }; };
+
 // ---------------------------------------------------------------------------
 
 /*
  * basic types traits
  */
- 
-ANDROID_BASIC_TYPES_TRAITS( void );
-ANDROID_BASIC_TYPES_TRAITS( bool );
-ANDROID_BASIC_TYPES_TRAITS( char );
-ANDROID_BASIC_TYPES_TRAITS( unsigned char );
-ANDROID_BASIC_TYPES_TRAITS( short );
-ANDROID_BASIC_TYPES_TRAITS( unsigned short );
-ANDROID_BASIC_TYPES_TRAITS( int );
-ANDROID_BASIC_TYPES_TRAITS( unsigned int );
-ANDROID_BASIC_TYPES_TRAITS( long );
-ANDROID_BASIC_TYPES_TRAITS( unsigned long );
-ANDROID_BASIC_TYPES_TRAITS( long long );
-ANDROID_BASIC_TYPES_TRAITS( unsigned long long );
-ANDROID_BASIC_TYPES_TRAITS( float );
-ANDROID_BASIC_TYPES_TRAITS( double );
+
+ANDROID_BASIC_TYPES_TRAITS( void )
+ANDROID_BASIC_TYPES_TRAITS( bool )
+ANDROID_BASIC_TYPES_TRAITS( char )
+ANDROID_BASIC_TYPES_TRAITS( unsigned char )
+ANDROID_BASIC_TYPES_TRAITS( short )
+ANDROID_BASIC_TYPES_TRAITS( unsigned short )
+ANDROID_BASIC_TYPES_TRAITS( int )
+ANDROID_BASIC_TYPES_TRAITS( unsigned int )
+ANDROID_BASIC_TYPES_TRAITS( long )
+ANDROID_BASIC_TYPES_TRAITS( unsigned long )
+ANDROID_BASIC_TYPES_TRAITS( long long )
+ANDROID_BASIC_TYPES_TRAITS( unsigned long long )
+ANDROID_BASIC_TYPES_TRAITS( float )
+ANDROID_BASIC_TYPES_TRAITS( double )
 
 // ---------------------------------------------------------------------------
 
-    
+
 /*
  * compare and order types
  */
@@ -111,9 +125,9 @@
 }
 
 /*
- * create, destroy, copy and assign types...
+ * create, destroy, copy and move types...
  */
- 
+
 template<typename TYPE> inline
 void construct_type(TYPE* p, size_t n) {
     if (!traits<TYPE>::has_trivial_ctor) {
@@ -146,17 +160,6 @@
 }
 
 template<typename TYPE> inline
-void assign_type(TYPE* d, const TYPE* s, size_t n) {
-    if (!traits<TYPE>::has_trivial_assign) {
-        while (n--) {
-            *d++ = *s++;
-        }
-    } else {
-        memcpy(d,s,n*sizeof(TYPE));
-    }
-}
-
-template<typename TYPE> inline
 void splat_type(TYPE* where, const TYPE* what, size_t n) {
     if (!traits<TYPE>::has_trivial_copy) {
         while (n--) {
@@ -164,15 +167,19 @@
             where++;
         }
     } else {
-         while (n--) {
-             *where++ = *what;
+        while (n--) {
+            *where++ = *what;
         }
     }
 }
 
 template<typename TYPE> inline
 void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
-    if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
+    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) 
+            || traits<TYPE>::has_trivial_move) 
+    {
+        memmove(d,s,n*sizeof(TYPE));
+    } else {
         d += n;
         s += n;
         while (n--) {
@@ -180,35 +187,37 @@
             if (!traits<TYPE>::has_trivial_copy) {
                 new(d) TYPE(*s);
             } else {
-                *d = *s;
+                *d = *s;   
             }
             if (!traits<TYPE>::has_trivial_dtor) {
                 s->~TYPE();
             }
         }
-    } else {
-        memmove(d,s,n*sizeof(TYPE));
     }
 }
 
 template<typename TYPE> inline
 void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
-    if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
+    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) 
+            || traits<TYPE>::has_trivial_move) 
+    {
+        memmove(d,s,n*sizeof(TYPE));
+    } else {
         while (n--) {
             if (!traits<TYPE>::has_trivial_copy) {
                 new(d) TYPE(*s);
             } else {
-                *d = *s;
+                *d = *s;   
             }
             if (!traits<TYPE>::has_trivial_dtor) {
                 s->~TYPE();
             }
             d++, s++;
         }
-    } else {
-        memmove(d,s,n*sizeof(TYPE));
     }
 }
+
+
 // ---------------------------------------------------------------------------
 
 /*
@@ -242,8 +251,8 @@
 { enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
 template<> 
 template <typename K, typename V>
-struct trait_trivial_assign< key_value_pair_t<K, V> >
-{ enum { value = aggregate_traits<K,V>::has_trivial_assign};};
+struct trait_trivial_move< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };
 
 // ---------------------------------------------------------------------------
 
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
index be365d8..ad59fd6 100644
--- a/include/utils/Vector.h
+++ b/include/utils/Vector.h
@@ -175,8 +175,7 @@
     : VectorImpl(sizeof(TYPE),
                 ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)
                 |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)
-                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0)
-                |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
+                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0))
                 )
 {
 }
diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h
index 2525229..49b03f1 100644
--- a/include/utils/VectorImpl.h
+++ b/include/utils/VectorImpl.h
@@ -44,7 +44,6 @@
         HAS_TRIVIAL_CTOR    = 0x00000001,
         HAS_TRIVIAL_DTOR    = 0x00000002,
         HAS_TRIVIAL_COPY    = 0x00000004,
-        HAS_TRIVIAL_ASSIGN  = 0x00000008
     };
 
                             VectorImpl(size_t itemSize, uint32_t flags);
diff --git a/include/utils/ZipEntry.h b/include/utils/ZipEntry.h
deleted file mode 100644
index e4698df..0000000
--- a/include/utils/ZipEntry.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-//
-// Zip archive entries.
-//
-// The ZipEntry class is tightly meshed with the ZipFile class.
-//
-#ifndef __LIBS_ZIPENTRY_H
-#define __LIBS_ZIPENTRY_H
-
-#include "Errors.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-namespace android {
-
-class ZipFile;
-
-/*
- * ZipEntry objects represent a single entry in a Zip archive.
- *
- * You can use one of these to get or set information about an entry, but
- * there are no functions here for accessing the data itself.  (We could
- * tuck a pointer to the ZipFile in here for convenience, but that raises
- * the likelihood of using ZipEntry objects after discarding the ZipFile.)
- *
- * File information is stored in two places: next to the file data (the Local
- * File Header, and possibly a Data Descriptor), and at the end of the file
- * (the Central Directory Entry).  The two must be kept in sync.
- */
-class ZipEntry {
-public:
-    friend class ZipFile;
-
-    ZipEntry(void)
-        : mDeleted(false), mMarked(false)
-        {}
-    ~ZipEntry(void) {}
-
-    /*
-     * Returns "true" if the data is compressed.
-     */
-    bool isCompressed(void) const {
-        return mCDE.mCompressionMethod != kCompressStored;
-    }
-    int getCompressionMethod(void) const { return mCDE.mCompressionMethod; }
-
-    /*
-     * Return the uncompressed length.
-     */
-    off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; }
-
-    /*
-     * Return the compressed length.  For uncompressed data, this returns
-     * the same thing as getUncompresesdLen().
-     */
-    off_t getCompressedLen(void) const { return mCDE.mCompressedSize; }
-
-    /*
-     * Return the absolute file offset of the start of the compressed or
-     * uncompressed data.
-     */
-    off_t getFileOffset(void) const {
-        return mCDE.mLocalHeaderRelOffset +
-                LocalFileHeader::kLFHLen +
-                mLFH.mFileNameLength +
-                mLFH.mExtraFieldLength;
-    }
-
-    /*
-     * Return the data CRC.
-     */
-    unsigned long getCRC32(void) const { return mCDE.mCRC32; }
-
-    /*
-     * Return file modification time in UNIX seconds-since-epoch.
-     */
-    time_t getModWhen(void) const;
-
-    /*
-     * Return the archived file name.
-     */
-    const char* getFileName(void) const { return (const char*) mCDE.mFileName; }
-
-    /*
-     * Application-defined "mark".  Can be useful when synchronizing the
-     * contents of an archive with contents on disk.
-     */
-    bool getMarked(void) const { return mMarked; }
-    void setMarked(bool val) { mMarked = val; }
-
-    /*
-     * Some basic functions for raw data manipulation.  "LE" means
-     * Little Endian.
-     */
-    static inline unsigned short getShortLE(const unsigned char* buf) {
-        return buf[0] | (buf[1] << 8);
-    }
-    static inline unsigned long getLongLE(const unsigned char* buf) {
-        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
-    }
-    static inline void putShortLE(unsigned char* buf, short val) {
-        buf[0] = (unsigned char) val;
-        buf[1] = (unsigned char) (val >> 8);
-    }
-    static inline void putLongLE(unsigned char* buf, long val) {
-        buf[0] = (unsigned char) val;
-        buf[1] = (unsigned char) (val >> 8);
-        buf[2] = (unsigned char) (val >> 16);
-        buf[3] = (unsigned char) (val >> 24);
-    }
-
-    /* defined for Zip archives */
-    enum {
-        kCompressStored     = 0,        // no compression
-        // shrunk           = 1,
-        // reduced 1        = 2,
-        // reduced 2        = 3,
-        // reduced 3        = 4,
-        // reduced 4        = 5,
-        // imploded         = 6,
-        // tokenized        = 7,
-        kCompressDeflated   = 8,        // standard deflate
-        // Deflate64        = 9,
-        // lib imploded     = 10,
-        // reserved         = 11,
-        // bzip2            = 12,
-    };
-
-    /*
-     * Deletion flag.  If set, the entry will be removed on the next
-     * call to "flush".
-     */
-    bool getDeleted(void) const { return mDeleted; }
-
-protected:
-    /*
-     * Initialize the structure from the file, which is pointing at
-     * our Central Directory entry.
-     */
-    status_t initFromCDE(FILE* fp);
-
-    /*
-     * Initialize the structure for a new file.  We need the filename
-     * and comment so that we can properly size the LFH area.  The
-     * filename is mandatory, the comment is optional.
-     */
-    void initNew(const char* fileName, const char* comment);
-
-    /*
-     * Initialize the structure with the contents of a ZipEntry from
-     * another file.
-     */
-    status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry);
-
-    /*
-     * Add some pad bytes to the LFH.  We do this by adding or resizing
-     * the "extra" field.
-     */
-    status_t addPadding(int padding);
-
-    /*
-     * Set information about the data for this entry.
-     */
-    void setDataInfo(long uncompLen, long compLen, unsigned long crc32,
-        int compressionMethod);
-
-    /*
-     * Set the modification date.
-     */
-    void setModWhen(time_t when);
-
-    /*
-     * Return the offset of the local file header.
-     */
-    off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }
-
-    /*
-     * Set the offset of the local file header, relative to the start of
-     * the current file.
-     */
-    void setLFHOffset(off_t offset) {
-        mCDE.mLocalHeaderRelOffset = (long) offset;
-    }
-
-    /* mark for deletion; used by ZipFile::remove() */
-    void setDeleted(void) { mDeleted = true; }
-
-private:
-    /* these are private and not defined */
-    ZipEntry(const ZipEntry& src);
-    ZipEntry& operator=(const ZipEntry& src);
-
-    /* returns "true" if the CDE and the LFH agree */
-    bool compareHeaders(void) const;
-    void copyCDEtoLFH(void);
-
-    bool        mDeleted;       // set if entry is pending deletion
-    bool        mMarked;        // app-defined marker
-
-    /*
-     * Every entry in the Zip archive starts off with one of these.
-     */
-    class LocalFileHeader {
-    public:
-        LocalFileHeader(void) :
-            mVersionToExtract(0),
-            mGPBitFlag(0),
-            mCompressionMethod(0),
-            mLastModFileTime(0),
-            mLastModFileDate(0),
-            mCRC32(0),
-            mCompressedSize(0),
-            mUncompressedSize(0),
-            mFileNameLength(0),
-            mExtraFieldLength(0),
-            mFileName(NULL),
-            mExtraField(NULL)
-        {}
-        virtual ~LocalFileHeader(void) {
-            delete[] mFileName;
-            delete[] mExtraField;
-        }
-
-        status_t read(FILE* fp);
-        status_t write(FILE* fp);
-
-        // unsigned long mSignature;
-        unsigned short  mVersionToExtract;
-        unsigned short  mGPBitFlag;
-        unsigned short  mCompressionMethod;
-        unsigned short  mLastModFileTime;
-        unsigned short  mLastModFileDate;
-        unsigned long   mCRC32;
-        unsigned long   mCompressedSize;
-        unsigned long   mUncompressedSize;
-        unsigned short  mFileNameLength;
-        unsigned short  mExtraFieldLength;
-        unsigned char*  mFileName;
-        unsigned char*  mExtraField;
-
-        enum {
-            kSignature      = 0x04034b50,
-            kLFHLen         = 30,       // LocalFileHdr len, excl. var fields
-        };
-
-        void dump(void) const;
-    };
-
-    /*
-     * Every entry in the Zip archive has one of these in the "central
-     * directory" at the end of the file.
-     */
-    class CentralDirEntry {
-    public:
-        CentralDirEntry(void) :
-            mVersionMadeBy(0),
-            mVersionToExtract(0),
-            mGPBitFlag(0),
-            mCompressionMethod(0),
-            mLastModFileTime(0),
-            mLastModFileDate(0),
-            mCRC32(0),
-            mCompressedSize(0),
-            mUncompressedSize(0),
-            mFileNameLength(0),
-            mExtraFieldLength(0),
-            mFileCommentLength(0),
-            mDiskNumberStart(0),
-            mInternalAttrs(0),
-            mExternalAttrs(0),
-            mLocalHeaderRelOffset(0),
-            mFileName(NULL),
-            mExtraField(NULL),
-            mFileComment(NULL)
-        {}
-        virtual ~CentralDirEntry(void) {
-            delete[] mFileName;
-            delete[] mExtraField;
-            delete[] mFileComment;
-        }
-
-        status_t read(FILE* fp);
-        status_t write(FILE* fp);
-
-        // unsigned long mSignature;
-        unsigned short  mVersionMadeBy;
-        unsigned short  mVersionToExtract;
-        unsigned short  mGPBitFlag;
-        unsigned short  mCompressionMethod;
-        unsigned short  mLastModFileTime;
-        unsigned short  mLastModFileDate;
-        unsigned long   mCRC32;
-        unsigned long   mCompressedSize;
-        unsigned long   mUncompressedSize;
-        unsigned short  mFileNameLength;
-        unsigned short  mExtraFieldLength;
-        unsigned short  mFileCommentLength;
-        unsigned short  mDiskNumberStart;
-        unsigned short  mInternalAttrs;
-        unsigned long   mExternalAttrs;
-        unsigned long   mLocalHeaderRelOffset;
-        unsigned char*  mFileName;
-        unsigned char*  mExtraField;
-        unsigned char*  mFileComment;
-
-        void dump(void) const;
-
-        enum {
-            kSignature      = 0x02014b50,
-            kCDELen         = 46,       // CentralDirEnt len, excl. var fields
-        };
-    };
-
-    enum {
-        //kDataDescriptorSignature  = 0x08074b50,   // currently unused
-        kDataDescriptorLen  = 16,           // four 32-bit fields
-
-        kDefaultVersion     = 20,           // need deflate, nothing much else
-        kDefaultMadeBy      = 0x0317,       // 03=UNIX, 17=spec v2.3
-        kUsesDataDescr      = 0x0008,       // GPBitFlag bit 3
-    };
-
-    LocalFileHeader     mLFH;
-    CentralDirEntry     mCDE;
-};
-
-}; // namespace android
-
-#endif // __LIBS_ZIPENTRY_H
diff --git a/include/utils/ZipFile.h b/include/utils/ZipFile.h
deleted file mode 100644
index 44df5bb..0000000
--- a/include/utils/ZipFile.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-//
-// General-purpose Zip archive access.  This class allows both reading and
-// writing to Zip archives, including deletion of existing entries.
-//
-#ifndef __LIBS_ZIPFILE_H
-#define __LIBS_ZIPFILE_H
-
-#include "ZipEntry.h"
-#include "Vector.h"
-#include "Errors.h"
-#include <stdio.h>
-
-namespace android {
-
-/*
- * Manipulate a Zip archive.
- *
- * Some changes will not be visible in the until until "flush" is called.
- *
- * The correct way to update a file archive is to make all changes to a
- * copy of the archive in a temporary file, and then unlink/rename over
- * the original after everything completes.  Because we're only interested
- * in using this for packaging, we don't worry about such things.  Crashing
- * after making changes and before flush() completes could leave us with
- * an unusable Zip archive.
- */
-class ZipFile {
-public:
-    ZipFile(void)
-      : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false)
-      {}
-    ~ZipFile(void) {
-        if (!mReadOnly)
-            flush();
-        if (mZipFp != NULL)
-            fclose(mZipFp);
-        discardEntries();
-    }
-
-    /*
-     * Open a new or existing archive.
-     */
-    typedef enum {
-        kOpenReadOnly   = 0x01,
-        kOpenReadWrite  = 0x02,
-        kOpenCreate     = 0x04,     // create if it doesn't exist
-        kOpenTruncate   = 0x08,     // if it exists, empty it
-    };
-    status_t open(const char* zipFileName, int flags);
-
-    /*
-     * Add a file to the end of the archive.  Specify whether you want the
-     * library to try to store it compressed.
-     *
-     * If "storageName" is specified, the archive will use that instead
-     * of "fileName".
-     *
-     * If there is already an entry with the same name, the call fails.
-     * Existing entries with the same name must be removed first.
-     *
-     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
-     */
-    status_t add(const char* fileName, int compressionMethod,
-        ZipEntry** ppEntry)
-    {
-        return add(fileName, fileName, compressionMethod, ppEntry);
-    }
-    status_t add(const char* fileName, const char* storageName,
-        int compressionMethod, ZipEntry** ppEntry)
-    {
-        return addCommon(fileName, NULL, 0, storageName,
-                         ZipEntry::kCompressStored,
-                         compressionMethod, ppEntry);
-    }
-
-    /*
-     * Add a file that is already compressed with gzip.
-     *
-     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
-     */
-    status_t addGzip(const char* fileName, const char* storageName,
-        ZipEntry** ppEntry)
-    {
-        return addCommon(fileName, NULL, 0, storageName,
-                         ZipEntry::kCompressDeflated,
-                         ZipEntry::kCompressDeflated, ppEntry);
-    }
-
-    /*
-     * Add a file from an in-memory data buffer.
-     *
-     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
-     */
-    status_t add(const void* data, size_t size, const char* storageName,
-        int compressionMethod, ZipEntry** ppEntry)
-    {
-        return addCommon(NULL, data, size, storageName,
-                         ZipEntry::kCompressStored,
-                         compressionMethod, ppEntry);
-    }
-
-    /*
-     * Add an entry by copying it from another zip file.  If "padding" is
-     * nonzero, the specified number of bytes will be added to the "extra"
-     * field in the header.
-     *
-     * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
-     */
-    status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
-        int padding, ZipEntry** ppEntry);
-
-    /*
-     * Mark an entry as having been removed.  It is not actually deleted
-     * from the archive or our internal data structures until flush() is
-     * called.
-     */
-    status_t remove(ZipEntry* pEntry);
-
-    /*
-     * Flush changes.  If mNeedCDRewrite is set, this writes the central dir.
-     */
-    status_t flush(void);
-
-    /*
-     * Expand the data into the buffer provided.  The buffer must hold
-     * at least <uncompressed len> bytes.  Variation expands directly
-     * to a file.
-     *
-     * Returns "false" if an error was encountered in the compressed data.
-     */
-    //bool uncompress(const ZipEntry* pEntry, void* buf) const;
-    //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;
-    void* uncompress(const ZipEntry* pEntry);
-
-    /*
-     * Get an entry, by name.  Returns NULL if not found.
-     *
-     * Does not return entries pending deletion.
-     */
-    ZipEntry* getEntryByName(const char* fileName) const;
-
-    /*
-     * Get the Nth entry in the archive.
-     *
-     * This will return an entry that is pending deletion.
-     */
-    int getNumEntries(void) const { return mEntries.size(); }
-    ZipEntry* getEntryByIndex(int idx) const;
-
-private:
-    /* these are private and not defined */
-    ZipFile(const ZipFile& src);
-    ZipFile& operator=(const ZipFile& src);
-
-    class EndOfCentralDir {
-    public:
-        EndOfCentralDir(void) :
-            mDiskNumber(0),
-            mDiskWithCentralDir(0),
-            mNumEntries(0),
-            mTotalNumEntries(0),
-            mCentralDirSize(0),
-            mCentralDirOffset(0),
-            mCommentLen(0),
-            mComment(NULL)
-            {}
-        virtual ~EndOfCentralDir(void) {
-            delete[] mComment;
-        }
-
-        status_t readBuf(const unsigned char* buf, int len);
-        status_t write(FILE* fp);
-
-        //unsigned long   mSignature;
-        unsigned short  mDiskNumber;
-        unsigned short  mDiskWithCentralDir;
-        unsigned short  mNumEntries;
-        unsigned short  mTotalNumEntries;
-        unsigned long   mCentralDirSize;
-        unsigned long   mCentralDirOffset;      // offset from first disk
-        unsigned short  mCommentLen;
-        unsigned char*  mComment;
-
-        enum {
-            kSignature      = 0x06054b50,
-            kEOCDLen        = 22,       // EndOfCentralDir len, excl. comment
-
-            kMaxCommentLen  = 65535,    // longest possible in ushort
-            kMaxEOCDSearch  = kMaxCommentLen + EndOfCentralDir::kEOCDLen,
-
-        };
-
-        void dump(void) const;
-    };
-
-
-    /* read all entries in the central dir */
-    status_t readCentralDir(void);
-
-    /* crunch deleted entries out */
-    status_t crunchArchive(void);
-
-    /* clean up mEntries */
-    void discardEntries(void);
-
-    /* common handler for all "add" functions */
-    status_t addCommon(const char* fileName, const void* data, size_t size,
-        const char* storageName, int sourceType, int compressionMethod,
-        ZipEntry** ppEntry);
-
-    /* copy all of "srcFp" into "dstFp" */
-    status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32);
-    /* copy all of "data" into "dstFp" */
-    status_t copyDataToFp(FILE* dstFp,
-        const void* data, size_t size, unsigned long* pCRC32);
-    /* copy some of "srcFp" into "dstFp" */
-    status_t copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
-        unsigned long* pCRC32);
-    /* like memmove(), but on parts of a single file */
-    status_t filemove(FILE* fp, off_t dest, off_t src, size_t n);
-    /* compress all of "srcFp" into "dstFp", using Deflate */
-    status_t compressFpToFp(FILE* dstFp, FILE* srcFp,
-        const void* data, size_t size, unsigned long* pCRC32);
-
-    /* get modification date from a file descriptor */
-    time_t getModTime(int fd);
-
-    /*
-     * We use stdio FILE*, which gives us buffering but makes dealing
-     * with files >2GB awkward.  Until we support Zip64, we're fine.
-     */
-    FILE*           mZipFp;             // Zip file pointer
-
-    /* one of these per file */
-    EndOfCentralDir mEOCD;
-
-    /* did we open this read-only? */
-    bool            mReadOnly;
-
-    /* set this when we trash the central dir */
-    bool            mNeedCDRewrite;
-
-    /*
-     * One ZipEntry per entry in the zip file.  I'm using pointers instead
-     * of objects because it's easier than making operator= work for the
-     * classes and sub-classes.
-     */
-    Vector<ZipEntry*>   mEntries;
-};
-
-}; // namespace android
-
-#endif // __LIBS_ZIPFILE_H
diff --git a/include/utils/executablepath.h b/include/utils/executablepath.h
deleted file mode 100644
index c979432..0000000
--- a/include/utils/executablepath.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _UTILS_EXECUTABLEPATH_H
-#define _UTILS_EXECUTABLEPATH_H
-
-#include <limits.h>
-
-// returns the path to this executable
-#if __cplusplus
-extern "C"
-#endif
-void executablepath(char s[PATH_MAX]);
-
-#endif // _UTILS_EXECUTABLEPATH_H
diff --git a/include/utils/inet_address.h b/include/utils/inet_address.h
deleted file mode 100644
index dbd8672..0000000
--- a/include/utils/inet_address.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// Internet address classes.  Modeled after Java classes.
-//
-#ifndef _RUNTIME_INET_ADDRESS_H
-#define _RUNTIME_INET_ADDRESS_H
-
-#ifdef HAVE_ANDROID_OS
-#error DO NOT USE THIS FILE IN THE DEVICE BUILD
-#endif
-
-
-namespace android {
-
-/*
- * This class holds Internet addresses.  Perhaps more useful is its
- * ability to look up addresses by name.
- *
- * Invoke one of the static factory methods to create a new object.
- */
-class InetAddress {
-public:
-    virtual ~InetAddress(void);
-
-    // create from w.x.y.z or foo.bar.com notation
-    static InetAddress* getByName(const char* host);
-
-    // copy-construction
-    InetAddress(const InetAddress& orig);
-
-    const void* getAddress(void) const { return mAddress; }
-    int getAddressLength(void) const { return mLength; }
-    const char* getHostName(void) const { return mName; }
-
-private:
-    InetAddress(void);
-    // assignment (private)
-    InetAddress& operator=(const InetAddress& addr);
-
-    // use a void* here so we don't have to expose actual socket headers
-    void*       mAddress;   // this is really a ptr to sockaddr_in
-    int         mLength;
-    char*       mName;
-};
-
-
-/*
- * Base class for socket addresses.
- */
-class SocketAddress {
-public:
-    SocketAddress() {}
-    virtual ~SocketAddress() {}
-};
-
-
-/*
- * Internet address class.  This combines an InetAddress with a port.
- */
-class InetSocketAddress : public SocketAddress {
-public:
-    InetSocketAddress() :
-        mAddress(0), mPort(-1)
-        {}
-    ~InetSocketAddress(void) {
-        delete mAddress;
-    }
-
-    // Create an address with a host wildcard (useful for servers).
-    bool create(int port);
-    // Create an address with the specified host and port.
-    bool create(const InetAddress* addr, int port);
-    // Create an address with the specified host and port.  Does the
-    // hostname lookup.
-    bool create(const char* host, int port);
-
-    const InetAddress* getAddress(void) const { return mAddress; }
-    const int getPort(void) const { return mPort; }
-    const char* getHostName(void) const { return mAddress->getHostName(); }
-
-private:
-    InetAddress* mAddress;
-    int         mPort;
-};
-
-}; // namespace android
-
-#endif // _RUNTIME_INET_ADDRESS_H
diff --git a/include/utils/misc.h b/include/utils/misc.h
index 62e84b4..23f2a4c 100644
--- a/include/utils/misc.h
+++ b/include/utils/misc.h
@@ -21,7 +21,7 @@
 #define _LIBS_UTILS_MISC_H
 
 #include <sys/time.h>
-#include "utils/Endian.h"
+#include <utils/Endian.h>
 
 namespace android {
 
diff --git a/include/utils/ported.h b/include/utils/ported.h
deleted file mode 100644
index eb3be01..0000000
--- a/include/utils/ported.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// Standard functions ported to the current platform.  Note these are NOT
-// in the "android" namespace.
-//
-#ifndef _LIBS_UTILS_PORTED_H
-#define _LIBS_UTILS_PORTED_H
-
-#include <sys/time.h>       // for timeval
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* library replacement functions */
-#if defined(NEED_GETTIMEOFDAY)
-int gettimeofday(struct timeval* tv, struct timezone* tz);
-#endif
-#if defined(NEED_USLEEP)
-void usleep(unsigned long usec);
-#endif
-#if defined(NEED_PIPE)
-int pipe(int filedes[2]);
-#endif
-#if defined(NEED_SETENV)
-int setenv(const char* name, const char* value, int overwrite);
-void unsetenv(const char* name);
-char* getenv(const char* name);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _LIBS_UTILS_PORTED_H
diff --git a/include/utils/string_array.h b/include/utils/string_array.h
deleted file mode 100644
index 064dda2..0000000
--- a/include/utils/string_array.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// Sortable array of strings.  STL-ish, but STL-free.
-//  
-#ifndef _LIBS_UTILS_STRING_ARRAY_H
-#define _LIBS_UTILS_STRING_ARRAY_H
-
-#include <stdlib.h>
-#include <string.h>
-
-namespace android {
-
-//
-// An expanding array of strings.  Add, get, sort, delete.
-//
-class StringArray {
-public:
-    StringArray()
-        : mMax(0), mCurrent(0), mArray(NULL)
-        {}
-    virtual ~StringArray() {
-        for (int i = 0; i < mCurrent; i++)
-            delete[] mArray[i];
-        delete[] mArray;
-    }
-
-    //
-    // Add a string.  A copy of the string is made.
-    //
-    bool push_back(const char* str) {
-        if (mCurrent >= mMax) {
-            char** tmp;
-
-            if (mMax == 0)
-                mMax = 16;      // initial storage
-            else
-                mMax *= 2;
-
-            tmp = new char*[mMax];
-            if (tmp == NULL)
-                return false;
-
-            memcpy(tmp, mArray, mCurrent * sizeof(char*));
-            delete[] mArray;
-            mArray = tmp;
-        }
-
-        int len = strlen(str);
-        mArray[mCurrent] = new char[len+1];
-        memcpy(mArray[mCurrent], str, len+1);
-        mCurrent++;
-
-        return true;
-    }
-
-    //
-    // Delete an entry.
-    //
-    void erase(int idx) {
-        if (idx < 0 || idx >= mCurrent)
-            return;
-        delete[] mArray[idx];
-        if (idx < mCurrent-1) {
-            memmove(&mArray[idx], &mArray[idx+1],
-                (mCurrent-1 - idx) * sizeof(char*));
-        }
-        mCurrent--;
-    }
-
-    //
-    // Sort the array.
-    //
-    void sort(int (*compare)(const void*, const void*)) {
-        qsort(mArray, mCurrent, sizeof(char*), compare);
-    }
-
-    //
-    // Pass this to the sort routine to do an ascending alphabetical sort.
-    //
-    static int cmpAscendingAlpha(const void* pstr1, const void* pstr2) {
-        return strcmp(*(const char**)pstr1, *(const char**)pstr2);
-    }
-
-    //
-    // Get the #of items in the array.
-    //
-    inline int size(void) const { return mCurrent; }
-
-    //
-    // Return entry N.
-    // [should use operator[] here]
-    //
-    const char* getEntry(int idx) const {
-        if (idx < 0 || idx >= mCurrent)
-            return NULL;
-        return mArray[idx];
-    }
-
-    //
-    // Set entry N to specified string.
-    // [should use operator[] here]
-    //
-    void setEntry(int idx, const char* str) {
-        if (idx < 0 || idx >= mCurrent)
-            return;
-        delete[] mArray[idx];
-        int len = strlen(str);
-        mArray[idx] = new char[len+1];
-        memcpy(mArray[idx], str, len+1);
-    }
-
-private:
-    int     mMax;
-    int     mCurrent;
-    char**  mArray;
-};
-
-}; // namespace android
-
-#endif // _LIBS_UTILS_STRING_ARRAY_H
diff --git a/include/utils/threads.h b/include/utils/threads.h
index b320915..e0cb664 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -199,11 +199,11 @@
     // constructed and released when Autolock goes out of scope.
     class Autolock {
     public:
-        inline Autolock(Mutex& mutex) : mpMutex(&mutex) { mutex.lock(); }
-        inline Autolock(Mutex* mutex) : mpMutex(mutex) { mutex->lock(); }
-        inline ~Autolock() { mpMutex->unlock(); }
+        inline Autolock(Mutex& mutex) : mLock(mutex)  { mLock.lock(); }
+        inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
+        inline ~Autolock() { mLock.unlock(); }
     private:
-        Mutex*  mpMutex;
+        Mutex& mLock;
     };
 
 private:
@@ -291,7 +291,7 @@
             bool        exitPending() const;
     
 private:
-    // Derived class must implemtent threadLoop(). The thread starts its life
+    // Derived class must implement threadLoop(). The thread starts its life
     // here. There are two ways of using the Thread object:
     // 1) loop: if threadLoop() returns true, it will be called again if
     //          requestExit() wasn't called.
diff --git a/libs/audioflinger/Android.mk b/libs/audioflinger/Android.mk
index 50d516b..ea7d6c2 100644
--- a/libs/audioflinger/Android.mk
+++ b/libs/audioflinger/Android.mk
@@ -11,6 +11,7 @@
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     libutils \
+	libbinder \
     libmedia \
     libhardware_legacy
 
@@ -34,6 +35,7 @@
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     libutils \
+	libbinder \
     libmedia \
     libhardware_legacy
 
@@ -49,8 +51,7 @@
   LOCAL_SRC_FILES += A2dpAudioInterface.cpp
   LOCAL_SHARED_LIBRARIES += liba2dp
   LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
-  LOCAL_C_INCLUDES += $(call include-path-for, bluez-libs)
-  LOCAL_C_INCLUDES += $(call include-path-for, bluez-utils)
+  LOCAL_C_INCLUDES += $(call include-path-for, bluez)
 endif
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index f5bdeda..598a356 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -24,10 +24,10 @@
 #include <sys/time.h>
 #include <sys/resource.h>
 
-#include <utils/IServiceManager.h>
+#include <binder/IServiceManager.h>
 #include <utils/Log.h>
-#include <utils/Parcel.h>
-#include <utils/IPCThreadState.h>
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
 #include <utils/String16.h>
 #include <utils/threads.h>
 
@@ -653,6 +653,7 @@
     }
 
     status_t ret = NO_ERROR;
+    
     if (stream == AudioSystem::VOICE_CALL ||
         stream == AudioSystem::BLUETOOTH_SCO) {
         float hwValue;
@@ -669,7 +670,13 @@
         mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
         ret = mAudioHardware->setVoiceVolume(hwValue);
         mHardwareStatus = AUDIO_HW_IDLE;
+        
     }
+    
+    mHardwareMixerThread->setStreamVolume(stream, value);
+#ifdef WITH_A2DP
+    mA2dpMixerThread->setStreamVolume(stream, value);
+#endif
 
     mHardwareMixerThread->setStreamVolume(stream, value);
 #ifdef WITH_A2DP
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 634934e..3531a58 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -30,7 +30,7 @@
 #include <utils/Atomic.h>
 #include <utils/Errors.h>
 #include <utils/threads.h>
-#include <utils/MemoryDealer.h>
+#include <binder/MemoryDealer.h>
 #include <utils/KeyedVector.h>
 #include <utils/SortedVector.h>
 #include <utils/Vector.h>
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk
new file mode 100644
index 0000000..2df6775
--- /dev/null
+++ b/libs/binder/Android.mk
@@ -0,0 +1,45 @@
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# we have the common sources, plus some device-specific stuff
+LOCAL_SRC_FILES:= \
+	Binder.cpp \
+	BpBinder.cpp \
+	IInterface.cpp \
+	IMemory.cpp \
+	IPCThreadState.cpp \
+	IPermissionController.cpp \
+	IServiceManager.cpp \
+	MemoryDealer.cpp \
+    MemoryBase.cpp \
+    MemoryHeapBase.cpp \
+    MemoryHeapPmem.cpp \
+	Parcel.cpp \
+	Permission.cpp \
+	ProcessState.cpp \
+	Static.cpp
+
+LOCAL_LDLIBS += -lpthread
+
+LOCAL_SHARED_LIBRARIES := \
+	liblog \
+	libcutils \
+	libutils
+
+LOCAL_MODULE:= libbinder
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/utils/Binder.cpp b/libs/binder/Binder.cpp
similarity index 92%
rename from libs/utils/Binder.cpp
rename to libs/binder/Binder.cpp
index 37e4685..0dd7622 100644
--- a/libs/utils/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-#include <utils/Binder.h>
+#include <binder/Binder.h>
 
 #include <utils/Atomic.h>
-#include <utils/BpBinder.h>
-#include <utils/IInterface.h>
-#include <utils/Parcel.h>
+#include <binder/BpBinder.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
 
 #include <stdio.h>
 
@@ -27,6 +27,17 @@
 
 // ---------------------------------------------------------------------------
 
+IBinder::IBinder()
+    : RefBase()
+{
+}
+
+IBinder::~IBinder()
+{
+}
+
+// ---------------------------------------------------------------------------
+
 sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)
 {
     return NULL;
@@ -58,6 +69,8 @@
 
 // ---------------------------------------------------------------------------
 
+String16 BBinder::sEmptyDescriptor;
+
 BBinder::BBinder()
     : mExtras(NULL)
 {
@@ -73,10 +86,10 @@
     return NO_ERROR;
 }
 
-String16 BBinder::getInterfaceDescriptor() const
+const String16& BBinder::getInterfaceDescriptor() const
 {
     LOGW("reached BBinder::getInterfaceDescriptor (this=%p)", this);
-    return String16();
+    return sEmptyDescriptor;
 }
 
 status_t BBinder::transact(
diff --git a/libs/utils/BpBinder.cpp b/libs/binder/BpBinder.cpp
similarity index 89%
rename from libs/utils/BpBinder.cpp
rename to libs/binder/BpBinder.cpp
index 69ab195..5de87ec 100644
--- a/libs/utils/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -17,9 +17,9 @@
 #define LOG_TAG "BpBinder"
 //#define LOG_NDEBUG 0
 
-#include <utils/BpBinder.h>
+#include <binder/BpBinder.h>
 
-#include <utils/IPCThreadState.h>
+#include <binder/IPCThreadState.h>
 #include <utils/Log.h>
 
 #include <stdio.h>
@@ -98,16 +98,33 @@
     IPCThreadState::self()->incWeakHandle(handle);
 }
 
-String16 BpBinder::getInterfaceDescriptor() const
+bool BpBinder::isDescriptorCached() const {
+    Mutex::Autolock _l(mLock);
+    return mDescriptorCache.size() ? true : false;
+}
+
+const String16& BpBinder::getInterfaceDescriptor() const
 {
-    String16 res;
-    Parcel send, reply;
-    status_t err = const_cast<BpBinder*>(this)->transact(
-            INTERFACE_TRANSACTION, send, &reply);
-    if (err == NO_ERROR) {
-        res = reply.readString16();
+    if (isDescriptorCached() == false) {
+        Parcel send, reply;
+        // do the IPC without a lock held.
+        status_t err = const_cast<BpBinder*>(this)->transact(
+                INTERFACE_TRANSACTION, send, &reply);
+        if (err == NO_ERROR) {
+            String16 res(reply.readString16());
+            Mutex::Autolock _l(mLock);
+            // mDescriptorCache could have been assigned while the lock was
+            // released.
+            if (mDescriptorCache.size() == 0)
+                mDescriptorCache = res;
+        }
     }
-    return res;
+    
+    // we're returning a reference to a non-static object here. Usually this
+    // is not something smart to do, however, with binder objects it is 
+    // (usually) safe because they are reference-counted.
+    
+    return mDescriptorCache;
 }
 
 bool BpBinder::isBinderAlive() const
diff --git a/libs/utils/IInterface.cpp b/libs/binder/IInterface.cpp
similarity index 90%
rename from libs/utils/IInterface.cpp
rename to libs/binder/IInterface.cpp
index 6ea8178..29acf5d 100644
--- a/libs/utils/IInterface.cpp
+++ b/libs/binder/IInterface.cpp
@@ -14,12 +14,19 @@
  * limitations under the License.
  */
 
-#include <utils/IInterface.h>
+#include <binder/IInterface.h>
 
 namespace android {
 
 // ---------------------------------------------------------------------------
 
+IInterface::IInterface() 
+    : RefBase() {
+}
+
+IInterface::~IInterface() {
+}
+
 sp<IBinder> IInterface::asBinder()
 {
     return this ? onAsBinder() : NULL;
diff --git a/libs/utils/IMemory.cpp b/libs/binder/IMemory.cpp
similarity index 96%
rename from libs/utils/IMemory.cpp
rename to libs/binder/IMemory.cpp
index 429bc2b..6c1d225 100644
--- a/libs/utils/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -25,11 +25,11 @@
 #include <sys/types.h>
 #include <sys/mman.h>
 
-#include <utils/IMemory.h>
+#include <binder/IMemory.h>
 #include <utils/KeyedVector.h>
 #include <utils/threads.h>
 #include <utils/Atomic.h>
-#include <utils/Parcel.h>
+#include <binder/Parcel.h>
 #include <utils/CallStack.h>
 
 #define VERBOSE   0
@@ -205,11 +205,11 @@
 
 IMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory");
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
+BnMemory::BnMemory() {
+}
+
+BnMemory::~BnMemory() { 
+}
 
 status_t BnMemory::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
@@ -299,11 +299,11 @@
         ssize_t size = reply.readInt32();
         uint32_t flags = reply.readInt32();
 
-        LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%d, err=%d (%s)",
+        LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)",
                 asBinder().get(), parcel_fd, size, err, strerror(-err));
 
         int fd = dup( parcel_fd );
-        LOGE_IF(fd==-1, "cannot dup fd=%d, size=%d, err=%d (%s)",
+        LOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)",
                 parcel_fd, size, err, strerror(errno));
 
         int access = PROT_READ;
@@ -316,7 +316,7 @@
             mRealHeap = true;
             mBase = mmap(0, size, access, MAP_SHARED, fd, 0);
             if (mBase == MAP_FAILED) {
-                LOGE("cannot map BpMemoryHeap (binder=%p), size=%d, fd=%d (%s)",
+                LOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)",
                         asBinder().get(), size, fd, strerror(errno));
                 close(fd);
             } else {
@@ -357,8 +357,14 @@
 
 IMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap");
 
+BnMemoryHeap::BnMemoryHeap() { 
+}
+
+BnMemoryHeap::~BnMemoryHeap() { 
+}
+
 status_t BnMemoryHeap::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
     switch(code) {
        case HEAP_ID: {
diff --git a/libs/utils/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
similarity index 99%
rename from libs/utils/IPCThreadState.cpp
rename to libs/binder/IPCThreadState.cpp
index 04ae142..c3889e9 100644
--- a/libs/utils/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-#include <utils/IPCThreadState.h>
+#include <binder/IPCThreadState.h>
 
-#include <utils/Binder.h>
-#include <utils/BpBinder.h>
+#include <binder/Binder.h>
+#include <binder/BpBinder.h>
 #include <utils/Debug.h>
 #include <utils/Log.h>
 #include <utils/TextOutput.h>
 #include <utils/threads.h>
 
-#include <private/utils/binder_module.h>
-#include <private/utils/Static.h>
+#include <private/binder/binder_module.h>
+#include <private/binder/Static.h>
 
 #include <sys/ioctl.h>
 #include <signal.h>
diff --git a/libs/utils/IPermissionController.cpp b/libs/binder/IPermissionController.cpp
similarity index 87%
rename from libs/utils/IPermissionController.cpp
rename to libs/binder/IPermissionController.cpp
index f01d38f..bff4c9b 100644
--- a/libs/utils/IPermissionController.cpp
+++ b/libs/binder/IPermissionController.cpp
@@ -16,14 +16,14 @@
 
 #define LOG_TAG "PermissionController"
 
-#include <utils/IPermissionController.h>
+#include <binder/IPermissionController.h>
 
 #include <utils/Debug.h>
 #include <utils/Log.h>
-#include <utils/Parcel.h>
+#include <binder/Parcel.h>
 #include <utils/String8.h>
 
-#include <private/utils/Static.h>
+#include <private/binder/Static.h>
 
 namespace android {
 
@@ -55,12 +55,6 @@
 
 // ----------------------------------------------------------------------
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t BnPermissionController::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/libs/utils/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
similarity index 93%
rename from libs/utils/IServiceManager.cpp
rename to libs/binder/IServiceManager.cpp
index 9beeadd..0cf4158 100644
--- a/libs/utils/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -16,16 +16,16 @@
 
 #define LOG_TAG "ServiceManager"
 
-#include <utils/IServiceManager.h>
+#include <binder/IServiceManager.h>
 
 #include <utils/Debug.h>
-#include <utils/IPCThreadState.h>
 #include <utils/Log.h>
-#include <utils/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <binder/Parcel.h>
 #include <utils/String8.h>
 #include <utils/SystemClock.h>
 
-#include <private/utils/Static.h>
+#include <private/binder/Static.h>
 
 #include <unistd.h>
 
@@ -53,14 +53,19 @@
 
 static String16 _permission("permission");
 
+
 bool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid)
 {
     IPCThreadState* ipcState = IPCThreadState::self();
-    int32_t pid = ipcState->getCallingPid();
-    int32_t uid = ipcState->getCallingUid();
+    pid_t pid = ipcState->getCallingPid();
+    uid_t uid = ipcState->getCallingUid();
     if (outPid) *outPid = pid;
-    if (outUid) *outUid= uid;
-    
+    if (outUid) *outUid = uid;
+    return checkPermission(permission, pid, uid);
+}
+
+bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
+{
     sp<IPermissionController> pc;
     gDefaultServiceManagerLock.lock();
     pc = gPermissionController;
@@ -178,12 +183,6 @@
 
 // ----------------------------------------------------------------------
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t BnServiceManager::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/libs/utils/MemoryBase.cpp b/libs/binder/MemoryBase.cpp
similarity index 97%
rename from libs/utils/MemoryBase.cpp
rename to libs/binder/MemoryBase.cpp
index f25e11c..033066b 100644
--- a/libs/utils/MemoryBase.cpp
+++ b/libs/binder/MemoryBase.cpp
@@ -18,7 +18,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 
-#include <utils/MemoryBase.h>
+#include <binder/MemoryBase.h>
 
 
 namespace android {
diff --git a/libs/utils/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
similarity index 94%
rename from libs/utils/MemoryDealer.cpp
rename to libs/binder/MemoryDealer.cpp
index cf8201b..d5ffe7f 100644
--- a/libs/utils/MemoryDealer.cpp
+++ b/libs/binder/MemoryDealer.cpp
@@ -16,13 +16,13 @@
 
 #define LOG_TAG "MemoryDealer"
 
-#include <utils/MemoryDealer.h>
+#include <binder/MemoryDealer.h>
 
 #include <utils/Log.h>
-#include <utils/IPCThreadState.h>
+#include <binder/IPCThreadState.h>
 #include <utils/SortedVector.h>
 #include <utils/String8.h>
-#include <utils/MemoryBase.h>
+#include <binder/MemoryBase.h>
 
 #include <stdint.h>
 #include <stdio.h>
@@ -38,7 +38,15 @@
 #include <sys/file.h>
 
 namespace android {
+// ----------------------------------------------------------------------------
 
+HeapInterface::HeapInterface() { }
+HeapInterface::~HeapInterface() { }
+
+// ----------------------------------------------------------------------------
+
+AllocatorInterface::AllocatorInterface() { }
+AllocatorInterface::~AllocatorInterface() { }
 
 // ----------------------------------------------------------------------------
 
@@ -107,7 +115,7 @@
         if (new_memory != 0) {
             memory = new Allocation(this, offset, size, new_memory);
         } else {
-            LOGE("couldn't map [%8x, %d]", offset, size);
+            LOGE("couldn't map [%8lx, %u]", offset, size);
             if (size) {
                 /* NOTE: it's VERY important to not free allocations of size 0
                  * because they're special as they don't have any record in the 
@@ -339,6 +347,10 @@
         
 // ----------------------------------------------------------------------------
 
+SharedHeap::SharedHeap() 
+    : HeapInterface(), MemoryHeapBase() 
+{ 
+}
 
 SharedHeap::SharedHeap(size_t size, uint32_t flags, char const * name)
     : MemoryHeapBase(size, flags, name)
diff --git a/libs/utils/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
similarity index 98%
rename from libs/utils/MemoryHeapBase.cpp
rename to libs/binder/MemoryHeapBase.cpp
index 8251728..ac38f51 100644
--- a/libs/utils/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -29,7 +29,7 @@
 #include <cutils/ashmem.h>
 #include <cutils/atomic.h>
 
-#include <utils/MemoryHeapBase.h>
+#include <binder/MemoryHeapBase.h>
 
 #if HAVE_ANDROID_OS
 #include <linux/android_pmem.h>
diff --git a/libs/utils/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
similarity index 98%
rename from libs/utils/MemoryHeapPmem.cpp
rename to libs/binder/MemoryHeapPmem.cpp
index eba2b30..3806a42 100644
--- a/libs/utils/MemoryHeapPmem.cpp
+++ b/libs/binder/MemoryHeapPmem.cpp
@@ -27,8 +27,8 @@
 
 #include <cutils/log.h>
 
-#include <utils/MemoryHeapPmem.h>
-#include <utils/MemoryHeapBase.h>
+#include <binder/MemoryHeapPmem.h>
+#include <binder/MemoryHeapBase.h>
 
 #if HAVE_ANDROID_OS
 #include <linux/android_pmem.h>
@@ -108,7 +108,7 @@
     // promote() it.
     
 #if HAVE_ANDROID_OS
-    if (mSize != NULL) {
+    if (mSize != 0) {
         const sp<MemoryHeapPmem>& heap(getHeap());
         int our_fd = heap->heapID();
         struct pmem_region sub;
diff --git a/libs/utils/Parcel.cpp b/libs/binder/Parcel.cpp
similarity index 98%
rename from libs/utils/Parcel.cpp
rename to libs/binder/Parcel.cpp
index b0e3750..f40e4bd 100644
--- a/libs/utils/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -17,19 +17,19 @@
 #define LOG_TAG "Parcel"
 //#define LOG_NDEBUG 0
 
-#include <utils/Parcel.h>
+#include <binder/Parcel.h>
 
-#include <utils/Binder.h>
-#include <utils/BpBinder.h>
+#include <binder/Binder.h>
+#include <binder/BpBinder.h>
 #include <utils/Debug.h>
-#include <utils/ProcessState.h>
+#include <binder/ProcessState.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
 #include <utils/String16.h>
 #include <utils/TextOutput.h>
 #include <utils/misc.h>
 
-#include <private/utils/binder_module.h>
+#include <private/binder/binder_module.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -441,9 +441,14 @@
     return writeString16(interface);
 }
 
+bool Parcel::checkInterface(IBinder* binder) const
+{
+    return enforceInterface(binder->getInterfaceDescriptor()); 
+}
+
 bool Parcel::enforceInterface(const String16& interface) const
 {
-    String16 str = readString16();
+    const String16 str(readString16());
     if (str == interface) {
         return true;
     } else {
diff --git a/libs/binder/Permission.cpp b/libs/binder/Permission.cpp
new file mode 100644
index 0000000..fd8fe69
--- /dev/null
+++ b/libs/binder/Permission.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/Permission.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+Permission::Permission(char const* name)
+    : mPermissionName(name), mPid(getpid())
+{
+}
+
+Permission::Permission(const String16& name)
+    : mPermissionName(name), mPid(getpid())
+{
+}
+
+Permission::Permission(const Permission& rhs)
+    : mPermissionName(rhs.mPermissionName),
+    mGranted(rhs.mGranted),
+    mPid(rhs.mPid)
+{
+}
+
+Permission::~Permission()
+{
+}
+
+bool Permission::operator < (const Permission& rhs) const
+{
+    return mPermissionName < rhs.mPermissionName;
+}
+
+bool Permission::checkCalling() const
+{
+    IPCThreadState* ipcState = IPCThreadState::self();
+    pid_t pid = ipcState->getCallingPid();
+    uid_t uid = ipcState->getCallingUid();
+    return doCheckPermission(pid, uid);
+}
+
+bool Permission::check(pid_t pid, uid_t uid) const
+{
+    return doCheckPermission(pid, uid);
+}
+
+bool Permission::doCheckPermission(pid_t pid, uid_t uid) const
+{
+    if ((uid == 0) || (pid == mPid)) {
+        // root and ourselves is always okay
+        return true;
+    } else {
+        // see if we already granted this permission for this uid
+        Mutex::Autolock _l(mLock);
+        if (mGranted.indexOf(uid) >= 0)
+            return true;
+    }
+
+    bool granted = checkPermission(mPermissionName, pid, uid);
+    if (granted) {
+        Mutex::Autolock _l(mLock);
+        // no need to check again, the old item will be replaced if it is
+        // already there.
+        mGranted.add(uid);
+    }
+    return granted;
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/utils/ProcessState.cpp b/libs/binder/ProcessState.cpp
similarity index 97%
rename from libs/utils/ProcessState.cpp
rename to libs/binder/ProcessState.cpp
index 4567df6..d7daf73 100644
--- a/libs/utils/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -18,19 +18,19 @@
 
 #include <cutils/process_name.h>
 
-#include <utils/ProcessState.h>
+#include <binder/ProcessState.h>
 
 #include <utils/Atomic.h>
-#include <utils/BpBinder.h>
-#include <utils/IPCThreadState.h>
+#include <binder/BpBinder.h>
+#include <binder/IPCThreadState.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
-#include <utils/IServiceManager.h>
+#include <binder/IServiceManager.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 
-#include <private/utils/binder_module.h>
-#include <private/utils/Static.h>
+#include <private/binder/binder_module.h>
+#include <private/binder/Static.h>
 
 #include <errno.h>
 #include <fcntl.h>
diff --git a/libs/binder/Static.cpp b/libs/binder/Static.cpp
new file mode 100644
index 0000000..12b0308
--- /dev/null
+++ b/libs/binder/Static.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// All static variables go here, to control initialization and
+// destruction order in the library.
+
+#include <private/binder/Static.h>
+
+#include <binder/IPCThreadState.h>
+#include <utils/Log.h>
+
+namespace android {
+
+// ------------ ProcessState.cpp
+
+Mutex gProcessMutex;
+sp<ProcessState> gProcess;
+
+class LibUtilsIPCtStatics
+{
+public:
+    LibUtilsIPCtStatics()
+    {
+    }
+    
+    ~LibUtilsIPCtStatics()
+    {
+        IPCThreadState::shutdown();
+    }
+};
+
+static LibUtilsIPCtStatics gIPCStatics;
+
+// ------------ ServiceManager.cpp
+
+Mutex gDefaultServiceManagerLock;
+sp<IServiceManager> gDefaultServiceManager;
+sp<IPermissionController> gPermissionController;
+
+}   // namespace android
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index ec5aa3f..93cb5ae 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -5,22 +5,25 @@
     clz.cpp.arm \
     DisplayHardware/DisplayHardware.cpp \
     DisplayHardware/DisplayHardwareBase.cpp \
-    GPUHardware/GPUHardware.cpp \
     BlurFilter.cpp.arm \
-    CPUGauge.cpp \
+    BufferAllocator.cpp \
     Layer.cpp \
     LayerBase.cpp \
     LayerBuffer.cpp \
     LayerBlur.cpp \
     LayerBitmap.cpp \
     LayerDim.cpp \
-    LayerOrientationAnim.cpp \
-    OrientationAnimation.cpp \
+    MessageQueue.cpp \
     SurfaceFlinger.cpp \
     Tokenizer.cpp \
-    Transform.cpp \
-    VRamHeap.cpp
+    Transform.cpp
 
+LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+ifeq ($(TARGET_BOARD_PLATFORM), msm7k)
+	LOCAL_CFLAGS += -DDIM_WITH_TEXTURE
+endif
 
 # need "-lrt" on Linux simulator to pick up clock_gettime
 ifeq ($(TARGET_SIMULATOR),true)
@@ -30,19 +33,21 @@
 endif
 
 LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libpixelflinger \
 	libhardware \
 	libutils \
-	libcutils \
-	libui \
-	libcorecg \
-	libsgl \
-	libpixelflinger \
+	libskia \
 	libEGL \
-	libGLESv1_CM
+	libGLESv1_CM \
+	libbinder \
+	libui
 
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, corecg graphics)
 
+LOCAL_C_INCLUDES += hardware/libhardware/modules/gralloc
+
 LOCAL_MODULE:= libsurfaceflinger
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp
new file mode 100644
index 0000000..cee8b64
--- /dev/null
+++ b/libs/surfaceflinger/BufferAllocator.cpp
@@ -0,0 +1,118 @@
+/* 
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#include <sys/mman.h>
+#include <cutils/ashmem.h>
+#include <cutils/log.h>
+
+#include <utils/Singleton.h>
+#include <utils/String8.h>
+
+#include "BufferAllocator.h"
+
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+ANDROID_SINGLETON_STATIC_INSTANCE( BufferAllocator )
+
+Mutex BufferAllocator::sLock;
+KeyedVector<buffer_handle_t, BufferAllocator::alloc_rec_t> BufferAllocator::sAllocList;
+
+BufferAllocator::BufferAllocator()
+    : mAllocDev(0)
+{
+    hw_module_t const* module;
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
+    if (err == 0) {
+        gralloc_open(module, &mAllocDev);
+    }
+}
+
+BufferAllocator::~BufferAllocator()
+{
+    gralloc_close(mAllocDev);
+}
+
+void BufferAllocator::dump(String8& result) const
+{
+    Mutex::Autolock _l(sLock);
+    KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+    size_t total = 0;
+    const size_t SIZE = 512;
+    char buffer[SIZE];
+    snprintf(buffer, SIZE, "Allocated buffers:\n");
+    result.append(buffer);
+    const size_t c = list.size();
+    for (size_t i=0 ; i<c ; i++) {
+        const alloc_rec_t& rec(list.valueAt(i));
+        snprintf(buffer, SIZE, "%10p: %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;
+    }
+    snprintf(buffer, SIZE, "Total allocated: %.2f KB\n", total/1024.0f);
+    result.append(buffer);
+}
+
+status_t BufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
+        int usage, buffer_handle_t* handle, int32_t* stride)
+{
+    Mutex::Autolock _l(mLock);
+    
+    // we have a h/w allocator and h/w buffer is requested
+    status_t err = mAllocDev->alloc(mAllocDev,
+            w, h, format, usage, handle, stride);
+    LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
+            w, h, format, usage, err, strerror(-err));
+    
+    if (err == NO_ERROR) {
+        Mutex::Autolock _l(sLock);
+        KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+        alloc_rec_t rec;
+        rec.w = w;
+        rec.h = h;
+        rec.format = format;
+        rec.usage = usage;
+        rec.vaddr = 0;
+        rec.size = h * stride[0] * bytesPerPixel(format);
+        list.add(*handle, rec);
+    }
+
+    return err;
+}
+
+status_t BufferAllocator::free(buffer_handle_t handle)
+{
+    Mutex::Autolock _l(mLock);
+
+    status_t err = mAllocDev->free(mAllocDev, handle);
+    LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err));
+    
+    if (err == NO_ERROR) {
+        Mutex::Autolock _l(sLock);
+        KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+        list.removeItem(handle);
+    }
+
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger/BufferAllocator.h b/libs/surfaceflinger/BufferAllocator.h
new file mode 100644
index 0000000..a279ded
--- /dev/null
+++ b/libs/surfaceflinger/BufferAllocator.h
@@ -0,0 +1,96 @@
+/* 
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#ifndef ANDROID_BUFFER_ALLOCATOR_H
+#define ANDROID_BUFFER_ALLOCATOR_H
+
+#include <stdint.h>
+
+#include <cutils/native_handle.h>
+
+#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Singleton.h>
+
+#include <ui/PixelFormat.h>
+
+#include <hardware/gralloc.h>
+
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class String8;
+
+class BufferAllocator : public Singleton<BufferAllocator>
+{
+public:
+    enum {
+        USAGE_SW_READ_NEVER     = GRALLOC_USAGE_SW_READ_NEVER,
+        USAGE_SW_READ_RARELY    = GRALLOC_USAGE_SW_READ_RARELY,
+        USAGE_SW_READ_OFTEN     = GRALLOC_USAGE_SW_READ_OFTEN,
+        USAGE_SW_READ_MASK      = GRALLOC_USAGE_SW_READ_MASK,
+        
+        USAGE_SW_WRITE_NEVER    = GRALLOC_USAGE_SW_WRITE_NEVER,
+        USAGE_SW_WRITE_RARELY   = GRALLOC_USAGE_SW_WRITE_RARELY,
+        USAGE_SW_WRITE_OFTEN    = GRALLOC_USAGE_SW_WRITE_OFTEN,
+        USAGE_SW_WRITE_MASK     = GRALLOC_USAGE_SW_WRITE_MASK,
+        
+        USAGE_SOFTWARE_MASK     = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK,
+        
+        USAGE_HW_TEXTURE        = GRALLOC_USAGE_HW_TEXTURE,
+        USAGE_HW_RENDER         = GRALLOC_USAGE_HW_RENDER,
+        USAGE_HW_2D             = GRALLOC_USAGE_HW_2D,
+        USAGE_HW_MASK           = GRALLOC_USAGE_HW_MASK
+    };
+
+    static inline BufferAllocator& get() { return getInstance(); }
+    
+
+    status_t alloc(uint32_t w, uint32_t h, PixelFormat format, int usage,
+            buffer_handle_t* handle, int32_t* stride);
+
+    status_t free(buffer_handle_t handle);
+
+    void dump(String8& res) const;
+
+private:
+    struct alloc_rec_t {
+        uint32_t w;
+        uint32_t h;
+        PixelFormat format;
+        uint32_t usage;
+        void* vaddr;
+        size_t size;
+    };
+    
+    static Mutex sLock;
+    static KeyedVector<buffer_handle_t, alloc_rec_t> sAllocList;
+    
+    friend class Singleton<BufferAllocator>;
+    BufferAllocator();
+    ~BufferAllocator();
+    
+    mutable Mutex mLock;
+    alloc_device_t  *mAllocDev;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_BUFFER_ALLOCATOR_H
diff --git a/libs/surfaceflinger/CPUGauge.cpp b/libs/surfaceflinger/CPUGauge.cpp
deleted file mode 100644
index 74a9270..0000000
--- a/libs/surfaceflinger/CPUGauge.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "CPUGauge"
-
-#include <stdint.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <math.h>
-
-#include <utils/threads.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-#include <ui/DisplayInfo.h>
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "CPUGauge.h"
-
-namespace android {
-
-CPUGauge::CPUGauge( const sp<ISurfaceComposer>& composer,
-                    nsecs_t interval,
-                    int clock,
-                    int refclock)
-    :   Thread(false), 
-        mInterval(interval), mClock(clock), mRefClock(refclock),
-        mReferenceTime(0),
-        mReferenceWorkingTime(0), mCpuUsage(0),
-        mRefIdleTime(0), mIdleTime(0)
-{
-    mFd = fopen("/proc/stat", "r");
-    setvbuf(mFd, NULL, _IONBF, 0);
-
-    mSession = SurfaceComposerClient::clientForConnection(
-        composer->createConnection()->asBinder());
-}
-
-CPUGauge::~CPUGauge()
-{
-    fclose(mFd);
-}
-
-const sp<SurfaceComposerClient>& CPUGauge::session() const 
-{
-    return mSession;
-}
-
-void CPUGauge::onFirstRef()
-{
-    run("CPU Gauge");
-}
-
-status_t CPUGauge::readyToRun()
-{
-    LOGI("Starting CPU gauge...");
-    return NO_ERROR;
-}
-
-bool CPUGauge::threadLoop()
-{
-    DisplayInfo dinfo;
-    session()->getDisplayInfo(0, &dinfo);
-    sp<Surface> s(session()->createSurface(getpid(), 0, dinfo.w, 4, PIXEL_FORMAT_OPAQUE));
-    session()->openTransaction();
-    s->setLayer(INT_MAX);
-    session()->closeTransaction();
-    
-    static const GGLfixed colors[4][4] = {
-            { 0x00000, 0x10000, 0x00000, 0x10000 },
-            { 0x10000, 0x10000, 0x00000, 0x10000 },
-            { 0x10000, 0x00000, 0x00000, 0x10000 },
-            { 0x00000, 0x00000, 0x00000, 0x10000 },
-        };
-
-    GGLContext* gl;
-    gglInit(&gl);
-    gl->activeTexture(gl, 0);
-    gl->disable(gl, GGL_TEXTURE_2D);
-    gl->disable(gl, GGL_BLEND);
-
-    const int w = dinfo.w;
-
-    while(!exitPending())
-    {
-        mLock.lock();
-            const float cpuUsage = this->cpuUsage();
-            const float totalCpuUsage = 1.0f - idle();
-        mLock.unlock();
-
-        Surface::SurfaceInfo info;
-        s->lock(&info);
-            GGLSurface fb;
-                fb.version = sizeof(GGLSurface);
-                fb.width   = info.w;
-                fb.height  = info.h;
-                fb.stride  = info.w;
-                fb.format  = info.format;
-                fb.data = (GGLubyte*)info.bits;
-
-            gl->colorBuffer(gl, &fb);
-            gl->color4xv(gl, colors[3]);
-            gl->recti(gl, 0, 0, w, 4);
-            gl->color4xv(gl, colors[2]); // red
-            gl->recti(gl, 0, 0, int(totalCpuUsage*w), 2);
-            gl->color4xv(gl, colors[0]); // green
-            gl->recti(gl, 0, 2, int(cpuUsage*w), 4);
-        
-        s->unlockAndPost(); 
-
-        usleep(ns2us(mInterval));
-    }
-
-    gglUninit(gl);
-    return false;
-}
-
-void CPUGauge::sample()
-{
-    if (mLock.tryLock() == NO_ERROR) {
-        const nsecs_t now = systemTime(mRefClock);
-        const nsecs_t referenceTime = now-mReferenceTime;
-        if (referenceTime >= mInterval) {
-            const float reftime = 1.0f / referenceTime;
-            const nsecs_t nowWorkingTime = systemTime(mClock);
-            
-            char buf[256];
-            fgets(buf, 256, mFd);
-            rewind(mFd);
-            char *str = buf+5;
-            char const * const usermode = strsep(&str, " ");  (void)usermode;
-            char const * const usernice = strsep(&str, " ");  (void)usernice;
-            char const * const systemmode = strsep(&str, " ");(void)systemmode;
-            char const * const idle = strsep(&str, " ");
-            const nsecs_t nowIdleTime = atoi(idle) * 10000000LL;
-            mIdleTime = float(nowIdleTime - mRefIdleTime) * reftime;
-            mRefIdleTime = nowIdleTime;
-            
-            const nsecs_t workingTime = nowWorkingTime - mReferenceWorkingTime;
-            const float newCpuUsage = float(workingTime) * reftime;
-            if (mCpuUsage != newCpuUsage) {        
-                mCpuUsage = newCpuUsage;
-                mReferenceWorkingTime = nowWorkingTime;
-                mReferenceTime = now;
-            }
-        }
-        mLock.unlock();
-    }
-}
-
-
-}; // namespace android
diff --git a/libs/surfaceflinger/CPUGauge.h b/libs/surfaceflinger/CPUGauge.h
deleted file mode 100644
index 5bb53c0..0000000
--- a/libs/surfaceflinger/CPUGauge.h
+++ /dev/null
@@ -1,74 +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_CPUGAUGE_H
-#define ANDROID_CPUGAUGE_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Timers.h>
-
-#include <ui/SurfaceComposerClient.h>
-
-namespace android {
-
-class CPUGauge : public Thread
-{
-public:
-    CPUGauge(   const sp<ISurfaceComposer>& composer,
-                nsecs_t interval=s2ns(1),
-                int clock=SYSTEM_TIME_THREAD,
-                int refclock=SYSTEM_TIME_MONOTONIC);
-                
-    ~CPUGauge();
-
-    const sp<SurfaceComposerClient>& session() const;
-
-    void sample();
- 
-    inline float cpuUsage() const { return mCpuUsage; }
-    inline float idle() const { return mIdleTime; }
-
-private:
-    virtual void        onFirstRef();
-    virtual status_t    readyToRun();
-    virtual bool        threadLoop();
-
-    Mutex mLock;
-
-    sp<SurfaceComposerClient> mSession;
-
-    const nsecs_t mInterval;
-    const int mClock;
-    const int mRefClock;
-
-    nsecs_t mReferenceTime;
-    nsecs_t mReferenceWorkingTime;
-    float mCpuUsage;
-    nsecs_t mRefIdleTime;
-    float mIdleTime;
-    FILE*   mFd;
-};
-
-
-}; // namespace android
-
-#endif // ANDROID_CPUGAUGE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index eec645e..21f87e3 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
@@ -23,18 +21,23 @@
 
 #include <cutils/properties.h>
 
+#include <utils/RefBase.h>
 #include <utils/Log.h>
 
-#include <ui/EGLDisplaySurface.h>
+#include <ui/PixelFormat.h>
+#include <ui/FramebufferNativeWindow.h>
 
 #include <GLES/gl.h>
+#include <EGL/egl.h>
 #include <EGL/eglext.h>
 
+#include <pixelflinger/pixelflinger.h>
 
 #include "DisplayHardware/DisplayHardware.h"
 
 #include <hardware/copybit.h>
 #include <hardware/overlay.h>
+#include <hardware/gralloc.h>
 
 using namespace android;
 
@@ -108,17 +111,28 @@
 
 void DisplayHardware::init(uint32_t dpy)
 {
+    hw_module_t const* module;
+
+    mNativeWindow = new FramebufferNativeWindow();
+
+    mOverlayEngine = NULL;
+    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
+        overlay_control_open(module, &mOverlayEngine);
+    }
+
+    framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
+
+    PixelFormatInfo fbFormatInfo;
+    getPixelFormatInfo(PixelFormat(fbDev->format), &fbFormatInfo);
+
     // initialize EGL
     const EGLint attribs[] = {
-            EGL_RED_SIZE,       5,
-            EGL_GREEN_SIZE,     6,
-            EGL_BLUE_SIZE,      5,
+            EGL_BUFFER_SIZE,    fbFormatInfo.bitsPerPixel,
             EGL_DEPTH_SIZE,     0,
             EGL_NONE
     };
     EGLint w, h, dummy;
-    EGLint numConfigs, n;
-    EGLConfig config;
+    EGLint numConfigs=0, n=0;
     EGLSurface surface;
     EGLContext context;
     mFlags = 0;
@@ -129,7 +143,32 @@
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     eglInitialize(display, NULL, NULL);
     eglGetConfigs(display, NULL, 0, &numConfigs);
-    eglChooseConfig(display, attribs, &config, 1, &n);
+
+    // Get all the "potential match" configs...
+    EGLConfig* const configs = new EGLConfig[numConfigs];
+    eglChooseConfig(display, attribs, configs, numConfigs, &n);
+    LOGE_IF(n<=0, "no EGLConfig available!");
+    EGLConfig config = configs[0];
+    if (n > 1) {
+        // if there is more than one candidate, go through the list
+        // and pick one that matches our framebuffer format
+        int fbSzA = fbFormatInfo.getSize(PixelFormatInfo::INDEX_ALPHA);
+        int fbSzR = fbFormatInfo.getSize(PixelFormatInfo::INDEX_RED);
+        int fbSzG = fbFormatInfo.getSize(PixelFormatInfo::INDEX_GREEN);
+        int fbSzB = fbFormatInfo.getSize(PixelFormatInfo::INDEX_BLUE); 
+        for (int i=0 ; i<n ; i++) {
+            EGLint r,g,b,a;
+            eglGetConfigAttrib(display, configs[i], EGL_RED_SIZE,   &r);
+            eglGetConfigAttrib(display, configs[i], EGL_GREEN_SIZE, &g);
+            eglGetConfigAttrib(display, configs[i], EGL_BLUE_SIZE,  &b);
+            eglGetConfigAttrib(display, configs[i], EGL_ALPHA_SIZE, &a);
+            if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB  == b) {
+                config = configs[i];
+                break;
+            }
+        }
+    }
+    delete [] configs;
 
     /*
      * Gather EGL extensions
@@ -145,12 +184,11 @@
     LOGI("extensions: %s", egl_extensions);
     LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
 
-    // TODO: get this from the devfb driver (probably should be HAL module)
-    mFlags |= SWAP_RECTANGLE_EXTENSION;
-    
-    // TODO: get the real "update_on_demand" behavior (probably should be HAL module)
-    mFlags |= UPDATE_ON_DEMAND;
 
+    if (mNativeWindow->isUpdateOnDemand()) {
+        mFlags |= UPDATE_ON_DEMAND;
+    }
+    
     if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
         if (dummy == EGL_SLOW_CONFIG)
             mFlags |= SLOW_CONFIG;
@@ -160,33 +198,29 @@
      * Create our main surface
      */
 
-    mDisplaySurface = new EGLDisplaySurface();
-
-    surface = eglCreateWindowSurface(display, config, mDisplaySurface.get(), NULL);
-    //checkEGLErrors("eglCreateDisplaySurfaceANDROID");
+    surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
+    checkEGLErrors("eglCreateWindowSurface");
 
     if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
         if (dummy == EGL_BUFFER_PRESERVED) {
             mFlags |= BUFFER_PRESERVED;
         }
     }
-    
-    GLint value = EGL_UNKNOWN;
-    eglQuerySurface(display, surface, EGL_HORIZONTAL_RESOLUTION, &value);
-    if (value == EGL_UNKNOWN) {
-        mDpiX = 160.0f;
-    } else {
-        mDpiX = 25.4f * float(value)/EGL_DISPLAY_SCALING;
+
+#ifdef EGL_ANDROID_swap_rectangle    
+    if (strstr(egl_extensions, "EGL_ANDROID_swap_rectangle")) {
+        mFlags |= SWAP_RECTANGLE;
     }
-    value = EGL_UNKNOWN;
-    eglQuerySurface(display, surface, EGL_VERTICAL_RESOLUTION, &value);
-    if (value == EGL_UNKNOWN) {
-        mDpiY = 160.0f;
-    } else {
-        mDpiY = 25.4f * float(value)/EGL_DISPLAY_SCALING;
-    }
-    mRefreshRate = 60.f;    // TODO: get the real refresh rate 
+    // when we have the choice between UPDATE_ON_DEMAND and SWAP_RECTANGLE
+    // choose UPDATE_ON_DEMAND, which is more efficient
+    if (mFlags & UPDATE_ON_DEMAND)
+        mFlags &= ~SWAP_RECTANGLE;
+#endif
     
+
+    mDpiX = mNativeWindow->xdpi;
+    mDpiY = mNativeWindow->ydpi;
+    mRefreshRate = fbDev->fps; 
     
     char property[PROPERTY_VALUE_MAX];
     /* Read density from build-specific ro.sf.lcd_density property
@@ -230,7 +264,10 @@
     if (strstr(gl_extensions, "GL_OES_draw_texture")) {
         mFlags |= DRAW_TEXTURE_EXTENSION;
     }
-    if (strstr(gl_extensions, "GL_ANDROID_direct_texture")) {
+    if (strstr( gl_extensions, "GL_OES_EGL_image") &&
+        (strstr(egl_extensions, "EGL_KHR_image_base") || 
+                strstr(egl_extensions, "EGL_KHR_image")) &&
+        strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) {
         mFlags |= DIRECT_TEXTURE;
     }
 
@@ -241,19 +278,8 @@
     mConfig  = config;
     mSurface = surface;
     mContext = context;
-    mFormat  = GGL_PIXEL_FORMAT_RGB_565;
-    
-    hw_module_t const* module;
-
-    mBlitEngine = NULL;
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        copybit_open(module, &mBlitEngine);
-    }
-
-    mOverlayEngine = NULL;
-    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
-        overlay_control_open(module, &mOverlayEngine);
-    }
+    mFormat  = fbDev->format;
+    mPageFlipCount = 0;
 }
 
 /*
@@ -267,7 +293,6 @@
 {
     eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglTerminate(mDisplay);
-    copybit_close(mBlitEngine);
     overlay_control_close(mOverlayEngine);
 }
 
@@ -281,28 +306,8 @@
     DisplayHardwareBase::acquireScreen();
 }
 
-void DisplayHardware::getDisplaySurface(copybit_image_t* img) const
-{
-    img->w      = mDisplaySurface->stride;
-    img->h      = mDisplaySurface->height;
-    img->format = mDisplaySurface->format;
-    img->offset = mDisplaySurface->offset;
-    img->base   = (void*)mDisplaySurface->base;
-    img->fd     = mDisplaySurface->fd;
-}
-
-void DisplayHardware::getDisplaySurface(GGLSurface* fb) const
-{
-    fb->version= sizeof(GGLSurface);
-    fb->width  = mDisplaySurface->width;
-    fb->height = mDisplaySurface->height;
-    fb->stride = mDisplaySurface->stride;
-    fb->format = mDisplaySurface->format;
-    fb->data   = (GGLubyte*)mDisplaySurface->base + mDisplaySurface->offset;
-}
-
 uint32_t DisplayHardware::getPageFlipCount() const {
-    return mDisplaySurface->getPageFlipCount();
+    return mPageFlipCount;
 }
 
 /*
@@ -316,21 +321,20 @@
     EGLDisplay dpy = mDisplay;
     EGLSurface surface = mSurface;
 
-    Region newDirty(dirty);
-    newDirty.andSelf(Rect(mWidth, mHeight));
-
-    if (mFlags & BUFFER_PRESERVED) {
-        const Region copyback(mDirty.subtract(newDirty));
-        mDirty = newDirty;
-        mDisplaySurface->copyFrontToBack(copyback);
-    } 
-
-    if (mFlags & SWAP_RECTANGLE_EXTENSION) {
-        const Rect& b(newDirty.bounds());
-        mDisplaySurface->setSwapRectangle(
+#ifdef EGL_ANDROID_swap_rectangle    
+    if (mFlags & SWAP_RECTANGLE) {
+        const Region newDirty(dirty.intersect(bounds()));
+        const Rect b(newDirty.getBounds());
+        eglSetSwapRectangleANDROID(dpy, surface,
                 b.left, b.top, b.width(), b.height());
+    } 
+#endif
+    
+    if (mFlags & UPDATE_ON_DEMAND) {
+        mNativeWindow->setUpdateRectangle(dirty.getBounds());
     }
-
+    
+    mPageFlipCount++;
     eglSwapBuffers(dpy, surface);
     checkEGLErrors("eglSwapBuffers");
 
@@ -348,11 +352,3 @@
 {
     eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
 }
-
-void DisplayHardware::copyFrontToImage(const copybit_image_t& front) const {
-    mDisplaySurface->copyFrontToImage(front);
-}
-
-void DisplayHardware::copyBackToImage(const copybit_image_t& front) const {
-    mDisplaySurface->copyBackToImage(front);
-}
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
index 550a4d1..8972d51 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -22,31 +22,35 @@
 #include <ui/PixelFormat.h>
 #include <ui/Region.h>
 
+#include <GLES/gl.h>
+#include <GLES/glext.h>
 #include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <pixelflinger/pixelflinger.h>
 
 #include "DisplayHardware/DisplayHardwareBase.h"
 
 struct overlay_control_device_t;
-struct copybit_device_t;
+struct framebuffer_device_t;
 struct copybit_image_t;
-struct copybit_t;
 
 namespace android {
 
-class EGLDisplaySurface;
+class FramebufferNativeWindow;
 
 class DisplayHardware : public DisplayHardwareBase
 {
 public:
     enum {
         DIRECT_TEXTURE          = 0x00000002,
-        SWAP_RECTANGLE_EXTENSION= 0x00000004,
         COPY_BITS_EXTENSION     = 0x00000008,
         NPOT_EXTENSION          = 0x00000100,
         DRAW_TEXTURE_EXTENSION  = 0x00000200,
         BUFFER_PRESERVED        = 0x00010000,
         UPDATE_ON_DEMAND        = 0x00020000,   // video driver feature
         SLOW_CONFIG             = 0x00040000,   // software
+        SWAP_RECTANGLE          = 0x00080000,
     };
 
     DisplayHardware(
@@ -73,15 +77,9 @@
     void        makeCurrent() const;
 
     uint32_t getPageFlipCount() const;
-    void getDisplaySurface(copybit_image_t* img) const;
-    void getDisplaySurface(GGLSurface* fb) const;
     EGLDisplay getEGLDisplay() const { return mDisplay; }
-    copybit_device_t* getBlitEngine() const { return mBlitEngine; }
     overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
     
-    void copyFrontToImage(const copybit_image_t& front) const;
-    void copyBackToImage(const copybit_image_t& front) const;
-       
     Rect bounds() const {
         return Rect(mWidth, mHeight);
     }
@@ -102,9 +100,9 @@
     int             mHeight;
     PixelFormat     mFormat;
     uint32_t        mFlags;
-    mutable Region  mDirty;
-    sp<EGLDisplaySurface> mDisplaySurface;
-    copybit_device_t*     mBlitEngine;
+    mutable uint32_t mPageFlipCount;
+    
+    sp<FramebufferNativeWindow> mNativeWindow;
     overlay_control_device_t* mOverlayEngine;
 };
 
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
index f75e5c2..1d09f84 100644
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
+++ b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 96395a8..9916158 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -14,26 +14,24 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <cutils/properties.h>
+#include <cutils/native_handle.h>
 
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/StopWatch.h>
 
 #include <ui/PixelFormat.h>
-#include <ui/EGLDisplaySurface.h>
+#include <ui/Surface.h>
 
 #include "clz.h"
 #include "Layer.h"
 #include "LayerBitmap.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 #include "DisplayHardware/DisplayHardware.h"
 
 
@@ -49,13 +47,12 @@
 
 // ---------------------------------------------------------------------------
 
-Layer::Layer(SurfaceFlinger* flinger, DisplayID display, Client* c, int32_t i)
+Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& c, int32_t i)
     :   LayerBaseClient(flinger, display, c, i),
         mSecure(false),
         mFrontBufferIndex(1),
         mNeedsBlending(true),
-        mResizeTransactionDone(false),
-        mTextureName(-1U), mTextureWidth(0), mTextureHeight(0)
+        mResizeTransactionDone(false)
 {
     // no OpenGL operation is possible here, since we might not be
     // in the OpenGL thread.
@@ -63,12 +60,25 @@
 
 Layer::~Layer()
 {
-    client->free(clientIndex());
-    // this should always be called from the OpenGL thread
-    if (mTextureName != -1U) {
-        //glDeleteTextures(1, &mTextureName);
-        deletedTextures.add(mTextureName);
+    destroy();
+    // the actual buffers will be destroyed here
+}
+
+void Layer::destroy()
+{
+    for (int i=0 ; i<NUM_BUFFERS ; i++) {
+        if (mTextures[i].name != -1U) {
+            glDeleteTextures(1, &mTextures[i].name);
+            mTextures[i].name = -1U;
+        }
+        if (mTextures[i].image != EGL_NO_IMAGE_KHR) {
+            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+            eglDestroyImageKHR(dpy, mTextures[i].image);
+            mTextures[i].image = EGL_NO_IMAGE_KHR;
+        }
+        mBuffers[i].free();
     }
+    mSurface.clear();
 }
 
 void Layer::initStates(uint32_t w, uint32_t h, uint32_t flags)
@@ -79,148 +89,206 @@
         lcblk->flags |= eNoCopyBack;
 }
 
-sp<LayerBaseClient::Surface> Layer::getSurface() const
+sp<LayerBaseClient::Surface> Layer::createSurface() const
 {
     return mSurface;
 }
 
-status_t Layer::setBuffers( Client* client,
-                            uint32_t w, uint32_t h,
+status_t Layer::ditch()
+{
+    // the layer is not on screen anymore. free as much resources as possible
+    destroy();
+    return NO_ERROR;
+}
+
+status_t Layer::setBuffers( uint32_t w, uint32_t h,
                             PixelFormat format, uint32_t flags)
 {
     PixelFormatInfo info;
     status_t err = getPixelFormatInfo(format, &info);
     if (err) return err;
 
-    // TODO: if eHardware is explicitly requested, we should fail
-    // on systems where we can't allocate memory that can be used with
-    // DMA engines for instance.
-    
-    // FIXME: we always ask for hardware for now (this should come from copybit)
-    flags |= ISurfaceComposer::eHardware;
+    uint32_t bufferFlags = 0;
+    if (flags & ISurfaceComposer::eGPU)
+        bufferFlags |= Buffer::GPU;
 
-    const uint32_t memory_flags = flags & 
-            (ISurfaceComposer::eGPU | 
-             ISurfaceComposer::eHardware | 
-             ISurfaceComposer::eSecure);
-    
-    // pixel-alignment. the final alignment may be bigger because
-    // we always force a 4-byte aligned bpr.
-    uint32_t alignment = 1;
+    if (flags & ISurfaceComposer::eSecure)
+        bufferFlags |= Buffer::SECURE;
 
-    if ((flags & ISurfaceComposer::eGPU) && (mFlinger->getGPU() != 0)) {
-        // FIXME: this value should come from the h/w
-        alignment = 8; 
+    /* FIXME we need this code for msm7201A
+    if (bufferFlags & Buffer::GPU) {
         // FIXME: this is msm7201A specific, as its GPU only supports
         // BGRA_8888.
         if (format == PIXEL_FORMAT_RGBA_8888) {
             format = PIXEL_FORMAT_BGRA_8888;
         }
     }
+    */
 
-    mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
+    mSecure = (bufferFlags & Buffer::SECURE) ? true : false;
     mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
-    sp<MemoryDealer> allocators[2];
     for (int i=0 ; i<2 ; i++) {
-        allocators[i] = client->createAllocator(memory_flags);
-        if (allocators[i] == 0)
-            return NO_MEMORY;
-        mBuffers[i].init(allocators[i]);
-        int err = mBuffers[i].setBits(w, h, alignment, format, LayerBitmap::SECURE_BITS);
-        if (err != NO_ERROR)
+        err = mBuffers[i].init(lcblk->surface + i, w, h, format, bufferFlags);
+        if (err != NO_ERROR) {
             return err;
-        mBuffers[i].clear(); // clear the bits for security
-        mBuffers[i].getInfo(lcblk->surface + i);
+        }
     }
-
-    mSurface = new Surface(clientIndex(),
-            allocators[0]->getMemoryHeap(),
-            allocators[1]->getMemoryHeap(),
-            mIdentity);
-
+    mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
     return NO_ERROR;
 }
 
 void Layer::reloadTexture(const Region& dirty)
 {
-    if (UNLIKELY(mTextureName == -1U)) {
-        // create the texture name the first time
-        // can't do that in the ctor, because it runs in another thread.
-        mTextureName = createTexture();
+    const sp<Buffer>& buffer(frontBuffer().getBuffer());
+    if (LIKELY(mFlags & DisplayHardware::DIRECT_TEXTURE)) {
+        int index = mFrontBufferIndex;
+        if (LIKELY(!mTextures[index].dirty)) {
+            glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
+        } else {
+            // we need to recreate the texture
+            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+            
+            // create the new texture name if needed
+            if (UNLIKELY(mTextures[index].name == -1U)) {
+                mTextures[index].name = createTexture();
+            } else {
+                glBindTexture(GL_TEXTURE_2D, mTextures[index].name);
+            }
+
+            // free the previous image
+            if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
+                eglDestroyImageKHR(dpy, mTextures[index].image);
+                mTextures[index].image = EGL_NO_IMAGE_KHR;
+            }
+            
+            // construct an EGL_NATIVE_BUFFER_ANDROID
+            android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
+            
+            // create the new EGLImageKHR
+            const EGLint attrs[] = { 
+                    EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE, 
+                    EGL_NONE,                   EGL_NONE 
+            };
+            mTextures[index].image = eglCreateImageKHR(
+                    dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+                    (EGLClientBuffer)clientBuf, attrs);
+
+            LOGE_IF(mTextures[index].image == EGL_NO_IMAGE_KHR,
+                    "eglCreateImageKHR() failed. err=0x%4x",
+                    eglGetError());
+            
+            if (mTextures[index].image != EGL_NO_IMAGE_KHR) {
+                glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 
+                        (GLeglImageOES)mTextures[index].image);
+                GLint error = glGetError();
+                if (UNLIKELY(error != GL_NO_ERROR)) {
+                    // this failed, for instance, because we don't support
+                    // NPOT.
+                    // FIXME: do something!
+                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
+                } else {
+                    // Everything went okay!
+                    mTextures[index].dirty  = false;
+                    mTextures[index].width  = clientBuf->width;
+                    mTextures[index].height = clientBuf->height;
+                }
+            }                
+        }
+    } else {
+        GGLSurface t;
+        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(&mTextures[0], mTextures[0].name, dirty, t);
+            buffer->unlock();
+        }
     }
-    const GGLSurface& t(frontBuffer().surface());
-    loadTexture(dirty, mTextureName, t, mTextureWidth, mTextureHeight);
 }
 
 
 void Layer::onDraw(const Region& clip) const
 {
-    if (UNLIKELY(mTextureName == -1LU)) {
-        //LOGW("Layer %p doesn't have a texture", this);
+    const int index = (mFlags & DisplayHardware::DIRECT_TEXTURE) ? 
+            mFrontBufferIndex : 0;
+    GLuint textureName = mTextures[index].name;
+
+    if (UNLIKELY(textureName == -1LU)) {
+        LOGW("Layer %p doesn't have a texture", this);
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. this happens frequently with
         // SurfaceView.
         clearWithOpenGL(clip);
         return;
     }
-
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    const LayerBitmap& front(frontBuffer());
-    const GGLSurface& t(front.surface());
-
-    status_t err = NO_ERROR;
-    const int can_use_copybit = canUseCopybit();
-    if (can_use_copybit)  {
-        // StopWatch watch("copybit");
-        const State& s(drawingState());
-
-        copybit_image_t dst;
-        hw.getDisplaySurface(&dst);
-        const copybit_rect_t& drect
-            = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
-
-        copybit_image_t src;
-        front.getBitmapSurface(&src);
-        copybit_rect_t srect = { 0, 0, t.width, t.height };
-
-        copybit_device_t* copybit = mFlinger->getBlitEngine();
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, getOrientation());
-        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
-        copybit->set_parameter(copybit, COPYBIT_DITHER,
-                s.flags & ISurfaceComposer::eLayerDither ?
-                        COPYBIT_ENABLE : COPYBIT_DISABLE);
-
-        region_iterator it(clip);
-        err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-    }
-
-    if (!can_use_copybit || err) {
-        drawWithOpenGL(clip, mTextureName, t);
-    }
+    drawWithOpenGL(clip, mTextures[index]);
 }
 
-status_t Layer::reallocateBuffer(int32_t index, uint32_t w, uint32_t h)
+sp<SurfaceBuffer> Layer::peekBuffer()
 {
-    LOGD_IF(DEBUG_RESIZE,
-                "reallocateBuffer (layer=%p), "
-                "requested (%dx%d), "
-                "index=%d, (%dx%d), (%dx%d)",
-                this,
-                int(w), int(h),
-                int(index),
-                int(mBuffers[0].width()), int(mBuffers[0].height()),
-                int(mBuffers[1].width()), int(mBuffers[1].height()));
+    /*
+     * This is called from the client's Surface::lock(), after it locked
+     * the surface successfully. We're therefore guaranteed that the
+     * back-buffer is not in use by ourselves.
+     * Of course, we need to validate all this, which is not trivial.
+     *
+     * FIXME: A resize could happen at any time here. What to do about this?
+     *  - resize() form post()
+     *  - resize() from doTransaction()
+     *  
+     *  We'll probably need an internal lock for this.
+     *     
+     * 
+     * TODO: We need to make sure that post() doesn't swap
+     *       the buffers under us.
+     */
 
-    status_t err = mBuffers[index].resize(w, h);
-    if (err == NO_ERROR) {
-        mBuffers[index].getInfo(lcblk->surface + index);
-    } else {
-        LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s",
-            index, w, h, err, strerror(err));
-        // XXX: what to do, what to do? We could try to free some
-        // hidden surfaces, instead of killing this one?
+    // it's okay to read swapState for the purpose of figuring out the 
+    // backbuffer index, which cannot change (since the app has locked it).
+    const uint32_t state = lcblk->swapState;
+    const int32_t backBufferIndex = layer_cblk_t::backBuffer(state);
+    
+    // get rid of the EGL image, since we shouldn't need it anymore
+    // (note that we're in a different thread than where it is being used)
+    if (mTextures[backBufferIndex].image != EGL_NO_IMAGE_KHR) {
+        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+        eglDestroyImageKHR(dpy, mTextures[backBufferIndex].image);
+        mTextures[backBufferIndex].image = EGL_NO_IMAGE_KHR;
     }
-    return err;
+    
+    LayerBitmap& layerBitmap(mBuffers[backBufferIndex]);
+    sp<SurfaceBuffer> buffer = layerBitmap.allocate();
+    
+    LOGD_IF(DEBUG_RESIZE,
+            "Layer::getBuffer(this=%p), index=%d, (%d,%d), (%d,%d)",
+            this, backBufferIndex,
+            layerBitmap.getWidth(),
+            layerBitmap.getHeight(),
+            layerBitmap.getBuffer()->getWidth(),
+            layerBitmap.getBuffer()->getHeight());
+
+    if (UNLIKELY(buffer == 0)) {
+        // XXX: what to do, what to do?
+    } else {
+        // texture is now dirty...
+        mTextures[backBufferIndex].dirty = true;
+        // ... so it the visible region (because we consider the surface's
+        // buffer size for visibility calculations)
+        forceVisibilityTransaction();
+        mFlinger->setTransactionFlags(eTraversalNeeded);
+    }
+    return buffer;
+}
+
+void Layer::scheduleBroadcast()
+{
+    sp<Client> ourClient(client.promote());
+    if (ourClient != 0) {
+        mFlinger->scheduleBroadcast(ourClient);
+    }
 }
 
 uint32_t Layer::doTransaction(uint32_t flags)
@@ -232,7 +300,7 @@
     // that the size changed back to its previous value before the buffer
     // was resized (in the eLocked case below), in which case, we still
     // need to execute the code below so the clients have a chance to be
-    // release. resze() deals with the fact that the size can be the same.
+    // release. resize() deals with the fact that the size can be the same.
 
     /*
      *  Various states we could be in...
@@ -276,8 +344,8 @@
                 int(temp.w), int(temp.h),
                 int(drawingState().w), int(drawingState().h),
                 int(clientBackBufferIndex),
-                int(mBuffers[0].width()), int(mBuffers[0].height()),
-                int(mBuffers[1].width()), int(mBuffers[1].height()));
+                int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+                int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
         // if we get there we're pretty screwed. the only reasonable
         // thing to do is to pretend we should do the resize since
         // backbufferChanged is set (this also will give a chance to
@@ -299,8 +367,8 @@
                     int(temp.w), int(temp.h),
                     int(drawingState().w), int(drawingState().h),
                     int(clientBackBufferIndex),
-                    int(mBuffers[0].width()), int(mBuffers[0].height()),
-                    int(mBuffers[1].width()), int(mBuffers[1].height()));
+                    int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+                    int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
 
         if (state & eLocked) {
             // if the buffer is locked, we can't resize anything because
@@ -314,10 +382,11 @@
             status_t err =
                 resize(clientBackBufferIndex, temp.w, temp.h, "transaction");
             if (err == NO_ERROR) {
-                const uint32_t mask = clientBackBufferIndex ? eResizeBuffer1 : eResizeBuffer0;
+                const uint32_t mask = clientBackBufferIndex ?
+                        eResizeBuffer1 : eResizeBuffer0;
                 android_atomic_and(~mask, &(lcblk->swapState));
                 // since a buffer became available, we can let the client go...
-                mFlinger->scheduleBroadcast(client);
+                scheduleBroadcast();
                 mResizeTransactionDone = true;
 
                 // we're being resized and there is a freeze display request,
@@ -353,14 +422,15 @@
 {
     /*
      * handle resize (backbuffer and frontbuffer reallocation)
+     * this is called from post() or from doTransaction()
      */
 
     const LayerBitmap& clientBackBuffer(mBuffers[clientBackBufferIndex]);
 
     // if the new (transaction) size is != from the the backbuffer
     // then we need to reallocate the backbuffer
-    bool backbufferChanged = (clientBackBuffer.width()  != width) ||
-                             (clientBackBuffer.height() != height);
+    bool backbufferChanged = (clientBackBuffer.getWidth()  != width) ||
+                             (clientBackBuffer.getHeight() != height);
 
     LOGD_IF(!backbufferChanged,
             "(%s) eResizeRequested (layer=%p), but size not changed: "
@@ -372,18 +442,28 @@
             int(currentState().w), int(currentState().h),
             long(lcblk->swapState),
             int(clientBackBufferIndex),
-            int(mBuffers[0].width()), int(mBuffers[0].height()),
-            int(mBuffers[1].width()), int(mBuffers[1].height()));
+            int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+            int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
 
     // this can happen when changing the size back and forth quickly
     status_t err = NO_ERROR;
     if (backbufferChanged) {
-        err = reallocateBuffer(clientBackBufferIndex, width, height);
-    }
-    if (UNLIKELY(err != NO_ERROR)) {
-        // couldn't reallocate the surface
-        android_atomic_write(eInvalidSurface, &lcblk->swapState);
-        memset(lcblk->surface+clientBackBufferIndex, 0, sizeof(surface_info_t));
+
+        LOGD_IF(DEBUG_RESIZE,
+                "resize (layer=%p), requested (%dx%d), "
+                "index=%d, (%dx%d), (%dx%d)",
+                this, int(width), int(height), int(clientBackBufferIndex),
+                int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+                int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
+
+        err = mBuffers[clientBackBufferIndex].setSize(width, height);
+        if (UNLIKELY(err != NO_ERROR)) {
+            // This really should never happen
+            LOGE("resizing buffer %d to (%u,%u) failed [%08x] %s",
+                    clientBackBufferIndex, width, height, err, strerror(err));
+            // couldn't reallocate the surface
+            android_atomic_write(eInvalidSurface, &lcblk->swapState);
+        }
     }
     return err;
 }
@@ -415,7 +495,7 @@
     if (UNLIKELY(state & eInvalidSurface)) {
         // if eInvalidSurface is set, this means the surface
         // became invalid during a transaction (NO_MEMORY for instance)
-        mFlinger->scheduleBroadcast(client);
+        scheduleBroadcast();
         return;
     }
 
@@ -457,15 +537,21 @@
 
     } while(android_atomic_cmpxchg(oldValue, newValue, &(lcblk->swapState)));
     *previousSate = oldValue;
-
+    
     const int32_t index = (newValue & eIndex) ^ 1;
     mFrontBufferIndex = index;
 
+    /* NOTE: it's safe to set this flag here because this is only touched
+     * from LayerBitmap::allocate(), which by construction cannot happen
+     * while we're in post().
+     */
+    lcblk->surface[index].flags &= ~surface_info_t::eBufferDirty;
+
     // ... post the new front-buffer
     Region dirty(lcblk->region + index);
-    dirty.andSelf(frontBuffer().bounds());
+    dirty.andSelf(frontBuffer().getBounds());
 
-    //LOGI("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n",
+    //LOGD("Did post oldValue=%08lx, newValue=%08lx, mFrontBufferIndex=%u\n",
     //    oldValue, newValue, mFrontBufferIndex);
     //dirty.dump("dirty");
 
@@ -476,8 +562,8 @@
                      "index=%d, (%dx%d), (%dx%d)",
                      this,  newValue,
                      int(1-index),
-                     int(mBuffers[0].width()), int(mBuffers[0].height()),
-                     int(mBuffers[1].width()), int(mBuffers[1].height()));
+                     int(mBuffers[0].getWidth()), int(mBuffers[0].getHeight()),
+                     int(mBuffers[1].getWidth()), int(mBuffers[1].getHeight()));
 
         // here, we just posted the surface and we have resolved
         // the front/back buffer indices. The client is blocked, so
@@ -522,8 +608,8 @@
 
 Point Layer::getPhysicalSize() const
 {
-    const LayerBitmap& front(frontBuffer());
-    return Point(front.width(), front.height());
+    sp<const Buffer> front(frontBuffer().getBuffer());
+    return Point(front->getWidth(), front->getHeight());
 }
 
 void Layer::unlockPageFlip(
@@ -547,7 +633,7 @@
 
         // client could be blocked, so signal them so they get a
         // chance to reevaluate their condition.
-        mFlinger->scheduleBroadcast(client);
+        scheduleBroadcast();
     }
 }
 
@@ -558,9 +644,30 @@
                 "layer %p wasn't locked!", this);
         android_atomic_and(~eBusy, &(lcblk->swapState));
     }
-    mFlinger->scheduleBroadcast(client);
+    scheduleBroadcast();
 }
 
+// ---------------------------------------------------------------------------
+
+Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
+        SurfaceID id, const sp<Layer>& owner)
+    : Surface(flinger, id, owner->getIdentity(), owner)
+{
+}
+
+Layer::SurfaceLayer::~SurfaceLayer()
+{
+}
+
+sp<SurfaceBuffer> Layer::SurfaceLayer::getBuffer()
+{
+    sp<SurfaceBuffer> buffer = 0;
+    sp<Layer> owner(getOwner());
+    if (owner != 0) {
+        buffer = owner->peekBuffer();
+    }
+    return buffer;
+}
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index 2867f2b..4c13d6e 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -27,6 +27,11 @@
 
 #include <pixelflinger/pixelflinger.h>
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
 #include "LayerBitmap.h"
 #include "LayerBase.h"
 #include "Transform.h"
@@ -37,11 +42,12 @@
 
 class Client;
 class LayerBitmap;
-class MemoryDealer;
 class FreezeLock;
 
 // ---------------------------------------------------------------------------
 
+const int NUM_BUFFERS = 2;
+
 class Layer : public LayerBaseClient
 {
 public:    
@@ -51,16 +57,15 @@
     virtual uint32_t getTypeInfo() const { return typeInfo; }
 
                  Layer(SurfaceFlinger* flinger, DisplayID display,
-                         Client* c, int32_t i);
+                         const sp<Client>& client, int32_t i);
 
         virtual ~Layer();
 
     inline PixelFormat pixelFormat() const {
-        return frontBuffer().pixelFormat();
+        return frontBuffer().getPixelFormat();
     }
 
-    status_t setBuffers(    Client* client,
-                            uint32_t w, uint32_t h,
+    status_t setBuffers(    uint32_t w, uint32_t h,
                             PixelFormat format, uint32_t flags=0);
 
     virtual void onDraw(const Region& clip) const;
@@ -73,8 +78,8 @@
     virtual void finishPageFlip();
     virtual bool needsBlending() const      { return mNeedsBlending; }
     virtual bool isSecure() const           { return mSecure; }
-    virtual GLuint getTextureName() const   { return mTextureName; }
-    virtual sp<Surface> getSurface() const;
+    virtual sp<Surface> createSurface() const;
+    virtual status_t ditch();
 
     const LayerBitmap& getBuffer(int i) const { return mBuffers[i]; }
           LayerBitmap& getBuffer(int i)       { return mBuffers[i]; }
@@ -96,21 +101,37 @@
 
     status_t resize(int32_t index, uint32_t w, uint32_t h, const char* what);
     Region post(uint32_t* oldState, bool& recomputeVisibleRegions);
-    status_t reallocateBuffer(int32_t index, uint32_t w, uint32_t h);
+    sp<SurfaceBuffer> peekBuffer();
+    void destroy();
+    void scheduleBroadcast();
 
+    
+    class SurfaceLayer : public LayerBaseClient::Surface
+    {
+    public:
+                SurfaceLayer(const sp<SurfaceFlinger>& flinger,
+                        SurfaceID id, const sp<Layer>& owner);
+                ~SurfaceLayer();
+
+    private:
+        virtual sp<SurfaceBuffer> getBuffer();
+
+        sp<Layer> getOwner() const {
+            return static_cast<Layer*>(Surface::getOwner().get());
+        }
+    };
+    friend class SurfaceLayer;
+    
     sp<Surface>             mSurface;
 
             bool            mSecure;
-            LayerBitmap     mBuffers[2];
+            LayerBitmap     mBuffers[NUM_BUFFERS];
+            Texture         mTextures[NUM_BUFFERS];
             int32_t         mFrontBufferIndex;
             bool            mNeedsBlending;
             bool            mResizeTransactionDone;
             Region          mPostedDirtyRegion;
             sp<FreezeLock>  mFreezeLock;
-            
-            GLuint          mTextureName;
-            GLuint          mTextureWidth;
-            GLuint          mTextureHeight;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 0cf53f7..a841ab3 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/Errors.h>
 #include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
 
 #include <GLES/gl.h>
 #include <GLES/glext.h>
@@ -53,19 +53,13 @@
 
 // ---------------------------------------------------------------------------
 
-Vector<GLuint> LayerBase::deletedTextures; 
-
-int32_t LayerBase::sIdentity = 0;
-
 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
     : dpy(display), contentDirty(false),
       mFlinger(flinger),
       mTransformed(false),
       mOrientation(0),
-      mCanUseCopyBit(false),
       mTransactionFlags(0),
       mPremultipliedAlpha(true),
-      mIdentity(uint32_t(android_atomic_inc(&sIdentity))),
       mInvalidate(0)
 {
     const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
@@ -265,43 +259,6 @@
     mTransformed = transformed;
     mLeft = tr.tx();
     mTop  = tr.ty();
-
-    // see if we can/should use 2D h/w with the new configuration
-    mCanUseCopyBit = false;
-    copybit_device_t* copybit = mFlinger->getBlitEngine();
-    if (copybit) { 
-        const int step = copybit->get(copybit, COPYBIT_ROTATION_STEP_DEG);
-        const int scaleBits = copybit->get(copybit, COPYBIT_SCALING_FRAC_BITS);
-        mCanUseCopyBit = true;
-        if ((mOrientation < 0) && (step > 1)) {
-            // arbitrary orientations not supported
-            mCanUseCopyBit = false;
-        } else if ((mOrientation > 0) && (step > 90)) {
-            // 90 deg rotations not supported
-            mCanUseCopyBit = false;
-        } else if ((tr.getType() & SkMatrix::kScale_Mask) && (scaleBits < 12)) { 
-            // arbitrary scaling not supported
-            mCanUseCopyBit = false;
-        }
-#if HONOR_PREMULTIPLIED_ALPHA 
-        else if (needsBlending() && mPremultipliedAlpha) {
-            // pre-multiplied alpha not supported
-            mCanUseCopyBit = false;
-        }
-#endif
-        else {
-            // here, we determined we can use copybit
-            if (tr.getType() & SkMatrix::kScale_Mask) {
-                // and we have scaling
-                if (!transparentRegionScreen.isRect()) {
-                    // we punt because blending is cheap (h/w) and the region is
-                    // complex, which may causes artifacts when copying
-                    // scaled content
-                    transparentRegionScreen.clear();
-                }
-            }
-        }
-    }
 }
 
 void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
@@ -329,8 +286,9 @@
 
 void LayerBase::drawRegion(const Region& reg) const
 {
-    Region::iterator iterator(reg);
-    if (iterator) {
+    Region::const_iterator it = reg.begin();
+    Region::const_iterator const end = reg.end();
+    if (it != end) {
         Rect r;
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         const int32_t fbWidth  = hw.getWidth();
@@ -338,7 +296,8 @@
         const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 
                 { fbWidth, fbHeight }, { 0, fbHeight }  };
         glVertexPointer(2, GL_SHORT, 0, vertices);
-        while (iterator.iterate(&r)) {
+        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); 
@@ -403,12 +362,14 @@
     glDisable(GL_TEXTURE_2D);
     glDisable(GL_BLEND);
     glDisable(GL_DITHER);
-    Rect r;
-    Region::iterator iterator(clip);
-    if (iterator) {
+
+    Region::const_iterator it = clip.begin();
+    Region::const_iterator const end = clip.end();
+    if (it != end) {
         glEnable(GL_SCISSOR_TEST);
         glVertexPointer(2, GL_FIXED, 0, mVertices);
-        while (iterator.iterate(&r)) {
+        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); 
@@ -416,15 +377,17 @@
     }
 }
 
-void LayerBase::drawWithOpenGL(const Region& clip,
-        GLint textureName, const GGLSurface& t, int transform) const
+void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
 {
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     const uint32_t fbHeight = hw.getHeight();
     const State& s(drawingState());
-
+    
     // bind our texture
-    validateTexture(textureName);
+    validateTexture(texture.name);
+    uint32_t width  = texture.width; 
+    uint32_t height = texture.height;
+    
     glEnable(GL_TEXTURE_2D);
 
     // Dithering...
@@ -472,8 +435,9 @@
             || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) 
     {
         //StopWatch watch("GL transformed");
-        Region::iterator iterator(clip);
-        if (iterator) {
+        Region::const_iterator it = clip.begin();
+        Region::const_iterator const end = clip.end();
+        if (it != end) {
             // always use high-quality filtering with fast configurations
             bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG);
             if (!fast && s.flags & ISurfaceComposer::eLayerFilter) {
@@ -490,21 +454,23 @@
             glMatrixMode(GL_TEXTURE);
             glLoadIdentity();
             
-            if (transform == HAL_TRANSFORM_ROT_90) {
+            // the texture's source is rotated
+            if (texture.transform == HAL_TRANSFORM_ROT_90) {
+                // TODO: handle the other orientations
                 glTranslatef(0, 1, 0);
                 glRotatef(-90, 0, 0, 1);
             }
 
             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);
             }
 
@@ -512,8 +478,8 @@
             glVertexPointer(2, GL_FIXED, 0, mVertices);
             glTexCoordPointer(2, GL_FIXED, 0, texCoords);
 
-            Rect r;
-            while (iterator.iterate(&r)) {
+            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); 
@@ -526,18 +492,19 @@
             glDisableClientState(GL_TEXTURE_COORD_ARRAY);
         }
     } else {
-        Region::iterator iterator(clip);
-        if (iterator) {
-            Rect r;
-            GLint crop[4] = { 0, t.height, t.width, -t.height };
+        Region::const_iterator it = clip.begin();
+        Region::const_iterator const end = clip.end();
+        if (it != end) {
+            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);
-            while (iterator.iterate(&r)) {
+            y = fbHeight - (y + height);
+            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, t.width, t.height);
+                glDrawTexiOES(x, y, 0, width, height);
             }
         }
     }
@@ -550,13 +517,16 @@
     // this is currently done in loadTexture() below
 }
 
-void LayerBase::loadTexture(const Region& dirty,
-        GLint textureName, const GGLSurface& t,
-        GLuint& textureWidth, GLuint& textureHeight) const
+void LayerBase::loadTexture(Texture* texture, GLint textureName, 
+        const Region& dirty, const GGLSurface& t) const
 {
     // TODO: defer the actual texture reload until LayerBase::validateTexture
     // is called.
 
+    texture->name = textureName;
+    GLuint& textureWidth(texture->width);
+    GLuint& textureHeight(texture->height);
+    
     uint32_t flags = mFlags;
     glBindTexture(GL_TEXTURE_2D, textureName);
 
@@ -565,8 +535,7 @@
 
     /*
      * In OpenGL ES we can't specify a stride with glTexImage2D (however,
-     * GL_UNPACK_ALIGNMENT is 4, which in essence allows a limited form of
-     * stride).
+     * GL_UNPACK_ALIGNMENT is a limited form of stride).
      * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
      * need to do something reasonable (here creating a bigger texture).
      * 
@@ -579,9 +548,11 @@
      *
      * This should never be a problem with POT textures
      */
-
-    tw += (((t.stride - tw) * bytesPerPixel(t.format)) / 4);
-
+    
+    int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
+    unpack = 1 << ((unpack > 3) ? 3 : unpack);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
+    
     /*
      * round to POT if needed 
      */
@@ -594,119 +565,98 @@
         texture_h = 1 << (31 - clz(t.height));
         if (texture_w < t.width)  texture_w <<= 1;
         if (texture_h < t.height) texture_h <<= 1;
-        if (texture_w != tw || texture_h != th) {
-            // we can't use DIRECT_TEXTURE since we changed the size
-            // of the texture
-            flags &= ~DisplayHardware::DIRECT_TEXTURE;
-        }
     }
-
-    if (flags & DisplayHardware::DIRECT_TEXTURE) {
-        // here we're guaranteed that texture_{w|h} == t{w|h}
-        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
-            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
-                    GL_RGB, tw, th, 0,
-                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, t.data);
-        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
-            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
-                    GL_RGBA, tw, th, 0,
-                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, t.data);
-        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
-            glTexImage2D(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0,
-                    GL_RGBA, tw, th, 0,
-                    GL_RGBA, GL_UNSIGNED_BYTE, t.data);
-        } else if (t.format == GGL_PIXEL_FORMAT_BGRA_8888) {
-            // TODO: add GL_BGRA extension
-        } else {
-            // oops, we don't handle this format, try the regular path
-            goto regular;
-        }
-        textureWidth = tw;
-        textureHeight = th;
-    } else {
+    
 regular:
-        Rect bounds(dirty.bounds());
-        GLvoid* data = 0;
-        if (texture_w!=textureWidth || texture_h!=textureHeight) {
-            // texture size changed, we need to create a new one
+    Rect bounds(dirty.bounds());
+    GLvoid* data = 0;
+    if (texture_w!=textureWidth || texture_h!=textureHeight) {
+        // texture size changed, we need to create a new one
 
-            if (!textureWidth || !textureHeight) {
-                // this is the first time, load the whole texture
-                if (texture_w==tw && texture_h==th) {
-                    // we can do it one pass
-                    data = t.data;
-                } else {
-                    // we have to create the texture first because it
-                    // doesn't match the size of the buffer
-                    bounds.set(Rect(tw, th));
-                }
-            }
-            
-            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
-                glTexImage2D(GL_TEXTURE_2D, 0,
-                        GL_RGB, texture_w, texture_h, 0,
-                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
-            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
-                glTexImage2D(GL_TEXTURE_2D, 0,
-                        GL_RGBA, texture_w, texture_h, 0,
-                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
-            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
-                glTexImage2D(GL_TEXTURE_2D, 0,
-                        GL_RGBA, texture_w, texture_h, 0,
-                        GL_RGBA, GL_UNSIGNED_BYTE, data);
-            } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
-                        t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
-                // just show the Y plane of YUV buffers
+        if (!textureWidth || !textureHeight) {
+            // this is the first time, load the whole texture
+            if (texture_w==tw && texture_h==th) {
+                // we can do it one pass
                 data = t.data;
-                glTexImage2D(GL_TEXTURE_2D, 0,
-                        GL_LUMINANCE, texture_w, texture_h, 0,
-                        GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
             } else {
-                // oops, we don't handle this format!
-                LOGE("layer %p, texture=%d, using format %d, which is not "
-                     "supported by the GL", this, textureName, t.format);
-                textureName = -1;
+                // we have to create the texture first because it
+                // doesn't match the size of the buffer
+                bounds.set(Rect(tw, th));
             }
-            textureWidth = texture_w;
-            textureHeight = texture_h;
         }
-        if (!data && textureName>=0) {
-            if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
-                glTexSubImage2D(GL_TEXTURE_2D, 0,
-                        0, bounds.top, t.width, bounds.height(),
-                        GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
-                        t.data + bounds.top*t.width*2);
-            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
-                glTexSubImage2D(GL_TEXTURE_2D, 0,
-                        0, bounds.top, t.width, bounds.height(),
-                        GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
-                        t.data + bounds.top*t.width*2);
-            } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
-                glTexSubImage2D(GL_TEXTURE_2D, 0,
-                        0, bounds.top, t.width, bounds.height(),
-                        GL_RGBA, GL_UNSIGNED_BYTE,
-                        t.data + bounds.top*t.width*4);
-            }
+        
+        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_RGB, texture_w, texture_h, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_RGBA, texture_w, texture_h, 0,
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_RGBA, texture_w, texture_h, 0,
+                    GL_RGBA, GL_UNSIGNED_BYTE, data);
+        } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
+                    t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
+            // just show the Y plane of YUV buffers
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_LUMINANCE, texture_w, texture_h, 0,
+                    GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+        } else {
+            // oops, we don't handle this format!
+            LOGE("layer %p, texture=%d, using format %d, which is not "
+                 "supported by the GL", this, textureName, t.format);
+            textureName = -1;
+        }
+        textureWidth = texture_w;
+        textureHeight = texture_h;
+    }
+    if (!data && textureName>=0) {
+        if (t.format == GGL_PIXEL_FORMAT_RGB_565) {
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+                    t.data + bounds.top*t.stride*2);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_4444) {
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
+                    t.data + bounds.top*t.stride*2);
+        } else if (t.format == GGL_PIXEL_FORMAT_RGBA_8888) {
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_RGBA, GL_UNSIGNED_BYTE,
+                    t.data + bounds.top*t.stride*4);
+        } else if ( t.format == GGL_PIXEL_FORMAT_YCbCr_422_SP ||
+                    t.format == GGL_PIXEL_FORMAT_YCbCr_420_SP) {
+            // just show the Y plane of YUV buffers
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_LUMINANCE, GL_UNSIGNED_BYTE,
+                    t.data + bounds.top*t.stride);
         }
     }
 }
 
-bool LayerBase::canUseCopybit() const
-{
-    return mCanUseCopyBit;
-}
-
 // ---------------------------------------------------------------------------
 
-LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
-        Client* c, int32_t i)
-    : LayerBase(flinger, display), client(c),
-      lcblk( c ? &(c->ctrlblk->layers[i]) : 0 ),
-      mIndex(i)
-{
-    if (client) {
-        client->bindLayer(this, i);
+int32_t LayerBaseClient::sIdentity = 0;
 
+LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
+        const sp<Client>& client, int32_t i)
+    : LayerBase(flinger, display), client(client),
+      lcblk( client!=0 ? &(client->ctrlblk->layers[i]) : 0 ),
+      mIndex(i),
+      mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
+{
+}
+
+void LayerBaseClient::onFirstRef()
+{    
+    sp<Client> client(this->client.promote());
+    if (client != 0) {
+        client->bindLayer(this, mIndex);
         // Initialize this layer's control block
         memset(this->lcblk, 0, sizeof(layer_cblk_t));
         this->lcblk->identity = mIdentity;
@@ -717,23 +667,121 @@
 
 LayerBaseClient::~LayerBaseClient()
 {
-    if (client) {
+    sp<Client> client(this->client.promote());
+    if (client != 0) {
         client->free(mIndex);
     }
 }
 
-int32_t LayerBaseClient::serverIndex() const {
-    if (client) {
+int32_t LayerBaseClient::serverIndex() const 
+{
+    sp<Client> client(this->client.promote());
+    if (client != 0) {
         return (client->cid<<16)|mIndex;
     }
     return 0xFFFF0000 | mIndex;
 }
 
-sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() const
+sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
 {
-    return new Surface(clientIndex(), mIdentity);
+    sp<Surface> s;
+    Mutex::Autolock _l(mLock);
+    s = mClientSurface.promote();
+    if (s == 0) {
+        s = createSurface();
+        mClientSurface = s;
+    }
+    return s;
 }
 
+sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
+{
+    return new Surface(mFlinger, clientIndex(), mIdentity,
+            const_cast<LayerBaseClient *>(this));
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBaseClient::Surface::Surface(
+        const sp<SurfaceFlinger>& flinger,
+        SurfaceID id, int identity, 
+        const sp<LayerBaseClient>& owner) 
+    : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner)
+{
+}
+
+
+LayerBaseClient::Surface::~Surface() 
+{
+    /*
+     * This is a good place to clean-up all client resources 
+     */
+
+    // destroy client resources
+    sp<LayerBaseClient> layer = getOwner();
+    if (layer != 0) {
+        mFlinger->destroySurface(layer);
+    }
+}
+
+sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
+    sp<LayerBaseClient> owner(mOwner.promote());
+    return owner;
+}
+
+
+void LayerBaseClient::Surface::getSurfaceData(
+        ISurfaceFlingerClient::surface_data_t* params) const 
+{
+    params->token = mToken;
+    params->identity = mIdentity;
+}
+
+status_t LayerBaseClient::Surface::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case REGISTER_BUFFERS:
+        case UNREGISTER_BUFFERS:
+        case CREATE_OVERLAY:
+        {
+            if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) {
+                IPCThreadState* ipc = IPCThreadState::self();
+                const int pid = ipc->getCallingPid();
+                const int uid = ipc->getCallingUid();
+                LOGE("Permission Denial: "
+                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+                return PERMISSION_DENIED;
+            }
+        }
+    }
+    return BnSurface::onTransact(code, data, reply, flags);
+}
+
+sp<SurfaceBuffer> LayerBaseClient::Surface::getBuffer() 
+{
+    return NULL; 
+}
+
+status_t LayerBaseClient::Surface::registerBuffers(
+        const ISurface::BufferHeap& buffers) 
+{ 
+    return INVALID_OPERATION; 
+}
+
+void LayerBaseClient::Surface::postBuffer(ssize_t offset) 
+{
+}
+
+void LayerBaseClient::Surface::unregisterBuffers() 
+{
+}
+
+sp<OverlayRef> LayerBaseClient::Surface::createOverlay(
+        uint32_t w, uint32_t h, int32_t format) 
+{
+    return NULL;
+};
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index a020f44..6fb1d1c 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -20,8 +20,13 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
 #include <private/ui/LayerState.h>
 
+#include <utils/RefBase.h>
+
 #include <ui/Region.h>
 #include <ui/Overlay.h>
 
@@ -37,10 +42,12 @@
 class DisplayHardware;
 class GraphicPlane;
 class Client;
+class SurfaceBuffer;
+class Buffer;
 
 // ---------------------------------------------------------------------------
 
-class LayerBase
+class LayerBase : public RefBase
 {
     // poor man's dynamic_cast below
     template<typename T>
@@ -69,10 +76,7 @@
     }
 
     
-    static Vector<GLuint> deletedTextures; 
-
     LayerBase(SurfaceFlinger* flinger, DisplayID display);
-    virtual ~LayerBase();
     
     DisplayID           dpy;
     mutable bool        contentDirty;
@@ -201,21 +205,29 @@
 
     /**
      * isSecure - true if this surface is secure, that is if it prevents
-     * screenshots or vns servers.
+     * screenshots or VNC servers.
      */
     virtual bool isSecure() const       { return false; }
 
-            enum { // flags for doTransaction()
-                eVisibleRegion      = 0x00000002,
-                eRestartTransaction = 0x00000008
-            };
+    /** signal this layer that it's not needed any longer. called from the 
+     * main thread */
+    virtual status_t ditch() { return NO_ERROR; }
+
+    
+    
+    enum { // flags for doTransaction()
+        eVisibleRegion      = 0x00000002,
+        eRestartTransaction = 0x00000008
+    };
 
 
     inline  const State&    drawingState() const    { return mDrawingState; }
     inline  const State&    currentState() const    { return mCurrentState; }
     inline  State&          currentState()          { return mCurrentState; }
 
-    static int compareCurrentStateZ(LayerBase*const* layerA, LayerBase*const* layerB) {
+    static int compareCurrentStateZ(
+            sp<LayerBase> const * layerA,
+            sp<LayerBase> const * layerB) {
         return layerA[0]->currentState().z - layerB[0]->currentState().z;
     }
 
@@ -229,20 +241,24 @@
 
           GLuint createTexture() const;
     
-          void drawWithOpenGL(const Region& clip,
-                  GLint textureName,
-                  const GGLSurface& surface,
-                  int transform = 0) const;
-
-          void clearWithOpenGL(const Region& clip) const;
-
-          void loadTexture(const Region& dirty,
-                  GLint textureName, const GGLSurface& t,
-                  GLuint& textureWidth, GLuint& textureHeight) const;
-
-          bool canUseCopybit() const;
+          struct Texture {
+              Texture() : name(-1U), width(0), height(0),
+                  image(EGL_NO_IMAGE_KHR), transform(0), dirty(true) { }
+              GLuint        name;
+              GLuint        width;
+              GLuint        height;
+              EGLImageKHR   image;
+              uint32_t      transform;
+              bool          dirty;
+          };
           
-                SurfaceFlinger* mFlinger;
+          void clearWithOpenGL(const Region& clip) const;
+          void drawWithOpenGL(const Region& clip, const Texture& texture) const;
+          void loadTexture(Texture* texture, GLint textureName, 
+                  const Region& dirty, const GGLSurface& t) const;
+
+          
+                sp<SurfaceFlinger> mFlinger;
                 uint32_t        mFlags;
 
                 // cached during validateVisibility()
@@ -250,7 +266,6 @@
                 int32_t         mOrientation;
                 GLfixed         mVertices[4][2];
                 Rect            mTransformedBounds;
-                bool            mCanUseCopyBit;
                 int             mLeft;
                 int             mTop;
             
@@ -262,16 +277,16 @@
                 // don't change, don't need a lock
                 bool            mPremultipliedAlpha;
 
-                // only read
-    const       uint32_t        mIdentity;
-     
                 // atomic
     volatile    int32_t         mInvalidate;
                 
 
+protected:
+    virtual ~LayerBase();
+
 private:
-                void validateTexture(GLint textureName) const;
-    static      int32_t         sIdentity;
+    LayerBase(const LayerBase& rhs);
+    void validateTexture(GLint textureName) const;
 };
 
 
@@ -287,66 +302,63 @@
     virtual uint32_t getTypeInfo() const { return typeInfo; }
 
     LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 
-            Client* client, int32_t i);
+            const sp<Client>& client, int32_t i);
     virtual ~LayerBaseClient();
+    virtual void onFirstRef();
 
-
-    Client*             const client;
+    wp<Client>          client;
     layer_cblk_t*       const lcblk;
 
+    inline  uint32_t    getIdentity() const { return mIdentity; }
     inline  int32_t     clientIndex() const { return mIndex; }
             int32_t     serverIndex() const;
 
-    virtual sp<Surface> getSurface() const;
    
-            uint32_t    getIdentity() const { return mIdentity; }
+            sp<Surface> getSurface();
+    virtual sp<Surface> createSurface() const;
+    
 
     class Surface : public BnSurface 
     {
     public:
-        Surface(SurfaceID id, int identity) { 
-            mParams.token = id;
-            mParams.identity = identity;
-        }
-        Surface(SurfaceID id, 
-                const sp<IMemoryHeap>& heap0,
-                const sp<IMemoryHeap>& heap1,
-                int identity)
-        {
-            mParams.token = id;
-            mParams.identity = identity;
-            mParams.heap[0] = heap0;
-            mParams.heap[1] = heap1;
-        }
-        virtual ~Surface() {
-            // TODO: We now have a point here were we can clean-up the
-            // client's mess.
-            // This is also where surface id should be recycled.
-            //LOGD("Surface %d, heaps={%p, %p} destroyed",
-            //        mId, mHeap[0].get(), mHeap[1].get());
-        }
-
+        
         virtual void getSurfaceData(
-                ISurfaceFlingerClient::surface_data_t* params) const {
-            *params = mParams;
-        }
+                ISurfaceFlingerClient::surface_data_t* params) const;
 
-        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers) 
-                { return INVALID_OPERATION; }
-        virtual void postBuffer(ssize_t offset) { }
-        virtual void unregisterBuffers() { };
-        virtual sp<OverlayRef> createOverlay(
-                uint32_t w, uint32_t h, int32_t format) {
-            return NULL;
-        };
+    protected:
+        Surface(const sp<SurfaceFlinger>& flinger, 
+                SurfaceID id, int identity, 
+                const sp<LayerBaseClient>& owner);
+        virtual ~Surface();
+        virtual status_t onTransact(uint32_t code, const Parcel& data,
+                Parcel* reply, uint32_t flags);
+        sp<LayerBaseClient> getOwner() const;
 
     private:
-        ISurfaceFlingerClient::surface_data_t mParams;
+        virtual sp<SurfaceBuffer> getBuffer();
+        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); 
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        virtual sp<OverlayRef> createOverlay(uint32_t w, uint32_t h,
+                int32_t format);
+
+    protected:
+        friend class LayerBaseClient;
+        sp<SurfaceFlinger>  mFlinger;
+        int32_t             mToken;
+        int32_t             mIdentity;
+        wp<LayerBaseClient> mOwner;
     };
 
-private:
-    int32_t mIndex;
+    friend class Surface;
 
+private:
+                int32_t         mIndex;
+    mutable     Mutex           mLock;
+    mutable     wp<Surface>     mClientSurface;
+    // only read
+    const       uint32_t        mIdentity;
+    static      int32_t         sIdentity;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerBitmap.cpp b/libs/surfaceflinger/LayerBitmap.cpp
index 397ddc8..9fffbbf 100644
--- a/libs/surfaceflinger/LayerBitmap.cpp
+++ b/libs/surfaceflinger/LayerBitmap.cpp
@@ -14,173 +14,196 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <cutils/memory.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
-#include <utils/MemoryDealer.h>
-#include <utils/IMemory.h>
+#include <binder/MemoryBase.h>
+#include <binder/IMemory.h>
+
 #include <ui/PixelFormat.h>
+#include <ui/Surface.h>
 #include <pixelflinger/pixelflinger.h>
 
+#include "BufferAllocator.h"
 #include "LayerBitmap.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 
 
 namespace android {
 
-// ---------------------------------------------------------------------------
+// ===========================================================================
+// Buffer and implementation of android_native_buffer_t
+// ===========================================================================
+
+Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
+    : SurfaceBuffer(), mInitCheck(NO_INIT), mFlags(flags), 
+    mVStride(0)
+{
+    this->format = format;
+    if (w>0 && h>0) {
+        mInitCheck = initSize(w, h);
+    }
+}
+
+Buffer::~Buffer()
+{
+    if (handle) {
+        BufferAllocator& allocator(BufferAllocator::get());
+        allocator.free(handle);
+    }
+}
+
+status_t Buffer::initCheck() const {
+    return mInitCheck;
+}
+
+android_native_buffer_t* Buffer::getNativeBuffer() const
+{
+    return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this));
+}
+
+status_t Buffer::initSize(uint32_t w, uint32_t h)
+{
+    status_t err = NO_ERROR;
+
+    BufferAllocator& allocator = BufferAllocator::get();
+        
+    /*
+     *  buffers used for software rendering, but h/w composition
+     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
+     *  
+     *  buffers used for h/w rendering and h/w composition
+     *  are allocated with  HW_RENDER | HW_TEXTURE
+     *  
+     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
+     *  are allocated with SW_READ_RARELY | HW_RENDER 
+     *  
+     */
+    
+    if (mFlags & Buffer::SECURE) {
+        // secure buffer, don't store it into the GPU
+        usage = BufferAllocator::USAGE_SW_READ_OFTEN | 
+                BufferAllocator::USAGE_SW_WRITE_OFTEN;
+    } else {
+        if (mFlags & Buffer::GPU) {
+            // the client wants to do GL rendering
+            usage = BufferAllocator::USAGE_HW_RENDER |
+                    BufferAllocator::USAGE_HW_TEXTURE;
+        } else {
+            // software rendering-client, h/w composition
+            usage = BufferAllocator::USAGE_SW_READ_OFTEN | 
+                    BufferAllocator::USAGE_SW_WRITE_OFTEN |
+                    BufferAllocator::USAGE_HW_TEXTURE;
+        }
+    }
+
+    err = allocator.alloc(w, h, format, usage, &handle, &stride);
+    
+    if (err == NO_ERROR) {
+        if (err == NO_ERROR) {
+            width  = w;
+            height = h;
+            mVStride = 0;
+        }
+    }
+
+    return err;
+}
+
+status_t Buffer::lock(GGLSurface* sur, uint32_t usage) 
+{
+    void* vaddr;
+    status_t res = SurfaceBuffer::lock(usage, &vaddr);
+    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*>(vaddr);
+    }
+    return res;
+}
+
+// ===========================================================================
+// LayerBitmap
+// ===========================================================================
 
 LayerBitmap::LayerBitmap()
-    : mAllocFlags(0), mOffset(0), mSize(-1U), mAlignment(2)
+    : mInfo(0), mWidth(0), mHeight(0)
 {
-    memset(&mSurface, 0, sizeof(mSurface));
 }
 
 LayerBitmap::~LayerBitmap()
 {
-    mSurface.data = 0;
 }
 
-status_t LayerBitmap::init(const sp<MemoryDealer>& allocator)
+status_t LayerBitmap::init(surface_info_t* info,
+        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
 {
-    if (mAllocator != NULL)
+    if (info == NULL)
         return BAD_VALUE;
-    mAllocator = allocator;
+    
+    mFormat = format;
+    mFlags = flags;
+    mWidth = w;
+    mHeight = h;
+
+    mInfo = info;
+    memset(info, 0, sizeof(surface_info_t));
+    info->flags = surface_info_t::eNeedNewBuffer;
+    
+    // init the buffer, but don't trigger an allocation
+    mBuffer = new Buffer(0, 0, format, flags);
     return NO_ERROR;
 }
 
-status_t LayerBitmap::setBits(uint32_t w, uint32_t h, uint32_t alignment, 
-        PixelFormat format, uint32_t flags)
+status_t LayerBitmap::setSize(uint32_t w, uint32_t h)
 {
-    const sp<MemoryDealer>& allocator(mAllocator);
-    if (allocator == NULL)
-        return NO_INIT;
-
-    if (UNLIKELY(w == mSurface.width && h == mSurface.height &&
-            format == mSurface.format))
-    { // same format and size, do nothing.
-        return NO_ERROR;
-    }
-
-    PixelFormatInfo info;
-    getPixelFormatInfo(format, &info);
-
-    uint32_t allocFlags = MemoryDealer::PAGE_ALIGNED;
-    const uint32_t align = 4; // must match GL_UNPACK_ALIGNMENT
-    const uint32_t Bpp = info.bytesPerPixel;
-    uint32_t stride = (w + (alignment-1)) & ~(alignment-1);
-    stride = ((stride * Bpp + (align-1)) & ~(align-1)) / Bpp;
-    size_t size = info.getScanlineSize(stride) * h;
-    if (allocFlags & MemoryDealer::PAGE_ALIGNED) {
-        size_t pagesize = getpagesize();
-        size = (size + (pagesize-1)) & ~(pagesize-1);
-    }
-
-    /* FIXME: we should be able to have a h/v stride because the user of the
-     * surface might have stride limitation (for instance h/w codecs often do)
-     */
-    int32_t vstride = 0;
-
-    mAlignment = alignment;
-    mAllocFlags = allocFlags;
-    mOffset = 0;
-    if (mSize != size) {
-        // would be nice to have a reallocate() api
-        mBitsMemory.clear(); // free-memory
-        mBitsMemory = allocator->allocate(size, allocFlags);
-        mSize = size;
-    } else {
-        // don't erase memory if we didn't have to reallocate
-        flags &= ~SECURE_BITS;
-    }
-    if (mBitsMemory != 0) {
-        mOffset = mBitsMemory->offset();
-        mSurface.data = static_cast<GGLubyte*>(mBitsMemory->pointer());
-        mSurface.version = sizeof(GGLSurface);
-        mSurface.width  = w;
-        mSurface.height = h;
-        mSurface.stride = stride;
-        mSurface.vstride = vstride;
-        mSurface.format = format;
-        if (flags & SECURE_BITS)
-            clear();
-    }
-
-    if (mBitsMemory==0 || mSurface.data==0) {
-        LOGE("not enough memory for layer bitmap "
-             "size=%u (w=%d, h=%d, stride=%d, format=%d)",
-             size, int(w), int(h), int(stride), int(format));
-        allocator->dump("LayerBitmap");
-        mSurface.data = 0;
-        mSize = -1U;
-        return NO_MEMORY;
+    Mutex::Autolock _l(mLock);
+    if ((w != mWidth) || (h != mHeight)) {
+        mWidth  = w;
+        mHeight = h;
+        // this will signal the client that it needs to asks us for a new buffer
+        mInfo->flags = surface_info_t::eNeedNewBuffer;
     }
     return NO_ERROR;
 }
 
-void LayerBitmap::clear()
+sp<Buffer> LayerBitmap::allocate()
 {
-    // NOTE: this memset should not be necessary, at least for
-    // opaque surface. However, for security reasons it's better to keep it
-    // (in the case of pmem, it's possible that the memory contains old
-    // data)
-    if (mSurface.data) {
-        memset(mSurface.data, 0, mSize);
-        //if (bytesPerPixel(mSurface.format) == 4) {
-        //    android_memset32((uint32_t*)mSurface.data, 0xFF0000FF, mSize);
-        //} else  {
-        //    android_memset16((uint16_t*)mSurface.data, 0xF800, mSize);
-        //}
+    Mutex::Autolock _l(mLock);
+    sp<Buffer> buffer(mBuffer);
+    const uint32_t w = mWidth; 
+    const uint32_t h = mHeight;
+    if (buffer!=0 && (w != buffer->getWidth() || h != buffer->getHeight())) {
+        surface_info_t* info = mInfo;
+        buffer = new Buffer(w, h, mFormat, mFlags);
+        status_t err = buffer->initCheck();
+        if (LIKELY(err == NO_ERROR)) {
+            info->flags  = surface_info_t::eBufferDirty;
+            info->status = NO_ERROR;
+        } else {
+            memset(info, 0, sizeof(surface_info_t));
+            info->status = NO_MEMORY;
+        }
+        mBuffer = buffer;
     }
+    return buffer;
 }
 
-status_t LayerBitmap::getInfo(surface_info_t* info) const
+status_t LayerBitmap::free()
 {
-    if (mSurface.data == 0) {
-        memset(info, 0, sizeof(surface_info_t));
-        info->bits_offset = NO_MEMORY;
-        return NO_MEMORY;
-    }
-    info->w     = uint16_t(width());
-    info->h     = uint16_t(height());
-    info->stride= uint16_t(stride());
-    info->bpr   = uint16_t(stride() * bytesPerPixel(pixelFormat()));
-    info->format= uint8_t(pixelFormat());
-    info->flags = surface_info_t::eBufferDirty;
-    info->bits_offset = ssize_t(mOffset);
+    mBuffer.clear();
+    mWidth = 0;
+    mHeight = 0;
     return NO_ERROR;
 }
 
-status_t LayerBitmap::resize(uint32_t w, uint32_t h)
-{
-    int err = setBits(w, h, mAlignment, pixelFormat(), SECURE_BITS);
-    return err;
-}
-
-size_t LayerBitmap::size() const
-{
-    return mSize;
-}
-
-void LayerBitmap::getBitmapSurface(copybit_image_t* img) const
-{
-    const sp<IMemoryHeap>& mh(getAllocator()->getMemoryHeap());
-    void* sbase = mh->base();
-    const GGLSurface& t(surface());
-    img->w = t.stride  ?: t.width;
-    img->h = t.vstride ?: t.height;
-    img->format = t.format;
-    img->offset = intptr_t(t.data) - intptr_t(sbase);
-    img->base = sbase;
-    img->fd = mh->heapID();
-}
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
index 9ad64c4..22525ce 100644
--- a/libs/surfaceflinger/LayerBitmap.h
+++ b/libs/surfaceflinger/LayerBitmap.h
@@ -20,63 +20,114 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <hardware/gralloc.h>
+
 #include <utils/Atomic.h>
+
 #include <ui/PixelFormat.h>
 #include <ui/Rect.h>
-#include <private/ui/SharedState.h>
+#include <ui/Surface.h>
+
 #include <pixelflinger/pixelflinger.h>
 
+#include <private/ui/SharedState.h>
+#include <private/ui/SurfaceBuffer.h>
+
 class copybit_image_t;
+struct android_native_buffer_t;
 
 namespace android {
 
 // ---------------------------------------------------------------------------
-
 class IMemory;
-class MemoryDealer;
 class LayerBitmap;
 
-// ---------------------------------------------------------------------------
+// ===========================================================================
+// Buffer
+// ===========================================================================
+
+class NativeBuffer;
+
+class Buffer : public SurfaceBuffer
+{
+public:
+    enum {
+        DONT_CLEAR  = 0x00000001,
+        GPU         = 0x00000002,
+        SECURE      = 0x00000004
+    };
+
+    // creates w * h buffer
+    Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags = 0);
+
+    // return status
+    status_t initCheck() const;
+
+    uint32_t getWidth() const           { return width; }
+    uint32_t getHeight() const          { return height; }
+    uint32_t getStride() const          { return stride; }
+    uint32_t getUsage() const           { return usage; }
+    PixelFormat getPixelFormat() const  { return format; }
+    Rect getBounds() const              { return Rect(width, height); }
+    
+    status_t lock(GGLSurface* surface, uint32_t usage);
+    
+    android_native_buffer_t* getNativeBuffer() const;
+    
+private:
+    friend class LightRefBase<Buffer>;
+    Buffer(const Buffer& rhs);
+    virtual ~Buffer();
+    Buffer& operator = (const Buffer& rhs);
+    const Buffer& operator = (const Buffer& rhs) const;
+
+    status_t initSize(uint32_t w, uint32_t h);
+
+    ssize_t                 mInitCheck;
+    uint32_t                mFlags;
+    uint32_t                mVStride;
+};
+
+// ===========================================================================
+// LayerBitmap
+// ===========================================================================
 
 class LayerBitmap
 {
 public:
-
     enum {
-        // erase memory to ensure security when necessary
-        SECURE_BITS = 0x00000001
+        DONT_CLEAR  = Buffer::DONT_CLEAR,
+        GPU         = Buffer::GPU,
+        SECURE      = Buffer::SECURE
     };
+    LayerBitmap();
+    ~LayerBitmap();
 
-                LayerBitmap();
-                ~LayerBitmap();
-    status_t    init(const sp<MemoryDealer>& allocator);
+    status_t init(surface_info_t* info,
+            uint32_t w, uint32_t h, PixelFormat format, uint32_t flags = 0);
 
-    status_t    setBits(uint32_t w, uint32_t h, uint32_t alignment,
-                        PixelFormat format, uint32_t flags = 0);
-    void        clear();
+    status_t setSize(uint32_t w, uint32_t h);
 
-    status_t    getInfo(surface_info_t* info) const;
-    status_t    resize(uint32_t w, uint32_t h);
-
-    const GGLSurface& surface() const   { return mSurface; }
-    Rect bounds() const                 { return Rect(width(), height()); }
-    uint32_t width() const              { return surface().width; }
-    uint32_t height() const             { return surface().height; }
-    uint32_t stride() const             { return surface().stride; }
-    PixelFormat pixelFormat() const     { return surface().format; }
-    void* serverBits() const            { return surface().data; }
-    size_t size() const;
-    const sp<MemoryDealer>& getAllocator() const { return mAllocator; }
-    void getBitmapSurface(copybit_image_t* img) const;
-
+    sp<Buffer> allocate();
+    status_t free();
+    
+    sp<const Buffer>  getBuffer() const { return mBuffer; }
+    sp<Buffer>        getBuffer()       { return mBuffer; }
+    
+    uint32_t getWidth() const           { return mWidth; }
+    uint32_t getHeight() const          { return mHeight; }
+    PixelFormat getPixelFormat() const  { return mBuffer->getPixelFormat(); }
+    Rect getBounds() const              { return mBuffer->getBounds(); }
+    
 private:
-    sp<MemoryDealer>        mAllocator;
-    sp<IMemory>             mBitsMemory;
-    uint32_t                mAllocFlags;
-    ssize_t                 mOffset;
-    GGLSurface              mSurface;
-    size_t                  mSize;
-    uint32_t                mAlignment;
+    surface_info_t* mInfo;
+    sp<Buffer>      mBuffer;
+    uint32_t        mWidth;
+    uint32_t        mHeight;
+    PixelFormat     mFormat;
+    uint32_t        mFlags;
+    // protects setSize() and allocate()
+    mutable Mutex   mLock;
 };
 
 }; // namespace android
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
index d3e456f..00abd5a 100644
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ b/libs/surfaceflinger/LayerBlur.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
@@ -40,7 +38,7 @@
 // ---------------------------------------------------------------------------
 
 LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
-        Client* client, int32_t i)
+        const sp<Client>& client, int32_t i)
      : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
      mRefreshCache(true), mCacheAge(0), mTextureName(-1U)
 {
@@ -49,8 +47,7 @@
 LayerBlur::~LayerBlur()
 {
     if (mTextureName != -1U) {
-        //glDeleteTextures(1, &mTextureName);
-        deletedTextures.add(mTextureName);
+        glDeleteTextures(1, &mTextureName);
     }
 }
 
@@ -139,8 +136,9 @@
         glGenTextures(1, &mTextureName);
     }
 
-    Region::iterator iterator(clip);
-    if (iterator) {
+    Region::const_iterator it = clip.begin();
+    Region::const_iterator const end = clip.end();
+    if (it != end) {
         glEnable(GL_TEXTURE_2D);
         glBindTexture(GL_TEXTURE_2D, mTextureName);
     
@@ -201,27 +199,25 @@
             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
             glVertexPointer(2, GL_FIXED, 0, mVertices);
             glTexCoordPointer(2, GL_FIXED, 0, mVertices);
-            Rect r;
-            while (iterator.iterate(&r)) {
+            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); 
             }       
         } else {
-            Region::iterator iterator(clip);
-            if (iterator) {
-                // 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 (iterator.iterate(&r)) {
-                    const GLint sy = fbHeight - (r.top + r.height());
-                    glScissor(r.left, sy, r.width(), r.height());
-                    glDrawTexiOES(x, y, 0, w, h);
-                }
+            // 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);
             }
         }
     }
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
index 24b1156..0c3e6eb 100644
--- a/libs/surfaceflinger/LayerBlur.h
+++ b/libs/surfaceflinger/LayerBlur.h
@@ -39,7 +39,7 @@
     virtual uint32_t getTypeInfo() const { return typeInfo; }
     
                 LayerBlur(SurfaceFlinger* flinger, DisplayID display,
-                        Client* client, int32_t i);
+                        const sp<Client>& client, int32_t i);
         virtual ~LayerBlur();
 
     virtual void onDraw(const Region& clip) const;
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 00fab70..a088b0a 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <math.h>
@@ -25,17 +23,16 @@
 #include <utils/Log.h>
 #include <utils/StopWatch.h>
 
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-
 #include <ui/PixelFormat.h>
-#include <ui/EGLDisplaySurface.h>
+#include <ui/FramebufferNativeWindow.h>
+
+#include <hardware/copybit.h>
 
 #include "LayerBuffer.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 #include "DisplayHardware/DisplayHardware.h"
 
+#include "gralloc_priv.h"   // needed for msm / copybit
 
 namespace android {
 
@@ -47,7 +44,7 @@
 // ---------------------------------------------------------------------------
 
 LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
-        Client* client, int32_t i)
+        const sp<Client>& client, int32_t i)
     : LayerBaseClient(flinger, display, client, i),
       mNeedsBlending(false)
 {
@@ -55,30 +52,24 @@
 
 LayerBuffer::~LayerBuffer()
 {
-    sp<SurfaceBuffer> s(getClientSurface());
-    if (s != 0) {
-        s->disown();
-        mClientSurface.clear();
-    }
 }
 
-sp<LayerBuffer::SurfaceBuffer> LayerBuffer::getClientSurface() const
+void LayerBuffer::onFirstRef()
 {
-    Mutex::Autolock _l(mLock);
-    return mClientSurface.promote();
+    LayerBaseClient::onFirstRef();
+    mSurface = new SurfaceBuffer(mFlinger, clientIndex(),
+            const_cast<LayerBuffer *>(this));
 }
 
-sp<LayerBaseClient::Surface> LayerBuffer::getSurface() const
+sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const
 {
-    sp<SurfaceBuffer> s;
-    Mutex::Autolock _l(mLock);
-    s = mClientSurface.promote();
-    if (s == 0) {
-        s = new SurfaceBuffer(clientIndex(),
-                const_cast<LayerBuffer *>(this));
-        mClientSurface = s;
-    }
-    return s;
+    return mSurface;
+}
+
+status_t LayerBuffer::ditch()
+{
+    mSurface.clear();
+    return NO_ERROR;
 }
 
 bool LayerBuffer::needsBlending() const {
@@ -192,82 +183,49 @@
 // LayerBuffer::SurfaceBuffer
 // ============================================================================
 
-LayerBuffer::SurfaceBuffer::SurfaceBuffer(SurfaceID id, LayerBuffer* owner)
-: LayerBaseClient::Surface(id, owner->getIdentity()), mOwner(owner)
+LayerBuffer::SurfaceBuffer::SurfaceBuffer(const sp<SurfaceFlinger>& flinger,
+        SurfaceID id, const sp<LayerBuffer>& owner)
+    : LayerBaseClient::Surface(flinger, id, owner->getIdentity(), owner)
 {
 }
 
 LayerBuffer::SurfaceBuffer::~SurfaceBuffer()
 {
     unregisterBuffers();
-    mOwner = 0;
 }
 
-status_t LayerBuffer::SurfaceBuffer::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+status_t LayerBuffer::SurfaceBuffer::registerBuffers(
+        const ISurface::BufferHeap& buffers)
 {
-    switch (code) {
-        case REGISTER_BUFFERS:
-        case UNREGISTER_BUFFERS:
-        case CREATE_OVERLAY:
-        {
-            // codes that require permission check
-            IPCThreadState* ipc = IPCThreadState::self();
-            const int pid = ipc->getCallingPid();
-            const int self_pid = getpid();
-            if (LIKELY(pid != self_pid)) {
-                // we're called from a different process, do the real check
-                if (!checkCallingPermission(
-                        String16("android.permission.ACCESS_SURFACE_FLINGER")))
-                {
-                    const int uid = ipc->getCallingUid();
-                    LOGE("Permission Denial: "
-                            "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
-                    return PERMISSION_DENIED;
-                }
-            }
-        }
-    }
-    return LayerBaseClient::Surface::onTransact(code, data, reply, flags);
-}
-
-status_t LayerBuffer::SurfaceBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
-{
-    LayerBuffer* owner(getOwner());
-    if (owner)
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
         return owner->registerBuffers(buffers);
     return NO_INIT;
 }
 
 void LayerBuffer::SurfaceBuffer::postBuffer(ssize_t offset)
 {
-    LayerBuffer* owner(getOwner());
-    if (owner)
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
         owner->postBuffer(offset);
 }
 
 void LayerBuffer::SurfaceBuffer::unregisterBuffers()
 {
-    LayerBuffer* owner(getOwner());
-    if (owner)
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
         owner->unregisterBuffers();
 }
 
 sp<OverlayRef> LayerBuffer::SurfaceBuffer::createOverlay(
         uint32_t w, uint32_t h, int32_t format) {
     sp<OverlayRef> result;
-    LayerBuffer* owner(getOwner());
-    if (owner)
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
         result = owner->createOverlay(w, h, format);
     return result;
 }
 
-void LayerBuffer::SurfaceBuffer::disown()
-{
-    Mutex::Autolock _l(mLock);
-    mOwner = 0;
-}
-
 // ============================================================================
 // LayerBuffer::Buffer
 // ============================================================================
@@ -276,20 +234,30 @@
     : mBufferHeap(buffers)
 {
     NativeBuffer& src(mNativeBuffer);
+    
     src.crop.l = 0;
     src.crop.t = 0;
     src.crop.r = buffers.w;
     src.crop.b = buffers.h;
-    src.img.w = buffers.hor_stride ?: buffers.w;
-    src.img.h = buffers.ver_stride ?: buffers.h;
-    src.img.format = buffers.format;
-    src.img.offset = offset;
-    src.img.base   = buffers.heap->base();
-    src.img.fd     = buffers.heap->heapID();
+    
+    src.img.w       = buffers.hor_stride ?: buffers.w;
+    src.img.h       = buffers.ver_stride ?: buffers.h;
+    src.img.format  = buffers.format;
+    src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
+
+    // FIXME: gross hack, we should never access private_handle_t from here,
+    // but this is needed by msm drivers
+    private_handle_t* hnd = new private_handle_t(
+            buffers.heap->heapID(), buffers.heap->getSize(), 0);
+    hnd->offset = offset;
+    src.img.handle = hnd;
 }
 
 LayerBuffer::Buffer::~Buffer()
 {
+    NativeBuffer& src(mNativeBuffer);
+    if (src.img.handle)
+        delete (private_handle_t*)src.img.handle;
 }
 
 // ============================================================================
@@ -323,8 +291,7 @@
 
 LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
         const ISurface::BufferHeap& buffers)
-    : Source(layer), mStatus(NO_ERROR), 
-      mBufferSize(0), mTextureName(-1U)
+    : Source(layer), mStatus(NO_ERROR), mBufferSize(0)
 {
     if (buffers.heap == NULL) {
         // this is allowed, but in this case, it is illegal to receive
@@ -363,13 +330,21 @@
     mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
     mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
     mLayer.forceVisibilityTransaction();
-    
+
+    hw_module_t const* module;
+    mBlitEngine = NULL;
+    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
+        copybit_open(module, &mBlitEngine);
+    }
 }
 
 LayerBuffer::BufferSource::~BufferSource()
 {    
-    if (mTextureName != -1U) {
-        LayerBase::deletedTextures.add(mTextureName);
+    if (mTexture.name != -1U) {
+        glDeleteTextures(1, &mTexture.name);
+    }
+    if (mBlitEngine) {
+        copybit_close(mBlitEngine);
     }
 }
 
@@ -427,19 +402,19 @@
 
 void LayerBuffer::BufferSource::onDraw(const Region& clip) const 
 {
-    sp<Buffer> buffer(getBuffer());
-    if (UNLIKELY(buffer == 0))  {
+    sp<Buffer> ourBuffer(getBuffer());
+    if (UNLIKELY(ourBuffer == 0))  {
         // nothing to do, we don't have a buffer
         mLayer.clearWithOpenGL(clip);
         return;
     }
 
     status_t err = NO_ERROR;
-    NativeBuffer src(buffer->getBuffer());
+    NativeBuffer src(ourBuffer->getBuffer());
     const Rect& transformedBounds = mLayer.getTransformedBounds();
-    const int can_use_copybit = mLayer.canUseCopybit();
+    copybit_device_t* copybit = mBlitEngine;
 
-    if (can_use_copybit)  {
+    if (copybit)  {
         const int src_width  = src.crop.r - src.crop.l;
         const int src_height = src.crop.b - src.crop.t;
         int W = transformedBounds.width();
@@ -448,89 +423,108 @@
             int t(W); W=H; H=t;
         }
 
-        /* With LayerBuffer, it is likely that we'll have to rescale the
-         * surface, because this is often used for video playback or
-         * camera-preview. Since we want these operation as fast as possible
-         * we make sure we can use the 2D H/W even if it doesn't support
-         * the requested scale factor, in which case we perform the scaling
-         * in several passes. */
+#ifdef EGL_ANDROID_get_render_buffer
+        EGLDisplay dpy = eglGetCurrentDisplay();
+        EGLSurface draw = eglGetCurrentSurface(EGL_DRAW); 
+        EGLClientBuffer clientBuf = eglGetRenderBufferANDROID(dpy, draw);
+        android_native_buffer_t* nb = (android_native_buffer_t*)clientBuf;
+        if (nb == 0) {
+            err = BAD_VALUE;
+        } else {
+            copybit_image_t dst;
+            dst.w       = nb->width;
+            dst.h       = nb->height;
+            dst.format  = nb->format;
+            dst.base    = NULL; // unused by copybit on msm7k
+            dst.handle  = (native_handle_t *)nb->handle;
 
-        copybit_device_t* copybit = mLayer.mFlinger->getBlitEngine();
-        const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
-        const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
+            /* With LayerBuffer, it is likely that we'll have to rescale the
+             * surface, because this is often used for video playback or
+             * camera-preview. Since we want these operation as fast as possible
+             * we make sure we can use the 2D H/W even if it doesn't support
+             * the requested scale factor, in which case we perform the scaling
+             * in several passes. */
 
-        float xscale = 1.0f;
-        if (src_width > W*min)          xscale = 1.0f / min;
-        else if (src_width*mag < W)     xscale = mag;
+            const float min = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
+            const float mag = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
 
-        float yscale = 1.0f;
-        if (src_height > H*min)         yscale = 1.0f / min;
-        else if (src_height*mag < H)    yscale = mag;
+            float xscale = 1.0f;
+            if (src_width > W*min)          xscale = 1.0f / min;
+            else if (src_width*mag < W)     xscale = mag;
 
-        if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
-            if (UNLIKELY(mTemporaryDealer == 0)) {
-                // allocate a memory-dealer for this the first time
-                mTemporaryDealer = mLayer.mFlinger->getSurfaceHeapManager()
-                    ->createHeap(ISurfaceComposer::eHardware);
-                mTempBitmap.init(mTemporaryDealer);
+            float yscale = 1.0f;
+            if (src_height > H*min)         yscale = 1.0f / min;
+            else if (src_height*mag < H)    yscale = mag;
+
+            if (UNLIKELY(xscale!=1.0f || yscale!=1.0f)) {
+                const int tmp_w = floorf(src_width  * xscale);
+                const int tmp_h = floorf(src_height * yscale);
+                
+                if (mTempBitmap==0 || 
+                        mTempBitmap->getWidth() < tmp_w || 
+                        mTempBitmap->getHeight() < tmp_h) {
+                    mTempBitmap.clear();
+                    mTempBitmap = new android::Buffer(tmp_w, tmp_h, src.img.format);
+                    err = mTempBitmap->initCheck();
+                }
+
+                if (LIKELY(err == NO_ERROR)) {
+                    NativeBuffer tmp;
+                    tmp.img.w = tmp_w;
+                    tmp.img.h = tmp_h;
+                    tmp.img.format = src.img.format;
+                    tmp.img.handle = (native_handle_t*)mTempBitmap->getNativeBuffer()->handle;
+                    tmp.crop.l = 0;
+                    tmp.crop.t = 0;
+                    tmp.crop.r = tmp.img.w;
+                    tmp.crop.b = tmp.img.h;
+
+                    region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b)));
+                    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+                    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+                    copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
+                    err = copybit->stretch(copybit,
+                            &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it);
+                    src = tmp;
+                }
             }
 
-            const int tmp_w = floorf(src_width  * xscale);
-            const int tmp_h = floorf(src_height * yscale);
-            err = mTempBitmap.setBits(tmp_w, tmp_h, 1, src.img.format);
+            const Rect& transformedBounds = mLayer.getTransformedBounds();
+            const copybit_rect_t& drect =
+                reinterpret_cast<const copybit_rect_t&>(transformedBounds);
+            const State& s(mLayer.drawingState());
+            region_iterator it(clip);
 
-            if (LIKELY(err == NO_ERROR)) {
-                NativeBuffer tmp;
-                mTempBitmap.getBitmapSurface(&tmp.img);
-                tmp.crop.l = 0;
-                tmp.crop.t = 0;
-                tmp.crop.r = tmp.img.w;
-                tmp.crop.b = tmp.img.h;
-
-                region_iterator tmp_it(Region(Rect(tmp.crop.r, tmp.crop.b)));
-                copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-                copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-                copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-                err = copybit->stretch(copybit,
-                        &tmp.img, &src.img, &tmp.crop, &src.crop, &tmp_it);
-                src = tmp;
+            // pick the right orientation for this buffer
+            int orientation = mLayer.getOrientation();
+            if (UNLIKELY(mBufferHeap.transform)) {
+                Transform rot90;
+                GraphicPlane::orientationToTransfrom(
+                        ISurfaceComposer::eOrientation90, 0, 0, &rot90);
+                const Transform& planeTransform(mLayer.graphicPlane(0).transform());
+                const Layer::State& s(mLayer.drawingState());
+                Transform tr(planeTransform * s.transform * rot90);
+                orientation = tr.getOrientation();
             }
-        }
 
-        const DisplayHardware& hw(mLayer.graphicPlane(0).displayHardware());
-        copybit_image_t dst;
-        hw.getDisplaySurface(&dst);
-        const copybit_rect_t& drect
-            = reinterpret_cast<const copybit_rect_t&>(transformedBounds);
-        const State& s(mLayer.drawingState());
-        region_iterator it(clip);
-        
-        // pick the right orientation for this buffer
-        int orientation = mLayer.getOrientation();
-        if (UNLIKELY(mBufferHeap.transform)) {
-            Transform rot90;
-            GraphicPlane::orientationToTransfrom(
-                    ISurfaceComposer::eOrientation90, 0, 0, &rot90);
-            const Transform& planeTransform(mLayer.graphicPlane(0).transform());
-            const Layer::State& s(mLayer.drawingState());
-            Transform tr(planeTransform * s.transform * rot90);
-            orientation = tr.getOrientation();
-        }
-        
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation);
-        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
-        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, orientation);
+            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
+            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
 
-        err = copybit->stretch(copybit,
-                &dst, &src.img, &drect, &src.crop, &it);
-        if (err != NO_ERROR) {
-            LOGE("copybit failed (%s)", strerror(err));
+            err = copybit->stretch(copybit,
+                    &dst, &src.img, &drect, &src.crop, &it);
+            if (err != NO_ERROR) {
+                LOGE("copybit failed (%s)", strerror(err));
+            }
         }
     }
-
-    if (!can_use_copybit || err) {
-        if (UNLIKELY(mTextureName == -1LU)) {
-            mTextureName = mLayer.createTexture();
+#endif
+    
+    if (!copybit || err) 
+    {
+        // OpenGL fall-back
+        if (UNLIKELY(mTexture.name == -1LU)) {
+            mTexture.name = mLayer.createTexture();
         }
         GLuint w = 0;
         GLuint h = 0;
@@ -541,10 +535,11 @@
         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);
+        t.data = (GGLubyte*)src.img.base;
         const Region dirty(Rect(t.width, t.height));
-        mLayer.loadTexture(dirty, mTextureName, t, w, h);
-        mLayer.drawWithOpenGL(clip, mTextureName, t, mBufferHeap.transform);
+        mLayer.loadTexture(&mTexture, mTexture.name, dirty, t);
+        mTexture.transform = mBufferHeap.transform;
+        mLayer.drawWithOpenGL(clip, mTexture);
     }
 }
 
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
index 2dc77f1..fe879eb 100644
--- a/libs/surfaceflinger/LayerBuffer.h
+++ b/libs/surfaceflinger/LayerBuffer.h
@@ -20,18 +20,18 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/IMemory.h>
+#include <binder/IMemory.h>
 #include <private/ui/LayerState.h>
-#include <EGL/eglnatives.h>
 
 #include "LayerBase.h"
 #include "LayerBitmap.h"
 
+struct copybit_device_t;
+
 namespace android {
 
 // ---------------------------------------------------------------------------
 
-class MemoryDealer;
 class Region;
 class OverlayRef;
 
@@ -51,7 +51,6 @@
         LayerBuffer& mLayer;
     };
 
-
 public:
     static const uint32_t typeInfo;
     static const char* const typeID;
@@ -59,12 +58,14 @@
     virtual uint32_t getTypeInfo() const { return typeInfo; }
 
             LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
-                        Client* client, int32_t i);
+                    const sp<Client>& client, int32_t i);
         virtual ~LayerBuffer();
 
+    virtual void onFirstRef();
     virtual bool needsBlending() const;
 
-    virtual sp<LayerBaseClient::Surface> getSurface() const;
+    virtual sp<LayerBaseClient::Surface> createSurface() const;
+    virtual status_t ditch();
     virtual void onDraw(const Region& clip) const;
     virtual uint32_t doTransaction(uint32_t flags);
     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
@@ -121,14 +122,14 @@
         virtual void unregisterBuffers();
         virtual bool transformed() const;
     private:
-        mutable Mutex   mLock;
-        sp<Buffer>      mBuffer;
-        status_t        mStatus;
-        ISurface::BufferHeap mBufferHeap;
-        size_t          mBufferSize;
-        mutable sp<MemoryDealer> mTemporaryDealer;
-        mutable LayerBitmap mTempBitmap;
-        mutable GLuint  mTextureName;
+        mutable Mutex                   mLock;
+        sp<Buffer>                      mBuffer;
+        status_t                        mStatus;
+        ISurface::BufferHeap            mBufferHeap;
+        size_t                          mBufferSize;
+        mutable sp<android::Buffer>     mTempBitmap;
+        mutable LayerBase::Texture      mTexture;
+        copybit_device_t*               mBlitEngine;
     };
     
     class OverlaySource : public Source {
@@ -179,34 +180,27 @@
     class SurfaceBuffer : public LayerBaseClient::Surface
     {
     public:
-                SurfaceBuffer(SurfaceID id, LayerBuffer* owner);
+                SurfaceBuffer(const sp<SurfaceFlinger>& flinger,
+                        SurfaceID id, const sp<LayerBuffer>& owner);
         virtual ~SurfaceBuffer();
-        virtual status_t onTransact(
-            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+
         virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
+        
         virtual sp<OverlayRef> createOverlay(
                 uint32_t w, uint32_t h, int32_t format);
-       void disown();
     private:
-        LayerBuffer* getOwner() const {
-            Mutex::Autolock _l(mLock);
-            return mOwner;
+        sp<LayerBuffer> getOwner() const {
+            return static_cast<LayerBuffer*>(Surface::getOwner().get());
         }
-        mutable Mutex   mLock;
-        LayerBuffer*    mOwner;
     };
-
-    friend class SurfaceFlinger;
-    sp<SurfaceBuffer>   getClientSurface() const;
-
+    
     mutable Mutex   mLock;
     sp<Source>      mSource;
-
+    sp<Surface>     mSurface;
     bool            mInvalidate;
     bool            mNeedsBlending;
-    mutable wp<SurfaceBuffer> mClientSurface;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
index 0c347cc..8e9df9c 100644
--- a/libs/surfaceflinger/LayerDim.cpp
+++ b/libs/surfaceflinger/LayerDim.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
@@ -25,7 +23,6 @@
 
 #include "LayerDim.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 #include "DisplayHardware/DisplayHardware.h"
 
 namespace android {
@@ -33,27 +30,74 @@
 
 const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
 const char* const LayerDim::typeID = "LayerDim";
-sp<MemoryDealer> LayerDim::mDimmerDealer;
-LayerBitmap LayerDim::mDimmerBitmap;
+
+bool LayerDim::sUseTexture;
+GLuint LayerDim::sTexId;
+EGLImageKHR LayerDim::sImage;
+int32_t LayerDim::sWidth;
+int32_t LayerDim::sHeight;
 
 // ---------------------------------------------------------------------------
 
 LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
-        Client* client, int32_t i)
-     : LayerBaseClient(flinger, display, client, i)
+        const sp<Client>& client, int32_t i)
+    : LayerBaseClient(flinger, display, client, i)
 {
 }
 
 void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
 {
-    // must only be called once.
-    mDimmerDealer = flinger->getSurfaceHeapManager()
-            ->createHeap(ISurfaceComposer::eHardware);
-    if (mDimmerDealer != 0) {
-        mDimmerBitmap.init(mDimmerDealer);
-        mDimmerBitmap.setBits(w, h, 1, PIXEL_FORMAT_RGB_565);
-        mDimmerBitmap.clear();
+    sTexId = -1;
+    sImage = EGL_NO_IMAGE_KHR;
+    sWidth = w;
+    sHeight = h;
+    sUseTexture = false;
+    
+#ifdef DIM_WITH_TEXTURE
+    
+#warning "using a texture to implement LayerDim"
+    
+    /* On some h/w like msm7K, it is faster to use a texture because the
+     * software renderer will defer to copybit, for this to work we need to
+     * use an EGLImage texture so copybit can actually make use of it.
+     * This burns a full-screen worth of graphic memory.
+     */
+
+    const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
+    uint32_t flags = hw.getFlags();
+
+    if (LIKELY(flags & DisplayHardware::DIRECT_TEXTURE)) {
+        // TODO: api to pass the usage flags
+        sp<Buffer> buffer = new Buffer(w, h, PIXEL_FORMAT_RGB_565);
+        android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
+
+        glGenTextures(1, &sTexId);
+        glBindTexture(GL_TEXTURE_2D, sTexId);
+
+        EGLDisplay dpy = eglGetCurrentDisplay();
+        sImage = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 
+                EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)clientBuf, 0);
+        if (sImage == EGL_NO_IMAGE_KHR) {
+            LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError());
+            return;
+        }
+
+        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)sImage);
+        GLint error = glGetError();
+        if (error != GL_NO_ERROR) {
+            eglDestroyImageKHR(dpy, sImage);
+            LOGE("glEGLImageTargetTexture2DOES() failed. err=0x%4x", error);
+            return;
+        }
+
+        // initialize the texture with zeros
+        GGLSurface t;
+        buffer->lock(&t, GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN);
+        memset(t.data, 0, t.stride * t.height * 2);
+        buffer->unlock();
+        sUseTexture = true;
     }
+#endif
 }
 
 LayerDim::~LayerDim()
@@ -63,49 +107,56 @@
 void LayerDim::onDraw(const Region& clip) const
 {
     const State& s(drawingState());
-
-    Region::iterator iterator(clip);
-    if (s.alpha>0 && iterator) {
+    Region::const_iterator it = clip.begin();
+    Region::const_iterator const end = clip.end();
+    if (s.alpha>0 && (it != end)) {
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
-
-        status_t err = NO_ERROR;
-        const int can_use_copybit = canUseCopybit();
-        if (can_use_copybit)  {
-            // StopWatch watch("copybit");
-            copybit_image_t dst;
-            hw.getDisplaySurface(&dst);
-            const copybit_rect_t& drect
-                = reinterpret_cast<const copybit_rect_t&>(mTransformedBounds);
-
-            copybit_image_t src;
-            mDimmerBitmap.getBitmapSurface(&src);
-            const copybit_rect_t& srect(drect);
-
-            copybit_device_t* copybit = mFlinger->getBlitEngine();
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, s.alpha);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-            region_iterator it(clip);
-            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+        const GGLfixed alpha = (s.alpha << 16)/255;
+        const uint32_t fbHeight = hw.getHeight();
+        glDisable(GL_DITHER);
+        glEnable(GL_BLEND);
+        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+        glColor4x(0, 0, 0, alpha);
+        
+#ifdef DIM_WITH_TEXTURE
+        if (sUseTexture) {
+            glBindTexture(GL_TEXTURE_2D, sTexId);
+            glEnable(GL_TEXTURE_2D);
+            glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+            const GLshort texCoords[4][2] = {
+                    { 0,  0 },
+                    { 0,  1 },
+                    { 1,  1 },
+                    { 1,  0 }
+            };
+            glMatrixMode(GL_TEXTURE);
+            glLoadIdentity();
+            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+            glTexCoordPointer(2, GL_SHORT, 0, texCoords);
+        } else
+#endif
+        {
+            glDisable(GL_TEXTURE_2D);
         }
 
-        if (!can_use_copybit || err) {
-            const GGLfixed alpha = (s.alpha << 16)/255;
-            const uint32_t fbHeight = hw.getHeight();
-            glDisable(GL_TEXTURE_2D);
-            glDisable(GL_DITHER);
-            glEnable(GL_BLEND);
-            glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-            glColor4x(0, 0, 0, alpha);
-            glVertexPointer(2, GL_FIXED, 0, mVertices);
-            Rect r;
-            while (iterator.iterate(&r)) {
-                const GLint sy = fbHeight - (r.top + r.height());
-                glScissor(r.left, sy, r.width(), r.height());
-                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
-            }
+        GLshort w = sWidth;
+        GLshort h = sHeight;
+        const GLshort vertices[4][2] = {
+                { 0, 0 },
+                { 0, h },
+                { w, h },
+                { w, 0 }
+        };
+        glVertexPointer(2, GL_SHORT, 0, vertices);
+
+        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/LayerDim.h b/libs/surfaceflinger/LayerDim.h
index 3e37a47..33bd49d 100644
--- a/libs/surfaceflinger/LayerDim.h
+++ b/libs/surfaceflinger/LayerDim.h
@@ -20,6 +20,9 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
 #include "LayerBase.h"
 #include "LayerBitmap.h"
 
@@ -29,6 +32,11 @@
 
 class LayerDim : public LayerBaseClient
 {
+    static bool sUseTexture;
+    static GLuint sTexId;
+    static EGLImageKHR sImage;
+    static int32_t sWidth;
+    static int32_t sHeight;
 public:    
     static const uint32_t typeInfo;
     static const char* const typeID;
@@ -36,7 +44,7 @@
     virtual uint32_t getTypeInfo() const { return typeInfo; }
     
                 LayerDim(SurfaceFlinger* flinger, DisplayID display,
-                        Client* client, int32_t i);
+                        const sp<Client>& client, int32_t i);
         virtual ~LayerDim();
 
     virtual void onDraw(const Region& clip) const;
@@ -44,10 +52,6 @@
     virtual bool isSecure() const       { return false; }
 
     static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h);
-
-private:
-    static sp<MemoryDealer> mDimmerDealer;
-    static LayerBitmap mDimmerBitmap;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerOrientationAnim.cpp b/libs/surfaceflinger/LayerOrientationAnim.cpp
deleted file mode 100644
index 79e5328..0000000
--- a/libs/surfaceflinger/LayerOrientationAnim.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/StopWatch.h>
-
-#include <core/SkBitmap.h>
-
-#include <ui/EGLDisplaySurface.h>
-
-#include "BlurFilter.h"
-#include "LayerBase.h"
-#include "LayerOrientationAnim.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-#include "OrientationAnimation.h"
-
-namespace android {
-// ---------------------------------------------------------------------------
-
-const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80;
-const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim";
-
-// ---------------------------------------------------------------------------
-
-// Animation...
-const float DURATION = ms2ns(200);
-const float BOUNCES_PER_SECOND = 0.5f;
-const float DIM_TARGET = 0.40f;
-#define INTERPOLATED_TIME(_t)   (_t)
-
-// ---------------------------------------------------------------------------
-
-LayerOrientationAnim::LayerOrientationAnim(
-        SurfaceFlinger* flinger, DisplayID display, 
-        OrientationAnimation* anim, 
-        const LayerBitmap& bitmapIn,
-        const LayerBitmap& bitmapOut)
-    : LayerOrientationAnimBase(flinger, display), mAnim(anim), 
-      mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), 
-      mTextureName(-1), mTextureNameIn(-1)
-{
-    // blur that texture. 
-    mOrientationCompleted = false;
-    mNeedsBlending = false;
-}
-
-LayerOrientationAnim::~LayerOrientationAnim()
-{
-    if (mTextureName != -1U) {
-        LayerBase::deletedTextures.add(mTextureName);
-    }
-    if (mTextureNameIn != -1U) {
-        LayerBase::deletedTextures.add(mTextureNameIn);
-    }
-}
-
-bool LayerOrientationAnim::needsBlending() const 
-{
-    return mNeedsBlending; 
-}
-
-Point LayerOrientationAnim::getPhysicalSize() const
-{
-    const GraphicPlane& plane(graphicPlane(0));
-    const DisplayHardware& hw(plane.displayHardware());
-    return Point(hw.getWidth(), hw.getHeight());
-}
-
-void LayerOrientationAnim::validateVisibility(const Transform&)
-{
-    const Layer::State& s(drawingState());
-    const Transform tr(s.transform);
-    const Point size(getPhysicalSize());
-    uint32_t w = size.x;
-    uint32_t h = size.y;
-    mTransformedBounds = tr.makeBounds(w, h);
-    mLeft = tr.tx();
-    mTop  = tr.ty();
-    transparentRegionScreen.clear();
-    mTransformed = true;
-    mCanUseCopyBit = false;
-    copybit_device_t* copybit = mFlinger->getBlitEngine();
-    if (copybit) { 
-        mCanUseCopyBit = true;
-    }
-}
-
-void LayerOrientationAnim::onOrientationCompleted()
-{
-    mAnim->onAnimationFinished();
-}
-
-void LayerOrientationAnim::onDraw(const Region& clip) const
-{
-    float alphaIn =  DIM_TARGET;
-    
-    // clear screen
-    // TODO: with update on demand, we may be able 
-    // to not erase the screen at all during the animation 
-    if (!mOrientationCompleted) {
-        glDisable(GL_BLEND);
-        glDisable(GL_DITHER);
-        glDisable(GL_SCISSOR_TEST);
-        glClearColor(0,0,0,0);
-        glClear(GL_COLOR_BUFFER_BIT);
-    }
-    
-    copybit_image_t dst;
-    const GraphicPlane& plane(graphicPlane(0));
-    const DisplayHardware& hw(plane.displayHardware());
-    hw.getDisplaySurface(&dst);
-
-    copybit_image_t src;
-    mBitmapIn.getBitmapSurface(&src);
-
-    copybit_image_t srcOut;
-    mBitmapOut.getBitmapSurface(&srcOut);
-
-    const int w = dst.w; 
-    const int h = dst.h; 
-    const int xc = uint32_t(dst.w-w)/2;
-    const int yc = uint32_t(dst.h-h)/2;
-    const copybit_rect_t drect = { xc, yc, xc+w, yc+h }; 
-    const copybit_rect_t srect = { 0, 0, src.w, src.h };
-    const Region reg(Rect( drect.l, drect.t, drect.r, drect.b ));
-
-    int err = NO_ERROR;
-    const int can_use_copybit = canUseCopybit();
-    if (can_use_copybit)  {
-        copybit_device_t* copybit = mFlinger->getBlitEngine();
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-        
-        if (alphaIn > 0) {
-            region_iterator it(reg);
-            copybit->set_parameter(copybit, COPYBIT_BLUR, COPYBIT_ENABLE);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, int(alphaIn*255));
-            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-            copybit->set_parameter(copybit, COPYBIT_BLUR, COPYBIT_DISABLE);
-        }
-        LOGE_IF(err != NO_ERROR, "copybit failed (%s)", strerror(err));
-    }
-    if (!can_use_copybit || err) {   
-        GGLSurface t;
-        t.version = sizeof(GGLSurface);
-        t.width  = src.w;
-        t.height = src.h;
-        t.stride = src.w;
-        t.vstride= src.h;
-        t.format = src.format;
-        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
-
-        Transform tr;
-        tr.set(xc, yc);
-        
-        // FIXME: we should not access mVertices and mDrawingState like that,
-        // but since we control the animation, we know it's going to work okay.
-        // eventually we'd need a more formal way of doing things like this.
-        LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
-        tr.transform(self.mVertices[0], 0, 0);
-        tr.transform(self.mVertices[1], 0, src.h);
-        tr.transform(self.mVertices[2], src.w, src.h);
-        tr.transform(self.mVertices[3], src.w, 0);
-        if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
-            // Too slow to do this in software
-            self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
-        }
-
-        if (alphaIn > 0.0f) {
-            t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
-            if (UNLIKELY(mTextureNameIn == -1LU)) {
-                mTextureNameIn = createTexture();
-                GLuint w=0, h=0;
-                const Region dirty(Rect(t.width, t.height));
-                loadTexture(dirty, mTextureNameIn, t, w, h);
-            }
-            self.mDrawingState.alpha = int(alphaIn*255);
-            drawWithOpenGL(reg, mTextureNameIn, t);
-        }
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/MessageQueue.cpp b/libs/surfaceflinger/MessageQueue.cpp
new file mode 100644
index 0000000..fb70b6a
--- /dev/null
+++ b/libs/surfaceflinger/MessageQueue.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+
+#include "MessageQueue.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+void MessageList::insert(const sp<MessageBase>& node) 
+{
+    LIST::iterator cur(mList.begin());
+    LIST::iterator end(mList.end());
+    while (cur != end) {
+        if (*node < **cur) {
+            mList.insert(cur, node);
+            return;
+        }
+        ++cur;
+    }
+    mList.insert(++end, node);
+}
+
+void MessageList::remove(MessageList::LIST::iterator pos) 
+{
+    mList.erase(pos);
+}
+
+// ---------------------------------------------------------------------------
+
+MessageQueue::MessageQueue()
+    : mInvalidate(false)
+{
+    mInvalidateMessage = new MessageBase(INVALIDATE);
+}
+
+MessageQueue::~MessageQueue()
+{
+}
+
+MessageList::value_type MessageQueue::waitMessage(nsecs_t timeout)
+{
+    MessageList::value_type result;
+
+    bool again;
+    do {
+        const nsecs_t timeoutTime = systemTime() + timeout;
+        while (true) {
+            Mutex::Autolock _l(mLock);
+            nsecs_t now = systemTime();
+            nsecs_t nextEventTime = -1;
+
+            // invalidate messages are always handled first
+            if (mInvalidate) {
+                mInvalidate = false;
+                mInvalidateMessage->when = now;
+                result = mInvalidateMessage;
+                break;
+            }
+
+            LIST::iterator cur(mMessages.begin());
+            if (cur != mMessages.end()) {
+                result = *cur;
+            }
+            
+            if (result != 0) {
+                if (result->when <= now) {
+                    // there is a message to deliver
+                    mMessages.remove(cur);
+                    break;
+                }
+                if (timeout>=0 && timeoutTime < now) {
+                    // we timed-out, return a NULL message
+                    result = 0;
+                    break;
+                }
+                nextEventTime = result->when;
+                result = 0;
+            }
+
+            if (timeout >= 0 && nextEventTime > 0) {
+                if (nextEventTime > timeoutTime) {
+                    nextEventTime = timeoutTime;
+                }
+            }
+
+            if (nextEventTime >= 0) {
+                //LOGD("nextEventTime = %lld ms", nextEventTime);
+                if (nextEventTime > 0) {
+                    // we're about to wait, flush the binder command buffer
+                    IPCThreadState::self()->flushCommands();
+                    mCondition.wait(mLock, nextEventTime);
+                }
+            } else {
+                //LOGD("going to wait");
+                // we're about to wait, flush the binder command buffer
+                IPCThreadState::self()->flushCommands();
+                mCondition.wait(mLock);
+            }
+        } 
+        // here we're not holding the lock anymore
+
+        if (result == 0)
+            break;
+
+        again = result->handler();
+        if (again) {
+            // the message has been processed. release our reference to it
+            // without holding the lock.
+            result = 0;
+        }
+        
+    } while (again);
+
+    return result;
+}
+
+status_t MessageQueue::postMessage(
+        const MessageList::value_type& message, nsecs_t relTime, uint32_t flags)
+{
+    return queueMessage(message, relTime, flags);
+}
+
+status_t MessageQueue::invalidate() {
+    Mutex::Autolock _l(mLock);
+    mInvalidate = true;
+    mCondition.signal();
+    return NO_ERROR;
+}
+
+status_t MessageQueue::queueMessage(
+        const MessageList::value_type& message, nsecs_t relTime, uint32_t flags)
+{
+    Mutex::Autolock _l(mLock);
+    message->when = systemTime() + relTime;
+    mMessages.insert(message);
+    
+    //LOGD("MessageQueue::queueMessage time = %lld ms", message->when);
+    //dumpLocked(message);
+
+    mCondition.signal();
+    return NO_ERROR;
+}
+
+void MessageQueue::dump(const MessageList::value_type& message)
+{
+    Mutex::Autolock _l(mLock);
+    dumpLocked(message);
+}
+
+void MessageQueue::dumpLocked(const MessageList::value_type& message)
+{
+    LIST::const_iterator cur(mMessages.begin());
+    LIST::const_iterator end(mMessages.end());
+    int c = 0;
+    while (cur != end) {
+        const char tick = (*cur == message) ? '>' : ' ';
+        LOGD("%c %d: msg{.what=%08x, when=%lld}",
+                tick, c, (*cur)->what, (*cur)->when);
+        ++cur;
+        c++;
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/MessageQueue.h b/libs/surfaceflinger/MessageQueue.h
new file mode 100644
index 0000000..dc8138d
--- /dev/null
+++ b/libs/surfaceflinger/MessageQueue.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MESSAGE_QUEUE_H
+#define ANDROID_MESSAGE_QUEUE_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/List.h>
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MessageBase;
+
+class MessageList 
+{
+    List< sp<MessageBase> > mList;
+    typedef List< sp<MessageBase> > LIST;
+public:
+    typedef sp<MessageBase> value_type;
+    inline LIST::iterator begin()                { return mList.begin(); }
+    inline LIST::const_iterator begin() const    { return mList.begin(); }
+    inline LIST::iterator end()                  { return mList.end(); }
+    inline LIST::const_iterator end() const      { return mList.end(); }
+    inline bool isEmpty() const { return mList.empty(); }
+    void insert(const sp<MessageBase>& node);
+    void remove(LIST::iterator pos);
+};
+
+// ============================================================================
+
+class MessageBase : 
+    public LightRefBase<MessageBase>
+{
+public:
+    nsecs_t     when;
+    uint32_t    what;
+    int32_t     arg0;    
+
+    MessageBase() : when(0), what(0), arg0(0) { }
+    MessageBase(uint32_t what, int32_t arg0=0)
+        : when(0), what(what), arg0(arg0) { }
+    
+    // return true if message has a handler
+    virtual bool handler() { return false; }
+    
+protected:
+    virtual ~MessageBase() { }
+
+private:
+    friend class LightRefBase<MessageBase>;
+};
+
+inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) {
+    return lhs.when < rhs.when;
+}
+
+// ---------------------------------------------------------------------------
+
+class MessageQueue
+{
+    typedef List< sp<MessageBase> > LIST;
+public:
+
+    // this is a work-around the multichar constant warning. A macro would
+    // work too, but would pollute the namespace.
+    template <int a, int b, int c, int d>
+    struct WHAT {
+        static const uint32_t Value = 
+            (uint32_t(a&0xff)<<24)|(uint32_t(b&0xff)<<16)|
+            (uint32_t(c&0xff)<<8)|uint32_t(d&0xff);
+    };
+    
+    MessageQueue();
+    ~MessageQueue();
+
+    // pre-defined messages
+    enum {
+        INVALIDATE = WHAT<'_','p','d','t'>::Value
+    };
+
+    MessageList::value_type waitMessage(nsecs_t timeout = -1);
+    
+    status_t postMessage(const MessageList::value_type& message, 
+            nsecs_t reltime=0, uint32_t flags = 0);
+        
+    status_t invalidate();
+    
+    void dump(const MessageList::value_type& message);
+
+private:
+    status_t queueMessage(const MessageList::value_type& message,
+            nsecs_t reltime, uint32_t flags);
+    void dumpLocked(const MessageList::value_type& message);
+    
+    Mutex           mLock;
+    Condition       mCondition;
+    MessageList     mMessages;
+    bool            mInvalidate;
+    MessageList::value_type mInvalidateMessage;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif /* ANDROID_MESSAGE_QUEUE_H */
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index fb25663..7a7574f 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdint.h>
@@ -23,6 +21,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <math.h>
+#include <limits.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
@@ -30,36 +29,30 @@
 #include <cutils/log.h>
 #include <cutils/properties.h>
 
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-#include <utils/MemoryDealer.h>
-#include <utils/MemoryBase.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryHeapBase.h>
+
 #include <utils/String8.h>
 #include <utils/String16.h>
 #include <utils/StopWatch.h>
 
 #include <ui/PixelFormat.h>
 #include <ui/DisplayInfo.h>
-#include <ui/EGLDisplaySurface.h>
 
 #include <pixelflinger/pixelflinger.h>
 #include <GLES/gl.h>
 
 #include "clz.h"
-#include "CPUGauge.h"
+#include "BufferAllocator.h"
 #include "Layer.h"
 #include "LayerBlur.h"
 #include "LayerBuffer.h"
 #include "LayerDim.h"
 #include "LayerBitmap.h"
-#include "LayerOrientationAnim.h"
-#include "OrientationAnimation.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 
 #include "DisplayHardware/DisplayHardware.h"
-#include "GPUHardware/GPUHardware.h"
-
 
 /* ideally AID_GRAPHICS would be in a semi-public header
  * or there would be a way to map a user/group name to its id
@@ -93,30 +86,30 @@
 }
 
 ssize_t SurfaceFlinger::LayerVector::indexOf(
-        LayerBase* key, size_t guess) const
+        const sp<LayerBase>& key, size_t guess) const
 {
     if (guess<size() && lookup.keyAt(guess) == key)
         return guess;
     const ssize_t i = lookup.indexOfKey(key);
     if (i>=0) {
         const size_t idx = lookup.valueAt(i);
-        LOG_ASSERT(layers[idx]==key,
+        LOGE_IF(layers[idx]!=key,
             "LayerVector[%p]: layers[%d]=%p, key=%p",
-            this, int(idx), layers[idx], key);
+            this, int(idx), layers[idx].get(), key.get());
         return idx;
     }
     return i;
 }
 
 ssize_t SurfaceFlinger::LayerVector::add(
-        LayerBase* layer,
-        Vector<LayerBase*>::compar_t cmp)
+        const sp<LayerBase>& layer,
+        Vector< sp<LayerBase> >::compar_t cmp)
 {
     size_t count = layers.size();
     ssize_t l = 0;
     ssize_t h = count-1;
     ssize_t mid;
-    LayerBase* const* a = layers.array();
+    sp<LayerBase> const* a = layers.array();
     while (l <= h) {
         mid = l + (h - l)/2;
         const int c = cmp(a+mid, &layer);
@@ -139,14 +132,14 @@
     return order;
 }
 
-ssize_t SurfaceFlinger::LayerVector::remove(LayerBase* layer)
+ssize_t SurfaceFlinger::LayerVector::remove(const sp<LayerBase>& layer)
 {
     const ssize_t keyIndex = lookup.indexOfKey(layer);
     if (keyIndex >= 0) {
         const size_t index = lookup.valueAt(keyIndex);
-        LOG_ASSERT(layers[index]==layer,
+        LOGE_IF(layers[index]!=layer,
                 "LayerVector[%p]: layers[%u]=%p, layer=%p",
-                this, int(index), layers[index], layer);
+                this, int(index), layers[index].get(), layer.get());
         layers.removeItemsAt(index);
         lookup.removeItemsAt(keyIndex);
         const size_t count = lookup.size();
@@ -161,8 +154,8 @@
 }
 
 ssize_t SurfaceFlinger::LayerVector::reorder(
-        LayerBase* layer,
-        Vector<LayerBase*>::compar_t cmp)
+        const sp<LayerBase>& layer,
+        Vector< sp<LayerBase> >::compar_t cmp)
 {
     // XXX: it's a little lame. but oh well...
     ssize_t err = remove(layer);
@@ -180,7 +173,11 @@
     :   BnSurfaceComposer(), Thread(false),
         mTransactionFlags(0),
         mTransactionCount(0),
+        mLayersRemoved(false),
         mBootTime(systemTime()),
+        mHardwareTest("android.permission.HARDWARE_TEST"),
+        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
+        mDump("android.permission.DUMP"),
         mLastScheduledBroadcast(NULL),
         mVisibleRegionsDirty(false),
         mDeferReleaseConsole(false),
@@ -188,11 +185,7 @@
         mFreezeCount(0),
         mFreezeDisplayTime(0),
         mDebugRegion(0),
-        mDebugCpu(0),
-        mDebugFps(0),
         mDebugBackground(0),
-        mSyncObject(),
-        mDeplayedTransactionPending(0),
         mConsoleSignals(0),
         mSecureFrameBuffer(0)
 {
@@ -207,28 +200,16 @@
     char value[PROPERTY_VALUE_MAX];
     property_get("debug.sf.showupdates", value, "0");
     mDebugRegion = atoi(value);
-    property_get("debug.sf.showcpu", value, "0");
-    mDebugCpu = atoi(value);
     property_get("debug.sf.showbackground", value, "0");
     mDebugBackground = atoi(value);
-    property_get("debug.sf.showfps", value, "0");
-    mDebugFps = atoi(value);
 
     LOGI_IF(mDebugRegion,           "showupdates enabled");
-    LOGI_IF(mDebugCpu,              "showcpu enabled");
     LOGI_IF(mDebugBackground,       "showbackground enabled");
-    LOGI_IF(mDebugFps,              "showfps enabled");
 }
 
 SurfaceFlinger::~SurfaceFlinger()
 {
     glDeleteTextures(1, &mWormholeTexName);
-    delete mOrientationAnimation;
-}
-
-copybit_device_t* SurfaceFlinger::getBlitEngine() const
-{
-    return graphicPlane(0).displayHardware().getBlitEngine();
 }
 
 overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
@@ -236,29 +217,9 @@
     return graphicPlane(0).displayHardware().getOverlayEngine();
 }
 
-sp<IMemory> SurfaceFlinger::getCblk() const
+sp<IMemoryHeap> SurfaceFlinger::getCblk() const
 {
-    return mServerCblkMemory;
-}
-
-status_t SurfaceFlinger::requestGPU(const sp<IGPUCallback>& callback,
-        gpu_info_t* gpu)
-{
-    if (mGPU == 0)
-        return INVALID_OPERATION;
-
-    IPCThreadState* ipc = IPCThreadState::self();
-    const int pid = ipc->getCallingPid();
-    status_t err = mGPU->request(pid, callback, gpu);
-    return err;
-}
-
-status_t SurfaceFlinger::revokeGPU()
-{
-    if (mGPU == 0)
-        return INVALID_OPERATION;
-
-    return mGPU->friendlyRevoke();
+    return mServerHeap;
 }
 
 sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
@@ -266,33 +227,34 @@
     Mutex::Autolock _l(mStateLock);
     uint32_t token = mTokens.acquire();
 
-    Client* client = new Client(token, this);
-    if ((client == 0) || (client->ctrlblk == 0)) {
+    sp<Client> client = new Client(token, this);
+    if (client->ctrlblk == 0) {
         mTokens.release(token);
         return 0;
     }
     status_t err = mClientsMap.add(token, client);
     if (err < 0) {
-        delete client;
         mTokens.release(token);
         return 0;
     }
     sp<BClient> bclient =
-        new BClient(this, token, client->controlBlockMemory());
+        new BClient(this, token, client->getControlBlockMemory());
     return bclient;
 }
 
 void SurfaceFlinger::destroyConnection(ClientID cid)
 {
     Mutex::Autolock _l(mStateLock);
-    Client* const client = mClientsMap.valueFor(cid);
-    if (client) {
+    sp<Client> client = mClientsMap.valueFor(cid);
+    if (client != 0) {
         // free all the layers this client owns
-        const Vector<LayerBaseClient*>& layers = client->getLayers();
+        Vector< wp<LayerBaseClient> > layers(client->getLayers());
         const size_t count = layers.size();
         for (size_t i=0 ; i<count ; i++) {
-            LayerBaseClient* const layer = layers[i];
-            removeLayer_l(layer);
+            sp<LayerBaseClient> layer(layers[i].promote());
+            if (layer != 0) {
+                purgatorizeLayer_l(layer);
+            }
         }
 
         // the resources associated with this client will be freed
@@ -339,41 +301,15 @@
     mReadyToRunBarrier.wait();
 }
 
-
 static inline uint16_t pack565(int r, int g, int b) {
     return (r<<11)|(g<<5)|b;
 }
 
-// this is defined in libGLES_CM.so
-extern ISurfaceComposer* GLES_localSurfaceManager;
-
 status_t SurfaceFlinger::readyToRun()
 {
     LOGI(   "SurfaceFlinger's main thread ready to run. "
             "Initializing graphics H/W...");
 
-    // create the shared control-block
-    mServerHeap = new MemoryDealer(4096, MemoryDealer::READ_ONLY);
-    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
-
-    mServerCblkMemory = mServerHeap->allocate(4096);
-    LOGE_IF(mServerCblkMemory==0, "can't create shared control block");
-
-    mServerCblk = static_cast<surface_flinger_cblk_t *>(mServerCblkMemory->pointer());
-    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
-    new(mServerCblk) surface_flinger_cblk_t;
-
-    // get a reference to the GPU if we have one
-    mGPU = GPUFactory::getGPU();
-
-    // create the surface Heap manager, which manages the heaps
-    // (be it in RAM or VRAM) where surfaces are allocated
-    // We give 8 MB per client.
-    mSurfaceHeapManager = new SurfaceHeapManager(this, 8 << 20);
-
-    
-    GLES_localSurfaceManager = static_cast<ISurfaceComposer*>(this);
-
     // we only support one display currently
     int dpy = 0;
 
@@ -384,6 +320,16 @@
         plane.setDisplayHardware(hw);
     }
 
+    // create the shared control-block
+    mServerHeap = new MemoryHeapBase(4096,
+            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
+    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
+    
+    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
+    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
+    
+    new(mServerCblk) surface_flinger_cblk_t;
+
     // initialize primary screen
     // (other display should be initialized in the same manner, but
     // asynchronously, as they could come and go. None of this is supported
@@ -450,13 +396,6 @@
      *  We're now ready to accept clients...
      */
 
-    mOrientationAnimation = new OrientationAnimation(this);
-    
-    // start CPU gauge display
-    if (mDebugCpu)
-        mCpuGauge = new CPUGauge(this, ms2ns(500));
-
-    
     // start boot animation
     property_set("ctl.start", "bootanim");
     
@@ -471,45 +410,53 @@
 
 void SurfaceFlinger::waitForEvent()
 {
-    // wait for something to do
-    if (UNLIKELY(isFrozen())) {
-        // wait 5 seconds
-        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
-        const nsecs_t now = systemTime();
-        if (mFreezeDisplayTime == 0) {
-            mFreezeDisplayTime = now;
+    while (true) {
+        nsecs_t timeout = -1;
+        if (UNLIKELY(isFrozen())) {
+            // wait 5 seconds
+            const nsecs_t freezeDisplayTimeout = ms2ns(5000);
+            const nsecs_t now = systemTime();
+            if (mFreezeDisplayTime == 0) {
+                mFreezeDisplayTime = now;
+            }
+            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
+            timeout = waitTime>0 ? waitTime : 0;
         }
-        nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
-        int err = (waitTime > 0) ? mSyncObject.wait(waitTime) : TIMED_OUT;
-        if (err != NO_ERROR) {
+
+        MessageList::value_type msg = mEventQueue.waitMessage(timeout);
+        if (msg != 0) {
+            mFreezeDisplayTime = 0;
+            switch (msg->what) {
+                case MessageQueue::INVALIDATE:
+                    // invalidate message, just return to the main loop
+                    return;
+            }
+        } else {
+            // we timed out
             if (isFrozen()) {
                 // we timed out and are still frozen
                 LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
                         mFreezeDisplay, mFreezeCount);
                 mFreezeCount = 0;
                 mFreezeDisplay = false;
+                return;
             }
         }
-    } else {
-        mFreezeDisplayTime = 0;
-        mSyncObject.wait();
     }
 }
 
 void SurfaceFlinger::signalEvent() {
-    mSyncObject.open();
+    mEventQueue.invalidate();
 }
 
 void SurfaceFlinger::signal() const {
-    mSyncObject.open();
+    // this is the IPC call
+    const_cast<SurfaceFlinger*>(this)->signalEvent();
 }
 
 void SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
 {
-    if (android_atomic_or(1, &mDeplayedTransactionPending) == 0) {
-        sp<DelayedTransaction> delayedEvent(new DelayedTransaction(this, delay));
-        delayedEvent->run("DelayedeEvent", PRIORITY_URGENT_DISPLAY);
-    }
+    mEventQueue.postMessage( new MessageBase(MessageQueue::INVALIDATE), delay);
 }
 
 // ----------------------------------------------------------------------------
@@ -548,11 +495,6 @@
         unlockClients();
         executeScheduledBroadcasts();
 
-        // sample the cpu gauge
-        if (UNLIKELY(mDebugCpu)) {
-            handleDebugCpu();
-        }
-
         postFramebuffer();
     } else {
         // pretend we did the post
@@ -565,28 +507,18 @@
 
 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());
-
-        if (UNLIKELY(mDebugFps)) {
-            debugShowFPS();
-        }
-
         hw.flip(mInvalidRegion);
-
         mInvalidRegion.clear();
-
-        if (Layer::deletedTextures.size()) {
-            glDeleteTextures(
-                    Layer::deletedTextures.size(),
-                    Layer::deletedTextures.array());
-            Layer::deletedTextures.clear();
-        }
     }
 }
 
@@ -601,15 +533,13 @@
     }
 
     if (mDeferReleaseConsole && hw.canDraw()) {
-        // We got the release signal before the aquire signal
+        // We got the release signal before the acquire signal
         mDeferReleaseConsole = false;
-        revokeGPU();
         hw.releaseScreen();
     }
 
     if (what & eConsoleReleased) {
         if (hw.canDraw()) {
-            revokeGPU();
             hw.releaseScreen();
         } else {
             mDeferReleaseConsole = true;
@@ -621,9 +551,25 @@
 
 void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
 {
-    Mutex::Autolock _l(mStateLock);
+    Vector< sp<LayerBase> > ditchedLayers;
 
-    const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+    { // scope for the lock
+        Mutex::Autolock _l(mStateLock);
+        handleTransactionLocked(transactionFlags, ditchedLayers);
+    }
+
+    // do this without lock held
+    const size_t count = ditchedLayers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        //LOGD("ditching layer %p", ditchedLayers[i].get());
+        ditchedLayers[i]->ditch();
+    }
+}
+
+void SurfaceFlinger::handleTransactionLocked(
+        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
+{
+    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
     const size_t count = currentLayers.size();
 
     /*
@@ -634,7 +580,7 @@
     const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
     if (layersNeedTransaction) {
         for (size_t i=0 ; i<count ; i++) {
-            LayerBase* const layer = currentLayers[i];
+            const sp<LayerBase>& layer = currentLayers[i];
             uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
             if (!trFlags) continue;
 
@@ -681,7 +627,6 @@
             mVisibleRegionsDirty = true;
             mDirtyRegion.set(hw.bounds());
             mFreezeDisplayTime = 0;
-            mOrientationAnimation->onOrientationChanged(type);
         }
 
         if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
@@ -689,19 +634,26 @@
             mFreezeDisplay = mCurrentState.freezeDisplay;
         }
 
-        // some layers might have been removed, so
-        // we need to update the regions they're exposing.
-        size_t c = mRemovedLayers.size();
-        if (c) {
-            mVisibleRegionsDirty = true;
-        }
-
-        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
         if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
             // layers have been added
             mVisibleRegionsDirty = true;
         }
 
+        // some layers might have been removed, so
+        // we need to update the regions they're exposing.
+        if (mLayersRemoved) {
+            mVisibleRegionsDirty = true;
+            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
+            const size_t count = previousLayers.size();
+            for (size_t i=0 ; i<count ; i++) {
+                const sp<LayerBase>& layer(previousLayers[i]);
+                if (currentLayers.indexOf( layer ) < 0) {
+                    // this layer is not visible anymore
+                    ditchedLayers.add(layer);
+                }
+            }
+        }
+
         // get rid of all resources we don't need anymore
         // (layers and clients)
         free_resources_l();
@@ -729,7 +681,7 @@
 
     size_t i = currentLayers.size();
     while (i--) {
-        LayerBase* const layer = currentLayers[i];
+        const sp<LayerBase>& layer = currentLayers[i];
         layer->validateVisibility(planeTransform);
 
         // start with the whole surface at its current location
@@ -782,7 +734,7 @@
         // accumulate to the screen dirty region
         dirtyRegion.orSelf(dirty);
 
-        // updade aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
+        // Update aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
         aboveOpaqueLayers.orSelf(opaqueRegion);
         aboveCoveredLayers.orSelf(visibleRegion);
         
@@ -790,7 +742,7 @@
         layer->setVisibleRegion(visibleRegion);
         layer->setCoveredRegion(coveredRegion);
 
-        // If a secure layer is partially visible, lockdown the screen!
+        // If a secure layer is partially visible, lock down the screen!
         if (layer->isSecure() && !visibleRegion.isEmpty()) {
             secureFrameBuffer = true;
         }
@@ -830,9 +782,9 @@
 {
     bool recomputeVisibleRegions = false;
     size_t count = currentLayers.size();
-    LayerBase* const* layers = currentLayers.array();
+    sp<LayerBase> const* layers = currentLayers.array();
     for (size_t i=0 ; i<count ; i++) {
-        LayerBase* const layer = layers[i];
+        const sp<LayerBase>& layer = layers[i];
         layer->lockPageFlip(recomputeVisibleRegions);
     }
     return recomputeVisibleRegions;
@@ -843,37 +795,58 @@
     const GraphicPlane& plane(graphicPlane(0));
     const Transform& planeTransform(plane.transform());
     size_t count = currentLayers.size();
-    LayerBase* const* layers = currentLayers.array();
+    sp<LayerBase> const* layers = currentLayers.array();
     for (size_t i=0 ; i<count ; i++) {
-        LayerBase* const layer = layers[i];
+        const sp<LayerBase>& layer = layers[i];
         layer->unlockPageFlip(planeTransform, mDirtyRegion);
     }
 }
 
+
 void SurfaceFlinger::handleRepaint()
 {
-    // set the frame buffer
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
+    // compute the invalid region
+    mInvalidRegion.orSelf(mDirtyRegion);
+    if (mInvalidRegion.isEmpty()) {
+        // nothing to do
+        return;
+    }
 
     if (UNLIKELY(mDebugRegion)) {
         debugFlashRegions();
     }
 
-    // compute the invalid region
-    mInvalidRegion.orSelf(mDirtyRegion);
+    // set the frame buffer
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
 
     uint32_t flags = hw.getFlags();
-    if (flags & DisplayHardware::BUFFER_PRESERVED) {
-        // here we assume DisplayHardware::flip()'s  implementation
-        // performs the copy-back optimization.
-    } else {
-        if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
-            // we need to fully redraw the part that will be updated
+    if ((flags & DisplayHardware::SWAP_RECTANGLE) || 
+        (flags & DisplayHardware::BUFFER_PRESERVED)) 
+    {
+        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
+        // takes a rectangle, we must make sure to update that whole
+        // rectangle in that case
+        if (flags & DisplayHardware::SWAP_RECTANGLE) {
+            // FIXME: we really should be able to pass a region to
+            // SWAP_RECTANGLE so that we don't have to redraw all this.
             mDirtyRegion.set(mInvalidRegion.bounds());
         } else {
-            // we need to redraw everything
+            // in the BUFFER_PRESERVED case, obviously, we can update only
+            // what's needed and nothing more.
+            // NOTE: this is NOT a common case, as preserving the backbuffer
+            // is costly and usually involves copying the whole update back.
+        }
+    } else {
+        if (flags & DisplayHardware::UPDATE_ON_DEMAND) {
+            // We need to redraw the rectangle that will be updated
+            // (pushed to the framebuffer).
+            // This is needed because UPDATE_ON_DEMAND only takes one
+            // rectangle instead of a region (see DisplayHardware::flip())
+            mDirtyRegion.set(mInvalidRegion.bounds());
+        } else {
+            // we need to redraw everything (the whole screen)
             mDirtyRegion.set(hw.bounds());
             mInvalidRegion = mDirtyRegion;
         }
@@ -896,9 +869,9 @@
     const SurfaceFlinger& flinger(*this);
     const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
     const size_t count = drawingLayers.size();
-    LayerBase const* const* const layers = drawingLayers.array();
+    sp<LayerBase> const* const layers = drawingLayers.array();
     for (size_t i=0 ; i<count ; ++i) {
-        LayerBase const * const layer = layers[i];
+        const sp<LayerBase>& layer = layers[i];
         const Region& visibleRegion(layer->visibleRegionScreen);
         if (!visibleRegion.isEmpty())  {
             const Region clip(dirty.intersect(visibleRegion));
@@ -913,14 +886,14 @@
 {
     const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
     const size_t count = drawingLayers.size();
-    LayerBase* const* const layers = drawingLayers.array();
+    sp<LayerBase> const* const layers = drawingLayers.array();
     for (size_t i=0 ; i<count ; ++i) {
-        LayerBase* const layer = layers[i];
+        const sp<LayerBase>& layer = layers[i];
         layer->finishPageFlip();
     }
 }
 
-void SurfaceFlinger::scheduleBroadcast(Client* client)
+void SurfaceFlinger::scheduleBroadcast(const sp<Client>& client)
 {
     if (mLastScheduledBroadcast != client) {
         mLastScheduledBroadcast = client;
@@ -930,50 +903,56 @@
 
 void SurfaceFlinger::executeScheduledBroadcasts()
 {
-    SortedVector<Client*>& list = mScheduledBroadcasts;
+    SortedVector< wp<Client> >& list(mScheduledBroadcasts);
     size_t count = list.size();
     while (count--) {
-        per_client_cblk_t* const cblk = list[count]->ctrlblk;
-        if (cblk->lock.tryLock() == NO_ERROR) {
-            cblk->cv.broadcast();
-            list.removeAt(count);
-            cblk->lock.unlock();
-        } else {
-            // schedule another round
-            LOGW("executeScheduledBroadcasts() skipped, "
-                "contention on the client. We'll try again later...");
-            signalDelayedEvent(ms2ns(4));
+        sp<Client> client = list[count].promote();
+        if (client != 0) {
+            per_client_cblk_t* const cblk = client->ctrlblk;
+            if (cblk->lock.tryLock() == NO_ERROR) {
+                cblk->cv.broadcast();
+                list.removeAt(count);
+                cblk->lock.unlock();
+            } else {
+                // schedule another round
+                LOGW("executeScheduledBroadcasts() skipped, "
+                        "contention on the client. We'll try again later...");
+                signalDelayedEvent(ms2ns(4));
+            }
         }
     }
     mLastScheduledBroadcast = 0;
 }
 
-void SurfaceFlinger::handleDebugCpu()
-{
-    Mutex::Autolock _l(mDebugLock);
-    if (mCpuGauge != 0)
-        mCpuGauge->sample();
-}
-
 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::SWAP_RECTANGLE) ||
+             (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);
-    while (iterator.iterate(&r)) {
+    Region::const_iterator it = mDirtyRegion.begin();
+    Region::const_iterator const end = mDirtyRegion.end();
+    while (it != end) {
+        const Rect& r = *it++;
         GLfloat vertices[][2] = {
                 { r.left,  r.top },
                 { r.left,  r.bottom },
@@ -983,10 +962,12 @@
         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();
+    
+    if (mInvalidRegion.isEmpty()) {
+        mDirtyRegion.dump("mDirtyRegion");
+        mInvalidRegion.dump("mInvalidRegion");
+    }
+    hw.flip(mInvalidRegion);
 
     if (mDebugRegion > 1)
        usleep(mDebugRegion * 1000);
@@ -1010,9 +991,10 @@
 
     if (LIKELY(!mDebugBackground)) {
         glClearColorx(0,0,0,0);
-        Rect r;
-        Region::iterator iterator(region);
-        while (iterator.iterate(&r)) {
+        Region::const_iterator it = region.begin();
+        Region::const_iterator const end = region.end();
+        while (it != end) {
+            const Rect& r = *it++;
             const GLint sy = height - (r.top + r.height());
             glScissor(r.left, sy, r.width(), r.height());
             glClear(GL_COLOR_BUFFER_BIT);
@@ -1030,9 +1012,10 @@
         glMatrixMode(GL_TEXTURE);
         glLoadIdentity();
         glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
-        Rect r;
-        Region::iterator iterator(region);
-        while (iterator.iterate(&r)) {
+        Region::const_iterator it = region.begin();
+        Region::const_iterator const end = region.end();
+        while (it != end) {
+            const Rect& r = *it++;
             const GLint sy = height - (r.top + r.height());
             glScissor(r.left, sy, r.width(), r.height());
             glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -1058,7 +1041,7 @@
     // XXX: mFPS has the value we want
  }
 
-status_t SurfaceFlinger::addLayer(LayerBase* layer)
+status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
 {
     Mutex::Autolock _l(mStateLock);
     addLayer_l(layer);
@@ -1066,62 +1049,72 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer(LayerBase* layer)
+status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
 {
     Mutex::Autolock _l(mStateLock);
-    removeLayer_l(layer);
-    setTransactionFlags(eTransactionNeeded);
-    return NO_ERROR;
+    status_t err = purgatorizeLayer_l(layer);
+    if (err == NO_ERROR)
+        setTransactionFlags(eTransactionNeeded);
+    return err;
 }
 
-status_t SurfaceFlinger::invalidateLayerVisibility(LayerBase* layer)
+status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
 {
     layer->forceVisibilityTransaction();
     setTransactionFlags(eTraversalNeeded);
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::addLayer_l(LayerBase* layer)
+status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
 {
     ssize_t i = mCurrentState.layersSortedByZ.add(
                 layer, &LayerBase::compareCurrentStateZ);
-    LayerBaseClient* lbc = LayerBase::dynamicCast<LayerBaseClient*>(layer);
-    if (lbc) {
+    sp<LayerBaseClient> lbc = LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
+    if (lbc != 0) {
         mLayerMap.add(lbc->serverIndex(), lbc);
     }
-    mRemovedLayers.remove(layer);
     return NO_ERROR;
 }
 
-status_t SurfaceFlinger::removeLayer_l(LayerBase* layerBase)
+status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
 {
     ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
     if (index >= 0) {
-        mRemovedLayers.add(layerBase);
-        LayerBaseClient* layer = LayerBase::dynamicCast<LayerBaseClient*>(layerBase);
-        if (layer) {
+        mLayersRemoved = true;
+        sp<LayerBaseClient> layer =
+            LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get());
+        if (layer != 0) {
             mLayerMap.removeItem(layer->serverIndex());
         }
         return NO_ERROR;
     }
+    return status_t(index);
+}
+
+status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
+{
+    // remove the layer from the main list (through a transaction).
+    ssize_t err = removeLayer_l(layerBase);
+
     // it's possible that we don't find a layer, because it might
     // have been destroyed already -- this is not technically an error
-    // from the user because there is a race between destroySurface,
-    // destroyclient and destroySurface-from-a-transaction.
-    return (index == NAME_NOT_FOUND) ? status_t(NO_ERROR) : index;
+    // from the user because there is a race between BClient::destroySurface(),
+    // ~BClient() and ~ISurface().
+    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
 }
 
+
 void SurfaceFlinger::free_resources_l()
 {
     // Destroy layers that were removed
-    destroy_all_removed_layers_l();
-
+    mLayersRemoved = false;
+    
     // free resources associated with disconnected clients
-    SortedVector<Client*>& scheduledBroadcasts(mScheduledBroadcasts);
-    Vector<Client*>& disconnectedClients(mDisconnectedClients);
+    SortedVector< wp<Client> >& scheduledBroadcasts(mScheduledBroadcasts);
+    Vector< sp<Client> >& disconnectedClients(mDisconnectedClients);
     const size_t count = disconnectedClients.size();
     for (size_t i=0 ; i<count ; i++) {
-        Client* client = disconnectedClients[i];
+        sp<Client> client = disconnectedClients[i];
         // if this client is the scheduled broadcast list,
         // remove it from there (and we don't need to signal it
         // since it is dead).
@@ -1130,27 +1123,10 @@
             scheduledBroadcasts.removeItemsAt(index);
         }
         mTokens.release(client->cid);
-        delete client;
     }
     disconnectedClients.clear();
 }
 
-void SurfaceFlinger::destroy_all_removed_layers_l()
-{
-    size_t c = mRemovedLayers.size();
-    while (c--) {
-        LayerBase* const removed_layer = mRemovedLayers[c];
-
-        LOGE_IF(mCurrentState.layersSortedByZ.indexOf(removed_layer) >= 0,
-            "layer %p removed but still in the current state list",
-            removed_layer);
-
-        delete removed_layer;
-    }
-    mRemovedLayers.clear();
-}
-
-
 uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
 {
     return android_atomic_and(~flags, &mTransactionFlags) & flags;
@@ -1191,7 +1167,7 @@
     setTransactionFlags(eTransactionNeeded);
 
     // flags is intended to communicate some sort of animation behavior
-    // (for instance fadding)
+    // (for instance fading)
     return NO_ERROR;
 }
 
@@ -1205,7 +1181,7 @@
     setTransactionFlags(eTransactionNeeded);
 
     // flags is intended to communicate some sort of animation behavior
-    // (for instance fadding)
+    // (for instance fading)
     return NO_ERROR;
 }
 
@@ -1234,7 +1210,7 @@
         DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
         uint32_t flags)
 {
-    LayerBaseClient* layer = 0;
+    sp<LayerBaseClient> layer;
     sp<LayerBaseClient::Surface> surfaceHandle;
 
     if (int32_t(w|h) < 0) {
@@ -1244,14 +1220,14 @@
     }
     
     Mutex::Autolock _l(mStateLock);
-    Client* const c = mClientsMap.valueFor(clientId);
-    if (UNLIKELY(!c)) {
+    sp<Client> client = mClientsMap.valueFor(clientId);
+    if (UNLIKELY(client == 0)) {
         LOGE("createSurface() failed, client not found (id=%d)", clientId);
         return surfaceHandle;
     }
 
     //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
-    int32_t id = c->generateId(pid);
+    int32_t id = client->generateId(pid);
     if (uint32_t(id) >= NUM_LAYERS_MAX) {
         LOGE("createSurface() failed, generateId = %d", id);
         return surfaceHandle;
@@ -1260,20 +1236,20 @@
     switch (flags & eFXSurfaceMask) {
         case eFXSurfaceNormal:
             if (UNLIKELY(flags & ePushBuffers)) {
-                layer = createPushBuffersSurfaceLocked(c, d, id, w, h, flags);
+                layer = createPushBuffersSurfaceLocked(client, d, id, w, h, flags);
             } else {
-                layer = createNormalSurfaceLocked(c, d, id, w, h, format, flags);
+                layer = createNormalSurfaceLocked(client, d, id, w, h, format, flags);
             }
             break;
         case eFXSurfaceBlur:
-            layer = createBlurSurfaceLocked(c, d, id, w, h, flags);
+            layer = createBlurSurfaceLocked(client, d, id, w, h, flags);
             break;
         case eFXSurfaceDim:
-            layer = createDimSurfaceLocked(c, d, id, w, h, flags);
+            layer = createDimSurfaceLocked(client, d, id, w, h, flags);
             break;
     }
 
-    if (layer) {
+    if (layer != 0) {
         setTransactionFlags(eTransactionNeeded);
         surfaceHandle = layer->getSurface();
         if (surfaceHandle != 0)
@@ -1283,8 +1259,8 @@
     return surfaceHandle;
 }
 
-LayerBaseClient* SurfaceFlinger::createNormalSurfaceLocked(
-        Client* client, DisplayID display,
+sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked(
+        const sp<Client>& client, DisplayID display,
         int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
 {
     // initialize the surfaces
@@ -1298,57 +1274,99 @@
         break;
     }
 
-    Layer* layer = new Layer(this, display, client, id);
-    status_t err = layer->setBuffers(client, w, h, format, flags);
+    sp<Layer> layer = new Layer(this, display, client, id);
+    status_t err = layer->setBuffers(w, h, format, flags);
     if (LIKELY(err == NO_ERROR)) {
         layer->initStates(w, h, flags);
         addLayer_l(layer);
     } else {
         LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
-        delete layer;
-        return 0;
+        layer.clear();
     }
     return layer;
 }
 
-LayerBaseClient* SurfaceFlinger::createBlurSurfaceLocked(
-        Client* client, DisplayID display,
+sp<LayerBaseClient> SurfaceFlinger::createBlurSurfaceLocked(
+        const sp<Client>& client, DisplayID display,
         int32_t id, uint32_t w, uint32_t h, uint32_t flags)
 {
-    LayerBlur* layer = new LayerBlur(this, display, client, id);
+    sp<LayerBlur> layer = new LayerBlur(this, display, client, id);
     layer->initStates(w, h, flags);
     addLayer_l(layer);
     return layer;
 }
 
-LayerBaseClient* SurfaceFlinger::createDimSurfaceLocked(
-        Client* client, DisplayID display,
+sp<LayerBaseClient> SurfaceFlinger::createDimSurfaceLocked(
+        const sp<Client>& client, DisplayID display,
         int32_t id, uint32_t w, uint32_t h, uint32_t flags)
 {
-    LayerDim* layer = new LayerDim(this, display, client, id);
+    sp<LayerDim> layer = new LayerDim(this, display, client, id);
     layer->initStates(w, h, flags);
     addLayer_l(layer);
     return layer;
 }
 
-LayerBaseClient* SurfaceFlinger::createPushBuffersSurfaceLocked(
-        Client* client, DisplayID display,
+sp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurfaceLocked(
+        const sp<Client>& client, DisplayID display,
         int32_t id, uint32_t w, uint32_t h, uint32_t flags)
 {
-    LayerBuffer* layer = new LayerBuffer(this, display, client, id);
+    sp<LayerBuffer> layer = new LayerBuffer(this, display, client, id);
     layer->initStates(w, h, flags);
     addLayer_l(layer);
     return layer;
 }
 
-status_t SurfaceFlinger::destroySurface(SurfaceID index)
+status_t SurfaceFlinger::removeSurface(SurfaceID index)
 {
+    /*
+     * called by the window manager, when a surface should be marked for
+     * destruction.
+     * 
+     * The surface is removed from the current and drawing lists, but placed
+     * in the purgatory queue, so it's not destroyed right-away (we need
+     * to wait for all client's references to go away first).
+     */
+
     Mutex::Autolock _l(mStateLock);
-    LayerBaseClient* const layer = getLayerUser_l(index);
-    status_t err = removeLayer_l(layer);
-    if (err < 0)
-        return err;
-    setTransactionFlags(eTransactionNeeded);
+    sp<LayerBaseClient> layer = getLayerUser_l(index);
+    status_t err = purgatorizeLayer_l(layer);
+    if (err == NO_ERROR) {
+        setTransactionFlags(eTransactionNeeded);
+    }
+    return err;
+}
+
+status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
+{
+    // called by ~ISurface() when all references are gone
+    
+    class MessageDestroySurface : public MessageBase {
+        SurfaceFlinger* flinger;
+        sp<LayerBaseClient> layer;
+    public:
+        MessageDestroySurface(
+                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
+            : flinger(flinger), layer(layer) { }
+        virtual bool handler() {
+            sp<LayerBaseClient> l(layer);
+            layer.clear(); // clear it outside of the lock;
+            Mutex::Autolock _l(flinger->mStateLock);
+            /*
+             * remove the layer from the current list -- chances are that it's 
+             * not in the list anyway, because it should have been removed 
+             * already upon request of the client (eg: window manager). 
+             * However, a buggy client could have not done that.
+             * Since we know we don't have any more clients, we don't need
+             * to use the purgatory.
+             */
+            status_t err = flinger->removeLayer_l(l);
+            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
+                    "error removing layer=%p (%s)", l.get(), strerror(-err));
+            return true;
+        }
+    };
+
+    mEventQueue.postMessage( new MessageDestroySurface(this, layer) );
     return NO_ERROR;
 }
 
@@ -1362,18 +1380,9 @@
     cid <<= 16;
     for (int i=0 ; i<count ; i++) {
         const layer_state_t& s = states[i];
-        LayerBaseClient* layer = getLayerUser_l(s.surface | cid);
-        if (layer) {
+        sp<LayerBaseClient> layer(getLayerUser_l(s.surface | cid));
+        if (layer != 0) {
             const uint32_t what = s.what;
-            // check if it has been destroyed first
-            if (what & eDestroyed) {
-                if (removeLayer_l(layer) == NO_ERROR) {
-                    flags |= eTransactionNeeded;
-                    // we skip everything else... well, no, not really
-                    // we skip ONLY that transaction.
-                    continue;
-                }
-            }
             if (what & ePositionChanged) {
                 if (layer->setPosition(s.x, s.y))
                     flags |= eTraversalNeeded;
@@ -1415,9 +1424,10 @@
     return NO_ERROR;
 }
 
-LayerBaseClient* SurfaceFlinger::getLayerUser_l(SurfaceID s) const
+sp<LayerBaseClient> SurfaceFlinger::getLayerUser_l(SurfaceID s) const
 {
-    return mLayerMap.valueFor(s);
+    sp<LayerBaseClient> layer = mLayerMap.valueFor(s);
+    return layer;
 }
 
 void SurfaceFlinger::screenReleased(int dpy)
@@ -1439,9 +1449,7 @@
     const size_t SIZE = 1024;
     char buffer[SIZE];
     String8 result;
-    if (checkCallingPermission(
-            String16("android.permission.DUMP")) == false)
-    { // not allowed
+    if (!mDump.checkCalling()) {
         snprintf(buffer, SIZE, "Permission Denial: "
                 "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
                 IPCThreadState::self()->getCallingPid(),
@@ -1452,7 +1460,7 @@
         size_t s = mClientsMap.size();
         char name[64];
         for (size_t i=0 ; i<s ; i++) {
-            Client* client = mClientsMap.valueAt(i);
+            sp<Client> client = mClientsMap.valueAt(i);
             sprintf(name, "  Client (id=0x%08x)", client->cid);
             client->dump(name);
         }
@@ -1460,7 +1468,7 @@
         const size_t count = currentLayers.size();
         for (size_t i=0 ; i<count ; i++) {
             /*** LayerBase ***/
-            LayerBase const * const layer = currentLayers[i];
+            const sp<LayerBase>& layer = currentLayers[i];
             const Layer::State& s = layer->drawingState();
             snprintf(buffer, SIZE,
                     "+ %s %p\n"
@@ -1468,7 +1476,7 @@
                     "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
                     "needsBlending=%1d, invalidate=%1d, "
                     "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
-                    layer->getTypeID(), layer,
+                    layer->getTypeID(), layer.get(),
                     s.z, layer->tx(), layer->ty(), s.w, s.h,
                     layer->needsBlending(), layer->contentDirty,
                     s.alpha, s.flags,
@@ -1477,30 +1485,33 @@
             result.append(buffer);
             buffer[0] = 0;
             /*** LayerBaseClient ***/
-            LayerBaseClient* const lbc =
-                LayerBase::dynamicCast<LayerBaseClient*>((LayerBase*)layer);
-            if (lbc) {
+            sp<LayerBaseClient> lbc =
+                LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
+            if (lbc != 0) {
+                sp<Client> client(lbc->client.promote());
                 snprintf(buffer, SIZE,
                         "      "
                         "id=0x%08x, client=0x%08x, identity=%u\n",
-                        lbc->clientIndex(), lbc->client ? lbc->client->cid : 0,
+                        lbc->clientIndex(), client.get() ? client->cid : 0,
                         lbc->getIdentity());
             }
             result.append(buffer);
             buffer[0] = 0;
             /*** Layer ***/
-            Layer* const l = LayerBase::dynamicCast<Layer*>((LayerBase*)layer);
-            if (l) {
+            sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get());
+            if (l != 0) {
                 const LayerBitmap& buf0(l->getBuffer(0));
                 const LayerBitmap& buf1(l->getBuffer(1));
                 snprintf(buffer, SIZE,
                         "      "
-                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u], mTextureName=%d,"
+                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
                         " freezeLock=%p, swapState=0x%08x\n",
                         l->pixelFormat(),
-                        buf0.width(), buf0.height(), buf0.stride(),
-                        buf1.width(), buf1.height(), buf1.stride(),
-                        l->getTextureName(), l->getFreezeLock().get(),
+                        buf0.getWidth(), buf0.getHeight(), 
+                        buf0.getBuffer()->getStride(),
+                        buf1.getWidth(), buf1.getHeight(), 
+                        buf1.getBuffer()->getStride(),
+                        l->getFreezeLock().get(),
                         l->lcblk->swapState);
             }
             result.append(buffer);
@@ -1516,20 +1527,10 @@
                 mFreezeDisplay?"yes":"no", mFreezeCount,
                 mCurrentState.orientation, hw.canDraw());
         result.append(buffer);
-
-        sp<AllocatorInterface> allocator;
-        if (mGPU != 0) {
-            snprintf(buffer, SIZE, "  GPU owner: %d\n", mGPU->getOwner());
-            result.append(buffer);
-            allocator = mGPU->getAllocator();
-            if (allocator != 0) {
-                allocator->dump(result, "GPU Allocator");
-            }
-        }
-        allocator = mSurfaceHeapManager->getAllocator(NATIVE_MEMORY_TYPE_PMEM);
-        if (allocator != 0) {
-            allocator->dump(result, "PMEM Allocator");
-        }
+        snprintf(buffer, SIZE, "  client count: %d\n", mClientsMap.size());
+        result.append(buffer);
+        const BufferAllocator& alloc(BufferAllocator::get());
+        alloc.dump(result);
     }
     write(fd, result.string(), result.size());
     return NO_ERROR;
@@ -1546,57 +1547,34 @@
         case FREEZE_DISPLAY:
         case UNFREEZE_DISPLAY:
         case BOOT_FINISHED:
-        case REVOKE_GPU:
         {
             // codes that require permission check
             IPCThreadState* ipc = IPCThreadState::self();
             const int pid = ipc->getCallingPid();
             const int uid = ipc->getCallingUid();
-            const int self_pid = getpid();
-            if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
-                // we're called from a different process, do the real check
-                if (!checkCallingPermission(
-                        String16("android.permission.ACCESS_SURFACE_FLINGER")))
-                {
-                    LOGE("Permission Denial: "
-                            "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
-                    return PERMISSION_DENIED;
-                }
+            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
+                LOGE("Permission Denial: "
+                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+                return PERMISSION_DENIED;
             }
         }
     }
-
     status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
     if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
-        // HARDWARE_TEST stuff...
-        if (UNLIKELY(checkCallingPermission(
-                String16("android.permission.HARDWARE_TEST")) == false))
-        { // not allowed
-            LOGE("Permission Denial: pid=%d, uid=%d\n",
-                    IPCThreadState::self()->getCallingPid(),
-                    IPCThreadState::self()->getCallingUid());
+        CHECK_INTERFACE(ISurfaceComposer, data, reply);
+        if (UNLIKELY(!mHardwareTest.checkCalling())) {
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int uid = ipc->getCallingUid();
+            LOGE("Permission Denial: "
+                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
             return PERMISSION_DENIED;
         }
         int n;
         switch (code) {
-            case 1000: // SHOW_CPU
-                n = data.readInt32();
-                mDebugCpu = n ? 1 : 0;
-                if (mDebugCpu) {
-                    if (mCpuGauge == 0) {
-                        mCpuGauge = new CPUGauge(this, ms2ns(500));
-                    }
-                } else {
-                    if (mCpuGauge != 0) {
-                        mCpuGauge->requestExitAndWait();
-                        Mutex::Autolock _l(mDebugLock);
-                        mCpuGauge.clear();
-                    }
-                }
+            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
                 return NO_ERROR;
-            case 1001:  // SHOW_FPS
-                n = data.readInt32();
-                mDebugFps = n ? 1 : 0;
+            case 1001:  // SHOW_FPS, NOT SUPPORTED ANYMORE
                 return NO_ERROR;
             case 1002:  // SHOW_UPDATES
                 n = data.readInt32();
@@ -1613,21 +1591,11 @@
                 signalEvent();
             }
             return NO_ERROR;
-            case 1005: // ask GPU revoke
-                if (mGPU != 0) {
-                    mGPU->friendlyRevoke();
-                }
-                return NO_ERROR;
-            case 1006: // revoke GPU
-                if (mGPU != 0) {
-                    mGPU->unconditionalRevoke();
-                }
-                return NO_ERROR;
             case 1007: // set mFreezeCount
                 mFreezeCount = data.readInt32();
                 return NO_ERROR;
             case 1010:  // interrogate.
-                reply->writeInt32(mDebugCpu);
+                reply->writeInt32(0);
                 reply->writeInt32(0);
                 reply->writeInt32(mDebugRegion);
                 reply->writeInt32(mDebugBackground);
@@ -1651,16 +1619,15 @@
 Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
     : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
 {
-    mSharedHeapAllocator = getSurfaceHeapManager()->createHeap();
     const int pgsize = getpagesize();
-    const int cblksize=((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
-    mCblkHeap = new MemoryDealer(cblksize);
-    mCblkMemory = mCblkHeap->allocate(cblksize);
-    if (mCblkMemory != 0) {
-        ctrlblk = static_cast<per_client_cblk_t *>(mCblkMemory->pointer());
-        if (ctrlblk) { // construct the shared structure in-place.
-            new(ctrlblk) per_client_cblk_t;
-        }
+    const int cblksize = ((sizeof(per_client_cblk_t)+(pgsize-1))&~(pgsize-1));
+
+    mCblkHeap = new MemoryHeapBase(cblksize, 0,
+            "SurfaceFlinger Client control-block");
+
+    ctrlblk = static_cast<per_client_cblk_t *>(mCblkHeap->getBase());
+    if (ctrlblk) { // construct the shared structure in-place.
+        new(ctrlblk) per_client_cblk_t;
     }
 }
 
@@ -1671,10 +1638,6 @@
     }
 }
 
-const sp<SurfaceHeapManager>& Client::getSurfaceHeapManager() const {
-    return mFlinger->getSurfaceHeapManager();
-}
-
 int32_t Client::generateId(int pid)
 {
     const uint32_t i = clz( ~mBitmap );
@@ -1686,13 +1649,15 @@
     mBitmap |= 1<<(31-i);
     return i;
 }
-status_t Client::bindLayer(LayerBaseClient* layer, int32_t id)
+
+status_t Client::bindLayer(const sp<LayerBaseClient>& layer, int32_t id)
 {
     ssize_t idx = mInUse.indexOf(id);
     if (idx < 0)
         return NAME_NOT_FOUND;
     return mLayers.insertAt(layer, idx);
 }
+
 void Client::free(int32_t id)
 {
     ssize_t idx = mInUse.remove(uint8_t(id));
@@ -1702,27 +1667,18 @@
     }
 }
 
-sp<MemoryDealer> Client::createAllocator(uint32_t flags)
-{
-    sp<MemoryDealer> allocator;
-    allocator = getSurfaceHeapManager()->createHeap(
-            flags, getClientPid(), mSharedHeapAllocator);
-    return allocator;
-}
-
 bool Client::isValid(int32_t i) const {
     return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
 }
-const uint8_t* Client::inUseArray() const {
-    return mInUse.array();
-}
-size_t Client::numActiveLayers() const {
-    return mInUse.size();
-}
-LayerBaseClient* Client::getLayerUser(int32_t i) const {
+
+sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
+    sp<LayerBaseClient> lbc;
     ssize_t idx = mInUse.indexOf(uint8_t(i));
-    if (idx<0) return 0;
-    return mLayers[idx];
+    if (idx >= 0) {
+        lbc = mLayers[idx].promote();
+        LOGE_IF(lbc==0, "getLayerUser(i=%d), idx=%d is dead", int(i), int(idx));
+    }
+    return lbc;
 }
 
 void Client::dump(const char* what)
@@ -1734,7 +1690,7 @@
 #pragma mark -
 #endif
 
-BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemory>& cblk)
+BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemoryHeap>& cblk)
     : mId(cid), mFlinger(flinger), mCblk(cblk)
 {
 }
@@ -1744,8 +1700,8 @@
     mFlinger->destroyConnection(mId);
 }
 
-void BClient::getControlBlocks(sp<IMemory>* ctrl) const {
-    *ctrl = mCblk;
+sp<IMemoryHeap> BClient::getControlBlock() const {
+    return mCblk;
 }
 
 sp<ISurface> BClient::createSurface(
@@ -1759,7 +1715,7 @@
 status_t BClient::destroySurface(SurfaceID sid)
 {
     sid |= (mId << 16); // add the client-part to id
-    return mFlinger->destroySurface(sid);
+    return mFlinger->removeSurface(sid);
 }
 
 status_t BClient::setState(int32_t count, const layer_state_t* states)
@@ -1859,6 +1815,10 @@
     return mGlobalTransform;
 }
 
+EGLDisplay GraphicPlane::getEGLDisplay() const {
+    return mHw->getEGLDisplay();
+}
+
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 15913f2..e8687a7 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -25,7 +25,10 @@
 #include <utils/threads.h>
 #include <utils/Atomic.h>
 #include <utils/Errors.h>
-#include <utils/MemoryDealer.h>
+#include <utils/RefBase.h>
+
+#include <binder/IMemory.h>
+#include <binder/Permission.h>
 
 #include <ui/PixelFormat.h>
 #include <ui/ISurfaceComposer.h>
@@ -33,13 +36,13 @@
 
 #include <private/ui/SharedState.h>
 #include <private/ui/LayerState.h>
-#include <private/ui/SurfaceFlingerSynchro.h>
 
 #include "Barrier.h"
-#include "CPUGauge.h"
 #include "Layer.h"
 #include "Tokenizer.h"
 
+#include "MessageQueue.h"
+
 struct copybit_device_t;
 struct overlay_device_t;
 
@@ -51,13 +54,8 @@
 class BClient;
 class DisplayHardware;
 class FreezeLock;
-class GPUHardwareInterface;
-class IGPUCallback;
 class Layer;
 class LayerBuffer;
-class LayerOrientationAnim;
-class OrientationAnimation;
-class SurfaceHeapManager;
 
 typedef int32_t ClientID;
 
@@ -66,7 +64,7 @@
 
 // ---------------------------------------------------------------------------
 
-class Client
+class Client : public RefBase
 {
 public:
             Client(ClientID cid, const sp<SurfaceFlinger>& flinger);
@@ -74,17 +72,19 @@
 
             int32_t                 generateId(int pid);
             void                    free(int32_t id);
-            status_t                bindLayer(LayerBaseClient* layer, int32_t id);
-            sp<MemoryDealer>        createAllocator(uint32_t memory_type);
+            status_t                bindLayer(const sp<LayerBaseClient>& layer, int32_t id);
 
     inline  bool                    isValid(int32_t i) const;
-    inline  const uint8_t*          inUseArray() const;
-    inline  size_t                  numActiveLayers() const;
-    LayerBaseClient*                getLayerUser(int32_t i) const;
-    const Vector<LayerBaseClient*>& getLayers() const { return mLayers; }
-    const sp<IMemory>&              controlBlockMemory() const { return mCblkMemory; }
+    sp<LayerBaseClient>             getLayerUser(int32_t i) const;
     void                            dump(const char* what);
-    const sp<SurfaceHeapManager>&   getSurfaceHeapManager() const;
+    
+    const Vector< wp<LayerBaseClient> >& getLayers() const { 
+        return mLayers; 
+    }
+    
+    const sp<IMemoryHeap>& getControlBlockMemory() const {
+        return mCblkHeap; 
+    }
     
     // pointer to this client's control block
     per_client_cblk_t*      ctrlblk;
@@ -92,17 +92,14 @@
 
     
 private:
-    int                     getClientPid() const { return mPid; }
+    int getClientPid() const { return mPid; }
         
-    int                         mPid;
-    uint32_t                    mBitmap;
-    SortedVector<uint8_t>       mInUse;
-    Vector<LayerBaseClient*>    mLayers;
-    sp<MemoryDealer>            mCblkHeap;
-    sp<SurfaceFlinger>          mFlinger;
-    sp<MemoryDealer>            mSharedHeapAllocator;
-    sp<MemoryDealer>            mPMemAllocator;
-    sp<IMemory>                 mCblkMemory;
+    int                             mPid;
+    uint32_t                        mBitmap;
+    SortedVector<uint8_t>           mInUse;
+    Vector< wp<LayerBaseClient> >   mLayers;
+    sp<IMemoryHeap>                 mCblkHeap;
+    sp<SurfaceFlinger>              mFlinger;
 };
 
 // ---------------------------------------------------------------------------
@@ -125,6 +122,8 @@
 
         const DisplayHardware&  displayHardware() const;
         const Transform&        transform() const;
+        EGLDisplay              getEGLDisplay() const;
+        
 private:
                                 GraphicPlane(const GraphicPlane&);
         GraphicPlane            operator = (const GraphicPlane&);
@@ -160,7 +159,7 @@
 
     // ISurfaceComposer interface
     virtual sp<ISurfaceFlingerClient>   createConnection();
-    virtual sp<IMemory>                 getCblk() const;
+    virtual sp<IMemoryHeap>             getCblk() const;
     virtual void                        bootFinished();
     virtual void                        openGlobalTransaction();
     virtual void                        closeGlobalTransaction();
@@ -168,56 +167,52 @@
     virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
     virtual int                         setOrientation(DisplayID dpy, int orientation, uint32_t flags);
     virtual void                        signal() const;
-    virtual status_t requestGPU(const sp<IGPUCallback>& callback, 
-            gpu_info_t* gpu);
-    virtual status_t revokeGPU();
 
             void                        screenReleased(DisplayID dpy);
             void                        screenAcquired(DisplayID dpy);
 
-            const sp<SurfaceHeapManager>& getSurfaceHeapManager() const { 
-                return mSurfaceHeapManager; 
-            }
-
-            const sp<GPUHardwareInterface>& getGPU() const {
-                return mGPU; 
-            }
-
-            copybit_device_t* getBlitEngine() const;
             overlay_control_device_t* getOverlayEngine() const;
 
             
-    status_t removeLayer(LayerBase* layer);
-    status_t addLayer(LayerBase* layer);
-    status_t invalidateLayerVisibility(LayerBase* layer);
+    status_t removeLayer(const sp<LayerBase>& layer);
+    status_t addLayer(const sp<LayerBase>& layer);
+    status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
     
 private:
     friend class BClient;
     friend class LayerBase;
     friend class LayerBuffer;
     friend class LayerBaseClient;
+    friend class LayerBaseClient::Surface;
     friend class Layer;
     friend class LayerBlur;
+    friend class LayerDim;
 
     sp<ISurface> createSurface(ClientID client, int pid, 
             ISurfaceFlingerClient::surface_data_t* params,
             DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
             uint32_t flags);
 
-    LayerBaseClient* createNormalSurfaceLocked(Client* client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
+    sp<LayerBaseClient> createNormalSurfaceLocked(
+            const sp<Client>& client, DisplayID display,
+            int32_t id, uint32_t w, uint32_t h, 
+            PixelFormat format, uint32_t flags);
 
-    LayerBaseClient* createBlurSurfaceLocked(Client* client, DisplayID display,
+    sp<LayerBaseClient> createBlurSurfaceLocked(
+            const sp<Client>& client, DisplayID display,
             int32_t id, uint32_t w, uint32_t h, uint32_t flags);
 
-    LayerBaseClient* createDimSurfaceLocked(Client* client, DisplayID display,
+    sp<LayerBaseClient> createDimSurfaceLocked(
+            const sp<Client>& client, DisplayID display,
             int32_t id, uint32_t w, uint32_t h, uint32_t flags);
 
-    LayerBaseClient* createPushBuffersSurfaceLocked(Client* client, DisplayID display,
+    sp<LayerBaseClient> createPushBuffersSurfaceLocked(
+            const sp<Client>& client, DisplayID display,
             int32_t id, uint32_t w, uint32_t h, uint32_t flags);
 
-    status_t    destroySurface(SurfaceID surface_id);
-    status_t    setClientState(ClientID cid, int32_t count, const layer_state_t* states);
+    status_t removeSurface(SurfaceID surface_id);
+    status_t destroySurface(const sp<LayerBaseClient>& layer);
+    status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states);
 
 
     class LayerVector {
@@ -225,15 +220,15 @@
         inline              LayerVector() { }
                             LayerVector(const LayerVector&);
         inline size_t       size() const { return layers.size(); }
-        inline LayerBase*const* array() const { return layers.array(); }
-        ssize_t             add(LayerBase*, Vector<LayerBase*>::compar_t);
-        ssize_t             remove(LayerBase*);
-        ssize_t             reorder(LayerBase*, Vector<LayerBase*>::compar_t);
-        ssize_t             indexOf(LayerBase* key, size_t guess=0) const;
-        inline LayerBase*   operator [] (size_t i) const { return layers[i]; }
+        inline sp<LayerBase> const* array() const { return layers.array(); }
+        ssize_t             add(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t);
+        ssize_t             remove(const sp<LayerBase>&);
+        ssize_t             reorder(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t);
+        ssize_t             indexOf(const sp<LayerBase>& key, size_t guess=0) const;
+        inline sp<LayerBase> operator [] (size_t i) const { return layers[i]; }
     private:
-        KeyedVector<LayerBase*, size_t> lookup;
-        Vector<LayerBase*>              layers;
+        KeyedVector< sp<LayerBase> , size_t> lookup;
+        Vector< sp<LayerBase> >              layers;
     };
 
     struct State {
@@ -247,25 +242,6 @@
         uint8_t         freezeDisplay;
     };
 
-    class DelayedTransaction : public Thread
-    {
-        friend class SurfaceFlinger;
-        sp<SurfaceFlinger>  mFlinger;
-        nsecs_t             mDelay;
-    public:
-        DelayedTransaction(const sp<SurfaceFlinger>& flinger, nsecs_t delay)
-            : Thread(false), mFlinger(flinger), mDelay(delay) {
-        }
-        virtual bool threadLoop() {
-            usleep(mDelay / 1000);
-            if (android_atomic_and(~1,
-                    &mFlinger->mDeplayedTransactionPending) == 1) {
-                mFlinger->signalEvent();
-            }
-            return false;
-        }
-    };
-
     virtual bool        threadLoop();
     virtual status_t    readyToRun();
     virtual void        onFirstRef();
@@ -279,6 +255,9 @@
 
             void        handleConsoleEvents();
             void        handleTransaction(uint32_t transactionFlags);
+            void        handleTransactionLocked(
+                            uint32_t transactionFlags, 
+                            Vector< sp<LayerBase> >& ditchedLayers);
 
             void        computeVisibleRegions(
                             LayerVector& currentLayers,
@@ -289,8 +268,7 @@
             bool        lockPageFlip(const LayerVector& currentLayers);
             void        unlockPageFlip(const LayerVector& currentLayers);
             void        handleRepaint();
-            void        handleDebugCpu();
-            void        scheduleBroadcast(Client* client);
+            void        scheduleBroadcast(const sp<Client>& client);
             void        executeScheduledBroadcasts();
             void        postFramebuffer();
             void        composeSurfaces(const Region& dirty);
@@ -298,10 +276,10 @@
 
 
             void        destroyConnection(ClientID cid);
-            LayerBaseClient* getLayerUser_l(SurfaceID index) const;
-            status_t    addLayer_l(LayerBase* layer);
-            status_t    removeLayer_l(LayerBase* layer);
-            void        destroy_all_removed_layers_l();
+            sp<LayerBaseClient> getLayerUser_l(SurfaceID index) const;
+            status_t    addLayer_l(const sp<LayerBase>& layer);
+            status_t    removeLayer_l(const sp<LayerBase>& layer);
+            status_t    purgatorizeLayer_l(const sp<LayerBase>& layer);
             void        free_resources_l();
 
             uint32_t    getTransactionFlags(uint32_t flags);
@@ -323,6 +301,11 @@
             void        debugShowFPS() const;
             void        drawWormhole() const;
            
+
+    mutable     MessageQueue    mEventQueue;
+    
+                
+                
                 // access must be protected by mStateLock
     mutable     Mutex                   mStateLock;
                 State                   mCurrentState;
@@ -330,53 +313,43 @@
     volatile    int32_t                 mTransactionFlags;
     volatile    int32_t                 mTransactionCount;
                 Condition               mTransactionCV;
-
+                
                 // protected by mStateLock (but we could use another lock)
                 Tokenizer                               mTokens;
-                DefaultKeyedVector<ClientID, Client*>   mClientsMap;
-                DefaultKeyedVector<SurfaceID, LayerBaseClient*>   mLayerMap;
+                DefaultKeyedVector<ClientID, sp<Client> >   mClientsMap;
+                DefaultKeyedVector<SurfaceID, sp<LayerBaseClient> >   mLayerMap;
                 GraphicPlane                            mGraphicPlanes[1];
-                SortedVector<LayerBase*>                mRemovedLayers;
-                Vector<Client*>                         mDisconnectedClients;
+                bool                                    mLayersRemoved;
+                Vector< sp<Client> >                    mDisconnectedClients;
 
                 // constant members (no synchronization needed for access)
-                sp<MemoryDealer>            mServerHeap;
-                sp<IMemory>                 mServerCblkMemory;
+                sp<IMemoryHeap>             mServerHeap;
                 surface_flinger_cblk_t*     mServerCblk;
-                sp<SurfaceHeapManager>      mSurfaceHeapManager;
-                sp<GPUHardwareInterface>    mGPU;
                 GLuint                      mWormholeTexName;
                 nsecs_t                     mBootTime;
+                Permission                  mHardwareTest;
+                Permission                  mAccessSurfaceFlinger;
+                Permission                  mDump;
                 
                 // Can only accessed from the main thread, these members
                 // don't need synchronization
                 Region                      mDirtyRegion;
                 Region                      mInvalidRegion;
                 Region                      mWormholeRegion;
-                Client*                     mLastScheduledBroadcast;
-                SortedVector<Client*>       mScheduledBroadcasts;
+                wp<Client>                  mLastScheduledBroadcast;
+                SortedVector< wp<Client> >  mScheduledBroadcasts;
                 bool                        mVisibleRegionsDirty;
                 bool                        mDeferReleaseConsole;
                 bool                        mFreezeDisplay;
                 int32_t                     mFreezeCount;
                 nsecs_t                     mFreezeDisplayTime;
-                friend class OrientationAnimation;
-                OrientationAnimation*       mOrientationAnimation;
-
-                // access protected by mDebugLock
-    mutable     Mutex                       mDebugLock;
-                sp<CPUGauge>                mCpuGauge;
 
                 // don't use a lock for these, we don't care
                 int                         mDebugRegion;
-                int                         mDebugCpu;
-                int                         mDebugFps;
                 int                         mDebugBackground;
 
                 // these are thread safe
     mutable     Barrier                     mReadyToRunBarrier;
-    mutable     SurfaceFlingerSynchro       mSyncObject;
-    volatile    int32_t                     mDeplayedTransactionPending;
 
                 // atomic variables
                 enum {
@@ -409,11 +382,11 @@
 {
 public:
     BClient(SurfaceFlinger *flinger, ClientID cid,
-            const sp<IMemory>& cblk);
+            const sp<IMemoryHeap>& cblk);
     ~BClient();
 
     // ISurfaceFlingerClient interface
-    virtual void getControlBlocks(sp<IMemory>* ctrl) const;
+    virtual sp<IMemoryHeap> getControlBlock() const;
 
     virtual sp<ISurface> createSurface(
             surface_data_t* params, int pid,
@@ -426,7 +399,7 @@
 private:
     ClientID            mId;
     SurfaceFlinger*     mFlinger;
-    sp<IMemory>         mCblk;
+    sp<IMemoryHeap>     mCblk;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/Tokenizer.cpp b/libs/surfaceflinger/Tokenizer.cpp
index ef51d6a..be3a239 100644
--- a/libs/surfaceflinger/Tokenizer.cpp
+++ b/libs/surfaceflinger/Tokenizer.cpp
@@ -162,9 +162,10 @@
 {
     const run_t* ranges = mRanges.array();
     const size_t c = mRanges.size();
-    printf("Tokenizer (%p, size = %lu)\n", this, c);
+    printf("Tokenizer (%p, size = %d)\n", this, int(c));
     for (size_t i=0 ; i<c ; i++) {
-        printf("%lu: (%u, %u)\n", i, ranges[i].first, ranges[i].length);
+        printf("%u: (%u, %u)\n", i,
+                uint32_t(ranges[i].first), uint32_t(ranges[i].length));
     }
 }
 
diff --git a/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp
index e8b0f45..1501536 100644
--- a/libs/surfaceflinger/Transform.cpp
+++ b/libs/surfaceflinger/Transform.cpp
@@ -177,10 +177,10 @@
     Region out;
     if (UNLIKELY(transformed())) {
         if (LIKELY(preserveRects())) {
-            Rect r;
-            Region::iterator iterator(reg);
-            while (iterator.iterate(&r)) {
-                out.orSelf(transform(r));
+            Region::const_iterator it = reg.begin();
+            Region::const_iterator const end = reg.end();
+            while (it != end) {
+                out.orSelf(transform(*it++));
             }
         } else {
             out.set(transform(reg.bounds()));
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.cpp b/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.cpp
similarity index 98%
rename from libs/surfaceflinger/GPUHardware/GPUHardware.cpp
rename to libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.cpp
index 7168bf2..2de628b 100644
--- a/libs/surfaceflinger/GPUHardware/GPUHardware.cpp
+++ b/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.cpp
@@ -30,12 +30,12 @@
 #include <cutils/log.h>
 #include <cutils/properties.h>
 
-#include <utils/IBinder.h>
-#include <utils/MemoryDealer.h>
-#include <utils/MemoryBase.h>
-#include <utils/MemoryHeapPmem.h>
-#include <utils/MemoryHeapBase.h>
-#include <utils/IPCThreadState.h>
+#include <binder/IBinder.h>
+#include <binder/MemoryDealer.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapPmem.h>
+#include <binder/MemoryHeapBase.h>
+#include <binder/IPCThreadState.h>
 #include <utils/StopWatch.h>
 
 #include <ui/ISurfaceComposer.h>
diff --git a/libs/surfaceflinger/GPUHardware/GPUHardware.h b/libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.h
similarity index 100%
rename from libs/surfaceflinger/GPUHardware/GPUHardware.h
rename to libs/surfaceflinger/purgatory/GPUHardware/GPUHardware.h
diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp
new file mode 100644
index 0000000..41c42d1
--- /dev/null
+++ b/libs/surfaceflinger/purgatory/LayerOrientationAnim.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/StopWatch.h>
+
+#include "BlurFilter.h"
+#include "LayerBase.h"
+#include "LayerOrientationAnim.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+#include "OrientationAnimation.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerOrientationAnim::typeInfo = LayerBase::typeInfo | 0x80;
+const char* const LayerOrientationAnim::typeID = "LayerOrientationAnim";
+
+// ---------------------------------------------------------------------------
+
+// Animation...
+const float DURATION = ms2ns(200);
+const float BOUNCES_PER_SECOND = 0.5f;
+//const float BOUNCES_AMPLITUDE = 1.0f/16.0f;
+const float BOUNCES_AMPLITUDE = 0;
+const float DIM_TARGET = 0.40f;
+//#define INTERPOLATED_TIME(_t)   ((_t)*(_t))
+#define INTERPOLATED_TIME(_t)   (_t)
+
+// ---------------------------------------------------------------------------
+
+LayerOrientationAnim::LayerOrientationAnim(
+        SurfaceFlinger* flinger, DisplayID display, 
+        OrientationAnimation* anim, 
+        const sp<Buffer>& bitmapIn,
+        const sp<Buffer>& bitmapOut)
+    : LayerOrientationAnimBase(flinger, display), mAnim(anim), 
+      mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), 
+      mTextureName(-1), mTextureNameIn(-1)
+{
+    // blur that texture. 
+    mStartTime = systemTime();
+    mFinishTime = 0;
+    mOrientationCompleted = false;
+    mFirstRedraw = false;
+    mLastNormalizedTime = 0;
+    mNeedsBlending = false;
+    mAlphaInLerp.set(1.0f, DIM_TARGET);
+    mAlphaOutLerp.set(0.5f, 1.0f);
+}
+
+LayerOrientationAnim::~LayerOrientationAnim()
+{
+    if (mTextureName != -1U) {
+        glDeleteTextures(1, &mTextureName);
+    }
+    if (mTextureNameIn != -1U) {
+        glDeleteTextures(1, &mTextureNameIn);
+    }
+}
+
+bool LayerOrientationAnim::needsBlending() const 
+{
+    return mNeedsBlending; 
+}
+
+Point LayerOrientationAnim::getPhysicalSize() const
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    return Point(hw.getWidth(), hw.getHeight());
+}
+
+void LayerOrientationAnim::validateVisibility(const Transform&)
+{
+    const Layer::State& s(drawingState());
+    const Transform tr(s.transform);
+    const Point size(getPhysicalSize());
+    uint32_t w = size.x;
+    uint32_t h = size.y;
+    mTransformedBounds = tr.makeBounds(w, h);
+    mLeft = tr.tx();
+    mTop  = tr.ty();
+    transparentRegionScreen.clear();
+    mTransformed = true;
+}
+
+void LayerOrientationAnim::onOrientationCompleted()
+{
+    mFinishTime = systemTime();
+    mOrientationCompleted = true;
+    mFirstRedraw = true;
+    mNeedsBlending = true;
+    mFlinger->invalidateLayerVisibility(this);
+}
+
+void LayerOrientationAnim::onDraw(const Region& clip) const
+{
+    const nsecs_t now = systemTime();
+    float alphaIn, alphaOut;
+    
+    if (mOrientationCompleted) {
+        if (mFirstRedraw) {
+            mFirstRedraw = false;
+            
+            // make a copy of what's on screen
+            copybit_image_t image;
+            mBitmapOut->getBitmapSurface(&image);
+            const DisplayHardware& hw(graphicPlane(0).displayHardware());
+            hw.copyBackToImage(image);
+
+            // and erase the screen for this round
+            glDisable(GL_BLEND);
+            glDisable(GL_DITHER);
+            glDisable(GL_SCISSOR_TEST);
+            glClearColor(0,0,0,0);
+            glClear(GL_COLOR_BUFFER_BIT);
+            
+            // FIXME: code below is gross
+            mNeedsBlending = false;
+            LayerOrientationAnim* self(const_cast<LayerOrientationAnim*>(this));
+            mFlinger->invalidateLayerVisibility(self);
+        }
+
+        // make sure pick-up where we left off
+        const float duration = DURATION * mLastNormalizedTime;
+        const float normalizedTime = (float(now - mFinishTime) / duration);
+        if (normalizedTime <= 1.0f) {
+            const float interpolatedTime = INTERPOLATED_TIME(normalizedTime);
+            alphaIn = mAlphaInLerp.getOut();
+            alphaOut = mAlphaOutLerp(interpolatedTime);
+        } else {
+            mAnim->onAnimationFinished();
+            alphaIn = mAlphaInLerp.getOut();
+            alphaOut = mAlphaOutLerp.getOut();
+        }
+    } else {
+        const float normalizedTime = float(now - mStartTime) / DURATION;
+        if (normalizedTime <= 1.0f) {
+            mLastNormalizedTime = normalizedTime;
+            const float interpolatedTime = INTERPOLATED_TIME(normalizedTime);
+            alphaIn = mAlphaInLerp(interpolatedTime);
+            alphaOut = 0.0f;
+        } else {
+            mLastNormalizedTime = 1.0f;
+            const float to_seconds = DURATION / seconds(1);
+            alphaIn = mAlphaInLerp.getOut();
+            if (BOUNCES_AMPLITUDE > 0.0f) {
+                const float phi = BOUNCES_PER_SECOND * 
+                        (((normalizedTime - 1.0f) * to_seconds)*M_PI*2);
+                if (alphaIn > 1.0f) alphaIn = 1.0f;
+                else if (alphaIn < 0.0f) alphaIn = 0.0f;
+                alphaIn += BOUNCES_AMPLITUDE * (1.0f - cosf(phi));
+            }
+            alphaOut = 0.0f;
+        }
+        mAlphaOutLerp.setIn(alphaIn);
+    }
+    drawScaled(1.0f, alphaIn, alphaOut);
+}
+
+void LayerOrientationAnim::drawScaled(float scale, float alphaIn, float alphaOut) const
+{
+    copybit_image_t dst;
+    const GraphicPlane& plane(graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    //hw.getDisplaySurface(&dst);
+
+    // clear screen
+    // TODO: with update on demand, we may be able 
+    // to not erase the screen at all during the animation 
+    if (!mOrientationCompleted) {
+        if (scale==1.0f && (alphaIn>=1.0f || alphaOut>=1.0f)) {
+            // we don't need to erase the screen in that case
+        } else {
+            glDisable(GL_BLEND);
+            glDisable(GL_DITHER);
+            glDisable(GL_SCISSOR_TEST);
+            glClearColor(0,0,0,0);
+            glClear(GL_COLOR_BUFFER_BIT);
+        }
+    }
+    
+    copybit_image_t src;
+    mBitmapIn->getBitmapSurface(&src);
+
+    copybit_image_t srcOut;
+    mBitmapOut->getBitmapSurface(&srcOut);
+
+    const int w = dst.w*scale; 
+    const int h = dst.h*scale; 
+    const int xc = uint32_t(dst.w-w)/2;
+    const int yc = uint32_t(dst.h-h)/2;
+    const copybit_rect_t drect = { xc, yc, xc+w, yc+h }; 
+    const copybit_rect_t srect = { 0, 0, src.w, src.h };
+    const Region reg(Rect( drect.l, drect.t, drect.r, drect.b ));
+
+    GGLSurface t;
+    t.version = sizeof(GGLSurface);
+    t.width  = src.w;
+    t.height = src.h;
+    t.stride = src.w;
+    t.vstride= src.h;
+    t.format = src.format;
+    t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+
+    Transform tr;
+    tr.set(scale,0,0,scale);
+    tr.set(xc, yc);
+    
+    // FIXME: we should not access mVertices and mDrawingState like that,
+    // but since we control the animation, we know it's going to work okay.
+    // eventually we'd need a more formal way of doing things like this.
+    LayerOrientationAnim& self(const_cast<LayerOrientationAnim&>(*this));
+    tr.transform(self.mVertices[0], 0, 0);
+    tr.transform(self.mVertices[1], 0, src.h);
+    tr.transform(self.mVertices[2], src.w, src.h);
+    tr.transform(self.mVertices[3], src.w, 0);
+    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
+        // Too slow to do this in software
+        self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
+    }
+
+    if (alphaIn > 0.0f) {
+        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+        if (UNLIKELY(mTextureNameIn == -1LU)) {
+            mTextureNameIn = createTexture();
+            GLuint w=0, h=0;
+            const Region dirty(Rect(t.width, t.height));
+            loadTexture(dirty, mTextureNameIn, t, w, h);
+        }
+        self.mDrawingState.alpha = int(alphaIn*255);
+        drawWithOpenGL(reg, mTextureNameIn, t);
+    }
+
+    if (alphaOut > 0.0f) {
+        t.data = (GGLubyte*)(intptr_t(srcOut.base) + srcOut.offset);
+        if (UNLIKELY(mTextureName == -1LU)) {
+            mTextureName = createTexture();
+            GLuint w=0, h=0;
+            const Region dirty(Rect(t.width, t.height));
+            loadTexture(dirty, mTextureName, t, w, h);
+        }
+        self.mDrawingState.alpha = int(alphaOut*255);
+        drawWithOpenGL(reg, mTextureName, t);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h
similarity index 67%
copy from libs/surfaceflinger/LayerOrientationAnim.h
copy to libs/surfaceflinger/purgatory/LayerOrientationAnim.h
index 12b6f1c..a1a2654 100644
--- a/libs/surfaceflinger/LayerOrientationAnim.h
+++ b/libs/surfaceflinger/purgatory/LayerOrientationAnim.h
@@ -20,7 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <utils/threads.h>
-#include <utils/Parcel.h>
+#include <binder/Parcel.h>
 
 #include "LayerBase.h"
 #include "LayerBitmap.h"
@@ -52,8 +52,8 @@
     
                 LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display,
                         OrientationAnimation* anim, 
-                        const LayerBitmap& bitmapIn,
-                        const LayerBitmap& bitmapOut);
+                        const sp<Buffer>& bitmapIn,
+                        const sp<Buffer>& bitmapOut);
         virtual ~LayerOrientationAnim();
 
             void onOrientationCompleted();
@@ -64,13 +64,45 @@
     virtual bool needsBlending() const;
     virtual bool isSecure() const       { return false; }
 private:
+    void drawScaled(float scale, float alphaIn, float alphaOut) const;
+
+    class Lerp {
+        float in;
+        float outMinusIn;
+    public:
+        Lerp() : in(0), outMinusIn(0) { }
+        Lerp(float in, float out) : in(in), outMinusIn(out-in) { }
+        float getIn() const { return in; };
+        float getOut() const { return in + outMinusIn; }
+        void set(float in, float out) { 
+            this->in = in; 
+            this->outMinusIn = out-in; 
+        }
+        void setIn(float in) { 
+            this->in = in; 
+        }
+        void setOut(float out) { 
+            this->outMinusIn = out - this->in; 
+        }
+        float operator()(float t) const { 
+            return outMinusIn*t + in; 
+        }
+    };
+    
     OrientationAnimation* mAnim;
-    LayerBitmap mBitmapIn;
-    LayerBitmap mBitmapOut;
+    sp<Buffer> mBitmapIn;
+    sp<Buffer> mBitmapOut;
+    nsecs_t mStartTime;
+    nsecs_t mFinishTime;
     bool mOrientationCompleted;
+    mutable bool mFirstRedraw;
+    mutable float mLastNormalizedTime;
     mutable GLuint  mTextureName;
     mutable GLuint  mTextureNameIn;
     mutable bool mNeedsBlending;
+    
+    mutable Lerp mAlphaInLerp;
+    mutable Lerp mAlphaOutLerp;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp
new file mode 100644
index 0000000..dc6b632
--- /dev/null
+++ b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.cpp
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include "LayerBase.h"
+#include "LayerOrientationAnim.h"
+#include "LayerOrientationAnimRotate.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+#include "OrientationAnimation.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+const uint32_t LayerOrientationAnimRotate::typeInfo = LayerBase::typeInfo | 0x100;
+const char* const LayerOrientationAnimRotate::typeID = "LayerOrientationAnimRotate";
+
+// ---------------------------------------------------------------------------
+
+const float ROTATION = M_PI * 0.5f;
+const float ROTATION_FACTOR = 1.0f; // 1.0 or 2.0
+const float DURATION = ms2ns(200);
+const float BOUNCES_PER_SECOND = 0.8;
+const float BOUNCES_AMPLITUDE = (5.0f/180.f) * M_PI;
+
+LayerOrientationAnimRotate::LayerOrientationAnimRotate(
+        SurfaceFlinger* flinger, DisplayID display, 
+        OrientationAnimation* anim, 
+        const sp<Buffer>& bitmapIn,
+        const sp<Buffer>& bitmapOut)
+    : LayerOrientationAnimBase(flinger, display), mAnim(anim), 
+      mBitmapIn(bitmapIn), mBitmapOut(bitmapOut), 
+      mTextureName(-1), mTextureNameIn(-1)
+{
+    mStartTime = systemTime();
+    mFinishTime = 0;
+    mOrientationCompleted = false;
+    mFirstRedraw = false;
+    mLastNormalizedTime = 0;
+    mLastAngle = 0;
+    mLastScale = 0;
+    mNeedsBlending = false;
+    const GraphicPlane& plane(graphicPlane(0));
+    mOriginalTargetOrientation = plane.getOrientation(); 
+}
+
+LayerOrientationAnimRotate::~LayerOrientationAnimRotate()
+{
+    if (mTextureName != -1U) {
+        glDeleteTextures(1, &mTextureName);
+    }
+    if (mTextureNameIn != -1U) {
+        glDeleteTextures(1, &mTextureNameIn);
+    }
+}
+
+bool LayerOrientationAnimRotate::needsBlending() const 
+{
+    return mNeedsBlending; 
+}
+
+Point LayerOrientationAnimRotate::getPhysicalSize() const
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    return Point(hw.getWidth(), hw.getHeight());
+}
+
+void LayerOrientationAnimRotate::validateVisibility(const Transform&)
+{
+    const Layer::State& s(drawingState());
+    const Transform tr(s.transform);
+    const Point size(getPhysicalSize());
+    uint32_t w = size.x;
+    uint32_t h = size.y;
+    mTransformedBounds = tr.makeBounds(w, h);
+    mLeft = tr.tx();
+    mTop  = tr.ty();
+    transparentRegionScreen.clear();
+    mTransformed = true;
+}
+
+void LayerOrientationAnimRotate::onOrientationCompleted()
+{
+    mFinishTime = systemTime();
+    mOrientationCompleted = true;
+    mFirstRedraw = true;
+    mNeedsBlending = true;
+    mFlinger->invalidateLayerVisibility(this);
+}
+
+void LayerOrientationAnimRotate::onDraw(const Region& clip) const
+{
+    // Animation...
+
+    const nsecs_t now = systemTime();
+    float angle, scale, alpha;
+    
+    if (mOrientationCompleted) {
+        if (mFirstRedraw) {
+            // make a copy of what's on screen
+            copybit_image_t image;
+            mBitmapIn->getBitmapSurface(&image);
+            const DisplayHardware& hw(graphicPlane(0).displayHardware());
+            hw.copyBackToImage(image);
+            
+            // FIXME: code below is gross
+            mFirstRedraw = false; 
+            mNeedsBlending = false;
+            LayerOrientationAnimRotate* self(const_cast<LayerOrientationAnimRotate*>(this));
+            mFlinger->invalidateLayerVisibility(self);
+        }
+
+        // make sure pick-up where we left off
+        const float duration = DURATION * mLastNormalizedTime;
+        const float normalizedTime = (float(now - mFinishTime) / duration);
+        if (normalizedTime <= 1.0f) {
+            const float squaredTime = normalizedTime*normalizedTime;
+            angle = (ROTATION*ROTATION_FACTOR - mLastAngle)*squaredTime + mLastAngle;
+            scale = (1.0f - mLastScale)*squaredTime + mLastScale;
+            alpha = normalizedTime;
+        } else {
+            mAnim->onAnimationFinished();
+            angle = ROTATION;
+            alpha = 1.0f;
+            scale = 1.0f;
+        }
+    } else {
+        // FIXME: works only for portrait framebuffers
+        const Point size(getPhysicalSize());
+        const float TARGET_SCALE = size.x * (1.0f / size.y);
+        const float normalizedTime = float(now - mStartTime) / DURATION;
+        if (normalizedTime <= 1.0f) {
+            mLastNormalizedTime = normalizedTime;
+            const float squaredTime = normalizedTime*normalizedTime;
+            angle = ROTATION * squaredTime;
+            scale = (TARGET_SCALE - 1.0f)*squaredTime + 1.0f;
+            alpha = 0;
+        } else {
+            mLastNormalizedTime = 1.0f;
+            angle = ROTATION;
+            if (BOUNCES_AMPLITUDE) {
+                const float to_seconds = DURATION / seconds(1);
+                const float phi = BOUNCES_PER_SECOND * 
+                (((normalizedTime - 1.0f) * to_seconds)*M_PI*2);
+                angle += BOUNCES_AMPLITUDE * sinf(phi);
+            }
+            scale = TARGET_SCALE;
+            alpha = 0;
+        }
+        mLastAngle = angle;
+        mLastScale = scale;
+    }
+    drawScaled(angle, scale, alpha);
+}
+
+void LayerOrientationAnimRotate::drawScaled(float f, float s, float alpha) const
+{
+    copybit_image_t dst;
+    const GraphicPlane& plane(graphicPlane(0));
+    const DisplayHardware& hw(plane.displayHardware());
+    //hw.getDisplaySurface(&dst);
+
+    // clear screen
+    // TODO: with update on demand, we may be able 
+    // to not erase the screen at all during the animation 
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+    glDisable(GL_SCISSOR_TEST);
+    glClearColor(0,0,0,0);
+    glClear(GL_COLOR_BUFFER_BIT);
+    
+    const int w = dst.w; 
+    const int h = dst.h; 
+
+    copybit_image_t src;
+    mBitmapIn->getBitmapSurface(&src);
+    const copybit_rect_t srect = { 0, 0, src.w, src.h };
+
+
+    GGLSurface t;
+    t.version = sizeof(GGLSurface);
+    t.width  = src.w;
+    t.height = src.h;
+    t.stride = src.w;
+    t.vstride= src.h;
+    t.format = src.format;
+    t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+
+    if (!mOriginalTargetOrientation) {
+        f = -f;
+    }
+
+    Transform tr;
+    tr.set(f, w*0.5f, h*0.5f);
+    tr.scale(s, w*0.5f, h*0.5f);
+
+    // FIXME: we should not access mVertices and mDrawingState like that,
+    // but since we control the animation, we know it's going to work okay.
+    // eventually we'd need a more formal way of doing things like this.
+    LayerOrientationAnimRotate& self(const_cast<LayerOrientationAnimRotate&>(*this));
+    tr.transform(self.mVertices[0], 0, 0);
+    tr.transform(self.mVertices[1], 0, src.h);
+    tr.transform(self.mVertices[2], src.w, src.h);
+    tr.transform(self.mVertices[3], src.w, 0);
+
+    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
+        // Too slow to do this in software
+        self.mDrawingState.flags |= ISurfaceComposer::eLayerFilter;
+    }
+
+    if (UNLIKELY(mTextureName == -1LU)) {
+        mTextureName = createTexture();
+        GLuint w=0, h=0;
+        const Region dirty(Rect(t.width, t.height));
+        loadTexture(dirty, mTextureName, t, w, h);
+    }
+    self.mDrawingState.alpha = 255; //-int(alpha*255);
+    const Region clip(Rect( srect.l, srect.t, srect.r, srect.b ));
+    drawWithOpenGL(clip, mTextureName, t);
+    
+    if (alpha > 0) {
+        const float sign = (!mOriginalTargetOrientation) ? 1.0f : -1.0f;
+        tr.set(f + sign*(M_PI * 0.5f * ROTATION_FACTOR), w*0.5f, h*0.5f);
+        tr.scale(s, w*0.5f, h*0.5f);
+        tr.transform(self.mVertices[0], 0, 0);
+        tr.transform(self.mVertices[1], 0, src.h);
+        tr.transform(self.mVertices[2], src.w, src.h);
+        tr.transform(self.mVertices[3], src.w, 0);
+
+        copybit_image_t src;
+        mBitmapIn->getBitmapSurface(&src);
+        t.data = (GGLubyte*)(intptr_t(src.base) + src.offset);
+        if (UNLIKELY(mTextureNameIn == -1LU)) {
+            mTextureNameIn = createTexture();
+            GLuint w=0, h=0;
+            const Region dirty(Rect(t.width, t.height));
+            loadTexture(dirty, mTextureNameIn, t, w, h);
+        }
+        self.mDrawingState.alpha = int(alpha*255);
+        const Region clip(Rect( srect.l, srect.t, srect.r, srect.b ));
+        drawWithOpenGL(clip, mTextureNameIn, t);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/surfaceflinger/LayerOrientationAnim.h b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h
similarity index 67%
rename from libs/surfaceflinger/LayerOrientationAnim.h
rename to libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h
index 12b6f1c..a88eec0 100644
--- a/libs/surfaceflinger/LayerOrientationAnim.h
+++ b/libs/surfaceflinger/purgatory/LayerOrientationAnimRotate.h
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_LAYER_ORIENTATION_ANIM_H
-#define ANDROID_LAYER_ORIENTATION_ANIM_H
+#ifndef ANDROID_LAYER_ORIENTATION_ANIM_ROTATE_H
+#define ANDROID_LAYER_ORIENTATION_ANIM_ROTATE_H
 
 #include <stdint.h>
 #include <sys/types.h>
 #include <utils/threads.h>
-#include <utils/Parcel.h>
+#include <binder/Parcel.h>
 
 #include "LayerBase.h"
 #include "LayerBitmap.h"
@@ -30,19 +30,7 @@
 // ---------------------------------------------------------------------------
 class OrientationAnimation;
 
-
-class LayerOrientationAnimBase : public LayerBase
-{
-public:
-    LayerOrientationAnimBase(SurfaceFlinger* flinger, DisplayID display)
-        : LayerBase(flinger, display) {
-    }
-    virtual void onOrientationCompleted() = 0;
-};
-
-// ---------------------------------------------------------------------------
-
-class LayerOrientationAnim : public LayerOrientationAnimBase
+class LayerOrientationAnimRotate : public LayerOrientationAnimBase
 {
 public:    
     static const uint32_t typeInfo;
@@ -50,11 +38,11 @@
     virtual char const* getTypeID() const { return typeID; }
     virtual uint32_t getTypeInfo() const { return typeInfo; }
     
-                LayerOrientationAnim(SurfaceFlinger* flinger, DisplayID display,
+    LayerOrientationAnimRotate(SurfaceFlinger* flinger, DisplayID display,
                         OrientationAnimation* anim, 
-                        const LayerBitmap& bitmapIn,
-                        const LayerBitmap& bitmapOut);
-        virtual ~LayerOrientationAnim();
+                        const sp<Buffer>& bitmapIn,
+                        const sp<Buffer>& bitmapOut);
+        virtual ~LayerOrientationAnimRotate();
 
             void onOrientationCompleted();
 
@@ -64,10 +52,19 @@
     virtual bool needsBlending() const;
     virtual bool isSecure() const       { return false; }
 private:
+    void drawScaled(float angle, float scale, float alpha) const;
+    
     OrientationAnimation* mAnim;
-    LayerBitmap mBitmapIn;
-    LayerBitmap mBitmapOut;
+    sp<Buffer> mBitmapIn;
+    sp<Buffer> mBitmapOut;
+    nsecs_t mStartTime;
+    nsecs_t mFinishTime;
     bool mOrientationCompleted;
+    int mOriginalTargetOrientation;
+    mutable bool mFirstRedraw;
+    mutable float mLastNormalizedTime;
+    mutable float mLastAngle;
+    mutable float mLastScale;
     mutable GLuint  mTextureName;
     mutable GLuint  mTextureNameIn;
     mutable bool mNeedsBlending;
@@ -77,4 +74,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_LAYER_ORIENTATION_ANIM_H
+#endif // ANDROID_LAYER_ORIENTATION_ANIM_ROTATE_H
diff --git a/libs/surfaceflinger/OrientationAnimation.cpp b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp
similarity index 81%
rename from libs/surfaceflinger/OrientationAnimation.cpp
rename to libs/surfaceflinger/purgatory/OrientationAnimation.cpp
index 12c0eef..a6c9c28 100644
--- a/libs/surfaceflinger/OrientationAnimation.cpp
+++ b/libs/surfaceflinger/purgatory/OrientationAnimation.cpp
@@ -14,16 +14,14 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdint.h>
 #include <sys/types.h>
 #include <limits.h>
 
 #include "LayerOrientationAnim.h"
+#include "LayerOrientationAnimRotate.h"
 #include "OrientationAnimation.h"
 #include "SurfaceFlinger.h"
-#include "VRamHeap.h"
 
 #include "DisplayHardware/DisplayHardware.h"
 
@@ -34,9 +32,6 @@
 OrientationAnimation::OrientationAnimation(const sp<SurfaceFlinger>& flinger)
     : mFlinger(flinger), mLayerOrientationAnim(NULL), mState(DONE)
 {
-    // allocate a memory-dealer for this the first time
-    mTemporaryDealer = mFlinger->getSurfaceHeapManager()->createHeap(
-            ISurfaceComposer::eHardware);
 }
 
 OrientationAnimation::~OrientationAnimation()
@@ -97,22 +92,22 @@
     const uint32_t w = hw.getWidth();
     const uint32_t h = hw.getHeight();
 
-    LayerBitmap bitmap;
-    bitmap.init(mTemporaryDealer);
-    bitmap.setBits(w, h, 1, hw.getFormat());
-
-    LayerBitmap bitmapIn;
-    bitmapIn.init(mTemporaryDealer);
-    bitmapIn.setBits(w, h, 1, hw.getFormat());
+    sp<Buffer> bitmap = new Buffer(w, h, hw.getFormat());
+    sp<Buffer> bitmapIn = new Buffer(w, h, hw.getFormat());
 
     copybit_image_t front;
-    bitmap.getBitmapSurface(&front);
-    hw.copyFrontToImage(front);
+    bitmap->getBitmapSurface(&front);
+    hw.copyFrontToImage(front); // FIXME: we need an extension to do this
 
-    LayerOrientationAnimBase* l;
+    sp<LayerOrientationAnimBase> l;
     
-    l = new LayerOrientationAnim(
-            mFlinger.get(), 0, this, bitmap, bitmapIn);
+    if (mType & 0x80) {
+        l = new LayerOrientationAnimRotate(
+                mFlinger.get(), 0, this, bitmap, bitmapIn);
+    } else {
+        l = new LayerOrientationAnim(
+                mFlinger.get(), 0, this, bitmap, bitmapIn);
+    }
 
     l->initStates(w, h, 0);
     l->setLayer(INT_MAX-1);
@@ -131,7 +126,7 @@
         return true;
         
     }
-    //mLayerOrientationAnim->invalidate();
+    mLayerOrientationAnim->invalidate();
     return false;
 }
 
@@ -146,7 +141,7 @@
 {
     mState = DONE;
     mFlinger->removeLayer(mLayerOrientationAnim);
-    mLayerOrientationAnim = NULL;
+    mLayerOrientationAnim.clear();
     return true;
 }
 
diff --git a/libs/surfaceflinger/OrientationAnimation.h b/libs/surfaceflinger/purgatory/OrientationAnimation.h
similarity index 95%
rename from libs/surfaceflinger/OrientationAnimation.h
rename to libs/surfaceflinger/purgatory/OrientationAnimation.h
index cafa38d..8ba6621 100644
--- a/libs/surfaceflinger/OrientationAnimation.h
+++ b/libs/surfaceflinger/purgatory/OrientationAnimation.h
@@ -72,8 +72,7 @@
     bool finished();
 
     sp<SurfaceFlinger> mFlinger;
-    sp<MemoryDealer> mTemporaryDealer;
-    LayerOrientationAnimBase* mLayerOrientationAnim;
+    sp< LayerOrientationAnimBase > mLayerOrientationAnim;
     int mState;
     uint32_t mType;
 };
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/purgatory/VRamHeap.cpp
similarity index 97%
rename from libs/surfaceflinger/VRamHeap.cpp
rename to libs/surfaceflinger/purgatory/VRamHeap.cpp
index 5f633bd..f3ed790 100644
--- a/libs/surfaceflinger/VRamHeap.cpp
+++ b/libs/surfaceflinger/purgatory/VRamHeap.cpp
@@ -14,8 +14,6 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlinger"
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdint.h>
@@ -35,8 +33,6 @@
 #include <utils/MemoryHeapPmem.h>
 #include <utils/MemoryHeapBase.h>
 
-#include <EGL/eglnatives.h>
-
 #include "GPUHardware/GPUHardware.h"
 #include "SurfaceFlinger.h"
 #include "VRamHeap.h"
@@ -100,7 +96,7 @@
         }
     }
 
-    if ((flags & ISurfaceComposer::eGPU) && (mFlinger->getGPU() != 0)) {
+    if (flags & ISurfaceComposer::eGPU) {
         // FIXME: this is msm7201A specific, where gpu surfaces may not be secure
         if (!(flags & ISurfaceComposer::eSecure)) {
             // if GPU doesn't work, we try eHardware
diff --git a/libs/surfaceflinger/VRamHeap.h b/libs/surfaceflinger/purgatory/VRamHeap.h
similarity index 100%
rename from libs/surfaceflinger/VRamHeap.h
rename to libs/surfaceflinger/purgatory/VRamHeap.h
diff --git a/libs/surfaceflinger/tests/overlays/overlays.cpp b/libs/surfaceflinger/tests/overlays/overlays.cpp
index f3c046f..0b9322e 100644
--- a/libs/surfaceflinger/tests/overlays/overlays.cpp
+++ b/libs/surfaceflinger/tests/overlays/overlays.cpp
@@ -1,6 +1,6 @@
-#include <utils/IPCThreadState.h>
-#include <utils/ProcessState.h>
-#include <utils/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
 #include <utils/Log.h>
 
 #include <ui/Surface.h>
diff --git a/libs/surfaceflinger/tests/resize/Android.mk b/libs/surfaceflinger/tests/resize/Android.mk
new file mode 100644
index 0000000..ef1532f
--- /dev/null
+++ b/libs/surfaceflinger/tests/resize/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	resize.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+    libui
+
+LOCAL_MODULE:= test-resize
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/surfaceflinger/tests/resize/resize.cpp b/libs/surfaceflinger/tests/resize/resize.cpp
new file mode 100644
index 0000000..21c6ab6
--- /dev/null
+++ b/libs/surfaceflinger/tests/resize/resize.cpp
@@ -0,0 +1,60 @@
+#include <cutils/memory.h>
+
+#include <utils/IPCThreadState.h>
+#include <utils/ProcessState.h>
+#include <utils/IServiceManager.h>
+#include <utils/Log.h>
+
+#include <ui/Surface.h>
+#include <ui/ISurface.h>
+#include <ui/Overlay.h>
+#include <ui/SurfaceComposerClient.h>
+
+using namespace android;
+
+namespace android {
+class Test {
+public:
+    static const sp<ISurface>& getISurface(const sp<Surface>& s) {
+        return s->getISurface();
+    }
+};
+};
+
+int main(int argc, char** argv)
+{
+    // set up the thread-pool
+    sp<ProcessState> proc(ProcessState::self());
+    ProcessState::self()->startThreadPool();
+
+    // create a client to surfaceflinger
+    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
+    
+    // create pushbuffer surface
+    sp<Surface> surface = client->createSurface(getpid(), 0, 160, 240, 
+            PIXEL_FORMAT_RGB_565);
+
+
+    client->openTransaction();
+    surface->setLayer(100000);
+    client->closeTransaction();
+
+    Surface::SurfaceInfo info;
+    surface->lock(&info);
+    ssize_t bpr = info.s * bytesPerPixel(info.format);
+    android_memset16((uint16_t*)info.bits, 0xF800, bpr*info.h);
+    surface->unlockAndPost();
+
+    surface->lock(&info);
+    android_memset16((uint16_t*)info.bits, 0x07E0, bpr*info.h);
+    surface->unlockAndPost();
+
+    client->openTransaction();
+    surface->setSize(320, 240);
+    client->closeTransaction();
+
+    
+    IPCThreadState::self()->joinThreadPool();
+    
+    return 0;
+}
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 7bbe38b..49939ca 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -2,12 +2,12 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
+	BufferMapper.cpp \
 	Camera.cpp \
 	CameraParameters.cpp \
-	EGLDisplaySurface.cpp \
-	EGLNativeWindowSurface.cpp \
 	EventHub.cpp \
 	EventRecurrence.cpp \
+	FramebufferNativeWindow.cpp \
 	KeyLayoutMap.cpp \
 	KeyCharacterMap.cpp \
 	ICamera.cpp \
@@ -27,9 +27,9 @@
 	SurfaceFlingerSynchro.cpp 
 
 LOCAL_SHARED_LIBRARIES := \
-	libcorecg \
 	libcutils \
 	libutils \
+	libbinder \
 	libpixelflinger \
 	libhardware \
 	libhardware_legacy
diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp
new file mode 100644
index 0000000..92a9a86
--- /dev/null
+++ b/libs/ui/BufferMapper.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BufferMapper"
+
+#include <stdint.h>
+#include <errno.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <ui/BufferMapper.h>
+#include <ui/Rect.h>
+
+#include <hardware/gralloc.h>
+
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+ANDROID_SINGLETON_STATIC_INSTANCE( BufferMapper )
+
+BufferMapper::BufferMapper()
+    : mAllocMod(0)
+{
+    hw_module_t const* module;
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
+    if (err == 0) {
+        mAllocMod = (gralloc_module_t const *)module;
+    }
+}
+
+status_t BufferMapper::registerBuffer(buffer_handle_t handle)
+{
+    status_t err = mAllocMod->registerBuffer(mAllocMod, handle);
+    LOGW_IF(err, "registerBuffer(%p) failed %d (%s)",
+            handle, err, strerror(-err));
+    return err;
+}
+
+status_t BufferMapper::unregisterBuffer(buffer_handle_t handle)
+{
+    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, void** vaddr)
+{
+    status_t err = mAllocMod->lock(mAllocMod, handle, usage,
+            bounds.left, bounds.top, bounds.width(), bounds.height(), vaddr);
+    LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
+    return err;
+}
+
+status_t BufferMapper::unlock(buffer_handle_t handle)
+{
+    status_t err = mAllocMod->unlock(mAllocMod, handle);
+    LOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index 5015379..12a7725 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -19,9 +19,9 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "Camera"
 #include <utils/Log.h>
-#include <utils/IServiceManager.h>
+#include <binder/IServiceManager.h>
 #include <utils/threads.h>
-#include <utils/IMemory.h>
+#include <binder/IMemory.h>
 #include <ui/Surface.h>
 #include <ui/Camera.h>
 #include <ui/ICameraService.h>
diff --git a/libs/ui/EGLDisplaySurface.cpp b/libs/ui/EGLDisplaySurface.cpp
deleted file mode 100644
index d06c98b..0000000
--- a/libs/ui/EGLDisplaySurface.cpp
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- **
- ** Copyright 2007 The Android Open Source Project
- **
- ** Licensed under the Apache License Version 2.0(the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- **     http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing software
- ** distributed under the License is distributed on an "AS IS" BASIS
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#define LOG_TAG "EGLDisplaySurface"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-
-#include <hardware/copybit.h>
-
-#include <ui/SurfaceComposerClient.h>
-#include <ui/DisplayInfo.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-#include <ui/EGLDisplaySurface.h>
-
-#if HAVE_ANDROID_OS
-#include <linux/msm_mdp.h>
-#endif
-
-#include <EGL/egl.h>
-
-#include <pixelflinger/format.h>
-
-
-// ----------------------------------------------------------------------------
-
-egl_native_window_t* android_createDisplaySurface()
-{
-    egl_native_window_t* s = new android::EGLDisplaySurface();
-    s->memory_type = NATIVE_MEMORY_TYPE_GPU;
-    return s;
-}
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-EGLDisplaySurface::EGLDisplaySurface()
-    : EGLNativeSurface<EGLDisplaySurface>()
-{
-    egl_native_window_t::version = sizeof(egl_native_window_t);
-    egl_native_window_t::ident = 0;
-    egl_native_window_t::incRef = &EGLDisplaySurface::hook_incRef;
-    egl_native_window_t::decRef = &EGLDisplaySurface::hook_decRef;
-    egl_native_window_t::swapBuffers = &EGLDisplaySurface::hook_swapBuffers;
-    egl_native_window_t::connect = 0;
-    egl_native_window_t::disconnect = 0;
-
-    mFb[0].data = 0;
-    mFb[1].data = 0;
-    mBlitEngine = 0;
-    egl_native_window_t::fd = mapFrameBuffer();
-    if (egl_native_window_t::fd >= 0) {
-        
-        hw_module_t const* module;
-        if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-            copybit_open(module, &mBlitEngine);
-        }
-        
-        const float in2mm = 25.4f;
-        float refreshRate = 1000000000000000LLU / (
-                float( mInfo.upper_margin + mInfo.lower_margin + mInfo.yres )
-                * ( mInfo.left_margin  + mInfo.right_margin + mInfo.xres )
-                * mInfo.pixclock);
-
-        const GGLSurface& buffer = mFb[1 - mIndex];
-        egl_native_window_t::width  = buffer.width;
-        egl_native_window_t::height = buffer.height;
-        egl_native_window_t::stride = buffer.stride;
-        egl_native_window_t::format = buffer.format;
-        egl_native_window_t::base   = intptr_t(mFb[0].data);
-        egl_native_window_t::offset =
-            intptr_t(buffer.data) - egl_native_window_t::base;
-        egl_native_window_t::flags  = 0;
-        egl_native_window_t::xdpi = (mInfo.xres * in2mm) / mInfo.width;
-        egl_native_window_t::ydpi = (mInfo.yres * in2mm) / mInfo.height;
-        egl_native_window_t::fps  = refreshRate;
-        egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_FB;
-        // no error, set the magic word
-        egl_native_window_t::magic = 0x600913;
-    }
-    mSwapCount = -1;
-    mPageFlipCount = 0;
-}
-
-EGLDisplaySurface::~EGLDisplaySurface()
-{
-    magic = 0;
-    copybit_close(mBlitEngine);
-    mBlitEngine = 0;
-    close(egl_native_window_t::fd);
-    munmap(mFb[0].data, mSize);
-    if (!(mFlags & PAGE_FLIP))
-        free((void*)mFb[1].data);
-}
-
-void EGLDisplaySurface::hook_incRef(NativeWindowType window) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    that->incStrong(that);
-}
-void EGLDisplaySurface::hook_decRef(NativeWindowType window) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    that->decStrong(that);
-}
-uint32_t EGLDisplaySurface::hook_swapBuffers(NativeWindowType window) {
-    EGLDisplaySurface* that = static_cast<EGLDisplaySurface*>(window);
-    return that->swapBuffers();
-}
-
-void EGLDisplaySurface::setSwapRectangle(int l, int t, int w, int h)
-{
-    mInfo.reserved[0] = 0x54445055; // "UPDT";
-    mInfo.reserved[1] = (uint16_t)l | ((uint32_t)t << 16);
-    mInfo.reserved[2] = (uint16_t)(l+w) | ((uint32_t)(t+h) << 16);
-}
-
-uint32_t EGLDisplaySurface::swapBuffers()
-{
-#define SHOW_FPS 0
-#if SHOW_FPS
-    nsecs_t now = systemTime();
-    if (mSwapCount == -1) {
-        mTime = now;
-        mSwapCount = 0;
-        mSleep = 0;
-    } else {
-        nsecs_t d = now-mTime;
-        if (d >= seconds(1)) {
-            double fps = (mSwapCount * double(seconds(1))) / double(d);
-            LOGD("%f fps, sleep=%d / frame",
-                    fps, (int)ns2us(mSleep / mSwapCount));
-            mSwapCount = 0;
-            mTime = now;
-            mSleep = 0;
-        } else {
-            mSwapCount++;
-        }
-    }
-#endif
-    /* If we can't do the page_flip, just copy the back buffer to the front */
-    if (!(mFlags & PAGE_FLIP)) {
-        memcpy(mFb[0].data, mFb[1].data, mInfo.xres*mInfo.yres*2);
-        return 0;
-    }
-
-    // do the actual flip
-    mIndex = 1 - mIndex;
-    mInfo.activate = FB_ACTIVATE_VBL;
-    mInfo.yoffset = mIndex ? mInfo.yres : 0;
-    if (ioctl(egl_native_window_t::fd, FBIOPUT_VSCREENINFO, &mInfo) == -1) {
-        LOGE("FBIOPUT_VSCREENINFO failed");
-        return 0;
-    }
-
-    /*
-     * this is a monstrous hack: Because the h/w accelerator is not able
-     * to render directly into the framebuffer, we need to copy its
-     * internal framebuffer out to the fb.
-     * oem[0] is used to access the fd of internal fb.
-     * All this is needed only in standalone mode, in SurfaceFlinger mode
-     * we control where the GPU renders.
-     * We do this only if we have copybit, since this hack is needed only
-     * with msm7k.
-     */
-    if (egl_native_window_t::memory_type == NATIVE_MEMORY_TYPE_GPU && oem[0] && mBlitEngine) {
-        copybit_device_t *copybit = mBlitEngine;
-        copybit_rect_t sdrect = { 0, 0,
-                egl_native_window_t::width, egl_native_window_t::height };
-        copybit_image_t dst = {
-                egl_native_window_t::width,
-                egl_native_window_t::height,
-                egl_native_window_t::format,
-                egl_native_window_t::offset,
-                (void*)egl_native_window_t::base,
-                egl_native_window_t::fd
-        };
-        copybit_image_t src = {
-                egl_native_window_t::width,
-                egl_native_window_t::height,
-                egl_native_window_t::format, // XXX: use proper format
-                egl_native_window_t::offset,
-                (void*)egl_native_window_t::base,  // XXX: use proper base
-                egl_native_window_t::oem[0]
-        };
-        region_iterator it(Region(Rect(
-                egl_native_window_t::width, egl_native_window_t::height)));
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-        copybit->stretch(copybit, &dst, &src, &sdrect, &sdrect, &it);
-    }
-
-    // update the address of the buffer to draw to next
-    const GGLSurface& buffer = mFb[1 - mIndex];
-    egl_native_window_t::offset =
-        intptr_t(buffer.data) - egl_native_window_t::base;
-
-#if SHOW_FPS
-    mSleep += systemTime()-now;
-#endif
-
-    mPageFlipCount++;
-
-    // We don't support screen-size changes for now
-    return 0;
-}
-
-int32_t EGLDisplaySurface::getPageFlipCount() const
-{
-    return mPageFlipCount;
-}
-
-void EGLDisplaySurface::copyFrontToBack(const Region& copyback)
-{
-#if HAVE_ANDROID_OS
-    if (mBlitEngine) {
-        copybit_image_t dst = {
-                w:      egl_native_window_t::stride,
-                h:      egl_native_window_t::height,
-                format: egl_native_window_t::format,
-                offset: mFb[1-mIndex].data - mFb[0].data,
-                base:   (void*)egl_native_window_t::base,
-                fd:     egl_native_window_t::fd
-        };
-        copybit_image_t src = {
-                w:      egl_native_window_t::stride,
-                h:      egl_native_window_t::height,
-                format: egl_native_window_t::format,
-                offset: mFb[mIndex].data - mFb[0].data,
-                base:   (void*)egl_native_window_t::base,
-                fd:     egl_native_window_t::fd
-        };
-        region_iterator it(copyback);
-        mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
-    } else
-#endif
-    {
-        /* no extra copy needed since we copied back to front instead of
-         * flipping */
-        if (!(mFlags & PAGE_FLIP)) {
-            return;
-        }
-
-        Region::iterator iterator(copyback);
-        if (iterator) {
-            Rect r;
-            uint8_t* const screen_src = mFb[  mIndex].data;
-            uint8_t* const screen_dst = mFb[1-mIndex].data;
-            const size_t bpp = bytesPerPixel(egl_native_window_t::format);
-            const size_t bpr = egl_native_window_t::stride * bpp;
-            while (iterator.iterate(&r)) {
-                ssize_t h = r.bottom - r.top;
-                if (h) {
-                    size_t size = (r.right - r.left) * bpp;
-                    size_t o = (r.left + egl_native_window_t::stride * r.top) * bpp;
-                    uint8_t* s = screen_src + o;
-                    uint8_t* d = screen_dst + o;
-                    if (size == bpr) {
-                        size *= h;
-                        h = 1;
-                    }
-                    do {
-                        memcpy(d, s, size);
-                        d += bpr;
-                        s += bpr;
-                    } while (--h > 0);
-                }
-            }
-        }
-    }
-}
-
-void EGLDisplaySurface::copyFrontToImage(const copybit_image_t& dst)
-{
-#if HAVE_ANDROID_OS
-    if (mBlitEngine) {
-        copybit_image_t src = {
-                w:      egl_native_window_t::stride,
-                h:      egl_native_window_t::height,
-                format: egl_native_window_t::format,
-                offset: mFb[mIndex].data - mFb[0].data,
-                base:   (void*)egl_native_window_t::base,
-                fd:     egl_native_window_t::fd
-        };
-        region_iterator it(Region(Rect(
-                egl_native_window_t::width, egl_native_window_t::height)));
-        mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
-    } else
-#endif
-    {
-        uint8_t* const screen_src = mFb[  mIndex].data;
-        const size_t bpp = bytesPerPixel(egl_native_window_t::format);
-        const size_t bpr = egl_native_window_t::stride * bpp;
-        memcpy((char*)dst.base + dst.offset, screen_src,
-                bpr*egl_native_window_t::height);
-    }
-}
-
-void EGLDisplaySurface::copyBackToImage(const copybit_image_t& dst)
-{
-#if HAVE_ANDROID_OS
-    if (mBlitEngine) {
-        copybit_image_t src = {
-                w:      egl_native_window_t::stride,
-                h:      egl_native_window_t::height,
-                format: egl_native_window_t::format,
-                offset: mFb[1-mIndex].data - mFb[0].data,
-                base:   (void*)egl_native_window_t::base,
-                fd:     egl_native_window_t::fd
-        };
-        region_iterator it(Region(Rect(
-                egl_native_window_t::width, egl_native_window_t::height)));
-        mBlitEngine->blit(mBlitEngine, &dst, &src, &it);
-    } else
-#endif
-    {
-        uint8_t* const screen_src = mFb[1-mIndex].data;
-        const size_t bpp = bytesPerPixel(egl_native_window_t::format);
-        const size_t bpr = egl_native_window_t::stride * bpp;
-        memcpy((char*)dst.base + dst.offset, screen_src,
-                bpr*egl_native_window_t::height);
-    }
-}
-
-
-status_t EGLDisplaySurface::mapFrameBuffer()
-{
-    char const * const device_template[] = {
-            "/dev/graphics/fb%u",
-            "/dev/fb%u",
-            0 };
-    int fd = -1;
-    int i=0;
-    char name[64];
-    while ((fd==-1) && device_template[i]) {
-        snprintf(name, 64, device_template[i], 0);
-        fd = open(name, O_RDWR, 0);
-        i++;
-    }
-    if (fd < 0)
-        return -errno;
-
-    struct fb_fix_screeninfo finfo;
-    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
-        return -errno;
-
-    struct fb_var_screeninfo info;
-    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
-        return -errno;
-
-    info.reserved[0] = 0;
-    info.reserved[1] = 0;
-    info.reserved[2] = 0;
-    info.xoffset = 0;
-    info.yoffset = 0;
-    info.yres_virtual = info.yres * 2;
-    info.bits_per_pixel = 16;
-    /* Explicitly request 5/6/5 */
-    info.red.offset = 11;
-    info.red.length = 5;
-    info.green.offset = 5;
-    info.green.length = 6;
-    info.blue.offset = 0;
-    info.blue.length = 5;
-    info.transp.offset = 0;
-    info.transp.length = 0;
-    info.activate = FB_ACTIVATE_NOW;
-
-    uint32_t flags = PAGE_FLIP;
-    if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
-        info.yres_virtual = info.yres;
-        flags &= ~PAGE_FLIP;
-        LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
-    }
-
-    if (info.yres_virtual < info.yres * 2) {
-        info.yres_virtual = info.yres;
-        flags &= ~PAGE_FLIP;
-        LOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
-                info.yres_virtual, info.yres*2);
-    }
-
-    if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
-        return -errno;
-
-    int refreshRate = 1000000000000000LLU /
-    (
-            uint64_t( info.upper_margin + info.lower_margin + info.yres )
-            * ( info.left_margin  + info.right_margin + info.xres )
-            * info.pixclock
-    );
-
-    if (refreshRate == 0) {
-        // bleagh, bad info from the driver
-        refreshRate = 60*1000;  // 60 Hz
-    }
-    if (int(info.width) <= 0 || int(info.height) <= 0) {
-        // the driver doesn't return that information
-        // default to 160 dpi
-        info.width  = ((info.xres * 25.4f)/160.0f + 0.5f);
-        info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
-    }
-
-    float xdpi = (info.xres * 25.4f) / info.width;
-    float ydpi = (info.yres * 25.4f) / info.height;
-    float fps  = refreshRate / 1000.0f;
-
-    LOGI(   "using (fd=%d)\n"
-            "id           = %s\n"
-            "xres         = %d px\n"
-            "yres         = %d px\n"
-            "xres_virtual = %d px\n"
-            "yres_virtual = %d px\n"
-            "bpp          = %d\n"
-            "r            = %2u:%u\n"
-            "g            = %2u:%u\n"
-            "b            = %2u:%u\n",
-            fd,
-            finfo.id,
-            info.xres,
-            info.yres,
-            info.xres_virtual,
-            info.yres_virtual,
-            info.bits_per_pixel,
-            info.red.offset, info.red.length,
-            info.green.offset, info.green.length,
-            info.blue.offset, info.blue.length
-    );
-
-    LOGI(   "width        = %d mm (%f dpi)\n"
-            "height       = %d mm (%f dpi)\n"
-            "refresh rate = %.2f Hz\n",
-            info.width,  xdpi,
-            info.height, ydpi,
-            fps
-    );
-
-
-    if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
-        return -errno;
-
-    if (finfo.smem_len <= 0)
-        return -errno;
-
-    /*
-     * Open and map the display.
-     */
-
-    void* buffer  = (uint16_t*) mmap(
-            0, finfo.smem_len,
-            PROT_READ | PROT_WRITE,
-            MAP_SHARED,
-            fd, 0);
-
-    if (buffer == MAP_FAILED)
-        return -errno;
-
-    // at least for now, always clear the fb
-    memset(buffer, 0, finfo.smem_len);
-
-    uint8_t* offscreen[2];
-    offscreen[0] = (uint8_t*)buffer;
-    if (flags & PAGE_FLIP) {
-        offscreen[1] = (uint8_t*)buffer + finfo.line_length*info.yres;
-    } else {
-        offscreen[1] = (uint8_t*)malloc(finfo.smem_len);
-        if (offscreen[1] == 0) {
-            munmap(buffer, finfo.smem_len);
-            return NO_MEMORY;
-        }
-    }
-
-    mFlags = flags;
-    mInfo = info;
-    mFinfo = finfo;
-    mSize = finfo.smem_len;
-    mIndex = 0;
-    for (int i=0 ; i<2 ; i++) {
-        mFb[i].version = sizeof(GGLSurface);
-        mFb[i].width   = info.xres;
-        mFb[i].height  = info.yres;
-        mFb[i].stride  = finfo.line_length / (info.bits_per_pixel >> 3);
-        mFb[i].data    = (GGLubyte*)(offscreen[i]);
-        mFb[i].format  = GGL_PIXEL_FORMAT_RGB_565;
-    }
-    return fd;
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
diff --git a/libs/ui/EGLNativeWindowSurface.cpp b/libs/ui/EGLNativeWindowSurface.cpp
deleted file mode 100644
index f1071cf..0000000
--- a/libs/ui/EGLNativeWindowSurface.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/* 
-**
-** Copyright 2007 The Android Open Source Project
-**
-** Licensed under the Apache License Version 2.0(the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing software 
-** distributed under the License is distributed on an "AS IS" BASIS 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
-
-#define LOG_TAG "EGLNativeWindowSurface"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-
-#include <ui/SurfaceComposerClient.h>
-#include <ui/DisplayInfo.h>
-#include <ui/Rect.h>
-
-#include <EGL/egl.h>
-
-#include <pixelflinger/format.h>
-
-#include <ui/EGLNativeWindowSurface.h>
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-EGLNativeWindowSurface::EGLNativeWindowSurface(const sp<Surface>& surface)
-    : EGLNativeSurface<EGLNativeWindowSurface>(),
-    mSurface(surface), mConnected(false)
-{
-    egl_native_window_t::magic = 0x600913;
-    egl_native_window_t::version = sizeof(egl_native_window_t);
-    egl_native_window_t::ident = 0;
-    egl_native_window_t::incRef = &EGLNativeWindowSurface::hook_incRef;
-    egl_native_window_t::decRef = &EGLNativeWindowSurface::hook_decRef;
-    egl_native_window_t::swapBuffers = &EGLNativeWindowSurface::hook_swapBuffers;
-    egl_native_window_t::connect = &EGLNativeWindowSurface::hook_connect;
-    egl_native_window_t::disconnect = &EGLNativeWindowSurface::hook_disconnect;
-    
-    DisplayInfo dinfo;
-    SurfaceComposerClient::getDisplayInfo(0, &dinfo);
-    egl_native_window_t::xdpi = dinfo.xdpi;
-    egl_native_window_t::ydpi = dinfo.ydpi;
-    egl_native_window_t::fps  = dinfo.fps;
-    egl_native_window_t::flags= EGL_NATIVES_FLAG_DESTROY_BACKBUFFER;
-}
-
-EGLNativeWindowSurface::~EGLNativeWindowSurface()
-{
-    disconnect();
-    mSurface.clear();
-    magic = 0;
-}
-
-void EGLNativeWindowSurface::hook_incRef(NativeWindowType window)
-{
-    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
-    that->incStrong(that);
-}
-
-void EGLNativeWindowSurface::hook_decRef(NativeWindowType window)
-{
-    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
-    that->decStrong(that);
-}
-
-void EGLNativeWindowSurface::hook_connect(NativeWindowType window)
-{
-    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
-    that->connect();
-}
-
-void EGLNativeWindowSurface::hook_disconnect(NativeWindowType window)
-{
-    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
-    that->disconnect();
-}
-
-uint32_t EGLNativeWindowSurface::hook_swapBuffers(NativeWindowType window)
-{
-    EGLNativeWindowSurface* that = static_cast<EGLNativeWindowSurface*>(window);
-    return that->swapBuffers();
-}
-
-void EGLNativeWindowSurface::setSwapRectangle(int l, int t, int w, int h)
-{
-    mSurface->setSwapRectangle(Rect(l, t, l+w, t+h));
-}
-
-uint32_t EGLNativeWindowSurface::swapBuffers()
-{
-    const int w = egl_native_window_t::width;
-    const int h = egl_native_window_t::height;
-    const sp<Surface>& surface(mSurface);
-    Surface::SurfaceInfo info;
-    surface->unlockAndPost();
-    surface->lock(&info);
-    // update the address of the buffer to draw to next
-    egl_native_window_t::base   = intptr_t(info.base);
-    egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
-    
-    // update size if it changed
-    if (w != int(info.w) || h != int(info.h)) {
-        egl_native_window_t::width  = info.w;
-        egl_native_window_t::height = info.h;
-        egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
-        egl_native_window_t::format = info.format;
-        return EGL_NATIVES_FLAG_SIZE_CHANGED;
-    }
-    return 0;
-}
-
-void EGLNativeWindowSurface::connect()
-{   
-    if (!mConnected) {
-        Surface::SurfaceInfo info;
-        mSurface->lock(&info);
-        mSurface->setSwapRectangle(Rect(info.w, info.h));
-        mConnected = true;
-
-        egl_native_window_t::width  = info.w;
-        egl_native_window_t::height = info.h;
-        egl_native_window_t::stride = info.bpr / bytesPerPixel(info.format);
-        egl_native_window_t::format = info.format;
-        egl_native_window_t::base   = intptr_t(info.base);
-        egl_native_window_t::offset = intptr_t(info.bits) - intptr_t(info.base);
-        // FIXME: egl_native_window_t::memory_type used to be set from
-        // mSurface, but we wanted to break this dependency. We set it to
-        // GPU because the software rendered doesn't care, but the h/w
-        // accelerator needs it. Eventually, this value should go away
-        // completely, since memory will be managed by OpenGL.
-        egl_native_window_t::memory_type = NATIVE_MEMORY_TYPE_GPU; 
-        egl_native_window_t::fd = 0;
-    }
-}
-
-void EGLNativeWindowSurface::disconnect()
-{
-    if (mConnected) {
-        mSurface->unlock();
-        mConnected = false;
-    }
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index 7c2fc8e..13c30a7 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -19,10 +19,11 @@
 #include <hardware_legacy/power.h>
 
 #include <cutils/properties.h>
-#include <utils/IServiceManager.h>
 #include <utils/Log.h>
 #include <utils/Timers.h>
-#include <utils.h>
+#include <utils/threads.h>
+#include <utils/List.h>
+#include <utils/Errors.h>
 
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
new file mode 100644
index 0000000..8c8fd6b
--- /dev/null
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -0,0 +1,210 @@
+/* 
+**
+** Copyright 2007 The Android Open Source Project
+**
+** Licensed under the Apache License Version 2.0(the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing software 
+** distributed under the License is distributed on an "AS IS" BASIS 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#define LOG_TAG "FramebufferNativeWindow"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+#include <utils/threads.h>
+
+#include <ui/SurfaceComposerClient.h>
+#include <ui/Rect.h>
+#include <ui/FramebufferNativeWindow.h>
+
+#include <EGL/egl.h>
+
+#include <pixelflinger/format.h>
+#include <pixelflinger/pixelflinger.h>
+
+#include <hardware/hardware.h>
+#include <hardware/gralloc.h>
+
+#include <private/ui/android_natives_priv.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class NativeBuffer 
+    : public EGLNativeBase<
+        android_native_buffer_t, 
+        NativeBuffer, 
+        LightRefBase<NativeBuffer> >
+{
+public:
+    NativeBuffer(int w, int h, int f, int u) : BASE() {
+        android_native_buffer_t::width  = w;
+        android_native_buffer_t::height = h;
+        android_native_buffer_t::format = f;
+        android_native_buffer_t::usage  = u;
+    }
+private:
+    friend class LightRefBase<NativeBuffer>;    
+    ~NativeBuffer() { }; // this class cannot be overloaded
+};
+
+
+/*
+ * This implements the (main) framebuffer management. This class is used
+ * mostly by SurfaceFlinger, but also by command line GL application.
+ * 
+ * In fact this is an implementation of android_native_window_t on top of
+ * the framebuffer.
+ * 
+ * Currently it is pretty simple, it manages only two buffers (the front and 
+ * back buffer).
+ * 
+ */
+
+FramebufferNativeWindow::FramebufferNativeWindow() 
+    : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false)
+{
+    hw_module_t const* module;
+    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
+        int stride;
+        framebuffer_open(module, &fbDev);
+        gralloc_open(module, &grDev);
+        int err;
+
+        
+        mUpdateOnDemand = (fbDev->setUpdateRect != 0);
+        
+        // initialize the buffer FIFO
+        mNumBuffers = 2;
+        mNumFreeBuffers = 2;
+        mBufferHead = mNumBuffers-1;
+        buffers[0] = new NativeBuffer(
+                fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
+        buffers[1] = new NativeBuffer(
+                fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
+        
+        err = grDev->alloc(grDev,
+                fbDev->width, fbDev->height, fbDev->format, 
+                GRALLOC_USAGE_HW_FB, &buffers[0]->handle, &buffers[0]->stride);
+
+        LOGE_IF(err, "fb buffer 0 allocation failed w=%d, h=%d, err=%s",
+                fbDev->width, fbDev->height, strerror(-err));
+
+        err = grDev->alloc(grDev,
+                fbDev->width, fbDev->height, fbDev->format, 
+                GRALLOC_USAGE_HW_FB, &buffers[1]->handle, &buffers[1]->stride);
+
+        LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s",
+                fbDev->width, fbDev->height, strerror(-err));
+    }
+
+    const_cast<uint32_t&>(android_native_window_t::flags) = fbDev->flags; 
+    const_cast<float&>(android_native_window_t::xdpi) = fbDev->xdpi;
+    const_cast<float&>(android_native_window_t::ydpi) = fbDev->ydpi;
+    const_cast<int&>(android_native_window_t::minSwapInterval) = 
+        fbDev->minSwapInterval;
+    const_cast<int&>(android_native_window_t::maxSwapInterval) = 
+        fbDev->maxSwapInterval;
+
+    android_native_window_t::setSwapInterval = setSwapInterval;
+    android_native_window_t::dequeueBuffer = dequeueBuffer;
+    android_native_window_t::lockBuffer = lockBuffer;
+    android_native_window_t::queueBuffer = queueBuffer;
+}
+
+FramebufferNativeWindow::~FramebufferNativeWindow() {
+    grDev->free(grDev, buffers[0]->handle);
+    grDev->free(grDev, buffers[1]->handle);
+    gralloc_close(grDev);
+    framebuffer_close(fbDev);
+}
+
+status_t FramebufferNativeWindow::setUpdateRectangle(const Rect& r) 
+{
+    if (!mUpdateOnDemand) {
+        return INVALID_OPERATION;
+    }
+    return fbDev->setUpdateRect(fbDev, r.left, r.top, r.width(), r.height());
+}
+
+int FramebufferNativeWindow::setSwapInterval(
+        android_native_window_t* window, int interval) 
+{
+    framebuffer_device_t* fb = getSelf(window)->fbDev;
+    return fb->setSwapInterval(fb, interval);
+}
+
+int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, 
+        android_native_buffer_t** buffer)
+{
+    FramebufferNativeWindow* self = getSelf(window);
+    Mutex::Autolock _l(self->mutex);
+    framebuffer_device_t* fb = self->fbDev;
+
+    // wait for a free buffer
+    while (!self->mNumFreeBuffers) {
+        self->mCondition.wait(self->mutex);
+    }
+    // get this buffer
+    self->mNumFreeBuffers--;
+    int index = self->mBufferHead++;
+    if (self->mBufferHead >= self->mNumBuffers)
+        self->mBufferHead = 0;
+
+    *buffer = self->buffers[index].get();
+
+    return 0;
+}
+
+int FramebufferNativeWindow::lockBuffer(android_native_window_t* window, 
+        android_native_buffer_t* buffer)
+{
+    FramebufferNativeWindow* self = getSelf(window);
+    Mutex::Autolock _l(self->mutex);
+
+    // wait that the buffer we're locking is not front anymore
+    while (self->front == buffer) {
+        self->mCondition.wait(self->mutex);
+    }
+
+    return NO_ERROR;
+}
+
+int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, 
+        android_native_buffer_t* buffer)
+{
+    FramebufferNativeWindow* self = getSelf(window);
+    Mutex::Autolock _l(self->mutex);
+    framebuffer_device_t* fb = self->fbDev;
+    buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle;
+    int res = fb->post(fb, handle);
+    self->front = static_cast<NativeBuffer*>(buffer);
+    self->mNumFreeBuffers++;
+    self->mCondition.broadcast();
+    return res;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+
+EGLNativeWindowType android_createDisplaySurface(void)
+{
+    return new android::FramebufferNativeWindow();
+}
+
diff --git a/libs/ui/ICamera.cpp b/libs/ui/ICamera.cpp
index ab0fef1..805c2ca 100644
--- a/libs/ui/ICamera.cpp
+++ b/libs/ui/ICamera.cpp
@@ -20,7 +20,7 @@
 #include <utils/Log.h>
 #include <stdint.h>
 #include <sys/types.h>
-#include <utils/Parcel.h>
+#include <binder/Parcel.h>
 #include <ui/ICamera.h>
 
 namespace android {
@@ -221,12 +221,6 @@
 
 // ----------------------------------------------------------------------
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t BnCamera::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/libs/ui/ICameraClient.cpp b/libs/ui/ICameraClient.cpp
index 59a6cf2..42b4da4 100644
--- a/libs/ui/ICameraClient.cpp
+++ b/libs/ui/ICameraClient.cpp
@@ -78,12 +78,6 @@
 
 // ----------------------------------------------------------------------
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t BnCameraClient::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/libs/ui/ICameraService.cpp b/libs/ui/ICameraService.cpp
index e5687fe..84986c6 100644
--- a/libs/ui/ICameraService.cpp
+++ b/libs/ui/ICameraService.cpp
@@ -18,9 +18,9 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/Parcel.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
 
 #include <ui/ICameraService.h>
 
@@ -49,12 +49,6 @@
 
 // ----------------------------------------------------------------------
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t BnCameraService::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/libs/ui/IOverlay.cpp b/libs/ui/IOverlay.cpp
index fed47c2..65e6b4f 100644
--- a/libs/ui/IOverlay.cpp
+++ b/libs/ui/IOverlay.cpp
@@ -18,8 +18,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/Parcel.h>
-#include <utils/IInterface.h>
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
 
 #include <ui/IOverlay.h>
 
@@ -49,12 +49,6 @@
 
 // ----------------------------------------------------------------------
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t BnOverlay::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
diff --git a/libs/ui/ISurface.cpp b/libs/ui/ISurface.cpp
index d5e9f81..9fbae1e 100644
--- a/libs/ui/ISurface.cpp
+++ b/libs/ui/ISurface.cpp
@@ -14,19 +14,25 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "ISurface"
+
 #include <stdio.h>
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/Parcel.h>
-#include <utils/IMemory.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
 
 #include <ui/ISurface.h>
 #include <ui/Overlay.h>
+#include <ui/Surface.h>
 
+#include <private/ui/SurfaceBuffer.h>
 
 namespace android {
 
+// ----------------------------------------------------------------------
+
 ISurface::BufferHeap::BufferHeap() 
     : w(0), h(0), hor_stride(0), ver_stride(0), format(0),
     transform(0), flags(0) 
@@ -55,6 +61,8 @@
 {     
 }
 
+// ----------------------------------------------------------------------
+
 class BpSurface : public BpInterface<ISurface>
 {
 public:
@@ -63,6 +71,15 @@
     {
     }
 
+    virtual sp<SurfaceBuffer> getBuffer()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        remote()->transact(GET_BUFFER, data, &reply);
+        sp<SurfaceBuffer> buffer = new SurfaceBuffer(reply);
+        return buffer;
+    }
+
     virtual status_t registerBuffers(const BufferHeap& buffers)
     {
         Parcel data, reply;
@@ -112,16 +129,15 @@
 
 // ----------------------------------------------------------------------
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t BnSurface::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
     switch(code) {
+        case GET_BUFFER: {
+            CHECK_INTERFACE(ISurface, data, reply);
+            sp<SurfaceBuffer> buffer(getBuffer());
+            return SurfaceBuffer::writeToParcel(reply, buffer.get());
+        }
         case REGISTER_BUFFERS: {
             CHECK_INTERFACE(ISurface, data, reply);
             BufferHeap buffer;
diff --git a/libs/ui/ISurfaceComposer.cpp b/libs/ui/ISurfaceComposer.cpp
index 76597e1..fd2a590 100644
--- a/libs/ui/ISurfaceComposer.cpp
+++ b/libs/ui/ISurfaceComposer.cpp
@@ -20,10 +20,10 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/Parcel.h>
-#include <utils/IMemory.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
 
 #include <ui/ISurfaceComposer.h>
 #include <ui/DisplayInfo.h>
@@ -54,12 +54,12 @@
         return interface_cast<ISurfaceFlingerClient>(reply.readStrongBinder());
     }
 
-    virtual sp<IMemory> getCblk() const
+    virtual sp<IMemoryHeap> getCblk() const
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         remote()->transact(BnSurfaceComposer::GET_CBLK, data, &reply);
-        return interface_cast<IMemory>(reply.readStrongBinder());
+        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
     }
 
     virtual void openGlobalTransaction()
@@ -114,36 +114,6 @@
         remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
     }
 
-    virtual status_t requestGPU(
-            const sp<IGPUCallback>& callback, gpu_info_t* gpu)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        data.writeStrongBinder(callback->asBinder());
-        remote()->transact(BnSurfaceComposer::REQUEST_GPU, data, &reply);
-        gpu->regs = interface_cast<IMemory>(reply.readStrongBinder());
-        gpu->count = reply.readInt32();
-
-        // FIXME: for now, we don't dynamically allocate the regions array
-        size_t maxCount = sizeof(gpu->regions)/sizeof(*gpu->regions);
-        if (gpu->count > maxCount)
-            return BAD_VALUE;
-
-        for (size_t i=0 ; i<gpu->count ; i++) {
-            gpu->regions[i].region = interface_cast<IMemory>(reply.readStrongBinder());
-            gpu->regions[i].reserved = reply.readInt32();
-        }
-        return reply.readInt32();
-    }
-
-    virtual status_t revokeGPU()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
-        remote()->transact(BnSurfaceComposer::REVOKE_GPU, data, &reply);
-        return reply.readInt32();
-    }
-
     virtual void signal() const
     {
         Parcel data, reply;
@@ -156,124 +126,61 @@
 
 // ----------------------------------------------------------------------
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t BnSurfaceComposer::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
-    status_t err = BnInterface<ISurfaceComposer>::onTransact(code, data, reply, flags);
-    if (err == NO_ERROR)
-        return err;
-
-    CHECK_INTERFACE(ISurfaceComposer, data, reply);
-
     switch(code) {
         case CREATE_CONNECTION: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> b = createConnection()->asBinder();
             reply->writeStrongBinder(b);
         } break;
         case OPEN_GLOBAL_TRANSACTION: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
             openGlobalTransaction();
         } break;
         case CLOSE_GLOBAL_TRANSACTION: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
             closeGlobalTransaction();
         } break;
         case SET_ORIENTATION: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
             DisplayID dpy = data.readInt32();
             int orientation = data.readInt32();
             uint32_t flags = data.readInt32();
             reply->writeInt32( setOrientation(dpy, orientation, flags) );
         } break;
         case FREEZE_DISPLAY: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
             DisplayID dpy = data.readInt32();
             uint32_t flags = data.readInt32();
             reply->writeInt32( freezeDisplay(dpy, flags) );
         } break;
         case UNFREEZE_DISPLAY: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
             DisplayID dpy = data.readInt32();
             uint32_t flags = data.readInt32();
             reply->writeInt32( unfreezeDisplay(dpy, flags) );
         } break;
         case BOOT_FINISHED: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
             bootFinished();
         } break;
-        case REVOKE_GPU: {
-            reply->writeInt32( revokeGPU() );
-        } break;
         case SIGNAL: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
             signal();
         } break;
         case GET_CBLK: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> b = getCblk()->asBinder();
             reply->writeStrongBinder(b);
         } break;
-        case REQUEST_GPU: {
-            // TODO: this should be protected by a permission
-            gpu_info_t info;
-            sp<IGPUCallback> callback
-                = interface_cast<IGPUCallback>(data.readStrongBinder());
-            status_t res = requestGPU(callback, &info);
-
-            // FIXME: for now, we don't dynamically allocate the regions array
-            size_t maxCount = sizeof(info.regions)/sizeof(*info.regions);
-            if (info.count > maxCount)
-                return BAD_VALUE;
-
-            reply->writeStrongBinder(info.regs->asBinder());
-            reply->writeInt32(info.count);
-            for (size_t i=0 ; i<info.count ; i++) {
-                reply->writeStrongBinder(info.regions[i].region->asBinder());
-                reply->writeInt32(info.regions[i].reserved);
-            }
-            reply->writeInt32(res);
-        } break;
         default:
-            return UNKNOWN_TRANSACTION;
+            return BBinder::onTransact(code, data, reply, flags);
     }
     return NO_ERROR;
 }
 
 // ----------------------------------------------------------------------------
 
-enum {
-    // Note: BOOT_FINISHED must remain this value, it is called by ActivityManagerService.
-    GPU_LOST = IBinder::FIRST_CALL_TRANSACTION
-};
-
-class BpGPUCallback : public BpInterface<IGPUCallback>
-{
-public:
-    BpGPUCallback(const sp<IBinder>& impl)
-        : BpInterface<IGPUCallback>(impl)
-    {
-    }
-
-    virtual void gpuLost()
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IGPUCallback::getInterfaceDescriptor());
-        remote()->transact(GPU_LOST, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-};
-
-IMPLEMENT_META_INTERFACE(GPUCallback, "android.ui.IGPUCallback");
-
-status_t BnGPUCallback::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case GPU_LOST: {
-            CHECK_INTERFACE(IGPUCallback, data, reply);
-            gpuLost();
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
 };
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp
index dab5f71..51e8422 100644
--- a/libs/ui/ISurfaceFlingerClient.cpp
+++ b/libs/ui/ISurfaceFlingerClient.cpp
@@ -21,10 +21,10 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <utils/Parcel.h>
-#include <utils/IMemory.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
 
 #include <ui/ISurface.h>
 #include <ui/ISurfaceFlingerClient.h>
@@ -64,12 +64,12 @@
     {
     }
 
-    virtual void getControlBlocks(sp<IMemory>* ctl) const
+    virtual sp<IMemoryHeap> getControlBlock() const
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
         remote()->transact(GET_CBLK, data, &reply);
-        *ctl  = interface_cast<IMemory>(reply.readStrongBinder());
+        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
     }
 
     virtual sp<ISurface> createSurface( surface_data_t* params,
@@ -118,12 +118,6 @@
 
 // ----------------------------------------------------------------------
 
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
 status_t BnSurfaceFlingerClient::onTransact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
 {
@@ -132,8 +126,7 @@
     switch(code) {
         case GET_CBLK: {
             CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            sp<IMemory> ctl;
-            getControlBlocks(&ctl);
+            sp<IMemoryHeap> ctl(getControlBlock());
             reply->writeStrongBinder(ctl->asBinder());
             return NO_ERROR;
         } break;
@@ -198,8 +191,6 @@
 {
     token = parcel.readInt32();
     identity  = parcel.readInt32();
-    heap[0] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
-    heap[1] = interface_cast<IMemoryHeap>(parcel.readStrongBinder());
     return NO_ERROR;
 }
 
@@ -207,8 +198,6 @@
 {
     parcel->writeInt32(token);
     parcel->writeInt32(identity);
-    parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder() : NULL);
-    parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder() : NULL);
     return NO_ERROR;
 }
 
diff --git a/libs/ui/LayerState.cpp b/libs/ui/LayerState.cpp
index 0b6374b..a53ffb7 100644
--- a/libs/ui/LayerState.cpp
+++ b/libs/ui/LayerState.cpp
@@ -15,7 +15,7 @@
  */
 
 #include <utils/Errors.h>
-#include <utils/Parcel.h>
+#include <binder/Parcel.h>
 #include <private/ui/LayerState.h>
 
 namespace android {
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
index 59c6514..a092f8d 100644
--- a/libs/ui/Overlay.cpp
+++ b/libs/ui/Overlay.cpp
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#include <utils/IMemory.h>
-#include <utils/Parcel.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
 #include <utils/Errors.h>
-#include <utils/MemoryHeapBase.h>
+#include <binder/MemoryHeapBase.h>
 
 #include <ui/IOverlay.h>
 #include <ui/Overlay.h>
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 26e694a..d21ed57 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -16,295 +16,661 @@
 
 #define LOG_TAG "Region"
 
-#include <stdio.h>
-#include <utils/Atomic.h>
-#include <utils/Debug.h>
+#include <limits.h>
+
+#include <utils/Log.h>
 #include <utils/String8.h>
+
+#include <ui/Rect.h>
 #include <ui/Region.h>
+#include <ui/Point.h>
+
+#include <private/ui/RegionHelper.h>
+
+// ----------------------------------------------------------------------------
+#define VALIDATE_REGIONS        (false)
+#define VALIDATE_WITH_CORECG    (false)
+// ----------------------------------------------------------------------------
+
+#if VALIDATE_WITH_CORECG
+#include <core/SkRegion.h>
+#endif
 
 namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+    op_nand = region_operator<Rect>::op_nand,
+    op_and  = region_operator<Rect>::op_and,
+    op_or   = region_operator<Rect>::op_or,
+    op_xor  = region_operator<Rect>::op_xor
+};
 
 // ----------------------------------------------------------------------------
 
 Region::Region()
+    : mBounds(0,0)
 {
 }
 
 Region::Region(const Region& rhs)
-    : mRegion(rhs.mRegion)
+    : mBounds(rhs.mBounds), mStorage(rhs.mStorage)
 {
 }
 
-Region::Region(const SkRegion& rhs)
-    : mRegion(rhs)
+Region::Region(const Rect& rhs)
+    : mBounds(rhs)
 {
 }
 
+Region::Region(const Parcel& parcel)
+{
+    status_t err = read(parcel);
+    LOGE_IF(err<0, "error %s reading Region from parcel", strerror(err));
+}
+
+Region::Region(const void* buffer)
+{
+    status_t err = read(buffer);
+    LOGE_IF(err<0, "error %s reading Region from parcel", strerror(err));
+}
+
 Region::~Region()
 {
 }
 
-Region::Region(const Rect& rhs)
-{
-    set(rhs);
-}
-
-Region::Region(const Parcel& parcel)
-{
-    read(parcel);
-}
-
-Region::Region(const void* buffer)
-{
-    read(buffer);
-}
-
 Region& Region::operator = (const Region& rhs)
 {
-    mRegion = rhs.mRegion;
+#if VALIDATE_REGIONS
+    validate(rhs, "operator=");
+#endif
+    mBounds = rhs.mBounds;
+    mStorage = rhs.mStorage;
     return *this;
 }
 
-const SkRegion& Region::toSkRegion() const
+Region& Region::makeBoundsSelf()
 {
-    return mRegion;
-}
-
-Rect Region::bounds() const
-{
-    const SkIRect& b(mRegion.getBounds());
-    return Rect(b.fLeft, b.fTop, b.fRight, b.fBottom);
+    mStorage.clear();
+    return *this;
 }
 
 void Region::clear()
 {
-    mRegion.setEmpty();
+    mBounds.clear();
+    mStorage.clear();
 }
 
 void Region::set(const Rect& r)
 {
-    SkIRect ir;
-    ir.set(r.left, r.top, r.right, r.bottom);
-    mRegion.setRect(ir);
+    mBounds = r;
+    mStorage.clear();
+}
+
+void Region::set(uint32_t w, uint32_t h)
+{
+    mBounds = Rect(int(w), int(h));
+    mStorage.clear();
 }
 
 // ----------------------------------------------------------------------------
 
-Region& Region::orSelf(const Rect& r)
+void Region::addRectUnchecked(int l, int t, int r, int b)
 {
-    SkIRect ir;
-    ir.set(r.left, r.top, r.right, r.bottom);
-    mRegion.op(ir, SkRegion::kUnion_Op);
-    return *this;
+    mStorage.add(Rect(l,t,r,b));
+#if VALIDATE_REGIONS
+    validate(*this, "addRectUnchecked");
+#endif
 }
 
-Region& Region::andSelf(const Rect& r)
-{
-    SkIRect ir;
-    ir.set(r.left, r.top, r.right, r.bottom);
-    mRegion.op(ir, SkRegion::kIntersect_Op);
+// ----------------------------------------------------------------------------
+
+Region& Region::orSelf(const Rect& r) {
+    return operationSelf(r, op_or);
+}
+Region& Region::andSelf(const Rect& r) {
+    return operationSelf(r, op_and);
+}
+Region& Region::subtractSelf(const Rect& r) {
+    return operationSelf(r, op_nand);
+}
+Region& Region::operationSelf(const Rect& r, int op) {
+    Region lhs(*this);
+    boolean_operation(op, *this, lhs, r);
     return *this;
 }
 
 // ----------------------------------------------------------------------------
 
 Region& Region::orSelf(const Region& rhs) {
-    mRegion.op(rhs.mRegion, SkRegion::kUnion_Op);
-    return *this;
+    return operationSelf(rhs, op_or);
 }
-
 Region& Region::andSelf(const Region& rhs) {
-    mRegion.op(rhs.mRegion, SkRegion::kIntersect_Op);
-    return *this;
+    return operationSelf(rhs, op_and);
 }
-
 Region& Region::subtractSelf(const Region& rhs) {
-    mRegion.op(rhs.mRegion, SkRegion::kDifference_Op);
+    return operationSelf(rhs, op_nand);
+}
+Region& Region::operationSelf(const Region& rhs, int op) {
+    Region lhs(*this);
+    boolean_operation(op, *this, lhs, rhs);
     return *this;
 }
 
 Region& Region::translateSelf(int x, int y) {
-    if (x|y) mRegion.translate(x, y);
+    if (x|y) translate(*this, x, y);
     return *this;
 }
 
-Region Region::merge(const Region& rhs) const {
+// ----------------------------------------------------------------------------
+
+const Region Region::merge(const Rect& rhs) const {
+    return operation(rhs, op_or);
+}
+const Region Region::intersect(const Rect& rhs) const {
+    return operation(rhs, op_and);
+}
+const Region Region::subtract(const Rect& rhs) const {
+    return operation(rhs, op_nand);
+}
+const Region Region::operation(const Rect& rhs, int op) const {
     Region result;
-    result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kUnion_Op);
+    boolean_operation(op, result, *this, rhs);
     return result;
 }
 
-Region Region::intersect(const Region& rhs) const {
+// ----------------------------------------------------------------------------
+
+const Region Region::merge(const Region& rhs) const {
+    return operation(rhs, op_or);
+}
+const Region Region::intersect(const Region& rhs) const {
+    return operation(rhs, op_and);
+}
+const Region Region::subtract(const Region& rhs) const {
+    return operation(rhs, op_nand);
+}
+const Region Region::operation(const Region& rhs, int op) const {
     Region result;
-    result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kIntersect_Op);
+    boolean_operation(op, result, *this, rhs);
     return result;
 }
 
-Region Region::subtract(const Region& rhs) const {
+const Region Region::translate(int x, int y) const {
     Region result;
-    result.mRegion.op(mRegion, rhs.mRegion, SkRegion::kDifference_Op);
-    return result;
-}
-
-Region Region::translate(int x, int y) const {
-    Region result;
-    mRegion.translate(x, y, &result.mRegion);
+    translate(result, *this, x, y);
     return result;
 }
 
 // ----------------------------------------------------------------------------
 
 Region& Region::orSelf(const Region& rhs, int dx, int dy) {
-    SkRegion r(rhs.mRegion);
-    r.translate(dx, dy);
-    mRegion.op(r, SkRegion::kUnion_Op);
-    return *this;
+    return operationSelf(rhs, dx, dy, op_or);
 }
-
 Region& Region::andSelf(const Region& rhs, int dx, int dy) {
-    SkRegion r(rhs.mRegion);
-    r.translate(dx, dy);
-    mRegion.op(r, SkRegion::kIntersect_Op);
-    return *this;
+    return operationSelf(rhs, dx, dy, op_and);
 }
-
 Region& Region::subtractSelf(const Region& rhs, int dx, int dy) {
-    SkRegion r(rhs.mRegion);
-    r.translate(dx, dy);
-    mRegion.op(r, SkRegion::kDifference_Op);
+    return operationSelf(rhs, dx, dy, op_nand);
+}
+Region& Region::operationSelf(const Region& rhs, int dx, int dy, int op) {
+    Region lhs(*this);
+    boolean_operation(op, *this, lhs, rhs, dx, dy);
     return *this;
 }
 
-Region Region::merge(const Region& rhs, int dx, int dy) const {
-    Region result;
-    SkRegion r(rhs.mRegion);
-    r.translate(dx, dy);
-    result.mRegion.op(mRegion, r, SkRegion::kUnion_Op);
-    return result;
-}
+// ----------------------------------------------------------------------------
 
-Region Region::intersect(const Region& rhs, int dx, int dy) const {
-    Region result;
-    SkRegion r(rhs.mRegion);
-    r.translate(dx, dy);
-    result.mRegion.op(mRegion, r, SkRegion::kIntersect_Op);
-    return result;
+const Region Region::merge(const Region& rhs, int dx, int dy) const {
+    return operation(rhs, dx, dy, op_or);
 }
-
-Region Region::subtract(const Region& rhs, int dx, int dy) const {
+const Region Region::intersect(const Region& rhs, int dx, int dy) const {
+    return operation(rhs, dx, dy, op_and);
+}
+const Region Region::subtract(const Region& rhs, int dx, int dy) const {
+    return operation(rhs, dx, dy, op_nand);
+}
+const Region Region::operation(const Region& rhs, int dx, int dy, int op) const {
     Region result;
-    SkRegion r(rhs.mRegion);
-    r.translate(dx, dy);
-    result.mRegion.op(mRegion, r, SkRegion::kDifference_Op);
+    boolean_operation(op, result, *this, rhs, dx, dy);
     return result;
 }
 
 // ----------------------------------------------------------------------------
 
-Region::iterator::iterator(const Region& r)
-    : mIt(r.mRegion)
+// This is our region rasterizer, which merges rects and spans together
+// to obtain an optimal region.
+class Region::rasterizer : public region_operator<Rect>::region_rasterizer 
 {
+    Rect& bounds;
+    Vector<Rect>& storage;
+    Rect* head;
+    Rect* tail;
+    Vector<Rect> span;
+    Rect* cur;
+public:
+    rasterizer(Region& reg) 
+        : bounds(reg.mBounds), storage(reg.mStorage), head(), tail(), cur() {
+        bounds.top = bounds.bottom = 0;
+        bounds.left   = INT_MAX;
+        bounds.right  = INT_MIN;
+        storage.clear();
+    }
+
+    ~rasterizer() {
+        if (span.size()) {
+            flushSpan();
+        }
+        if (storage.size()) {
+            bounds.top = storage.itemAt(0).top;
+            bounds.bottom = storage.top().bottom;
+            if (storage.size() == 1) {
+                storage.clear();
+            }
+        } else {
+            bounds.left  = 0;
+            bounds.right = 0;
+        }
+    }
+    
+    virtual void operator()(const Rect& rect) {
+        //LOGD(">>> %3d, %3d, %3d, %3d", 
+        //        rect.left, rect.top, rect.right, rect.bottom);
+        if (span.size()) {
+            if (cur->top != rect.top) {
+                flushSpan();
+            } else if (cur->right == rect.left) {
+                cur->right = rect.right;
+                return;
+            }
+        }
+        span.add(rect);
+        cur = span.editArray() + (span.size() - 1);
+    }
+private:
+    template<typename T> 
+    static inline T min(T rhs, T lhs) { return rhs < lhs ? rhs : lhs; }
+    template<typename T> 
+    static inline T max(T rhs, T lhs) { return rhs > lhs ? rhs : lhs; }
+    void flushSpan() {
+        bool merge = false;
+        if (tail-head == ssize_t(span.size())) {
+            Rect const* p = cur;
+            Rect const* q = head;
+            if (p->top == q->bottom) {
+                merge = true;
+                while (q != tail) {
+                    if ((p->left != q->left) || (p->right != q->right)) {
+                        merge = false;
+                        break;
+                    }
+                    p++, q++;
+                }
+            }
+        }
+        if (merge) {
+            const int bottom = span[0].bottom;
+            Rect* r = head;
+            while (r != tail) {
+                r->bottom = bottom;
+                r++;
+            }
+        } else {
+            bounds.left = min(span.itemAt(0).left, bounds.left);
+            bounds.right = max(span.top().right, bounds.right);
+            storage.appendVector(span);
+            tail = storage.editArray() + storage.size();
+            head = tail - span.size();
+        }
+        span.clear();
+    }
+};
+
+bool Region::validate(const Region& reg, const char* name)
+{
+    bool result = true;
+    const_iterator cur = reg.begin();
+    const_iterator const tail = reg.end();
+    const_iterator prev = cur++;
+    Rect b(*prev);
+    while (cur != tail) {
+        b.left   = b.left   < cur->left   ? b.left   : cur->left;
+        b.top    = b.top    < cur->top    ? b.top    : cur->top;
+        b.right  = b.right  > cur->right  ? b.right  : cur->right;
+        b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom;
+        if (cur->top == prev->top) {
+            if (cur->bottom != prev->bottom) {
+                LOGE("%s: invalid span %p", name, cur);
+                result = false;
+            } else if (cur->left < prev->right) {
+                LOGE("%s: spans overlap horizontally prev=%p, cur=%p",
+                        name, prev, cur);
+                result = false;
+            }
+        } else if (cur->top < prev->bottom) {
+            LOGE("%s: spans overlap vertically prev=%p, cur=%p",
+                    name, prev, cur);
+            result = false;
+        }
+        prev = cur;
+        cur++;
+    }
+    if (b != reg.getBounds()) {
+        result = false;
+        LOGE("%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name,
+                b.left, b.top, b.right, b.bottom,
+                reg.getBounds().left, reg.getBounds().top, 
+                reg.getBounds().right, reg.getBounds().bottom);
+    }
+    if (result == false) {
+        reg.dump(name);
+    }
+    return result;
 }
 
-int Region::iterator::iterate(Rect* rect)
+void Region::boolean_operation(int op, Region& dst,
+        const Region& lhs,
+        const Region& rhs, int dx, int dy)
 {
-    if (mIt.done())
-        return 0;
-    const SkIRect& r(mIt.rect());
-    rect->left  = r.fLeft;
-    rect->top   = r.fTop;
-    rect->right = r.fRight;
-    rect->bottom= r.fBottom;
-    mIt.next();
-    return 1;
+    size_t lhs_count;
+    Rect const * const lhs_rects = lhs.getArray(&lhs_count);
+
+    size_t rhs_count;
+    Rect const * const rhs_rects = rhs.getArray(&rhs_count);
+
+    region_operator<Rect>::region lhs_region(lhs_rects, lhs_count);
+    region_operator<Rect>::region rhs_region(rhs_rects, rhs_count, dx, dy);
+    region_operator<Rect> operation(op, lhs_region, rhs_region);
+    { // scope for rasterizer (dtor has side effects)
+        rasterizer r(dst);
+        operation(r);
+    }
+
+#if VALIDATE_REGIONS
+    validate(lhs, "boolean_operation: lhs");
+    validate(rhs, "boolean_operation: rhs");
+    validate(dst, "boolean_operation: dst");
+#endif
+
+#if VALIDATE_WITH_CORECG
+    SkRegion sk_lhs;
+    SkRegion sk_rhs;
+    SkRegion sk_dst;
+    
+    for (size_t i=0 ; i<lhs_count ; i++)
+        sk_lhs.op(
+                lhs_rects[i].left   + dx,
+                lhs_rects[i].top    + dy,
+                lhs_rects[i].right  + dx,
+                lhs_rects[i].bottom + dy,
+                SkRegion::kUnion_Op);
+    
+    for (size_t i=0 ; i<rhs_count ; i++)
+        sk_rhs.op(
+                rhs_rects[i].left   + dx,
+                rhs_rects[i].top    + dy,
+                rhs_rects[i].right  + dx,
+                rhs_rects[i].bottom + dy,
+                SkRegion::kUnion_Op);
+ 
+    const char* name = "---";
+    SkRegion::Op sk_op;
+    switch (op) {
+        case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break;
+        case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break;
+        case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break;
+    }
+    sk_dst.op(sk_lhs, sk_rhs, sk_op);
+
+    if (sk_dst.isEmpty() && dst.isEmpty())
+        return;
+    
+    bool same = true;
+    Region::const_iterator head = dst.begin();
+    Region::const_iterator const tail = dst.end();
+    SkRegion::Iterator it(sk_dst);
+    while (!it.done()) {
+        if (head != tail) {
+            if (
+                    head->left != it.rect().fLeft ||     
+                    head->top != it.rect().fTop ||     
+                    head->right != it.rect().fRight ||     
+                    head->bottom != it.rect().fBottom
+            ) {
+                same = false;
+                break;
+            }
+        } else {
+            same = false;
+            break;
+        }
+        head++;
+        it.next();
+    }
+    
+    if (head != tail) {
+        same = false;
+    }
+    
+    if(!same) {
+        LOGD("---\nregion boolean %s failed", name);
+        lhs.dump("lhs");
+        rhs.dump("rhs");
+        dst.dump("dst");
+        LOGD("should be");
+        SkRegion::Iterator it(sk_dst);
+        while (!it.done()) {
+            LOGD("    [%3d, %3d, %3d, %3d]",
+                it.rect().fLeft,
+                it.rect().fTop,
+                it.rect().fRight,
+                it.rect().fBottom);
+            it.next();
+        }
+    }
+#endif
+}
+
+void Region::boolean_operation(int op, Region& dst,
+        const Region& lhs,
+        const Rect& rhs, int dx, int dy)
+{
+#if VALIDATE_WITH_CORECG || VALIDATE_REGIONS
+    boolean_operation(op, dst, lhs, Region(rhs), dx, dy);
+#else
+    size_t lhs_count;
+    Rect const * const lhs_rects = lhs.getArray(&lhs_count);
+
+    region_operator<Rect>::region lhs_region(lhs_rects, lhs_count);
+    region_operator<Rect>::region rhs_region(&rhs, 1, dx, dy);
+    region_operator<Rect> operation(op, lhs_region, rhs_region);
+    { // scope for rasterizer (dtor has side effects)
+        rasterizer r(dst);
+        operation(r);
+    }
+
+#endif
+}
+
+void Region::boolean_operation(int op, Region& dst,
+        const Region& lhs, const Region& rhs)
+{
+    boolean_operation(op, dst, lhs, rhs, 0, 0);
+}
+
+void Region::boolean_operation(int op, Region& dst,
+        const Region& lhs, const Rect& rhs)
+{
+    boolean_operation(op, dst, lhs, rhs, 0, 0);
+}
+
+void Region::translate(Region& reg, int dx, int dy)
+{
+    if (!reg.isEmpty()) {
+#if VALIDATE_REGIONS
+        validate(reg, "translate (before)");
+#endif
+        reg.mBounds.translate(dx, dy);
+        size_t count = reg.mStorage.size();
+        Rect* rects = reg.mStorage.editArray();
+        while (count) {
+            rects->translate(dx, dy);
+            rects++;
+            count--;
+        }
+#if VALIDATE_REGIONS
+        validate(reg, "translate (after)");
+#endif
+    }
+}
+
+void Region::translate(Region& dst, const Region& reg, int dx, int dy)
+{
+    dst = reg;
+    translate(dst, dx, dy);
 }
 
 // ----------------------------------------------------------------------------
 
-// we write a 4byte size ahead of the actual region, so we know how much we'll need for reading
-
 status_t Region::write(Parcel& parcel) const
 {
-    int32_t size = mRegion.flatten(NULL);
-    parcel.writeInt32(size);
-    mRegion.flatten(parcel.writeInplace(size));
+#if VALIDATE_REGIONS
+    validate(*this, "write(Parcel)");
+#endif
+    status_t err;
+    const size_t count = mStorage.size();
+    const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect);
+    void* buffer = parcel.writeInplace(sizeNeeded);
+    if (!buffer) return NO_MEMORY;
+    ssize_t written = Region::write(buffer, sizeNeeded);
+    if (written < 0) return status_t(written);
     return NO_ERROR;
 }
 
 status_t Region::read(const Parcel& parcel)
 {
-    size_t size = parcel.readInt32();
-    mRegion.unflatten(parcel.readInplace(size));
+    void const* buffer = parcel.readInplace(sizeof(int32_t));
+    if (!buffer) return NO_MEMORY;
+    const size_t count = *static_cast<int32_t const *>(buffer);
+    void const* dummy = parcel.readInplace((1+count)*sizeof(Rect));
+    if (!dummy) return NO_MEMORY;
+    const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect);
+    const ssize_t read = Region::read(buffer);
+    if (read < 0) return status_t(read);
+#if VALIDATE_REGIONS
+    validate(*this, "read(Parcel)");
+#endif
     return NO_ERROR;
 }
 
 ssize_t Region::write(void* buffer, size_t size) const
 {
-    size_t sizeNeeded = mRegion.flatten(NULL);
+#if VALIDATE_REGIONS
+    validate(*this, "write(buffer)");
+#endif
+    const size_t count = mStorage.size();
+    const size_t sizeNeeded = sizeof(int32_t) + (1+count)*sizeof(Rect);
     if (sizeNeeded > size) return NO_MEMORY;
-    return mRegion.flatten(buffer);
+    int32_t* const p = static_cast<int32_t*>(buffer); 
+    *p = count;
+    memcpy(p+1, &mBounds, sizeof(Rect));
+    if (count) {
+        memcpy(p+5, mStorage.array(), count*sizeof(Rect));
+    }
+    return ssize_t(sizeNeeded);
 }
 
 ssize_t Region::read(const void* buffer)
 {
-    return mRegion.unflatten(buffer);
+    int32_t const* const p = static_cast<int32_t const*>(buffer); 
+    const size_t count = *p;
+    memcpy(&mBounds, p+1, sizeof(Rect));
+    mStorage.clear();
+    if (count) {
+        mStorage.insertAt(0, count);
+        memcpy(mStorage.editArray(), p+5, count*sizeof(Rect));
+    }
+#if VALIDATE_REGIONS
+    validate(*this, "read(buffer)");
+#endif
+    return ssize_t(sizeof(int32_t) + (1+count)*sizeof(Rect));
 }
 
 ssize_t Region::writeEmpty(void* buffer, size_t size)
 {
-    if (size < 4) return NO_MEMORY;
-    // this needs to stay in sync with SkRegion
-    *static_cast<int32_t*>(buffer) = -1;
-    return 4;
+    const size_t sizeNeeded = sizeof(int32_t) + sizeof(Rect);
+    if (sizeNeeded > size) return NO_MEMORY;
+    int32_t* const p = static_cast<int32_t*>(buffer); 
+    memset(p, 0, sizeNeeded);
+    return ssize_t(sizeNeeded);
 }
 
 bool Region::isEmpty(void* buffer)
 {
-    // this needs to stay in sync with SkRegion
-    return *static_cast<int32_t*>(buffer) == -1;
+    int32_t const* const p = static_cast<int32_t const*>(buffer); 
+    Rect const* const b = reinterpret_cast<Rect const *>(p+1);
+    return b->isEmpty();
 }
 
-size_t Region::rects(Vector<Rect>& rectList) const
+// ----------------------------------------------------------------------------
+
+Region::const_iterator Region::begin() const {
+    return isRect() ? &mBounds : mStorage.array();
+}
+
+Region::const_iterator Region::end() const {
+    return isRect() ? ((&mBounds) + 1) : (mStorage.array() + mStorage.size());
+}
+
+Rect const* Region::getArray(size_t* count) const {
+    const_iterator const b(begin());
+    const_iterator const e(end());
+    if (count) *count = e-b;
+    return b;
+}
+
+size_t Region::getRects(Vector<Rect>& rectList) const
 {
-    rectList.clear();
-    if (!isEmpty()) {
-        SkRegion::Iterator iterator(mRegion);
-        while( !iterator.done() ) {
-            const SkIRect& ir(iterator.rect());
-            rectList.push(Rect(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom));
-            iterator.next();
-        }
+    rectList = mStorage;
+    if (rectList.isEmpty()) {
+        rectList.clear();
+        rectList.add(mBounds);
     }
     return rectList.size();
 }
 
+// ----------------------------------------------------------------------------
+
 void Region::dump(String8& out, const char* what, uint32_t flags) const
 {
     (void)flags;
-    Vector<Rect> r;
-    rects(r);
-    
+    const_iterator head = begin();
+    const_iterator const tail = end();
+
     size_t SIZE = 256;
     char buffer[SIZE];
-    
-    snprintf(buffer, SIZE, "  Region %s (this=%p, count=%d)\n", what, this, r.size());
+
+    snprintf(buffer, SIZE, "  Region %s (this=%p, count=%d)\n",
+            what, this, tail-head);
     out.append(buffer);
-    for (size_t i=0 ; i<r.size() ; i++) {
+    while (head != tail) {
         snprintf(buffer, SIZE, "    [%3d, %3d, %3d, %3d]\n",
-            r[i].left, r[i].top,r[i].right,r[i].bottom);
+                head->left, head->top, head->right, head->bottom);
         out.append(buffer);
+        head++;
     }
 }
 
 void Region::dump(const char* what, uint32_t flags) const
 {
     (void)flags;
-    Vector<Rect> r;
-    rects(r);
-    LOGD("  Region %s (this=%p, count=%d)\n", what, this, r.size());
-    for (size_t i=0 ; i<r.size() ; i++) {
+    const_iterator head = begin();
+    const_iterator const tail = end();
+    LOGD("  Region %s (this=%p, count=%d)\n", what, this, tail-head);
+    while (head != tail) {
         LOGD("    [%3d, %3d, %3d, %3d]\n",
-            r[i].left, r[i].top,r[i].right,r[i].bottom);
+                head->left, head->top, head->right, head->bottom);
+        head++;
     }
 }
 
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index 4ea9ae2..b8b428f 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -23,202 +23,319 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#include <utils/Atomic.h>
 #include <utils/Errors.h>
 #include <utils/threads.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IMemory.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IMemory.h>
 #include <utils/Log.h>
 
+#include <ui/DisplayInfo.h>
+#include <ui/BufferMapper.h>
 #include <ui/ISurface.h>
 #include <ui/Surface.h>
 #include <ui/SurfaceComposerClient.h>
 #include <ui/Rect.h>
 
+#include <pixelflinger/pixelflinger.h>
+
 #include <private/ui/SharedState.h>
 #include <private/ui/LayerState.h>
+#include <private/ui/SurfaceBuffer.h>
 
 namespace android {
 
-// ---------------------------------------------------------------------------
+// ============================================================================
+//  SurfaceBuffer
+// ============================================================================
 
-Surface::Surface(const sp<SurfaceComposerClient>& client, 
+SurfaceBuffer::SurfaceBuffer() 
+    : BASE(), mOwner(false), mBufferMapper(BufferMapper::get())
+{
+    width  = 
+    height = 
+    stride = 
+    format = 
+    usage  = 0;
+    handle = NULL;
+}
+
+SurfaceBuffer::SurfaceBuffer(const Parcel& data) 
+    : BASE(), mOwner(true), mBufferMapper(BufferMapper::get())
+{
+    // we own the handle in this case
+    width  = data.readInt32();
+    height = data.readInt32();
+    stride = data.readInt32();
+    format = data.readInt32();
+    usage  = data.readInt32();
+    handle = data.readNativeHandle();
+}
+
+SurfaceBuffer::~SurfaceBuffer()
+{
+    if (handle && mOwner) {
+        native_handle_close(handle);
+        native_handle_delete(const_cast<native_handle*>(handle));
+    }
+}
+
+status_t SurfaceBuffer::lock(uint32_t usage, void** vaddr)
+{
+    const Rect lockBounds(width, height);
+    status_t res = lock(usage, lockBounds, vaddr);
+    return res;
+}
+
+status_t SurfaceBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
+{
+    status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
+    return res;
+}
+
+status_t SurfaceBuffer::unlock()
+{
+    status_t res = getBufferMapper().unlock(handle);
+    return res;
+}
+
+status_t SurfaceBuffer::writeToParcel(Parcel* reply, 
+        android_native_buffer_t const* buffer)
+{
+    reply->writeInt32(buffer->width);
+    reply->writeInt32(buffer->height);
+    reply->writeInt32(buffer->stride);
+    reply->writeInt32(buffer->format);
+    reply->writeInt32(buffer->usage);
+    reply->writeNativeHandle(buffer->handle);
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------
+
+static void copyBlt(
+        const sp<SurfaceBuffer>& dst, 
+        const sp<SurfaceBuffer>& src, 
+        const Region& reg)
+{
+    uint8_t const * src_bits;
+    src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
+
+    uint8_t* dst_bits;
+    dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
+    
+    size_t c;
+    Rect const* const rects = reg.getArray(&c);
+    
+    if (c) {
+        // 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;
+
+        for (size_t i=0 ; i<c ; i++) {
+            const Rect& r = rects[i];
+            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
+// ============================================================================
+
+SurfaceControl::SurfaceControl(
+        const sp<SurfaceComposerClient>& client, 
         const sp<ISurface>& surface,
         const ISurfaceFlingerClient::surface_data_t& data,
-        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
-        bool owner)
+        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
     : mClient(client), mSurface(surface),
       mToken(data.token), mIdentity(data.identity),
-      mFormat(format), mFlags(flags), mOwner(owner)
+      mFormat(format), mFlags(flags)
 {
-    mSwapRectangle.makeInvalid();
-    mSurfaceHeapBase[0] = 0;
-    mSurfaceHeapBase[1] = 0;
-    mHeap[0] = data.heap[0]; 
-    mHeap[1] = data.heap[1];
+}
+        
+SurfaceControl::~SurfaceControl()
+{
+    destroy();
 }
 
-Surface::Surface(Surface const* rhs)
-    : mOwner(false)
+void SurfaceControl::destroy()
 {
-    mToken   = rhs->mToken;
-    mIdentity= rhs->mIdentity;
-    mClient  = rhs->mClient;
-    mSurface = rhs->mSurface;
-    mHeap[0] = rhs->mHeap[0];
-    mHeap[1] = rhs->mHeap[1];
-    mFormat  = rhs->mFormat;
-    mFlags   = rhs->mFlags;
-    mSurfaceHeapBase[0] = rhs->mSurfaceHeapBase[0];
-    mSurfaceHeapBase[1] = rhs->mSurfaceHeapBase[1];
-    mSwapRectangle.makeInvalid();
-}
-
-Surface::~Surface()
-{
-    if (mOwner && mToken>=0 && mClient!=0) {
+    if (isValid()) {
         mClient->destroySurface(mToken);
     }
+
+    // clear all references and trigger an IPC now, to make sure things
+    // happen without delay, since these resources are quite heavy.
     mClient.clear();
     mSurface.clear();
-    mHeap[0].clear();
-    mHeap[1].clear();
     IPCThreadState::self()->flushCommands();
 }
 
-sp<Surface> Surface::dup() const
+void SurfaceControl::clear() 
 {
-    Surface const * r = this;
-    if (this && mOwner) {
-        // the only reason we need to do this is because of Java's garbage
-        // collector: because we're creating a copy of the Surface
-        // instead of a reference, we can garantee that when our last
-        // reference goes away, the real surface will be deleted.
-        // Without this hack (the code is correct too), we'd have to
-        // wait for a GC for the surface to go away.
-        r = new Surface(this);        
+    // here, the window manager tells us explicitly that we should destroy
+    // the surface's resource. Soon after this call, it will also release
+    // its last reference (which will call the dtor); however, it is possible
+    // that a client living in the same process still holds references which
+    // would delay the call to the dtor -- that is why we need this explicit
+    // "clear()" call.
+    destroy();
+}
+
+bool SurfaceControl::isSameSurface(
+        const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs) 
+{
+    if (lhs == 0 || rhs == 0)
+        return false;
+    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
+}
+
+status_t SurfaceControl::setLayer(int32_t layer) {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->setLayer(mToken, layer);
+}
+status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->setPosition(mToken, x, y);
+}
+status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->setSize(mToken, w, h);
+}
+status_t SurfaceControl::hide() {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->hide(mToken);
+}
+status_t SurfaceControl::show(int32_t layer) {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->show(mToken, layer);
+}
+status_t SurfaceControl::freeze() {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->freeze(mToken);
+}
+status_t SurfaceControl::unfreeze() {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->unfreeze(mToken);
+}
+status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->setFlags(mToken, flags, mask);
+}
+status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->setTransparentRegionHint(mToken, transparent);
+}
+status_t SurfaceControl::setAlpha(float alpha) {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->setAlpha(mToken, alpha);
+}
+status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
+}
+status_t SurfaceControl::setFreezeTint(uint32_t tint) {
+    const sp<SurfaceComposerClient>& client(mClient);
+    if (client == 0) return NO_INIT;
+    status_t err = validate(client->mControl);
+    if (err < 0) return err;
+    return client->setFreezeTint(mToken, tint);
+}
+
+status_t SurfaceControl::validate(per_client_cblk_t const* cblk) const
+{
+    if (mToken<0 || mClient==0) {
+        LOGE("invalid token (%d, identity=%u) or client (%p)", 
+                mToken, mIdentity, mClient.get());
+        return NO_INIT;
     }
-    return const_cast<Surface*>(r);
+    if (cblk == 0) {
+        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
+        return NO_INIT;
+    }
+    status_t err = cblk->validate(mToken);
+    if (err != NO_ERROR) {
+        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
+                mToken, mIdentity, err, strerror(-err));
+        return err;
+    }
+    if (mIdentity != uint32_t(cblk->layers[mToken].identity)) {
+        LOGE("using an invalid surface id=%d, identity=%u should be %d",
+                mToken, mIdentity, cblk->layers[mToken].identity);
+        return NO_INIT;
+    }
+    return NO_ERROR;
 }
 
-status_t Surface::nextBuffer(SurfaceInfo* info) {
-    return mClient->nextBuffer(this, info);
-}
-
-status_t Surface::lock(SurfaceInfo* info, bool blocking) {
-    return Surface::lock(info, NULL, blocking);
-}
-
-status_t Surface::lock(SurfaceInfo* info, Region* dirty, bool blocking) {
-    if (heapBase(0) == 0) return INVALID_OPERATION;
-    if (heapBase(1) == 0) return INVALID_OPERATION;
-    return mClient->lockSurface(this, info, dirty, blocking);
-}
-
-status_t Surface::unlockAndPost() {
-    if (heapBase(0) == 0) return INVALID_OPERATION;
-    if (heapBase(1) == 0) return INVALID_OPERATION;
-    return mClient->unlockAndPostSurface(this);
-}
-
-status_t Surface::unlock() {
-    if (heapBase(0) == 0) return INVALID_OPERATION;
-    if (heapBase(1) == 0) return INVALID_OPERATION;
-    return mClient->unlockSurface(this);
-}
-
-status_t Surface::setLayer(int32_t layer) {
-    return mClient->setLayer(this, layer);
-}
-status_t Surface::setPosition(int32_t x, int32_t y) {
-    return mClient->setPosition(this, x, y);
-}
-status_t Surface::setSize(uint32_t w, uint32_t h) {
-    return mClient->setSize(this, w, h);
-}
-status_t Surface::hide() {
-    return mClient->hide(this);
-}
-status_t Surface::show(int32_t layer) {
-    return mClient->show(this, layer);
-}
-status_t Surface::freeze() {
-    return mClient->freeze(this);
-}
-status_t Surface::unfreeze() {
-    return mClient->unfreeze(this);
-}
-status_t Surface::setFlags(uint32_t flags, uint32_t mask) {
-    return mClient->setFlags(this, flags, mask);
-}
-status_t Surface::setTransparentRegionHint(const Region& transparent) {
-    return mClient->setTransparentRegionHint(this, transparent);
-}
-status_t Surface::setAlpha(float alpha) {
-    return mClient->setAlpha(this, alpha);
-}
-status_t Surface::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
-    return mClient->setMatrix(this, dsdx, dtdx, dsdy, dtdy);
-}
-status_t Surface::setFreezeTint(uint32_t tint) {
-    return mClient->setFreezeTint(this, tint);
-}
-
-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;
-}
-
-sp<Surface> Surface::readFromParcel(Parcel* parcel)
+status_t SurfaceControl::writeSurfaceToParcel(
+        const sp<SurfaceControl>& control, Parcel* parcel)
 {
-    sp<SurfaceComposerClient> client;
-    ISurfaceFlingerClient::surface_data_t data;
-    sp<IBinder> clientBinder= parcel->readStrongBinder();
-    sp<ISurface> surface    = interface_cast<ISurface>(parcel->readStrongBinder());
-    data.heap[0]            = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
-    data.heap[1]            = interface_cast<IMemoryHeap>(parcel->readStrongBinder());
-    data.token              = parcel->readInt32();
-    data.identity           = parcel->readInt32();
-    PixelFormat format      = parcel->readInt32();
-    uint32_t flags          = parcel->readInt32();
-
-    if (clientBinder != NULL)
-        client = SurfaceComposerClient::clientForConnection(clientBinder);
-
-    return new Surface(client, surface, data, 0, 0, format, flags, false);
-}
-
-status_t Surface::writeToParcel(const sp<Surface>& surface, Parcel* parcel)
-{
-    uint32_t flags=0;
-    uint32_t format=0;
+    uint32_t flags = 0;
+    uint32_t format = 0;
     SurfaceID token = -1;
     uint32_t identity = 0;
     sp<SurfaceComposerClient> client;
     sp<ISurface> sur;
-    sp<IMemoryHeap> heap[2];
-    if (surface->isValid()) {
-        token = surface->mToken;
-        identity = surface->mIdentity;
-        client = surface->mClient;
-        sur = surface->mSurface;
-        heap[0] = surface->mHeap[0];
-        heap[1] = surface->mHeap[1];
-        format = surface->mFormat;
-        flags = surface->mFlags;
+    if (SurfaceControl::isValid(control)) {
+        token    = control->mToken;
+        identity = control->mIdentity;
+        client   = control->mClient;
+        sur      = control->mSurface;
+        format   = control->mFormat;
+        flags    = control->mFlags;
     }
     parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
     parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
-    parcel->writeStrongBinder(heap[0]!=0 ? heap[0]->asBinder()  : NULL);
-    parcel->writeStrongBinder(heap[1]!=0 ? heap[1]->asBinder()  : NULL);
     parcel->writeInt32(token);
     parcel->writeInt32(identity);
     parcel->writeInt32(format);
@@ -226,30 +343,348 @@
     return NO_ERROR;
 }
 
-bool Surface::isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs) 
+sp<Surface> SurfaceControl::getSurface() const
+{
+    Mutex::Autolock _l(mLock);
+    if (mSurfaceData == 0) {
+        mSurfaceData = new Surface(const_cast<SurfaceControl*>(this));
+    }
+    return mSurfaceData;
+}
+
+// ============================================================================
+//  Surface
+// ============================================================================
+
+Surface::Surface(const sp<SurfaceControl>& surface)
+    : mClient(surface->mClient), mSurface(surface->mSurface),
+      mToken(surface->mToken), mIdentity(surface->mIdentity),
+      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());
+    mToken      = parcel.readInt32();
+    mIdentity   = parcel.readInt32();
+    mFormat     = parcel.readInt32();
+    mFlags      = parcel.readInt32();
+
+    if (clientBinder != NULL)
+        mClient = SurfaceComposerClient::clientForConnection(clientBinder);
+
+    init();
+}
+
+void Surface::init()
+{
+    android_native_window_t::setSwapInterval  = setSwapInterval;
+    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;
+    const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi;
+    // FIXME: set real values here
+    const_cast<int&>(android_native_window_t::minSwapInterval) = 1;
+    const_cast<int&>(android_native_window_t::maxSwapInterval) = 1;
+    const_cast<uint32_t&>(android_native_window_t::flags) = 0;
+}
+
+
+Surface::~Surface()
+{
+    // this is a client-side operation, the surface is destroyed, unmap
+    // its buffers in this process.
+    for (int i=0 ; i<2 ; i++) {
+        if (mBuffers[i] != 0) {
+            getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
+        }
+    }
+
+    // clear all references and trigger an IPC now, to make sure things
+    // happen without delay, since these resources are quite heavy.
+    mClient.clear();
+    mSurface.clear();
+    IPCThreadState::self()->flushCommands();
+}
+
+status_t Surface::validate(per_client_cblk_t const* cblk) const
+{
+    if (mToken<0 || mClient==0) {
+        LOGE("invalid token (%d, identity=%u) or client (%p)", 
+                mToken, mIdentity, mClient.get());
+        return NO_INIT;
+    }
+    if (cblk == 0) {
+        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
+        return NO_INIT;
+    }
+    status_t err = cblk->validate(mToken);
+    if (err != NO_ERROR) {
+        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
+                mToken, mIdentity, err, strerror(-err));
+        return err;
+    }
+    if (mIdentity != uint32_t(cblk->layers[mToken].identity)) {
+        LOGE("using an invalid surface id=%d, identity=%u should be %d",
+                mToken, mIdentity, cblk->layers[mToken].identity);
+        return NO_INIT;
+    }
+    return NO_ERROR;
+}
+
+
+bool Surface::isSameSurface(
+        const sp<Surface>& lhs, const sp<Surface>& rhs) 
 {
     if (lhs == 0 || rhs == 0)
         return false;
     return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
 }
 
-void* Surface::heapBase(int i) const 
+// ----------------------------------------------------------------------------
+
+int Surface::setSwapInterval(android_native_window_t* window, int interval)
 {
-    void* heapBase = mSurfaceHeapBase[i];
-    // map lazily so it doesn't get mapped in clients that don't need it
-    if (heapBase == 0) {
-        const sp<IMemoryHeap>& heap(mHeap[i]);
-        if (heap != 0) {
-            heapBase = static_cast<uint8_t*>(heap->base());
-            if (heapBase == MAP_FAILED) {
-                heapBase = NULL;
-                LOGE("Couldn't map Surface's heap (binder=%p, heap=%p)",
-                        heap->asBinder().get(), heap.get());
+    return 0;
+}
+
+int Surface::dequeueBuffer(android_native_window_t* window, 
+        android_native_buffer_t** buffer)
+{
+    Surface* self = getSelf(window);
+    return self->dequeueBuffer(buffer);
+}
+
+int Surface::lockBuffer(android_native_window_t* window, 
+        android_native_buffer_t* buffer)
+{
+    Surface* self = getSelf(window);
+    return self->lockBuffer(buffer);
+}
+
+int Surface::queueBuffer(android_native_window_t* window, 
+        android_native_buffer_t* buffer)
+{
+    Surface* self = getSelf(window);
+    return self->queueBuffer(buffer);
+}
+
+// ----------------------------------------------------------------------------
+
+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
+
+    Mutex::Autolock _l(mSurfaceLock);
+
+    per_client_cblk_t* const cblk = mClient->mControl;
+    status_t err = validate(cblk);
+    if (err != NO_ERROR)
+        return err;
+
+    SurfaceID index(mToken); 
+    
+    int32_t backIdx = cblk->lock_layer(size_t(index),
+            per_client_cblk_t::BLOCKING);
+
+    if (backIdx < 0)
+        return status_t(backIdx); 
+
+    mBackbufferIndex = backIdx;
+    layer_cblk_t* const lcblk = &(cblk->layers[index]);
+
+    volatile const surface_info_t* const back = lcblk->surface + backIdx;
+    if (back->flags & surface_info_t::eNeedNewBuffer) {
+        getBufferLocked(backIdx);
+    }
+
+    const sp<SurfaceBuffer>& backBuffer(mBuffers[backIdx]);
+    mDirtyRegion.set(backBuffer->width, backBuffer->height);
+    *buffer = backBuffer.get();
+  
+    return NO_ERROR;
+}
+
+int Surface::lockBuffer(android_native_buffer_t* buffer)
+{
+    Mutex::Autolock _l(mSurfaceLock);
+
+    per_client_cblk_t* const cblk = mClient->mControl;
+    status_t err = validate(cblk);
+    if (err != NO_ERROR)
+        return err;
+
+    // FIXME: lockBuffer() needs proper implementation
+    return 0;
+}
+
+int Surface::queueBuffer(android_native_buffer_t* buffer)
+{   
+    Mutex::Autolock _l(mSurfaceLock);
+
+    per_client_cblk_t* const cblk = mClient->mControl;
+    status_t err = validate(cblk);
+    if (err != NO_ERROR)
+        return err;
+
+    if (mSwapRectangle.isValid()) {
+        mDirtyRegion.set(mSwapRectangle);
+    }
+    
+    // transmit the dirty region
+    SurfaceID index(mToken); 
+    layer_cblk_t* const lcblk = &(cblk->layers[index]);
+    _send_dirty_region(lcblk, mDirtyRegion);
+
+    uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
+    if (!(newstate & eNextFlipPending))
+        mClient->signalServer();
+
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+status_t Surface::lock(SurfaceInfo* info, bool blocking) {
+    return Surface::lock(info, NULL, blocking);
+}
+
+status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking) 
+{
+    // FIXME: needs some locking here
+    
+    sp<SurfaceBuffer> backBuffer;
+    status_t err = dequeueBuffer(&backBuffer);
+    if (err == NO_ERROR) {
+        err = lockBuffer(backBuffer);
+        if (err == NO_ERROR) {
+            // we handle copy-back here...
+            
+            const Rect bounds(backBuffer->width, backBuffer->height);
+            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)]);
+            volatile const surface_info_t* const back = lcblk->surface + mBackbufferIndex;
+            if (back->flags & surface_info_t::eBufferDirty) {
+                // content is meaningless in this case and the whole surface
+                // needs to be redrawn.
+                newDirtyRegion.set(bounds);
+            } else {
+                newDirtyRegion.andSelf(bounds);
+                if (!(lcblk->flags & eNoCopyBack)) {
+                    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);
+                    }
+                }
             }
-            mSurfaceHeapBase[i] = heapBase;
+            mDirtyRegion = newDirtyRegion;
+            mOldDirtyRegion = newDirtyRegion;
+
+            void* vaddr;
+            status_t res = backBuffer->lock(
+                    GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+                    newDirtyRegion.bounds(), &vaddr);
+            
+            LOGW_IF(res, "failed locking buffer %d (%p)", 
+                    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   = vaddr;
         }
     }
-    return heapBase;
+    return err;
+}
+    
+status_t Surface::unlockAndPost() 
+{
+    // FIXME: needs some locking here
+
+    if (mLockedBuffer == 0)
+        return BAD_VALUE;
+
+    status_t res = mLockedBuffer->unlock();
+    LOGW_IF(res, "failed unlocking buffer %d (%p)",
+            mBackbufferIndex, mLockedBuffer->handle);
+    
+    status_t err = queueBuffer(mLockedBuffer);
+    mLockedBuffer = 0;
+    return err;
+}
+
+void Surface::_send_dirty_region(
+        layer_cblk_t* lcblk, const Region& dirty)
+{
+    const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
+    flat_region_t* flat_region = lcblk->region + index;
+    status_t err = dirty.write(flat_region, sizeof(flat_region_t));
+    if (err < NO_ERROR) {
+        // region doesn't fit, use the bounds
+        const Region reg(dirty.bounds());
+        reg.write(flat_region, sizeof(flat_region_t));
+    }
+}
+
+void Surface::setSwapRectangle(const Rect& r) {
+    mSwapRectangle = r;
+}
+
+status_t Surface::getBufferLocked(int index)
+{
+    status_t err = NO_MEMORY;
+    sp<SurfaceBuffer> buffer = mSurface->getBuffer();
+    LOGE_IF(buffer==0, "ISurface::getBuffer() returned NULL");
+    if (buffer != 0) {
+        sp<SurfaceBuffer>& currentBuffer(mBuffers[index]);
+        if (currentBuffer != 0) {
+            getBufferMapper().unregisterBuffer(currentBuffer->handle);
+            currentBuffer.clear();
+        }
+        err = getBufferMapper().registerBuffer(buffer->handle);
+        LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
+        if (err == NO_ERROR) {
+            currentBuffer = buffer;
+        }
+    }
+    return err; 
 }
 
 }; // namespace android
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/ui/SurfaceComposerClient.cpp
index fe803ff..d2cef78 100644
--- a/libs/ui/SurfaceComposerClient.cpp
+++ b/libs/ui/SurfaceComposerClient.cpp
@@ -29,27 +29,21 @@
 #include <utils/Errors.h>
 #include <utils/threads.h>
 #include <utils/KeyedVector.h>
-#include <utils/IPCThreadState.h>
-#include <utils/IServiceManager.h>
-#include <utils/IMemory.h>
+#include <binder/IServiceManager.h>
+#include <binder/IMemory.h>
 #include <utils/Log.h>
 
+#include <ui/DisplayInfo.h>
 #include <ui/ISurfaceComposer.h>
 #include <ui/ISurfaceFlingerClient.h>
 #include <ui/ISurface.h>
 #include <ui/SurfaceComposerClient.h>
-#include <ui/DisplayInfo.h>
 #include <ui/Rect.h>
-#include <ui/Point.h>
 
 #include <private/ui/SharedState.h>
 #include <private/ui/LayerState.h>
 #include <private/ui/SurfaceFlingerSynchro.h>
 
-#include <pixelflinger/pixelflinger.h>
-
-#include <utils/BpBinder.h>
-
 #define VERBOSE(...)	((void)0)
 //#define VERBOSE			LOGD
 
@@ -65,7 +59,7 @@
 static sp<ISurfaceComposer>                                 gSurfaceManager;
 static DefaultKeyedVector< sp<IBinder>, sp<SurfaceComposerClient> > gActiveConnections;
 static SortedVector<sp<SurfaceComposerClient> >             gOpenTransactions;
-static sp<IMemory>                                          gServerCblkMemory;
+static sp<IMemoryHeap>                                      gServerCblkMemory;
 static volatile surface_flinger_cblk_t*                     gServerCblk;
 
 const sp<ISurfaceComposer>& _get_surface_manager()
@@ -100,7 +94,7 @@
         if (gServerCblk == 0) {
             gServerCblkMemory = sm->getCblk();
             LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
-            gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->pointer();
+            gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase();
             LOGE_IF(gServerCblk==0, "Can't get server control block address");
         }
     }
@@ -109,50 +103,8 @@
 
 // ---------------------------------------------------------------------------
 
-static void copyBlt(const GGLSurface& dst,
-        const GGLSurface& src, const Region& reg)
-{
-    Region::iterator iterator(reg);
-    if (iterator) {
-        // NOTE: dst and src must be the same format
-        Rect r;
-        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 = src.data + (r.left + src.stride * r.top) * bpp;
-                uint8_t* d = dst.data + (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);
-            }
-        }
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-surface_flinger_cblk_t::surface_flinger_cblk_t()
-{
-}
-
-// ---------------------------------------------------------------------------
-
-per_client_cblk_t::per_client_cblk_t()
-{
-}
-
 // these functions are used by the clients
-inline status_t per_client_cblk_t::validate(size_t i) const {
+status_t per_client_cblk_t::validate(size_t i) const {
     if (uint32_t(i) >= NUM_LAYERS_MAX)
         return BAD_INDEX;
     if (layers[i].swapState & eInvalidSurface)
@@ -248,8 +200,9 @@
         index = (state&eIndex) ^ ((state&eFlipRequested)>>1);
 
 	    // make sure this buffer is valid
-	    if (layer->surface[index].bits_offset < 0) {
-	        return status_t(layer->surface[index].bits_offset);
+        status_t err = layer->surface[index].status;
+	    if (err < 0) {
+	        return err;
 	    }
 
         if (inspect) {
@@ -273,7 +226,7 @@
 
 uint32_t per_client_cblk_t::unlock_layer_and_post(size_t i)
 {
-    // atomically set eFlipRequested and clear eLocked and optionnaly
+    // atomically set eFlipRequested and clear eLocked and optionally
     // set eNextFlipPending if eFlipRequested was already set
 
     layer_cblk_t * const layer = layers + i;
@@ -290,7 +243,7 @@
 
         if (oldvalue & eFlipRequested)
             newvalue |= eNextFlipPending;
-            // if eFlipRequested was alread set, set eNextFlipPending
+            // if eFlipRequested was already set, set eNextFlipPending
 
     } while (android_atomic_cmpxchg(oldvalue, newvalue, &(layer->swapState)));
 
@@ -298,9 +251,9 @@
             int(i), int((layer->flags & eBufferIndex) >> eBufferIndexShift),
             int(newvalue));
 
-    // from this point, the server can kick in at anytime and use the first
+    // from this point, the server can kick in at any time and use the first
     // buffer, so we cannot use it anymore, and we must use the 'other'
-    // buffer instead (or wait if it is not availlable yet, see lock_layer).
+    // buffer instead (or wait if it is not available yet, see lock_layer).
 
     return newvalue;
 }
@@ -360,9 +313,9 @@
         return;
     }
 
-    mClient->getControlBlocks(&mControlMemory);
+    mControlMemory = mClient->getControlBlock();
     mSignalServer = new SurfaceFlingerSynchro(sm);
-    mControl = static_cast<per_client_cblk_t *>(mControlMemory->pointer());
+    mControl = static_cast<per_client_cblk_t *>(mControlMemory->getBase());
 }
 
 SurfaceComposerClient::~SurfaceComposerClient()
@@ -376,32 +329,6 @@
     return mStatus;
 }
 
-status_t SurfaceComposerClient::validateSurface(
-        per_client_cblk_t const* cblk, Surface const * surface)
-{
-    SurfaceID index = surface->ID();
-    if (cblk == 0) {
-        LOGE("cblk is null (surface id=%d, identity=%u)",
-                index, surface->getIdentity());
-        return NO_INIT;
-    }
-
-    status_t err = cblk->validate(index);
-    if (err != NO_ERROR) {
-        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
-                index, surface->getIdentity(), err, strerror(-err));
-        return err;
-    }
-
-    if (surface->getIdentity() != uint32_t(cblk->layers[index].identity)) {
-        LOGE("using an invalid surface id=%d, identity=%u should be %d",
-                index, surface->getIdentity(), cblk->layers[index].identity);
-        return NO_INIT;
-    }
-
-    return NO_ERROR;
-}
-
 sp<IBinder> SurfaceComposerClient::connection() const
 {
     return (mClient != 0) ? mClient->asBinder() : 0;
@@ -437,9 +364,8 @@
 {
     // this can be called more than once.
 
-    sp<IMemory>                 controlMemory;
+    sp<IMemoryHeap>             controlMemory;
     sp<ISurfaceFlingerClient>   client;
-    sp<IMemoryHeap>             surfaceHeap;
 
     {
         Mutex::Autolock _lg(gLock);
@@ -462,9 +388,7 @@
         delete mPrebuiltLayerState;
         mPrebuiltLayerState = 0;
         controlMemory = mControlMemory;
-        surfaceHeap = mSurfaceHeap;
         mControlMemory.clear();
-        mSurfaceHeap.clear();
         mControl = 0;
         mStatus = NO_INIT;
     }
@@ -528,7 +452,13 @@
     return n;
 }
 
-sp<Surface> SurfaceComposerClient::createSurface(
+
+void SurfaceComposerClient::signalServer()
+{
+    mSignalServer->signal();
+}
+
+sp<SurfaceControl> SurfaceComposerClient::createSurface(
         int pid,
         DisplayID display,
         uint32_t w,
@@ -536,14 +466,14 @@
         PixelFormat format,
         uint32_t flags)
 {
-    sp<Surface> result;
+    sp<SurfaceControl> result;
     if (mStatus == NO_ERROR) {
         ISurfaceFlingerClient::surface_data_t data;
         sp<ISurface> surface = mClient->createSurface(&data, pid,
                 display, w, h, format, flags);
         if (surface != 0) {
             if (uint32_t(data.token) < NUM_LAYERS_MAX) {
-                result = new Surface(this, surface, data, w, h, format, flags);
+                result = new SurfaceControl(this, surface, data, w, h, format, flags);
             }
         }
     }
@@ -568,186 +498,6 @@
     return err;
 }
 
-status_t SurfaceComposerClient::nextBuffer(Surface* surface,
-                        Surface::SurfaceInfo* info)
-{
-    SurfaceID index = surface->ID();
-    per_client_cblk_t* const cblk = mControl;
-    status_t err = validateSurface(cblk, surface);
-    if (err != NO_ERROR)
-        return err;
-
-    int32_t backIdx = surface->mBackbufferIndex;
-    layer_cblk_t* const lcblk = &(cblk->layers[index]);
-    const surface_info_t* const front = lcblk->surface + (1-backIdx);
-        info->w      = front->w;
-        info->h      = front->h;
-        info->format = front->format;
-        info->base   = surface->heapBase(1-backIdx);
-        info->bits   = reinterpret_cast<void*>(intptr_t(info->base) + front->bits_offset);
-        info->bpr    = front->bpr;
-
-    return 0;
-}
-
-status_t SurfaceComposerClient::lockSurface(
-        Surface* surface,
-        Surface::SurfaceInfo* other,
-        Region* dirty,
-        bool blocking)
-{
-    Mutex::Autolock _l(surface->getLock());
-
-    SurfaceID index = surface->ID();
-    per_client_cblk_t* const cblk = mControl;
-    status_t err = validateSurface(cblk, surface);
-    if (err != NO_ERROR)
-        return err;
-
-    int32_t backIdx = cblk->lock_layer(size_t(index),
-            per_client_cblk_t::BLOCKING);
-    if (backIdx >= 0) {
-        surface->mBackbufferIndex = backIdx;
-        layer_cblk_t* const lcblk = &(cblk->layers[index]);
-        const surface_info_t* const back = lcblk->surface + backIdx;
-        const surface_info_t* const front = lcblk->surface + (1-backIdx);
-            other->w      = back->w;
-            other->h      = back->h;
-            other->format = back->format;
-            other->base   = surface->heapBase(backIdx);
-            other->bits   = reinterpret_cast<void*>(intptr_t(other->base) + back->bits_offset);
-            other->bpr    = back->bpr;
-
-        const Rect bounds(other->w, other->h);
-        Region newDirtyRegion;
-
-        if (back->flags & surface_info_t::eBufferDirty) {
-            /* it is safe to write *back here, because we're guaranteed
-             * SurfaceFlinger is not touching it (since it just granted
-             * access to us) */
-            const_cast<surface_info_t*>(back)->flags &=
-                    ~surface_info_t::eBufferDirty;
-
-            // content is meaningless in this case and the whole surface
-            // needs to be redrawn.
-
-            newDirtyRegion.set(bounds);
-            if (dirty) {
-                *dirty = newDirtyRegion;
-            }
-
-            //if (bytesPerPixel(other->format) == 4) {
-            //    android_memset32(
-            //        (uint32_t*)other->bits, 0xFF00FF00, other->h * other->bpr);
-            //} else {
-            //    android_memset16( // fill with green
-            //        (uint16_t*)other->bits, 0x7E0, other->h * other->bpr);
-            //}
-        }
-        else
-        {
-            if (dirty) {
-                dirty->andSelf(Region(bounds));
-                newDirtyRegion = *dirty;
-            } else {
-                newDirtyRegion.set(bounds);
-            }
-
-            Region copyback;
-            if (!(lcblk->flags & eNoCopyBack)) {
-                const Region previousDirtyRegion(surface->dirtyRegion());
-                copyback = previousDirtyRegion.subtract(newDirtyRegion);
-            }
-
-            if (!copyback.isEmpty()) {
-                // copy front to back
-                GGLSurface cb;
-                    cb.version = sizeof(GGLSurface);
-                    cb.width = back->w;
-                    cb.height = back->h;
-                    cb.stride = back->stride;
-                    cb.data = (GGLubyte*)surface->heapBase(backIdx);
-                    cb.data += back->bits_offset;
-                    cb.format = back->format;
-
-                GGLSurface t;
-                    t.version = sizeof(GGLSurface);
-                    t.width = front->w;
-                    t.height = front->h;
-                    t.stride = front->stride;
-                    t.data = (GGLubyte*)surface->heapBase(1-backIdx);
-                    t.data += front->bits_offset;
-                    t.format = front->format;
-
-                //const Region copyback(lcblk->region + 1-backIdx);
-                copyBlt(cb, t, copyback);
-            }
-        }
-
-        // update dirty region
-        surface->setDirtyRegion(newDirtyRegion);
-    }
-    return (backIdx < 0) ? status_t(backIdx) : status_t(NO_ERROR);
-}
-
-void SurfaceComposerClient::_signal_server()
-{
-    mSignalServer->signal();
-}
-
-void SurfaceComposerClient::_send_dirty_region(
-        layer_cblk_t* lcblk, const Region& dirty)
-{
-    const int32_t index = (lcblk->flags & eBufferIndex) >> eBufferIndexShift;
-    flat_region_t* flat_region = lcblk->region + index;
-    status_t err = dirty.write(flat_region, sizeof(flat_region_t));
-    if (err < NO_ERROR) {
-        // region doesn't fit, use the bounds
-        const Region reg(dirty.bounds());
-        reg.write(flat_region, sizeof(flat_region_t));
-    }
-}
-
-status_t SurfaceComposerClient::unlockAndPostSurface(Surface* surface)
-{
-    Mutex::Autolock _l(surface->getLock());
-
-    SurfaceID index = surface->ID();
-    per_client_cblk_t* const cblk = mControl;
-    status_t err = validateSurface(cblk, surface);
-    if (err != NO_ERROR)
-        return err;
-
-    Region dirty(surface->dirtyRegion());
-    const Rect& swapRect(surface->swapRectangle());
-    if (swapRect.isValid()) {
-        dirty.set(swapRect);
-    }
-
-    // transmit the dirty region
-    layer_cblk_t* const lcblk = &(cblk->layers[index]);
-    _send_dirty_region(lcblk, dirty);
-    uint32_t newstate = cblk->unlock_layer_and_post(size_t(index));
-    if (!(newstate & eNextFlipPending))
-        _signal_server();
-    return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::unlockSurface(Surface* surface)
-{
-    Mutex::Autolock _l(surface->getLock());
-
-    SurfaceID index = surface->ID();
-    per_client_cblk_t* const cblk = mControl;
-    status_t err = validateSurface(cblk, surface);
-    if (err != NO_ERROR)
-        return err;
-
-    layer_cblk_t* const lcblk = &(cblk->layers[index]);
-    cblk->unlock_layer(size_t(index));
-    return NO_ERROR;
-}
-
 void SurfaceComposerClient::openGlobalTransaction()
 {
     Mutex::Autolock _l(gLock);
@@ -866,14 +616,8 @@
     return NO_ERROR;
 }
 
-layer_state_t* SurfaceComposerClient::_get_state_l(const sp<Surface>& surface)
+layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index)
 {
-    SurfaceID index = surface->ID();
-    per_client_cblk_t* const cblk = mControl;
-    status_t err = validateSurface(cblk, surface.get());
-    if (err != NO_ERROR)
-        return 0;
-
     // API usage error, do nothing.
     if (mTransactionOpen<=0) {
         LOGE("Not in transaction (client=%p, SurfaceID=%d, mTransactionOpen=%d",
@@ -892,11 +636,11 @@
     return mStates.editArray() + i;
 }
 
-layer_state_t* SurfaceComposerClient::_lockLayerState(const sp<Surface>& surface)
+layer_state_t* SurfaceComposerClient::_lockLayerState(SurfaceID id)
 {
     layer_state_t* s;
     mLock.lock();
-    s = _get_state_l(surface);
+    s = _get_state_l(id);
     if (!s) mLock.unlock();
     return s;
 }
@@ -906,9 +650,9 @@
     mLock.unlock();
 }
 
-status_t SurfaceComposerClient::setPosition(Surface* surface, int32_t x, int32_t y)
+status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
 {
-    layer_state_t* s = _lockLayerState(surface);
+    layer_state_t* s = _lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::ePositionChanged;
     s->x = x;
@@ -917,9 +661,9 @@
     return NO_ERROR;
 }
 
-status_t SurfaceComposerClient::setSize(Surface* surface, uint32_t w, uint32_t h)
+status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h)
 {
-    layer_state_t* s = _lockLayerState(surface);
+    layer_state_t* s = _lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eSizeChanged;
     s->w = w;
@@ -928,9 +672,9 @@
     return NO_ERROR;
 }
 
-status_t SurfaceComposerClient::setLayer(Surface* surface, int32_t z)
+status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)
 {
-    layer_state_t* s = _lockLayerState(surface);
+    layer_state_t* s = _lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eLayerChanged;
     s->z = z;
@@ -938,32 +682,32 @@
     return NO_ERROR;
 }
 
-status_t SurfaceComposerClient::hide(Surface* surface)
+status_t SurfaceComposerClient::hide(SurfaceID id)
 {
-    return setFlags(surface, ISurfaceComposer::eLayerHidden,
+    return setFlags(id, ISurfaceComposer::eLayerHidden,
             ISurfaceComposer::eLayerHidden);
 }
 
-status_t SurfaceComposerClient::show(Surface* surface, int32_t)
+status_t SurfaceComposerClient::show(SurfaceID id, int32_t)
 {
-    return setFlags(surface, 0, ISurfaceComposer::eLayerHidden);
+    return setFlags(id, 0, ISurfaceComposer::eLayerHidden);
 }
 
-status_t SurfaceComposerClient::freeze(Surface* surface)
+status_t SurfaceComposerClient::freeze(SurfaceID id)
 {
-    return setFlags(surface, ISurfaceComposer::eLayerFrozen,
+    return setFlags(id, ISurfaceComposer::eLayerFrozen,
             ISurfaceComposer::eLayerFrozen);
 }
 
-status_t SurfaceComposerClient::unfreeze(Surface* surface)
+status_t SurfaceComposerClient::unfreeze(SurfaceID id)
 {
-    return setFlags(surface, 0, ISurfaceComposer::eLayerFrozen);
+    return setFlags(id, 0, ISurfaceComposer::eLayerFrozen);
 }
 
-status_t SurfaceComposerClient::setFlags(Surface* surface,
+status_t SurfaceComposerClient::setFlags(SurfaceID id,
         uint32_t flags, uint32_t mask)
 {
-    layer_state_t* s = _lockLayerState(surface);
+    layer_state_t* s = _lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eVisibilityChanged;
     s->flags &= ~mask;
@@ -973,11 +717,10 @@
     return NO_ERROR;
 }
 
-
 status_t SurfaceComposerClient::setTransparentRegionHint(
-        Surface* surface, const Region& transparentRegion)
+        SurfaceID id, const Region& transparentRegion)
 {
-    layer_state_t* s = _lockLayerState(surface);
+    layer_state_t* s = _lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eTransparentRegionChanged;
     s->transparentRegion = transparentRegion;
@@ -985,9 +728,9 @@
     return NO_ERROR;
 }
 
-status_t SurfaceComposerClient::setAlpha(Surface* surface, float alpha)
+status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha)
 {
-    layer_state_t* s = _lockLayerState(surface);
+    layer_state_t* s = _lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eAlphaChanged;
     s->alpha = alpha;
@@ -996,11 +739,11 @@
 }
 
 status_t SurfaceComposerClient::setMatrix(
-        Surface* surface,
+        SurfaceID id,
         float dsdx, float dtdx,
         float dsdy, float dtdy )
 {
-    layer_state_t* s = _lockLayerState(surface);
+    layer_state_t* s = _lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eMatrixChanged;
     layer_state_t::matrix22_t matrix;
@@ -1013,9 +756,9 @@
     return NO_ERROR;
 }
 
-status_t SurfaceComposerClient::setFreezeTint(Surface* surface, uint32_t tint)
+status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
 {
-    layer_state_t* s = _lockLayerState(surface);
+    layer_state_t* s = _lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eFreezeTintChanged;
     s->tint = tint;
diff --git a/libs/ui/SurfaceFlingerSynchro.cpp b/libs/ui/SurfaceFlingerSynchro.cpp
index 5cd9755..c81db71 100644
--- a/libs/ui/SurfaceFlingerSynchro.cpp
+++ b/libs/ui/SurfaceFlingerSynchro.cpp
@@ -14,19 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "SurfaceFlingerSynchro"
-
 #include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <utils/IPCThreadState.h>
-#include <utils/Log.h>
 
 #include <private/ui/SurfaceFlingerSynchro.h>
 
@@ -34,61 +22,10 @@
 
 // ---------------------------------------------------------------------------
 
-SurfaceFlingerSynchro::Barrier::Barrier()
-    : state(CLOSED) { 
-}
-
-SurfaceFlingerSynchro::Barrier::~Barrier() { 
-}
-
-void SurfaceFlingerSynchro::Barrier::open() {
-    asm volatile ("":::"memory");
-    Mutex::Autolock _l(lock);
-    state = OPENED;
-    cv.broadcast();
-}
-
-void SurfaceFlingerSynchro::Barrier::close() {
-    Mutex::Autolock _l(lock);
-    state = CLOSED;
-}
-
-void SurfaceFlingerSynchro::Barrier::waitAndClose() 
-{
-    Mutex::Autolock _l(lock);
-    while (state == CLOSED) {
-        // we're about to wait, flush the binder command buffer
-        IPCThreadState::self()->flushCommands();
-        cv.wait(lock);
-    }
-    state = CLOSED;
-}
-
-status_t SurfaceFlingerSynchro::Barrier::waitAndClose(nsecs_t timeout) 
-{
-    Mutex::Autolock _l(lock);
-    while (state == CLOSED) {
-        // we're about to wait, flush the binder command buffer
-        IPCThreadState::self()->flushCommands();
-        int err = cv.waitRelative(lock, timeout);
-        if (err != 0)
-            return err;
-    }
-    state = CLOSED;
-    return NO_ERROR;
-}
-
-// ---------------------------------------------------------------------------
-
 SurfaceFlingerSynchro::SurfaceFlingerSynchro(const sp<ISurfaceComposer>& flinger)
     : mSurfaceComposer(flinger)
 {
 }
-
-SurfaceFlingerSynchro::SurfaceFlingerSynchro()
-{
-}
-
 SurfaceFlingerSynchro::~SurfaceFlingerSynchro()
 {
 }
@@ -99,24 +36,6 @@
     return NO_ERROR;
 }
 
-status_t SurfaceFlingerSynchro::wait()
-{
-    mBarrier.waitAndClose();
-    return NO_ERROR;
-}
-
-status_t SurfaceFlingerSynchro::wait(nsecs_t timeout)
-{
-    if (timeout == 0)
-        return SurfaceFlingerSynchro::wait();
-    return mBarrier.waitAndClose(timeout);
-}
-
-void SurfaceFlingerSynchro::open()
-{
-    mBarrier.open();
-}
-
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
new file mode 100644
index 0000000..6cc4a5a
--- /dev/null
+++ b/libs/ui/tests/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	region.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+    libui
+
+LOCAL_MODULE:= test-region
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/ui/tests/region.cpp b/libs/ui/tests/region.cpp
new file mode 100644
index 0000000..0deb2ba
--- /dev/null
+++ b/libs/ui/tests/region.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Region"
+
+#include <stdio.h>
+#include <utils/Debug.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+using namespace android;
+
+int main()
+{
+    Region reg0( Rect(  0, 0,  100, 100 ) );
+    Region reg1 = reg0;
+    Region reg2, reg3;
+    
+    reg0.dump("reg0");
+    reg1.dump("reg1");
+
+    reg0 = reg0 | reg0.translate(150, 0);
+    reg0.dump("reg0");
+    reg1.dump("reg1");
+
+    reg0 = reg0 | reg0.translate(300, 0);
+    reg0.dump("reg0");
+    reg1.dump("reg1");
+
+    //reg2 = reg0 | reg0.translate(0, 100);
+    //reg0.dump("reg0");
+    //reg1.dump("reg1");
+    //reg2.dump("reg2");
+
+    //reg3 = reg0 | reg0.translate(0, 150);
+    //reg0.dump("reg0");
+    //reg1.dump("reg1");
+    //reg2.dump("reg2");
+    //reg3.dump("reg3");
+
+    LOGD("---");
+    reg2 = reg0 | reg0.translate(100, 0);
+    reg0.dump("reg0");
+    reg1.dump("reg1");
+    reg2.dump("reg2");
+    
+    return 0;
+}
+
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index 9bdd64a..3f5cb85 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -32,51 +32,30 @@
 	StopWatch.cpp \
 	String8.cpp \
 	String16.cpp \
+	StringArray.cpp \
 	SystemClock.cpp \
 	TextOutput.cpp \
 	Threads.cpp \
-	TimerProbe.cpp \
 	Timers.cpp \
 	VectorImpl.cpp \
     ZipFileCRO.cpp \
 	ZipFileRO.cpp \
 	ZipUtils.cpp \
-	misc.cpp \
-	ported.cpp \
-	LogSocket.cpp
+	misc.cpp
 
-#
-# The cpp files listed here do not belong in the device
-# build.  Consult with the swetland before even thinking about
-# putting them in commonSources.
-#
-# They're used by the simulator runtime and by host-side tools like
-# aapt and the simulator front-end.
-#
-hostSources:= \
-	InetAddress.cpp \
-	Pipe.cpp \
-	Socket.cpp \
-	ZipEntry.cpp \
-	ZipFile.cpp
 
 # For the host
 # =====================================================
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= $(commonSources) $(hostSources)
+LOCAL_SRC_FILES:= $(commonSources)
 
 ifeq ($(HOST_OS),linux)
 # Use the futex based mutex and condition variable
 # implementation from android-arm because it's shared mem safe
 	LOCAL_SRC_FILES += \
-		futex_synchro.c \
-		executablepath_linux.cpp
-endif
-ifeq ($(HOST_OS),darwin)
-	LOCAL_SRC_FILES += \
-		executablepath_darwin.cpp
+		futex_synchro.c
 endif
 
 LOCAL_MODULE:= libutils
@@ -103,27 +82,10 @@
 # we have the common sources, plus some device-specific stuff
 LOCAL_SRC_FILES:= \
 	$(commonSources) \
-	Binder.cpp \
-	BpBinder.cpp \
-	IInterface.cpp \
-	IMemory.cpp \
-	IPCThreadState.cpp \
-	MemoryDealer.cpp \
-    MemoryBase.cpp \
-    MemoryHeapBase.cpp \
-    MemoryHeapPmem.cpp \
-	Parcel.cpp \
-	ProcessState.cpp \
-	IPermissionController.cpp \
-	IServiceManager.cpp \
 	Unicode.cpp \
     BackupData.cpp \
 	BackupHelpers.cpp
 
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_SRC_FILES += $(hostSources)
-endif
-
 ifeq ($(TARGET_OS),linux)
 # Use the futex based mutex and condition variable
 # implementation from android-arm because it's shared mem safe
@@ -150,9 +112,5 @@
 endif # sim
 
 LOCAL_MODULE:= libutils
-
-#LOCAL_CFLAGS+=
-#LOCAL_LDFLAGS:=
-
 include $(BUILD_SHARED_LIBRARY)
 
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
index 2fdaa71..55b6024 100644
--- a/libs/utils/CallStack.cpp
+++ b/libs/utils/CallStack.cpp
@@ -311,7 +311,8 @@
     } else { 
         void const* start = 0;
         name = MapInfo::mapAddressToName(ip, "<unknown>", &start);
-        snprintf(tmp, 256, "pc %08lx  %s", uintptr_t(ip)-uintptr_t(start), name);
+        snprintf(tmp, 256, "pc %08lx  %s", 
+                long(uintptr_t(ip)-uintptr_t(start)), name);
         res.append(tmp);
     }
     res.append("\n");
diff --git a/libs/utils/IDataConnection.cpp b/libs/utils/IDataConnection.cpp
deleted file mode 100644
index c6d49aa..0000000
--- a/libs/utils/IDataConnection.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Parcel.h>
-
-#include <utils/IDataConnection.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-enum
-{
-    CONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
-    DISCONNECT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 1
-};
-
-class BpDataConnection : public BpInterface<IDataConnection>
-{
-public:
-    BpDataConnection::BpDataConnection(const sp<IBinder>& impl)
-        : BpInterface<IDataConnection>(impl)
-    {
-    }
-
-	virtual void connect()
-	{
-		Parcel data, reply;
-        data.writeInterfaceToken(IDataConnection::descriptor());
-		remote()->transact(CONNECT_TRANSACTION, data, &reply);
-	}
-	
-	virtual void disconnect()
-	{
-		Parcel data, reply;
-		remote()->transact(DISCONNECT_TRANSACTION, data, &reply);
-	}
-};
-
-IMPLEMENT_META_INTERFACE(DataConnection, "android.utils.IDataConnection");
-
-#define CHECK_INTERFACE(interface, data, reply) \
-        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
-            LOGW("Call incorrectly routed to " #interface); \
-            return PERMISSION_DENIED; \
-        } } while (0)
-
-status_t BnDataConnection::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code)
-    {
-		case CONNECT_TRANSACTION:
-		{                   
-            CHECK_INTERFACE(IDataConnection, data, reply);
-			connect();
-			return NO_ERROR;
-		}    
-		
-		case DISCONNECT_TRANSACTION:
-		{                   
-            CHECK_INTERFACE(IDataConnection, data, reply);
-			disconnect();
-			return NO_ERROR;
-		}
-       
-		default:
-			return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/utils/InetAddress.cpp b/libs/utils/InetAddress.cpp
deleted file mode 100644
index 39a0a68..0000000
--- a/libs/utils/InetAddress.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// Internet address class.
-//
-#ifdef HAVE_WINSOCK
-# include <winsock2.h>
-#else
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-//# include <arpa/inet.h>
-# include <netdb.h>
-#endif
-
-#include <utils/inet_address.h>
-#include <utils/threads.h>
-#include <utils/Log.h>
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-using namespace android;
-
-
-/*
- * ===========================================================================
- *      InetAddress
- * ===========================================================================
- */
-
-// lock for the next couple of functions; could tuck into InetAddress
-static Mutex*   gGHBNLock;
-
-/*
- * Lock/unlock access to the hostent struct returned by gethostbyname().
- */
-static inline void lock_gethostbyname(void)
-{
-    if (gGHBNLock == NULL)
-        gGHBNLock = new Mutex;
-    gGHBNLock->lock();
-}
-static inline void unlock_gethostbyname(void)
-{
-    assert(gGHBNLock != NULL);
-    gGHBNLock->unlock();
-}
-
-
-/*
- * Constructor -- just init members.  This is private so that callers
- * are required to use getByName().
- */
-InetAddress::InetAddress(void)
-    : mAddress(NULL), mLength(-1), mName(NULL)
-{
-}
-
-/*
- * Destructor -- free address storage.
- */
-InetAddress::~InetAddress(void)
-{
-    delete[] (char*) mAddress;
-    delete[] mName;
-}
-
-/*
- * Copy constructor.
- */
-InetAddress::InetAddress(const InetAddress& orig)
-{
-    *this = orig;   // use assignment code
-}
-
-/*
- * Assignment operator.
- */
-InetAddress& InetAddress::operator=(const InetAddress& addr)
-{
-    // handle self-assignment
-    if (this == &addr)
-        return *this;
-    // copy mLength and mAddress
-    mLength = addr.mLength;
-    if (mLength > 0) {
-        mAddress = new char[mLength];
-        memcpy(mAddress, addr.mAddress, mLength);
-        LOG(LOG_DEBUG, "socket",
-            "HEY: copied %d bytes in assignment operator\n", mLength);
-    } else {
-        mAddress = NULL;
-    }
-    // copy mName
-    mName = new char[strlen(addr.mName)+1];
-    strcpy(mName, addr.mName);
-
-    return *this;
-}
-
-/*
- * Create a new object from a name or a dotted-number IP notation.
- *
- * Returns NULL on failure.
- */
-InetAddress*
-InetAddress::getByName(const char* host)
-{
-    InetAddress* newAddr = NULL;
-    struct sockaddr_in addr;
-    struct hostent* he;
-    DurationTimer hostTimer, lockTimer;
-
-    // gethostbyname() isn't reentrant, so we need to lock things until
-    // we can copy the data out.
-    lockTimer.start();
-    lock_gethostbyname();
-    hostTimer.start();
-
-    he = gethostbyname(host);
-    if (he == NULL) {
-        LOG(LOG_WARN, "socket", "WARNING: cannot resolve host %s\n", host);
-        unlock_gethostbyname();
-        return NULL;
-    }
-
-    memcpy(&addr.sin_addr, he->h_addr, he->h_length);
-    addr.sin_family = he->h_addrtype;
-    addr.sin_port = 0;
-
-    // got it, unlock us
-    hostTimer.stop();
-    he = NULL;
-    unlock_gethostbyname();
-
-    lockTimer.stop();
-    if ((long) lockTimer.durationUsecs() > 100000) {
-        long lockTime = (long) lockTimer.durationUsecs();
-        long hostTime = (long) hostTimer.durationUsecs();
-        LOG(LOG_DEBUG, "socket",
-            "Lookup of %s took %.3fs (gethostbyname=%.3fs lock=%.3fs)\n",
-            host, lockTime / 1000000.0, hostTime / 1000000.0,
-            (lockTime - hostTime) / 1000000.0);
-    }
-
-    // Alloc storage and copy it over.
-    newAddr = new InetAddress();
-    if (newAddr == NULL)
-        return NULL;
-
-    newAddr->mLength = sizeof(struct sockaddr_in);
-    newAddr->mAddress = new char[sizeof(struct sockaddr_in)];
-    if (newAddr->mAddress == NULL) {
-        delete newAddr;
-        return NULL;
-    }
-    memcpy(newAddr->mAddress, &addr, newAddr->mLength);
-
-    // Keep this for debug messages.
-    newAddr->mName = new char[strlen(host)+1];
-    if (newAddr->mName == NULL) {
-        delete newAddr;
-        return NULL;
-    }
-    strcpy(newAddr->mName, host);
-
-    return newAddr;
-}
-
-
-/*
- * ===========================================================================
- *      InetSocketAddress
- * ===========================================================================
- */
-
-/*
- * Create an address with the host wildcard (INADDR_ANY).
- */
-bool InetSocketAddress::create(int port)
-{
-    assert(mAddress == NULL);
-
-    mAddress = InetAddress::getByName("0.0.0.0");
-    if (mAddress == NULL)
-        return false;
-    mPort = port;
-    return true;
-}
-
-/*
- * Create address with host and port specified.
- */
-bool InetSocketAddress::create(const InetAddress* addr, int port)
-{
-    assert(mAddress == NULL);
-
-    mAddress = new InetAddress(*addr);  // make a copy
-    if (mAddress == NULL)
-        return false;
-    mPort = port;
-    return true;
-}
-
-/*
- * Create address with host and port specified.
- */
-bool InetSocketAddress::create(const char* host, int port)
-{
-    assert(mAddress == NULL);
-
-    mAddress = InetAddress::getByName(host);
-    if (mAddress == NULL)
-        return false;
-    mPort = port;
-    return true;
-}
-
diff --git a/libs/utils/LogSocket.cpp b/libs/utils/LogSocket.cpp
deleted file mode 100644
index 55c1b99..0000000
--- a/libs/utils/LogSocket.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef HAVE_WINSOCK
-//#define SOCKETLOG
-#endif
-
-#ifdef SOCKETLOG
-
-#define LOG_TAG "SOCKETLOG"
-
-#include <string.h>
-#include <cutils/log.h>
-#include "utils/LogSocket.h"
-#include "utils/logger.h"
-#include "cutils/hashmap.h"
-
-// defined in //device/data/etc/event-log-tags
-#define SOCKET_CLOSE_LOG 51000
-
-static Hashmap* statsMap = NULL;
-
-#define LOG_LIST_NUMBER 5
-
-typedef struct SocketStats {
-    int fd;
-    unsigned int send;
-    unsigned int recv;
-    unsigned int ip;
-    unsigned short port;
-    short reason;
-}SocketStats;
-
-SocketStats *get_socket_stats(int fd) {
-    if (statsMap == NULL) {
-        statsMap = hashmapCreate(8, &hashmapIntHash, &hashmapIntEquals);
-    }
-
-    SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
-    if (s == NULL) {
-        // LOGD("create SocketStats for fd %d", fd);
-        s = (SocketStats*) malloc(sizeof(SocketStats));
-        memset(s, 0, sizeof(SocketStats));
-        s->fd = fd;
-        hashmapPut(statsMap, &s->fd, s);
-    }
-    return s;
-}
-
-void log_socket_connect(int fd, unsigned int ip, unsigned short port) {
-    // LOGD("log_socket_connect for fd %d ip %d port%d", fd, ip, port);
-    SocketStats *s = get_socket_stats(fd);
-    s->ip = ip;
-    s->port = port;
-}
-
-void add_send_stats(int fd, int send) {
-    if (send <=0) {
-        LOGE("add_send_stats send %d", send);
-        return;
-    }
-    SocketStats *s = get_socket_stats(fd);
-    s->send += send;
-    // LOGD("add_send_stats for fd %d ip %d port%d", fd, s->ip, s->port);
-}
-
-void add_recv_stats(int fd, int recv) {
-    if (recv <=0) {
-        LOGE("add_recv_stats recv %d", recv);
-        return;
-    }
-    SocketStats *s = get_socket_stats(fd);
-    s->recv += recv;
-    // LOGD("add_recv_stats for fd %d ip %d port%d", fd, s->ip, s->port);
-}
-
-char* put_int(char* buf, int value) {
-    *buf = EVENT_TYPE_INT;
-    buf++;
-    memcpy(buf, &value, sizeof(int));
-    return buf + sizeof(int);
-}
-
-void log_socket_close(int fd, short reason) {
-    if (statsMap) {
-        SocketStats *s = (SocketStats*) hashmapGet(statsMap, &fd);
-        if (s != NULL) {
-            if (s->send != 0 || s->recv != 0) {
-                s->reason = reason;
-                // 5 int + list type need 2 bytes
-                char buf[LOG_LIST_NUMBER * 5 + 2];
-                buf[0] = EVENT_TYPE_LIST;
-                buf[1] = LOG_LIST_NUMBER;
-                char* writePos = buf + 2;
-                writePos = put_int(writePos, s->send);
-                writePos = put_int(writePos, s->recv);
-                writePos = put_int(writePos, s->ip);
-                writePos = put_int(writePos, s->port);
-                writePos = put_int(writePos, s->reason);
-                
-                android_bWriteLog(SOCKET_CLOSE_LOG, buf, sizeof(buf));
-                // LOGD("send %d recv %d reason %d", s->send, s->recv, s->reason);
-            }
-            hashmapRemove(statsMap, &s->fd);
-            free(s);
-        }
-    }
-}
-
-#else
-void add_send_stats(int fd, int send) {} 
-void add_recv_stats(int fd, int recv) {}
-void log_socket_close(int fd, short reason) {}
-void log_socket_connect(int fd, unsigned int ip, unsigned short port) {}
-#endif
diff --git a/libs/utils/Pipe.cpp b/libs/utils/Pipe.cpp
deleted file mode 100644
index 613906b..0000000
--- a/libs/utils/Pipe.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// Unidirectional pipe.
-//
-
-#include <utils/Pipe.h>
-#include <utils/Log.h>
-
-#if defined(HAVE_WIN32_IPC)
-# include <windows.h>
-#else
-# include <fcntl.h>
-# include <unistd.h>
-# include <errno.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-
-using namespace android;
-
-const unsigned long kInvalidHandle = (unsigned long) -1;
-
-
-/*
- * Constructor.  Do little.
- */
-Pipe::Pipe(void)
-    : mReadNonBlocking(false), mReadHandle(kInvalidHandle),
-      mWriteHandle(kInvalidHandle)
-{
-}
-
-/*
- * Destructor.  Use the system-appropriate close call.
- */
-Pipe::~Pipe(void)
-{
-#if defined(HAVE_WIN32_IPC)
-    if (mReadHandle != kInvalidHandle) {
-        if (!CloseHandle((HANDLE)mReadHandle))
-            LOG(LOG_WARN, "pipe", "failed closing read handle (%ld)\n",
-                mReadHandle);
-    }
-    if (mWriteHandle != kInvalidHandle) {
-        FlushFileBuffers((HANDLE)mWriteHandle);
-        if (!CloseHandle((HANDLE)mWriteHandle))
-            LOG(LOG_WARN, "pipe", "failed closing write handle (%ld)\n",
-                mWriteHandle);
-    }
-#else
-    if (mReadHandle != kInvalidHandle) {
-        if (close((int) mReadHandle) != 0)
-            LOG(LOG_WARN, "pipe", "failed closing read fd (%d)\n",
-                (int) mReadHandle);
-    }
-    if (mWriteHandle != kInvalidHandle) {
-        if (close((int) mWriteHandle) != 0)
-            LOG(LOG_WARN, "pipe", "failed closing write fd (%d)\n",
-                (int) mWriteHandle);
-    }
-#endif
-}
-
-/*
- * Create the pipe.
- *
- * Use the POSIX stuff for everything but Windows.
- */
-bool Pipe::create(void)
-{
-    assert(mReadHandle == kInvalidHandle);
-    assert(mWriteHandle == kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
-    /* we use this across processes, so they need to be inheritable */
-    HANDLE handles[2];
-    SECURITY_ATTRIBUTES saAttr;
-
-    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
-    saAttr.bInheritHandle = TRUE;
-    saAttr.lpSecurityDescriptor = NULL;
-
-    if (!CreatePipe(&handles[0], &handles[1], &saAttr, 0)) {
-        LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
-        return false;
-    }
-    mReadHandle = (unsigned long) handles[0];
-    mWriteHandle = (unsigned long) handles[1];
-    return true;
-#else
-    int fds[2];
-
-    if (pipe(fds) != 0) {
-        LOG(LOG_ERROR, "pipe", "unable to create pipe\n");
-        return false;
-    }
-    mReadHandle = fds[0];
-    mWriteHandle = fds[1];
-    return true;
-#endif
-}
-
-/*
- * Create a "half pipe".  Please, no Segway riding.
- */
-bool Pipe::createReader(unsigned long handle)
-{
-    mReadHandle = handle;
-    assert(mWriteHandle == kInvalidHandle);
-    return true;
-}
-
-/*
- * Create a "half pipe" for writing.
- */
-bool Pipe::createWriter(unsigned long handle)
-{
-    mWriteHandle = handle;
-    assert(mReadHandle == kInvalidHandle);
-    return true;
-}
-
-/*
- * Return "true" if create() has been called successfully.
- */
-bool Pipe::isCreated(void)
-{
-    // one or the other should be open
-    return (mReadHandle != kInvalidHandle || mWriteHandle != kInvalidHandle);
-}
-
-
-/*
- * Read data from the pipe.
- *
- * For Linux and Darwin, just call read().  For Windows, implement
- * non-blocking reads by calling PeekNamedPipe first.
- */
-int Pipe::read(void* buf, int count)
-{
-    assert(mReadHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
-    DWORD totalBytesAvail = count;
-    DWORD bytesRead;
-
-    if (mReadNonBlocking) {
-        // use PeekNamedPipe to adjust read count expectations
-        if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
-                &totalBytesAvail, NULL))
-        {
-            LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
-            return -1;
-        }
-
-        if (totalBytesAvail == 0)
-            return 0;
-    }
-
-    if (!ReadFile((HANDLE) mReadHandle, buf, totalBytesAvail, &bytesRead,
-            NULL))
-    {
-        DWORD err = GetLastError();
-        if (err == ERROR_HANDLE_EOF || err == ERROR_BROKEN_PIPE)
-            return 0;
-        LOG(LOG_ERROR, "pipe", "ReadFile failed (err=%ld)\n", err);
-        return -1;
-    }
-
-    return (int) bytesRead;
-#else
-    int cc;
-    cc = ::read(mReadHandle, buf, count);
-    if (cc < 0 && errno == EAGAIN)
-        return 0;
-    return cc;
-#endif
-}
-
-/*
- * Write data to the pipe.
- *
- * POSIX systems are trivial, Windows uses a different call and doesn't
- * handle non-blocking writes.
- *
- * If we add non-blocking support here, we probably want to make it an
- * all-or-nothing write.
- *
- * DO NOT use LOG() here, we could be writing a log message.
- */
-int Pipe::write(const void* buf, int count)
-{
-    assert(mWriteHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
-    DWORD bytesWritten;
-
-    if (mWriteNonBlocking) {
-        // BUG: can't use PeekNamedPipe() to get the amount of space
-        // left.  Looks like we need to use "overlapped I/O" functions.
-        // I just don't care that much.
-    }
-
-    if (!WriteFile((HANDLE) mWriteHandle, buf, count, &bytesWritten, NULL)) {
-        // can't LOG, use stderr
-        fprintf(stderr, "WriteFile failed (err=%ld)\n", GetLastError());
-        return -1;
-    }
-
-    return (int) bytesWritten;
-#else
-    int cc;
-    cc = ::write(mWriteHandle, buf, count);
-    if (cc < 0 && errno == EAGAIN)
-        return 0;
-    return cc;
-#endif
-}
-
-/*
- * Figure out if there is data available on the read fd.
- *
- * We return "true" on error because we want the caller to try to read
- * from the pipe.  They'll notice the read failure and do something
- * appropriate.
- */
-bool Pipe::readReady(void)
-{
-    assert(mReadHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
-    DWORD totalBytesAvail;
-
-    if (!PeekNamedPipe((HANDLE) mReadHandle, NULL, 0, NULL,
-            &totalBytesAvail, NULL))
-    {
-        LOG(LOG_ERROR, "pipe", "PeekNamedPipe failed\n");
-        return true;
-    }
-
-    return (totalBytesAvail != 0);
-#else
-    errno = 0;
-    fd_set readfds;
-    struct timeval tv = { 0, 0 };
-    int cc;
-
-    FD_ZERO(&readfds);
-    FD_SET(mReadHandle, &readfds);
-
-    cc = select(mReadHandle+1, &readfds, NULL, NULL, &tv);
-    if (cc < 0) {
-        LOG(LOG_ERROR, "pipe", "select() failed\n");
-        return true;
-    } else if (cc == 0) {
-        /* timed out, nothing available */
-        return false;
-    } else if (cc == 1) {
-        /* our fd is ready */
-        return true;
-    } else {
-        LOG(LOG_ERROR, "pipe", "HUH? select() returned > 1\n");
-        return true;
-    }
-#endif
-}
-
-/*
- * Enable or disable non-blocking mode for the read descriptor.
- *
- * NOTE: the calls succeed under Mac OS X, but the pipe doesn't appear to
- * actually be in non-blocking mode.  If this matters -- i.e. you're not
- * using a select() call -- put a call to readReady() in front of the
- * ::read() call, with a PIPE_NONBLOCK_BROKEN #ifdef in the Makefile for
- * Darwin.
- */
-bool Pipe::setReadNonBlocking(bool val)
-{
-    assert(mReadHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
-    // nothing to do
-#else
-    int flags;
-
-    if (fcntl(mReadHandle, F_GETFL, &flags) == -1) {
-        LOG(LOG_ERROR, "pipe", "couldn't get flags for pipe read fd\n");
-        return false;
-    }
-    if (val)
-        flags |= O_NONBLOCK;
-    else
-        flags &= ~(O_NONBLOCK);
-    if (fcntl(mReadHandle, F_SETFL, &flags) == -1) {
-        LOG(LOG_ERROR, "pipe", "couldn't set flags for pipe read fd\n");
-        return false;
-    }
-#endif
-
-    mReadNonBlocking = val;
-    return true;
-}
-
-/*
- * Enable or disable non-blocking mode for the write descriptor.
- *
- * As with setReadNonBlocking(), this does not work on the Mac.
- */
-bool Pipe::setWriteNonBlocking(bool val)
-{
-    assert(mWriteHandle != kInvalidHandle);
-
-#if defined(HAVE_WIN32_IPC)
-    // nothing to do
-#else
-    int flags;
-
-    if (fcntl(mWriteHandle, F_GETFL, &flags) == -1) {
-        LOG(LOG_WARN, "pipe",
-            "Warning: couldn't get flags for pipe write fd (errno=%d)\n",
-            errno);
-        return false;
-    }
-    if (val)
-        flags |= O_NONBLOCK;
-    else
-        flags &= ~(O_NONBLOCK);
-    if (fcntl(mWriteHandle, F_SETFL, &flags) == -1) {
-        LOG(LOG_WARN, "pipe",
-            "Warning: couldn't set flags for pipe write fd (errno=%d)\n",
-            errno);
-        return false;
-    }
-#endif
-
-    mWriteNonBlocking = val;
-    return true;
-}
-
-/*
- * Specify whether a file descriptor can be inherited by a child process.
- * Under Linux this means setting the close-on-exec flag, under Windows
- * this is SetHandleInformation(HANDLE_FLAG_INHERIT).
- */
-bool Pipe::disallowReadInherit(void)
-{
-    if (mReadHandle == kInvalidHandle)
-        return false;
-
-#if defined(HAVE_WIN32_IPC)
-    if (SetHandleInformation((HANDLE) mReadHandle, HANDLE_FLAG_INHERIT, 0) == 0)
-        return false;
-#else
-    if (fcntl((int) mReadHandle, F_SETFD, FD_CLOEXEC) != 0)
-        return false;
-#endif
-    return true;
-}
-bool Pipe::disallowWriteInherit(void)
-{
-    if (mWriteHandle == kInvalidHandle)
-        return false;
-
-#if defined(HAVE_WIN32_IPC)
-    if (SetHandleInformation((HANDLE) mWriteHandle, HANDLE_FLAG_INHERIT, 0) == 0)
-        return false;
-#else
-    if (fcntl((int) mWriteHandle, F_SETFD, FD_CLOEXEC) != 0)
-        return false;
-#endif
-    return true;
-}
-
-/*
- * Close read descriptor.
- */
-bool Pipe::closeRead(void)
-{
-    if (mReadHandle == kInvalidHandle)
-        return false;
-
-#if defined(HAVE_WIN32_IPC)
-    if (mReadHandle != kInvalidHandle) {
-        if (!CloseHandle((HANDLE)mReadHandle)) {
-            LOG(LOG_WARN, "pipe", "failed closing read handle\n");
-            return false;
-        }
-    }
-#else
-    if (mReadHandle != kInvalidHandle) {
-        if (close((int) mReadHandle) != 0) {
-            LOG(LOG_WARN, "pipe", "failed closing read fd\n");
-            return false;
-        }
-    }
-#endif
-    mReadHandle = kInvalidHandle;
-    return true;
-}
-
-/*
- * Close write descriptor.
- */
-bool Pipe::closeWrite(void)
-{
-    if (mWriteHandle == kInvalidHandle)
-        return false;
-
-#if defined(HAVE_WIN32_IPC)
-    if (mWriteHandle != kInvalidHandle) {
-        if (!CloseHandle((HANDLE)mWriteHandle)) {
-            LOG(LOG_WARN, "pipe", "failed closing write handle\n");
-            return false;
-        }
-    }
-#else
-    if (mWriteHandle != kInvalidHandle) {
-        if (close((int) mWriteHandle) != 0) {
-            LOG(LOG_WARN, "pipe", "failed closing write fd\n");
-            return false;
-        }
-    }
-#endif
-    mWriteHandle = kInvalidHandle;
-    return true;
-}
-
-/*
- * Get the read handle.
- */
-unsigned long Pipe::getReadHandle(void)
-{
-    assert(mReadHandle != kInvalidHandle);
-
-    return mReadHandle;
-}
-
-/*
- * Get the write handle.
- */
-unsigned long Pipe::getWriteHandle(void)
-{
-    assert(mWriteHandle != kInvalidHandle);
-
-    return mWriteHandle;
-}
-
diff --git a/libs/utils/Socket.cpp b/libs/utils/Socket.cpp
deleted file mode 100644
index 51509a3..0000000
--- a/libs/utils/Socket.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// Internet address class.
-//
-
-#ifdef HAVE_WINSOCK
-// This needs to come first, or Cygwin gets concerned about a potential
-// clash between WinSock and <sys/types.h>.
-# include <winsock2.h>
-#endif
-
-#include <utils/Socket.h>
-#include <utils/inet_address.h>
-#include <utils/Log.h>
-#include <utils/Timers.h>
-
-#ifndef HAVE_WINSOCK
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-
-/*
- * ===========================================================================
- *      Socket
- * ===========================================================================
- */
-
-#ifndef INVALID_SOCKET
-# define INVALID_SOCKET (-1)
-#endif
-#define UNDEF_SOCKET   ((unsigned long) INVALID_SOCKET)
-
-/*static*/ bool Socket::mBootInitialized = false;
-
-/*
- * Extract system-dependent error code.
- */
-static inline int getSocketError(void) {
-#ifdef HAVE_WINSOCK
-    return WSAGetLastError();
-#else
-    return errno;
-#endif
-}
-
-/*
- * One-time initialization for socket code.
- */
-/*static*/ bool Socket::bootInit(void)
-{
-#ifdef HAVE_WINSOCK
-    WSADATA wsaData;
-    int err;
-
-    err = WSAStartup(MAKEWORD(2, 0), &wsaData);
-    if (err != 0) {
-        LOG(LOG_ERROR, "socket", "Unable to start WinSock\n");
-        return false;
-    }
-
-    LOG(LOG_INFO, "socket", "Using WinSock v%d.%d\n",
-        LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
-#endif
-
-    mBootInitialized = true;
-    return true;
-}
-
-/*
- * One-time shutdown for socket code.
- */
-/*static*/ void Socket::finalShutdown(void)
-{
-#ifdef HAVE_WINSOCK
-    WSACleanup();
-#endif
-    mBootInitialized = false;
-}
-
-
-/*
- * Simple constructor.  Allow the application to create us and then make
- * bind/connect calls.
- */
-Socket::Socket(void)
-    : mSock(UNDEF_SOCKET)
-{
-    if (!mBootInitialized)
-        LOG(LOG_WARN, "socket", "WARNING: sockets not initialized\n");
-}
-
-/*
- * Destructor.  Closes the socket and resets our storage.
- */
-Socket::~Socket(void)
-{
-    close();
-}
-
-
-/*
- * Create a socket and connect to the specified host and port.
- */
-int Socket::connect(const char* host, int port)
-{
-    if (mSock != UNDEF_SOCKET) {
-        LOG(LOG_WARN, "socket", "Socket already connected\n");
-        return -1;
-    }
-
-    InetSocketAddress sockAddr;
-    if (!sockAddr.create(host, port))
-        return -1;
-
-    //return doConnect(sockAddr);
-    int foo;
-    foo = doConnect(sockAddr);
-    return foo;
-}
-
-/*
- * Create a socket and connect to the specified host and port.
- */
-int Socket::connect(const InetAddress* addr, int port)
-{
-    if (mSock != UNDEF_SOCKET) {
-        LOG(LOG_WARN, "socket", "Socket already connected\n");
-        return -1;
-    }
-
-    InetSocketAddress sockAddr;
-    if (!sockAddr.create(addr, port))
-        return -1;
-
-    return doConnect(sockAddr);
-}
-
-/*
- * Finish creating a socket by connecting to the remote host.
- *
- * Returns 0 on success.
- */
-int Socket::doConnect(const InetSocketAddress& sockAddr)
-{
-#ifdef HAVE_WINSOCK
-    SOCKET sock;
-#else
-    int sock;
-#endif
-    const InetAddress* addr = sockAddr.getAddress();
-    int port = sockAddr.getPort();
-    struct sockaddr_in inaddr;
-    DurationTimer connectTimer;
-
-    assert(sizeof(struct sockaddr_in) == addr->getAddressLength());
-    memcpy(&inaddr, addr->getAddress(), addr->getAddressLength());
-    inaddr.sin_port = htons(port);
-
-    //fprintf(stderr, "--- connecting to %s:%d\n",
-    //    sockAddr.getHostName(), port);
-
-    sock = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (sock == INVALID_SOCKET) {
-        int err = getSocketError();
-        LOG(LOG_ERROR, "socket", "Unable to create socket (err=%d)\n", err);
-        return (err != 0) ? err : -1;
-    }
-
-    connectTimer.start();
-
-    if (::connect(sock, (struct sockaddr*) &inaddr, sizeof(inaddr)) != 0) {
-        int err = getSocketError();
-        LOG(LOG_WARN, "socket", "Connect to %s:%d failed: %d\n",
-            sockAddr.getHostName(), port, err);
-        return (err != 0) ? err : -1;
-    }
-
-    connectTimer.stop();
-    if ((long) connectTimer.durationUsecs() > 100000) {
-        LOG(LOG_INFO, "socket",
-            "Connect to %s:%d took %.3fs\n", sockAddr.getHostName(),
-            port, ((long) connectTimer.durationUsecs()) / 1000000.0);
-    }
-
-    mSock = (unsigned long) sock;
-    LOG(LOG_VERBOSE, "socket",
-        "--- connected to %s:%d\n", sockAddr.getHostName(), port);
-    return 0;
-}
-
-
-/*
- * Close the socket if it needs closing.
- */
-bool Socket::close(void)
-{
-    if (mSock != UNDEF_SOCKET) {
-        //fprintf(stderr, "--- closing socket %lu\n", mSock);
-#ifdef HAVE_WINSOCK
-        if (::closesocket((SOCKET) mSock) != 0)
-            return false;
-#else
-        if (::close((int) mSock) != 0)
-            return false;
-#endif
-    }
-
-    mSock = UNDEF_SOCKET;
-
-    return true;
-}
-
-/*
- * Read data from socket.
- *
- * Standard semantics: read up to "len" bytes into "buf".  Returns the
- * number of bytes read, or less than zero on error.
- */
-int Socket::read(void* buf, ssize_t len) const
-{
-    if (mSock == UNDEF_SOCKET) {
-        LOG(LOG_ERROR, "socket", "ERROR: read on invalid socket\n");
-        return -500;
-    }
-
-#ifdef HAVE_WINSOCK
-    SOCKET sock = (SOCKET) mSock;
-#else
-    int sock = (int) mSock;
-#endif
-    int cc;
-
-    cc = recv(sock, (char*)buf, len, 0);
-    if (cc < 0) {
-        int err = getSocketError();
-        return (err > 0) ? -err : -1;
-    }
-
-    return cc;
-}
-
-/*
- * Write data to a socket.
- *
- * Standard semantics: write up to "len" bytes into "buf".  Returns the
- * number of bytes written, or less than zero on error.
- */
-int Socket::write(const void* buf, ssize_t len) const
-{
-    if (mSock == UNDEF_SOCKET) {
-        LOG(LOG_ERROR, "socket", "ERROR: write on invalid socket\n");
-        return -500;
-    }
-
-#ifdef HAVE_WINSOCK
-    SOCKET sock = (SOCKET) mSock;
-#else
-    int sock = (int) mSock;
-#endif
-    int cc;
-
-    cc = send(sock, (const char*)buf, len, 0);
-    if (cc < 0) {
-        int err = getSocketError();
-        return (err > 0) ? -err : -1;
-    }
-
-    return cc;
-}
-
-
-/*
- * ===========================================================================
- *      Socket tests
- * ===========================================================================
- */
-
-/*
- * Read all data from the socket.  The data is read into a buffer that
- * expands as needed.
- *
- * On exit, the buffer is returned, and the length of the data is stored
- * in "*sz".  A null byte is added to the end, but is not included in
- * the length.
- */
-static char* socketReadAll(const Socket& s, int *sz)
-{
-    int max, r;
-    char *data, *ptr, *tmp;
-
-    data = (char*) malloc(max = 32768);
-    if (data == NULL)
-        return NULL;
-
-    ptr = data;
-    
-    for (;;) {
-        if ((ptr - data) == max) {
-            tmp = (char*) realloc(data, max *= 2);
-            if(tmp == 0) {
-                free(data);
-                return 0;
-            }
-        }
-        r = s.read(ptr, max - (ptr - data));
-        if (r == 0)
-            break;
-        if (r < 0) {
-            LOG(LOG_WARN, "socket", "WARNING: socket read failed (res=%d)\n",r);
-            break;
-        }
-        ptr += r;
-    }
-
-    if ((ptr - data) == max) {
-        tmp = (char*) realloc(data, max + 1);
-        if (tmp == NULL) {
-            free(data);
-            return NULL;
-        }
-    }
-    *ptr = '\0';
-    *sz = (ptr - data);
-    return data;
-}
-
-/*
- * Exercise the Socket class.
- */
-void android::TestSockets(void)
-{
-    printf("----- SOCKET TEST ------\n");
-    Socket::bootInit();
-
-    char* buf = NULL;
-    int len, cc;
-    const char* kTestStr =
-        "GET / HTTP/1.0\n"
-        "Connection: close\n"
-        "\n";
-
-    Socket sock;
-    if (sock.connect("www.google.com", 80) != 0) {
-        fprintf(stderr, "socket connected failed\n");
-        goto bail;
-    }
-
-    cc = sock.write(kTestStr, strlen(kTestStr));
-    if (cc != (int) strlen(kTestStr)) {
-        fprintf(stderr, "write failed, res=%d\n", cc);
-        goto bail;
-    }
-    buf = socketReadAll(sock, &len);
-
-    printf("GOT '%s'\n", buf);
-
-bail:
-    sock.close();
-    free(buf);
-}
-
diff --git a/libs/utils/Static.cpp b/libs/utils/Static.cpp
index 93f7e4f..4dfa578 100644
--- a/libs/utils/Static.cpp
+++ b/libs/utils/Static.cpp
@@ -20,7 +20,6 @@
 #include <private/utils/Static.h>
 
 #include <utils/BufferedTextOutput.h>
-#include <utils/IPCThreadState.h>
 #include <utils/Log.h>
 
 namespace android {
@@ -87,34 +86,4 @@
 TextOutput& aout(gStdoutTextOutput);
 TextOutput& aerr(gStderrTextOutput);
 
-#ifndef LIBUTILS_NATIVE
-
-// ------------ ProcessState.cpp
-
-Mutex gProcessMutex;
-sp<ProcessState> gProcess;
-
-class LibUtilsIPCtStatics
-{
-public:
-    LibUtilsIPCtStatics()
-    {
-    }
-    
-    ~LibUtilsIPCtStatics()
-    {
-        IPCThreadState::shutdown();
-    }
-};
-
-static LibUtilsIPCtStatics gIPCStatics;
-
-// ------------ ServiceManager.cpp
-
-Mutex gDefaultServiceManagerLock;
-sp<IServiceManager> gDefaultServiceManager;
-sp<IPermissionController> gPermissionController;
-
-#endif
-
 }   // namespace android
diff --git a/libs/utils/StringArray.cpp b/libs/utils/StringArray.cpp
new file mode 100644
index 0000000..aa42d68
--- /dev/null
+++ b/libs/utils/StringArray.cpp
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Sortable array of strings.  STL-ish, but STL-free.
+//  
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <utils/StringArray.h>
+
+namespace android {
+
+//
+// An expanding array of strings.  Add, get, sort, delete.
+//
+StringArray::StringArray()
+    : mMax(0), mCurrent(0), mArray(NULL)
+{
+}
+
+StringArray:: ~StringArray() {
+    for (int i = 0; i < mCurrent; i++)
+        delete[] mArray[i];
+    delete[] mArray;
+}
+
+//
+// Add a string.  A copy of the string is made.
+//
+bool StringArray::push_back(const char* str) {
+    if (mCurrent >= mMax) {
+        char** tmp;
+
+        if (mMax == 0)
+            mMax = 16;      // initial storage
+        else
+            mMax *= 2;
+
+        tmp = new char*[mMax];
+        if (tmp == NULL)
+            return false;
+
+        memcpy(tmp, mArray, mCurrent * sizeof(char*));
+        delete[] mArray;
+        mArray = tmp;
+    }
+
+    int len = strlen(str);
+    mArray[mCurrent] = new char[len+1];
+    memcpy(mArray[mCurrent], str, len+1);
+    mCurrent++;
+
+    return true;
+}
+
+//
+// Delete an entry.
+//
+void StringArray::erase(int idx) {
+    if (idx < 0 || idx >= mCurrent)
+        return;
+    delete[] mArray[idx];
+    if (idx < mCurrent-1) {
+        memmove(&mArray[idx], &mArray[idx+1],
+                (mCurrent-1 - idx) * sizeof(char*));
+    }
+    mCurrent--;
+}
+
+//
+// Sort the array.
+//
+void StringArray::sort(int (*compare)(const void*, const void*)) {
+    qsort(mArray, mCurrent, sizeof(char*), compare);
+}
+
+//
+// Pass this to the sort routine to do an ascending alphabetical sort.
+//
+int StringArray::cmpAscendingAlpha(const void* pstr1, const void* pstr2) {
+    return strcmp(*(const char**)pstr1, *(const char**)pstr2);
+}
+
+//
+// Set entry N to specified string.
+// [should use operator[] here]
+//
+void StringArray::setEntry(int idx, const char* str) {
+    if (idx < 0 || idx >= mCurrent)
+        return;
+    delete[] mArray[idx];
+    int len = strlen(str);
+    mArray[idx] = new char[len+1];
+    memcpy(mArray[idx], str, len+1);
+}
+
+
+}; // namespace android
diff --git a/libs/utils/TextOutput.cpp b/libs/utils/TextOutput.cpp
index cebee99..e04823d 100644
--- a/libs/utils/TextOutput.cpp
+++ b/libs/utils/TextOutput.cpp
@@ -22,9 +22,17 @@
 #include <stdlib.h>
 #include <string.h>
 
+namespace android {
+
 // ---------------------------------------------------------------------------
 
-namespace android {
+TextOutput::TextOutput() { 
+}
+
+TextOutput::~TextOutput() { 
+}
+
+// ---------------------------------------------------------------------------
 
 TextOutput& operator<<(TextOutput& to, bool val)
 {
diff --git a/libs/utils/TimerProbe.cpp b/libs/utils/TimerProbe.cpp
deleted file mode 100644
index 835480d..0000000
--- a/libs/utils/TimerProbe.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/TimerProbe.h>
- 
-#if ENABLE_TIMER_PROBE
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "time"
-
-namespace android {
-
-Vector<TimerProbe::Bucket> TimerProbe::gBuckets;
-TimerProbe* TimerProbe::gExecuteChain;
-int TimerProbe::gIndent;
-timespec TimerProbe::gRealBase;
-
-TimerProbe::TimerProbe(const char tag[], int* slot) : mTag(tag)
-{
-    mNext = gExecuteChain;
-    gExecuteChain = this;
-    mIndent = gIndent;
-    gIndent += 1;
-    if (mIndent > 0) {
-        if (*slot == 0) {
-            int count = gBuckets.add();
-            *slot = count;
-            Bucket& bucket = gBuckets.editItemAt(count);
-            memset(&bucket, 0, sizeof(Bucket));
-            bucket.mTag = tag;
-            bucket.mSlotPtr = slot;
-            bucket.mIndent = mIndent;
-        }
-        mBucket = *slot;
-    }
-    clock_gettime(CLOCK_REALTIME, &mRealStart);
-    if (gRealBase.tv_sec == 0)
-        gRealBase = mRealStart;
-    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &mPStart);
-    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &mTStart);
-}
-
-void TimerProbe::end()
-{
-    timespec realEnd, pEnd, tEnd;
-    clock_gettime(CLOCK_REALTIME, &realEnd);
-    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &pEnd);
-    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tEnd);
-    print(realEnd, pEnd, tEnd);
-    mTag = NULL;
-}
-
-TimerProbe::~TimerProbe()
-{
-    if (mTag != NULL)
-        end();
-    gExecuteChain = mNext;
-    gIndent--;
-}
-
-
-uint32_t TimerProbe::ElapsedTime(const timespec& start, const timespec& end)
-{
-    int sec = end.tv_sec - start.tv_sec;
-    int nsec = end.tv_nsec - start.tv_nsec;
-    if (nsec < 0) {
-        sec--;
-        nsec += 1000000000;
-    }
-    return sec * 1000000 + nsec / 1000;
-}
-
-void TimerProbe::print(const timespec& r, const timespec& p,
-        const timespec& t) const
-{
-    uint32_t es = ElapsedTime(gRealBase, mRealStart);
-    uint32_t er = ElapsedTime(mRealStart, r);
-    uint32_t ep = ElapsedTime(mPStart, p);
-    uint32_t et = ElapsedTime(mTStart, t);
-    if (mIndent > 0) {
-        Bucket& bucket = gBuckets.editItemAt(mBucket);
-        if (bucket.mStart == 0)
-            bucket.mStart = es;
-        bucket.mReal += er;
-        bucket.mProcess += ep;
-        bucket.mThread += et;
-        bucket.mCount++;
-        return;
-    }
-    int index = 0;
-    int buckets = gBuckets.size();
-    int count = 1;
-    const char* tag = mTag;
-    int indent = mIndent;
-    do {
-        LOGD("%-30.30s: (%3d) %-5.*s time=%-10.3f real=%7dus process=%7dus (%3d%%) thread=%7dus (%3d%%)\n", 
-            tag, count, indent > 5 ? 5 : indent, "+++++", es / 1000000.0,
-            er, ep, ep * 100 / er, et, et * 100 / er);
-        if (index >= buckets)
-            break;
-        Bucket& bucket = gBuckets.editItemAt(index);
-        count = bucket.mCount;
-        es = bucket.mStart;
-        er = bucket.mReal;
-        ep = bucket.mProcess;
-        et = bucket.mThread;
-        tag = bucket.mTag;
-        indent = bucket.mIndent;
-        *bucket.mSlotPtr = 0;
-    } while (++index); // always true
-    gBuckets.clear();
-}
-
-}; // namespace android
-
-#endif
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
index 2abc811..784f035 100644
--- a/libs/utils/Timers.cpp
+++ b/libs/utils/Timers.cpp
@@ -18,7 +18,6 @@
 // Timer functions.
 //
 #include <utils/Timers.h>
-#include <utils/ported.h>     // may need usleep
 #include <utils/Log.h>
 
 #include <stdlib.h>
@@ -54,130 +53,6 @@
 #endif
 }
 
-//#define MONITOR_USLEEP
-
-/*
- * Sleep long enough that we'll wake up "interval" milliseconds after
- * the previous snooze.
- *
- * The "nextTick" argument is updated on each call, and should be passed
- * in every time.  Set its fields to zero on the first call.
- *
- * Returns the #of intervals we have overslept, which will be zero if we're
- * on time.  [Currently just returns 0 or 1.]
- */
-int sleepForInterval(long interval, struct timeval* pNextTick)
-{
-    struct timeval now;
-    long long timeBeforeNext;
-    long sleepTime = 0;
-    bool overSlept = false;
-    //int usleepBias = 0;
-
-#ifdef USLEEP_BIAS
-    /*
-     * Linux likes to add 9000ms or so.
-     * [not using this for now]
-     */
-    //usleepBias = USLEEP_BIAS;
-#endif
-
-    gettimeofday(&now, NULL);
-
-    if (pNextTick->tv_sec == 0) {
-        /* special-case for first time through */
-        *pNextTick = now;
-        sleepTime = interval;
-        android::DurationTimer::addToTimeval(pNextTick, interval);
-    } else {
-        /*
-         * Compute how much time there is before the next tick.  If this
-         * value is negative, we've run over.  If we've run over a little
-         * bit we can shorten the next frame to keep the pace steady, but
-         * if we've dramatically overshot we need to re-sync.
-         */
-        timeBeforeNext = android::DurationTimer::subtractTimevals(pNextTick, &now);
-        //printf("TOP: now=%ld.%ld next=%ld.%ld diff=%ld\n",
-        //    now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
-        //    (long) timeBeforeNext);
-        if (timeBeforeNext < -interval) {
-            /* way over */
-            overSlept = true;
-            sleepTime = 0;
-            *pNextTick = now;
-        } else if (timeBeforeNext <= 0) {
-            /* slightly over, keep the pace steady */
-            overSlept = true;
-            sleepTime = 0;
-        } else if (timeBeforeNext <= interval) {
-            /* right on schedule */
-            sleepTime = timeBeforeNext;
-        } else if (timeBeforeNext > interval && timeBeforeNext <= 2*interval) {
-            /* sleep call returned early; do a longer sleep this time */
-            sleepTime = timeBeforeNext;
-        } else if (timeBeforeNext > interval) {
-            /* we went back in time -- somebody updated system clock? */
-            /* (could also be a *seriously* broken usleep()) */
-            LOG(LOG_DEBUG, "",
-                " Impossible: timeBeforeNext = %ld\n", (long)timeBeforeNext);
-            sleepTime = 0;
-            *pNextTick = now;
-        }
-        android::DurationTimer::addToTimeval(pNextTick, interval);
-    }
-    //printf(" Before sleep: now=%ld.%ld next=%ld.%ld sleepTime=%ld\n",
-    //    now.tv_sec, now.tv_usec, pNextTick->tv_sec, pNextTick->tv_usec,
-    //    sleepTime);
-
-    /*
-     * Sleep for the designated period of time.
-     *
-     * Linux tends to sleep for longer than requested, often by 17-18ms.
-     * MinGW tends to sleep for less than requested, by as much as 14ms,
-     * but occasionally oversleeps for 40+ms (looks like some external
-     * factors plus round-off on a 64Hz clock).  Cygwin is pretty steady.
-     *
-     * If you start the MinGW version, and then launch the Cygwin version,
-     * the MinGW clock becomes more erratic.  Not entirely sure why.
-     *
-     * (There's a lot of stuff here; it's really just a usleep() call with
-     * a bunch of instrumentation.)
-     */
-    if (sleepTime > 0) {
-#if defined(MONITOR_USLEEP)
-        struct timeval before, after;
-        long long actual;
-
-        gettimeofday(&before, NULL);
-        usleep((long) sleepTime);
-        gettimeofday(&after, NULL);
-
-        /* check usleep() accuracy; default Linux threads are pretty sloppy */
-        actual = android::DurationTimer::subtractTimevals(&after, &before);
-        if ((long) actual < sleepTime - 14000 /*(sleepTime/10)*/ ||
-            (long) actual > sleepTime + 20000 /*(sleepTime/10)*/)
-        {
-            LOG(LOG_DEBUG, "", " Odd usleep: req=%ld, actual=%ld\n", sleepTime,
-                (long) actual);
-        }
-#else
-#ifdef HAVE_WIN32_THREADS
-        Sleep( sleepTime/1000 );
-#else        
-        usleep((long) sleepTime);
-#endif        
-#endif
-    }
-
-    //printf("slept %d\n", sleepTime);
-
-    if (overSlept)
-        return 1;       // close enough
-    else
-        return 0;
-}
-
-
 /*
  * ===========================================================================
  *      DurationTimer
diff --git a/libs/utils/ZipEntry.cpp b/libs/utils/ZipEntry.cpp
deleted file mode 100644
index 96f9fc4..0000000
--- a/libs/utils/ZipEntry.cpp
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-//
-// Access to entries in a Zip archive.
-//
-
-#define LOG_TAG "zip"
-
-#include <utils/ZipEntry.h>
-#include <utils/Log.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-using namespace android;
-
-/*
- * Initialize a new ZipEntry structure from a FILE* positioned at a
- * CentralDirectoryEntry.
- *
- * On exit, the file pointer will be at the start of the next CDE or
- * at the EOCD.
- */
-status_t ZipEntry::initFromCDE(FILE* fp)
-{
-    status_t result;
-    long posn;
-    bool hasDD;
-
-    //LOGV("initFromCDE ---\n");
-
-    /* read the CDE */
-    result = mCDE.read(fp);
-    if (result != NO_ERROR) {
-        LOGD("mCDE.read failed\n");
-        return result;
-    }
-
-    //mCDE.dump();
-
-    /* using the info in the CDE, go load up the LFH */
-    posn = ftell(fp);
-    if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) {
-        LOGD("local header seek failed (%ld)\n",
-            mCDE.mLocalHeaderRelOffset);
-        return UNKNOWN_ERROR;
-    }
-
-    result = mLFH.read(fp);
-    if (result != NO_ERROR) {
-        LOGD("mLFH.read failed\n");
-        return result;
-    }
-
-    if (fseek(fp, posn, SEEK_SET) != 0)
-        return UNKNOWN_ERROR;
-
-    //mLFH.dump();
-
-    /*
-     * We *might* need to read the Data Descriptor at this point and
-     * integrate it into the LFH.  If this bit is set, the CRC-32,
-     * compressed size, and uncompressed size will be zero.  In practice
-     * these seem to be rare.
-     */
-    hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0;
-    if (hasDD) {
-        // do something clever
-        //LOGD("+++ has data descriptor\n");
-    }
-
-    /*
-     * Sanity-check the LFH.  Note that this will fail if the "kUsesDataDescr"
-     * flag is set, because the LFH is incomplete.  (Not a problem, since we
-     * prefer the CDE values.)
-     */
-    if (!hasDD && !compareHeaders()) {
-        LOGW("WARNING: header mismatch\n");
-        // keep going?
-    }
-
-    /*
-     * If the mVersionToExtract is greater than 20, we may have an
-     * issue unpacking the record -- could be encrypted, compressed
-     * with something we don't support, or use Zip64 extensions.  We
-     * can defer worrying about that to when we're extracting data.
-     */
-
-    return NO_ERROR;
-}
-
-/*
- * Initialize a new entry.  Pass in the file name and an optional comment.
- *
- * Initializes the CDE and the LFH.
- */
-void ZipEntry::initNew(const char* fileName, const char* comment)
-{
-    assert(fileName != NULL && *fileName != '\0');  // name required
-
-    /* most fields are properly initialized by constructor */
-    mCDE.mVersionMadeBy = kDefaultMadeBy;
-    mCDE.mVersionToExtract = kDefaultVersion;
-    mCDE.mCompressionMethod = kCompressStored;
-    mCDE.mFileNameLength = strlen(fileName);
-    if (comment != NULL)
-        mCDE.mFileCommentLength = strlen(comment);
-    mCDE.mExternalAttrs = 0x81b60020;   // matches what WinZip does
-
-    if (mCDE.mFileNameLength > 0) {
-        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
-        strcpy((char*) mCDE.mFileName, fileName);
-    }
-    if (mCDE.mFileCommentLength > 0) {
-        /* TODO: stop assuming null-terminated ASCII here? */
-        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
-        strcpy((char*) mCDE.mFileComment, comment);
-    }
-
-    copyCDEtoLFH();
-}
-
-/*
- * Initialize a new entry, starting with the ZipEntry from a different
- * archive.
- *
- * Initializes the CDE and the LFH.
- */
-status_t ZipEntry::initFromExternal(const ZipFile* pZipFile,
-    const ZipEntry* pEntry)
-{
-    /*
-     * Copy everything in the CDE over, then fix up the hairy bits.
-     */
-    memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE));
-
-    if (mCDE.mFileNameLength > 0) {
-        mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1];
-        if (mCDE.mFileName == NULL)
-            return NO_MEMORY;
-        strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName);
-    }
-    if (mCDE.mFileCommentLength > 0) {
-        mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1];
-        if (mCDE.mFileComment == NULL)
-            return NO_MEMORY;
-        strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment);
-    }
-    if (mCDE.mExtraFieldLength > 0) {
-        /* we null-terminate this, though it may not be a string */
-        mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1];
-        if (mCDE.mExtraField == NULL)
-            return NO_MEMORY;
-        memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField,
-            mCDE.mExtraFieldLength+1);
-    }
-
-    /* construct the LFH from the CDE */
-    copyCDEtoLFH();
-
-    /*
-     * The LFH "extra" field is independent of the CDE "extra", so we
-     * handle it here.
-     */
-    assert(mLFH.mExtraField == NULL);
-    mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength;
-    if (mLFH.mExtraFieldLength > 0) {
-        mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1];
-        if (mLFH.mExtraField == NULL)
-            return NO_MEMORY;
-        memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField,
-            mLFH.mExtraFieldLength+1);
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Insert pad bytes in the LFH by tweaking the "extra" field.  This will
- * potentially confuse something that put "extra" data in here earlier,
- * but I can't find an actual problem.
- */
-status_t ZipEntry::addPadding(int padding)
-{
-    if (padding <= 0)
-        return INVALID_OPERATION;
-
-    //LOGI("HEY: adding %d pad bytes to existing %d in %s\n",
-    //    padding, mLFH.mExtraFieldLength, mCDE.mFileName);
-
-    if (mLFH.mExtraFieldLength > 0) {
-        /* extend existing field */
-        unsigned char* newExtra;
-
-        newExtra = new unsigned char[mLFH.mExtraFieldLength + padding];
-        if (newExtra == NULL)
-            return NO_MEMORY;
-        memset(newExtra + mLFH.mExtraFieldLength, 0, padding);
-        memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength);
-
-        delete[] mLFH.mExtraField;
-        mLFH.mExtraField = newExtra;
-        mLFH.mExtraFieldLength += padding;
-    } else {
-        /* create new field */
-        mLFH.mExtraField = new unsigned char[padding];
-        memset(mLFH.mExtraField, 0, padding);
-        mLFH.mExtraFieldLength = padding;
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Set the fields in the LFH equal to the corresponding fields in the CDE.
- *
- * This does not touch the LFH "extra" field.
- */
-void ZipEntry::copyCDEtoLFH(void)
-{
-    mLFH.mVersionToExtract  = mCDE.mVersionToExtract;
-    mLFH.mGPBitFlag         = mCDE.mGPBitFlag;
-    mLFH.mCompressionMethod = mCDE.mCompressionMethod;
-    mLFH.mLastModFileTime   = mCDE.mLastModFileTime;
-    mLFH.mLastModFileDate   = mCDE.mLastModFileDate;
-    mLFH.mCRC32             = mCDE.mCRC32;
-    mLFH.mCompressedSize    = mCDE.mCompressedSize;
-    mLFH.mUncompressedSize  = mCDE.mUncompressedSize;
-    mLFH.mFileNameLength    = mCDE.mFileNameLength;
-    // the "extra field" is independent
-
-    delete[] mLFH.mFileName;
-    if (mLFH.mFileNameLength > 0) {
-        mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1];
-        strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName);
-    } else {
-        mLFH.mFileName = NULL;
-    }
-}
-
-/*
- * Set some information about a file after we add it.
- */
-void ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32,
-    int compressionMethod)
-{
-    mCDE.mCompressionMethod = compressionMethod;
-    mCDE.mCRC32 = crc32;
-    mCDE.mCompressedSize = compLen;
-    mCDE.mUncompressedSize = uncompLen;
-    mCDE.mCompressionMethod = compressionMethod;
-    if (compressionMethod == kCompressDeflated) {
-        mCDE.mGPBitFlag |= 0x0002;      // indicates maximum compression used
-    }
-    copyCDEtoLFH();
-}
-
-/*
- * See if the data in mCDE and mLFH match up.  This is mostly useful for
- * debugging these classes, but it can be used to identify damaged
- * archives.
- *
- * Returns "false" if they differ.
- */
-bool ZipEntry::compareHeaders(void) const
-{
-    if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) {
-        LOGV("cmp: VersionToExtract\n");
-        return false;
-    }
-    if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) {
-        LOGV("cmp: GPBitFlag\n");
-        return false;
-    }
-    if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) {
-        LOGV("cmp: CompressionMethod\n");
-        return false;
-    }
-    if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) {
-        LOGV("cmp: LastModFileTime\n");
-        return false;
-    }
-    if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) {
-        LOGV("cmp: LastModFileDate\n");
-        return false;
-    }
-    if (mCDE.mCRC32 != mLFH.mCRC32) {
-        LOGV("cmp: CRC32\n");
-        return false;
-    }
-    if (mCDE.mCompressedSize != mLFH.mCompressedSize) {
-        LOGV("cmp: CompressedSize\n");
-        return false;
-    }
-    if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) {
-        LOGV("cmp: UncompressedSize\n");
-        return false;
-    }
-    if (mCDE.mFileNameLength != mLFH.mFileNameLength) {
-        LOGV("cmp: FileNameLength\n");
-        return false;
-    }
-#if 0       // this seems to be used for padding, not real data
-    if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) {
-        LOGV("cmp: ExtraFieldLength\n");
-        return false;
-    }
-#endif
-    if (mCDE.mFileName != NULL) {
-        if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) {
-            LOGV("cmp: FileName\n");
-            return false;
-        }
-    }
-
-    return true;
-}
-
-
-/*
- * Convert the DOS date/time stamp into a UNIX time stamp.
- */
-time_t ZipEntry::getModWhen(void) const
-{
-    struct tm parts;
-
-    parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1;
-    parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5;
-    parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11;
-    parts.tm_mday = (mCDE.mLastModFileDate & 0x001f);
-    parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1;
-    parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80;
-    parts.tm_wday = parts.tm_yday = 0;
-    parts.tm_isdst = -1;        // DST info "not available"
-
-    return mktime(&parts);
-}
-
-/*
- * Set the CDE/LFH timestamp from UNIX time.
- */
-void ZipEntry::setModWhen(time_t when)
-{
-#ifdef HAVE_LOCALTIME_R
-    struct tm tmResult;
-#endif
-    time_t even;
-    unsigned short zdate, ztime;
-
-    struct tm* ptm;
-
-    /* round up to an even number of seconds */
-    even = (time_t)(((unsigned long)(when) + 1) & (~1));
-
-    /* expand */
-#ifdef HAVE_LOCALTIME_R
-    ptm = localtime_r(&even, &tmResult);
-#else
-    ptm = localtime(&even);
-#endif
-
-    int year;
-    year = ptm->tm_year;
-    if (year < 80)
-        year = 80;
-
-    zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;
-    ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
-
-    mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;
-    mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;
-}
-
-
-/*
- * ===========================================================================
- *      ZipEntry::LocalFileHeader
- * ===========================================================================
- */
-
-/*
- * Read a local file header.
- *
- * On entry, "fp" points to the signature at the start of the header.
- * On exit, "fp" points to the start of data.
- */
-status_t ZipEntry::LocalFileHeader::read(FILE* fp)
-{
-    status_t result = NO_ERROR;
-    unsigned char buf[kLFHLen];
-
-    assert(mFileName == NULL);
-    assert(mExtraField == NULL);
-
-    if (fread(buf, 1, kLFHLen, fp) != kLFHLen) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
-        LOGD("whoops: didn't find expected signature\n");
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]);
-    mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]);
-    mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]);
-    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]);
-    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]);
-    mCRC32 = ZipEntry::getLongLE(&buf[0x0e]);
-    mCompressedSize = ZipEntry::getLongLE(&buf[0x12]);
-    mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]);
-    mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]);
-    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]);
-
-    // TODO: validate sizes
-
-    /* grab filename */
-    if (mFileNameLength != 0) {
-        mFileName = new unsigned char[mFileNameLength+1];
-        if (mFileName == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mFileName[mFileNameLength] = '\0';
-    }
-
-    /* grab extra field */
-    if (mExtraFieldLength != 0) {
-        mExtraField = new unsigned char[mExtraFieldLength+1];
-        if (mExtraField == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mExtraField[mExtraFieldLength] = '\0';
-    }
-
-bail:
-    return result;
-}
-
-/*
- * Write a local file header.
- */
-status_t ZipEntry::LocalFileHeader::write(FILE* fp)
-{
-    unsigned char buf[kLFHLen];
-
-    ZipEntry::putLongLE(&buf[0x00], kSignature);
-    ZipEntry::putShortLE(&buf[0x04], mVersionToExtract);
-    ZipEntry::putShortLE(&buf[0x06], mGPBitFlag);
-    ZipEntry::putShortLE(&buf[0x08], mCompressionMethod);
-    ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime);
-    ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate);
-    ZipEntry::putLongLE(&buf[0x0e], mCRC32);
-    ZipEntry::putLongLE(&buf[0x12], mCompressedSize);
-    ZipEntry::putLongLE(&buf[0x16], mUncompressedSize);
-    ZipEntry::putShortLE(&buf[0x1a], mFileNameLength);
-    ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength);
-
-    if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen)
-        return UNKNOWN_ERROR;
-
-    /* write filename */
-    if (mFileNameLength != 0) {
-        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
-            return UNKNOWN_ERROR;
-    }
-
-    /* write "extra field" */
-    if (mExtraFieldLength != 0) {
-        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
-            return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-
-/*
- * Dump the contents of a LocalFileHeader object.
- */
-void ZipEntry::LocalFileHeader::dump(void) const
-{
-    LOGD(" LocalFileHeader contents:\n");
-    LOGD("  versToExt=%u gpBits=0x%04x compression=%u\n",
-        mVersionToExtract, mGPBitFlag, mCompressionMethod);
-    LOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
-        mLastModFileTime, mLastModFileDate, mCRC32);
-    LOGD("  compressedSize=%lu uncompressedSize=%lu\n",
-        mCompressedSize, mUncompressedSize);
-    LOGD("  filenameLen=%u extraLen=%u\n",
-        mFileNameLength, mExtraFieldLength);
-    if (mFileName != NULL)
-        LOGD("  filename: '%s'\n", mFileName);
-}
-
-
-/*
- * ===========================================================================
- *      ZipEntry::CentralDirEntry
- * ===========================================================================
- */
-
-/*
- * Read the central dir entry that appears next in the file.
- *
- * On entry, "fp" should be positioned on the signature bytes for the
- * entry.  On exit, "fp" will point at the signature word for the next
- * entry or for the EOCD.
- */
-status_t ZipEntry::CentralDirEntry::read(FILE* fp)
-{
-    status_t result = NO_ERROR;
-    unsigned char buf[kCDELen];
-
-    /* no re-use */
-    assert(mFileName == NULL);
-    assert(mExtraField == NULL);
-    assert(mFileComment == NULL);
-
-    if (fread(buf, 1, kCDELen, fp) != kCDELen) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) {
-        LOGD("Whoops: didn't find expected signature\n");
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]);
-    mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]);
-    mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]);
-    mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]);
-    mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]);
-    mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]);
-    mCRC32 = ZipEntry::getLongLE(&buf[0x10]);
-    mCompressedSize = ZipEntry::getLongLE(&buf[0x14]);
-    mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]);
-    mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]);
-    mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]);
-    mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]);
-    mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]);
-    mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]);
-    mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]);
-    mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]);
-
-    // TODO: validate sizes and offsets
-
-    /* grab filename */
-    if (mFileNameLength != 0) {
-        mFileName = new unsigned char[mFileNameLength+1];
-        if (mFileName == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mFileName[mFileNameLength] = '\0';
-    }
-
-    /* read "extra field" */
-    if (mExtraFieldLength != 0) {
-        mExtraField = new unsigned char[mExtraFieldLength+1];
-        if (mExtraField == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mExtraField[mExtraFieldLength] = '\0';
-    }
-
-
-    /* grab comment, if any */
-    if (mFileCommentLength != 0) {
-        mFileComment = new unsigned char[mFileCommentLength+1];
-        if (mFileComment == NULL) {
-            result = NO_MEMORY;
-            goto bail;
-        }
-        if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
-        {
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        mFileComment[mFileCommentLength] = '\0';
-    }
-
-bail:
-    return result;
-}
-
-/*
- * Write a central dir entry.
- */
-status_t ZipEntry::CentralDirEntry::write(FILE* fp)
-{
-    unsigned char buf[kCDELen];
-
-    ZipEntry::putLongLE(&buf[0x00], kSignature);
-    ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy);
-    ZipEntry::putShortLE(&buf[0x06], mVersionToExtract);
-    ZipEntry::putShortLE(&buf[0x08], mGPBitFlag);
-    ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod);
-    ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime);
-    ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate);
-    ZipEntry::putLongLE(&buf[0x10], mCRC32);
-    ZipEntry::putLongLE(&buf[0x14], mCompressedSize);
-    ZipEntry::putLongLE(&buf[0x18], mUncompressedSize);
-    ZipEntry::putShortLE(&buf[0x1c], mFileNameLength);
-    ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength);
-    ZipEntry::putShortLE(&buf[0x20], mFileCommentLength);
-    ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart);
-    ZipEntry::putShortLE(&buf[0x24], mInternalAttrs);
-    ZipEntry::putLongLE(&buf[0x26], mExternalAttrs);
-    ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset);
-
-    if (fwrite(buf, 1, kCDELen, fp) != kCDELen)
-        return UNKNOWN_ERROR;
-
-    /* write filename */
-    if (mFileNameLength != 0) {
-        if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength)
-            return UNKNOWN_ERROR;
-    }
-
-    /* write "extra field" */
-    if (mExtraFieldLength != 0) {
-        if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength)
-            return UNKNOWN_ERROR;
-    }
-
-    /* write comment */
-    if (mFileCommentLength != 0) {
-        if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength)
-            return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Dump the contents of a CentralDirEntry object.
- */
-void ZipEntry::CentralDirEntry::dump(void) const
-{
-    LOGD(" CentralDirEntry contents:\n");
-    LOGD("  versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n",
-        mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod);
-    LOGD("  modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n",
-        mLastModFileTime, mLastModFileDate, mCRC32);
-    LOGD("  compressedSize=%lu uncompressedSize=%lu\n",
-        mCompressedSize, mUncompressedSize);
-    LOGD("  filenameLen=%u extraLen=%u commentLen=%u\n",
-        mFileNameLength, mExtraFieldLength, mFileCommentLength);
-    LOGD("  diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n",
-        mDiskNumberStart, mInternalAttrs, mExternalAttrs,
-        mLocalHeaderRelOffset);
-
-    if (mFileName != NULL)
-        LOGD("  filename: '%s'\n", mFileName);
-    if (mFileComment != NULL)
-        LOGD("  comment: '%s'\n", mFileComment);
-}
-
diff --git a/libs/utils/ZipFile.cpp b/libs/utils/ZipFile.cpp
deleted file mode 100644
index 6f27d17..0000000
--- a/libs/utils/ZipFile.cpp
+++ /dev/null
@@ -1,1296 +0,0 @@
-/*
- * Copyright (C) 2006 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.
- */
-
-//
-// Access to Zip archives.
-//
-
-#define LOG_TAG "zip"
-
-#include <utils/ZipFile.h>
-#include <utils/ZipUtils.h>
-#include <utils/Log.h>
-
-#include <zlib.h>
-#define DEF_MEM_LEVEL 8                // normally in zutil.h?
-
-#include <memory.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <assert.h>
-
-using namespace android;
-
-/*
- * Some environments require the "b", some choke on it.
- */
-#define FILE_OPEN_RO        "rb"
-#define FILE_OPEN_RW        "r+b"
-#define FILE_OPEN_RW_CREATE "w+b"
-
-/* should live somewhere else? */
-static status_t errnoToStatus(int err)
-{
-    if (err == ENOENT)
-        return NAME_NOT_FOUND;
-    else if (err == EACCES)
-        return PERMISSION_DENIED;
-    else
-        return UNKNOWN_ERROR;
-}
-
-/*
- * Open a file and parse its guts.
- */
-status_t ZipFile::open(const char* zipFileName, int flags)
-{
-    bool newArchive = false;
-
-    assert(mZipFp == NULL);     // no reopen
-
-    if ((flags & kOpenTruncate))
-        flags |= kOpenCreate;           // trunc implies create
-
-    if ((flags & kOpenReadOnly) && (flags & kOpenReadWrite))
-        return INVALID_OPERATION;       // not both
-    if (!((flags & kOpenReadOnly) || (flags & kOpenReadWrite)))
-        return INVALID_OPERATION;       // not neither
-    if ((flags & kOpenCreate) && !(flags & kOpenReadWrite))
-        return INVALID_OPERATION;       // create requires write
-
-    if (flags & kOpenTruncate) {
-        newArchive = true;
-    } else {
-        newArchive = (access(zipFileName, F_OK) != 0);
-        if (!(flags & kOpenCreate) && newArchive) {
-            /* not creating, must already exist */
-            LOGD("File %s does not exist", zipFileName);
-            return NAME_NOT_FOUND;
-        }
-    }
-
-    /* open the file */
-    const char* openflags;
-    if (flags & kOpenReadWrite) {
-        if (newArchive)
-            openflags = FILE_OPEN_RW_CREATE;
-        else
-            openflags = FILE_OPEN_RW;
-    } else {
-        openflags = FILE_OPEN_RO;
-    }
-    mZipFp = fopen(zipFileName, openflags);
-    if (mZipFp == NULL) {
-		int err = errno;
-		LOGD("fopen failed: %d\n", err);
-        return errnoToStatus(err);
-	}
-
-    status_t result;
-    if (!newArchive) {
-        /*
-         * Load the central directory.  If that fails, then this probably
-         * isn't a Zip archive.
-         */
-        result = readCentralDir();
-    } else {
-        /*
-         * Newly-created.  The EndOfCentralDir constructor actually
-         * sets everything to be the way we want it (all zeroes).  We
-         * set mNeedCDRewrite so that we create *something* if the
-         * caller doesn't add any files.  (We could also just unlink
-         * the file if it's brand new and nothing was added, but that's
-         * probably doing more than we really should -- the user might
-         * have a need for empty zip files.)
-         */
-        mNeedCDRewrite = true;
-        result = NO_ERROR;
-    }
-
-    if (flags & kOpenReadOnly)
-        mReadOnly = true;
-    else
-        assert(!mReadOnly);
-
-    return result;
-}
-
-/*
- * Return the Nth entry in the archive.
- */
-ZipEntry* ZipFile::getEntryByIndex(int idx) const
-{
-    if (idx < 0 || idx >= (int) mEntries.size())
-        return NULL;
-
-    return mEntries[idx];
-}
-
-/*
- * Find an entry by name.
- */
-ZipEntry* ZipFile::getEntryByName(const char* fileName) const
-{
-    /*
-     * Do a stupid linear string-compare search.
-     *
-     * There are various ways to speed this up, especially since it's rare
-     * to intermingle changes to the archive with "get by name" calls.  We
-     * don't want to sort the mEntries vector itself, however, because
-     * it's used to recreate the Central Directory.
-     *
-     * (Hash table works, parallel list of pointers in sorted order is good.)
-     */
-    int idx;
-
-    for (idx = mEntries.size()-1; idx >= 0; idx--) {
-        ZipEntry* pEntry = mEntries[idx];
-        if (!pEntry->getDeleted() &&
-            strcmp(fileName, pEntry->getFileName()) == 0)
-        {
-            return pEntry;
-        }
-    }
-
-    return NULL;
-}
-
-/*
- * Empty the mEntries vector.
- */
-void ZipFile::discardEntries(void)
-{
-    int count = mEntries.size();
-
-    while (--count >= 0)
-        delete mEntries[count];
-
-    mEntries.clear();
-}
-
-
-/*
- * Find the central directory and read the contents.
- *
- * The fun thing about ZIP archives is that they may or may not be
- * readable from start to end.  In some cases, notably for archives
- * that were written to stdout, the only length information is in the
- * central directory at the end of the file.
- *
- * Of course, the central directory can be followed by a variable-length
- * comment field, so we have to scan through it backwards.  The comment
- * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff
- * itself, plus apparently sometimes people throw random junk on the end
- * just for the fun of it.
- *
- * This is all a little wobbly.  If the wrong value ends up in the EOCD
- * area, we're hosed.  This appears to be the way that everbody handles
- * it though, so we're in pretty good company if this fails.
- */
-status_t ZipFile::readCentralDir(void)
-{
-    status_t result = NO_ERROR;
-    unsigned char* buf = NULL;
-    off_t fileLength, seekStart;
-    long readAmount;
-    int i;
-
-    fseek(mZipFp, 0, SEEK_END);
-    fileLength = ftell(mZipFp);
-    rewind(mZipFp);
-
-    /* too small to be a ZIP archive? */
-    if (fileLength < EndOfCentralDir::kEOCDLen) {
-        LOGD("Length is %ld -- too small\n", (long)fileLength);
-        result = INVALID_OPERATION;
-        goto bail;
-    }
-
-    buf = new unsigned char[EndOfCentralDir::kMaxEOCDSearch];
-    if (buf == NULL) {
-		LOGD("Failure allocating %d bytes for EOCD search",
-			 EndOfCentralDir::kMaxEOCDSearch);
-        result = NO_MEMORY;
-        goto bail;
-    }
-
-    if (fileLength > EndOfCentralDir::kMaxEOCDSearch) {
-        seekStart = fileLength - EndOfCentralDir::kMaxEOCDSearch;
-        readAmount = EndOfCentralDir::kMaxEOCDSearch;
-    } else {
-        seekStart = 0;
-        readAmount = (long) fileLength;
-    }
-    if (fseek(mZipFp, seekStart, SEEK_SET) != 0) {
-		LOGD("Failure seeking to end of zip at %ld", (long) seekStart);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /* read the last part of the file into the buffer */
-    if (fread(buf, 1, readAmount, mZipFp) != (size_t) readAmount) {
-        LOGD("short file? wanted %ld\n", readAmount);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /* find the end-of-central-dir magic */
-    for (i = readAmount - 4; i >= 0; i--) {
-        if (buf[i] == 0x50 &&
-            ZipEntry::getLongLE(&buf[i]) == EndOfCentralDir::kSignature)
-        {
-            LOGV("+++ Found EOCD at buf+%d\n", i);
-            break;
-        }
-    }
-    if (i < 0) {
-        LOGD("EOCD not found, not Zip\n");
-        result = INVALID_OPERATION;
-        goto bail;
-    }
-
-    /* extract eocd values */
-    result = mEOCD.readBuf(buf + i, readAmount - i);
-    if (result != NO_ERROR) {
-		LOGD("Failure reading %ld bytes of EOCD values", readAmount - i);
-        goto bail;
-	}
-    //mEOCD.dump();
-
-    if (mEOCD.mDiskNumber != 0 || mEOCD.mDiskWithCentralDir != 0 ||
-        mEOCD.mNumEntries != mEOCD.mTotalNumEntries)
-    {
-        LOGD("Archive spanning not supported\n");
-        result = INVALID_OPERATION;
-        goto bail;
-    }
-
-    /*
-     * So far so good.  "mCentralDirSize" is the size in bytes of the
-     * central directory, so we can just seek back that far to find it.
-     * We can also seek forward mCentralDirOffset bytes from the
-     * start of the file.
-     *
-     * We're not guaranteed to have the rest of the central dir in the
-     * buffer, nor are we guaranteed that the central dir will have any
-     * sort of convenient size.  We need to skip to the start of it and
-     * read the header, then the other goodies.
-     *
-     * The only thing we really need right now is the file comment, which
-     * we're hoping to preserve.
-     */
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
-		LOGD("Failure seeking to central dir offset %ld\n",
-			 mEOCD.mCentralDirOffset);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /*
-     * Loop through and read the central dir entries.
-     */
-    LOGV("Scanning %d entries...\n", mEOCD.mTotalNumEntries);
-    int entry;
-    for (entry = 0; entry < mEOCD.mTotalNumEntries; entry++) {
-        ZipEntry* pEntry = new ZipEntry;
-
-        result = pEntry->initFromCDE(mZipFp);
-        if (result != NO_ERROR) {
-            LOGD("initFromCDE failed\n");
-            delete pEntry;
-            goto bail;
-        }
-
-        mEntries.add(pEntry);
-    }
-
-
-    /*
-     * If all went well, we should now be back at the EOCD.
-     */
-    {
-        unsigned char checkBuf[4];
-        if (fread(checkBuf, 1, 4, mZipFp) != 4) {
-            LOGD("EOCD check read failed\n");
-            result = INVALID_OPERATION;
-            goto bail;
-        }
-        if (ZipEntry::getLongLE(checkBuf) != EndOfCentralDir::kSignature) {
-            LOGD("EOCD read check failed\n");
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-        LOGV("+++ EOCD read check passed\n");
-    }
-
-bail:
-    delete[] buf;
-    return result;
-}
-
-
-/*
- * Add a new file to the archive.
- *
- * This requires creating and populating a ZipEntry structure, and copying
- * the data into the file at the appropriate position.  The "appropriate
- * position" is the current location of the central directory, which we
- * casually overwrite (we can put it back later).
- *
- * If we were concerned about safety, we would want to make all changes
- * in a temp file and then overwrite the original after everything was
- * safely written.  Not really a concern for us.
- */
-status_t ZipFile::addCommon(const char* fileName, const void* data, size_t size,
-    const char* storageName, int sourceType, int compressionMethod,
-    ZipEntry** ppEntry)
-{
-    ZipEntry* pEntry = NULL;
-    status_t result = NO_ERROR;
-    long lfhPosn, startPosn, endPosn, uncompressedLen;
-    FILE* inputFp = NULL;
-    unsigned long crc;
-    time_t modWhen;
-
-    if (mReadOnly)
-        return INVALID_OPERATION;
-
-    assert(compressionMethod == ZipEntry::kCompressDeflated ||
-           compressionMethod == ZipEntry::kCompressStored);
-
-    /* make sure we're in a reasonable state */
-    assert(mZipFp != NULL);
-    assert(mEntries.size() == mEOCD.mTotalNumEntries);
-
-    /* make sure it doesn't already exist */
-    if (getEntryByName(storageName) != NULL)
-        return ALREADY_EXISTS;
-
-    if (!data) {
-        inputFp = fopen(fileName, FILE_OPEN_RO);
-        if (inputFp == NULL)
-            return errnoToStatus(errno);
-    }
-
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    pEntry = new ZipEntry;
-    pEntry->initNew(storageName, NULL);
-
-    /*
-     * From here on out, failures are more interesting.
-     */
-    mNeedCDRewrite = true;
-
-    /*
-     * Write the LFH, even though it's still mostly blank.  We need it
-     * as a place-holder.  In theory the LFH isn't necessary, but in
-     * practice some utilities demand it.
-     */
-    lfhPosn = ftell(mZipFp);
-    pEntry->mLFH.write(mZipFp);
-    startPosn = ftell(mZipFp);
-
-    /*
-     * Copy the data in, possibly compressing it as we go.
-     */
-    if (sourceType == ZipEntry::kCompressStored) {
-        if (compressionMethod == ZipEntry::kCompressDeflated) {
-            bool failed = false;
-            result = compressFpToFp(mZipFp, inputFp, data, size, &crc);
-            if (result != NO_ERROR) {
-                LOGD("compression failed, storing\n");
-                failed = true;
-            } else {
-                /*
-                 * Make sure it has compressed "enough".  This probably ought
-                 * to be set through an API call, but I don't expect our
-                 * criteria to change over time.
-                 */
-                long src = inputFp ? ftell(inputFp) : size;
-                long dst = ftell(mZipFp) - startPosn;
-                if (dst + (dst / 10) > src) {
-                    LOGD("insufficient compression (src=%ld dst=%ld), storing\n",
-                        src, dst);
-                    failed = true;
-                }
-            }
-
-            if (failed) {
-                compressionMethod = ZipEntry::kCompressStored;
-                if (inputFp) rewind(inputFp);
-                fseek(mZipFp, startPosn, SEEK_SET);
-                /* fall through to kCompressStored case */
-            }
-        }
-        /* handle "no compression" request, or failed compression from above */
-        if (compressionMethod == ZipEntry::kCompressStored) {
-            if (inputFp) {
-                result = copyFpToFp(mZipFp, inputFp, &crc);
-            } else {
-                result = copyDataToFp(mZipFp, data, size, &crc);
-            }
-            if (result != NO_ERROR) {
-                // don't need to truncate; happens in CDE rewrite
-                LOGD("failed copying data in\n");
-                goto bail;
-            }
-        }
-
-        // currently seeked to end of file
-        uncompressedLen = inputFp ? ftell(inputFp) : size;
-    } else if (sourceType == ZipEntry::kCompressDeflated) {
-        /* we should support uncompressed-from-compressed, but it's not
-         * important right now */
-        assert(compressionMethod == ZipEntry::kCompressDeflated);
-
-        bool scanResult;
-        int method;
-        long compressedLen;
-
-        scanResult = ZipUtils::examineGzip(inputFp, &method, &uncompressedLen,
-                        &compressedLen, &crc);
-        if (!scanResult || method != ZipEntry::kCompressDeflated) {
-            LOGD("this isn't a deflated gzip file?");
-            result = UNKNOWN_ERROR;
-            goto bail;
-        }
-
-        result = copyPartialFpToFp(mZipFp, inputFp, compressedLen, NULL);
-        if (result != NO_ERROR) {
-            LOGD("failed copying gzip data in\n");
-            goto bail;
-        }
-    } else {
-        assert(false);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /*
-     * We could write the "Data Descriptor", but there doesn't seem to
-     * be any point since we're going to go back and write the LFH.
-     *
-     * Update file offsets.
-     */
-    endPosn = ftell(mZipFp);            // seeked to end of compressed data
-
-    /*
-     * Success!  Fill out new values.
-     */
-    pEntry->setDataInfo(uncompressedLen, endPosn - startPosn, crc,
-        compressionMethod);
-    modWhen = getModTime(inputFp ? fileno(inputFp) : fileno(mZipFp));
-    pEntry->setModWhen(modWhen);
-    pEntry->setLFHOffset(lfhPosn);
-    mEOCD.mNumEntries++;
-    mEOCD.mTotalNumEntries++;
-    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
-    mEOCD.mCentralDirOffset = endPosn;
-
-    /*
-     * Go back and write the LFH.
-     */
-    if (fseek(mZipFp, lfhPosn, SEEK_SET) != 0) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-    pEntry->mLFH.write(mZipFp);
-
-    /*
-     * Add pEntry to the list.
-     */
-    mEntries.add(pEntry);
-    if (ppEntry != NULL)
-        *ppEntry = pEntry;
-    pEntry = NULL;
-
-bail:
-    if (inputFp != NULL)
-        fclose(inputFp);
-    delete pEntry;
-    return result;
-}
-
-/*
- * Add an entry by copying it from another zip file.  If "padding" is
- * nonzero, the specified number of bytes will be added to the "extra"
- * field in the header.
- *
- * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
- */
-status_t ZipFile::add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
-    int padding, ZipEntry** ppEntry)
-{
-    ZipEntry* pEntry = NULL;
-    status_t result;
-    long lfhPosn, endPosn;
-
-    if (mReadOnly)
-        return INVALID_OPERATION;
-
-    /* make sure we're in a reasonable state */
-    assert(mZipFp != NULL);
-    assert(mEntries.size() == mEOCD.mTotalNumEntries);
-
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0) {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    pEntry = new ZipEntry;
-    if (pEntry == NULL) {
-        result = NO_MEMORY;
-        goto bail;
-    }
-
-    result = pEntry->initFromExternal(pSourceZip, pSourceEntry);
-    if (result != NO_ERROR)
-        goto bail;
-    if (padding != 0) {
-        result = pEntry->addPadding(padding);
-        if (result != NO_ERROR)
-            goto bail;
-    }
-
-    /*
-     * From here on out, failures are more interesting.
-     */
-    mNeedCDRewrite = true;
-
-    /*
-     * Write the LFH.  Since we're not recompressing the data, we already
-     * have all of the fields filled out.
-     */
-    lfhPosn = ftell(mZipFp);
-    pEntry->mLFH.write(mZipFp);
-
-    /*
-     * Copy the data over.
-     *
-     * If the "has data descriptor" flag is set, we want to copy the DD
-     * fields as well.  This is a fixed-size area immediately following
-     * the data.
-     */
-    if (fseek(pSourceZip->mZipFp, pSourceEntry->getFileOffset(), SEEK_SET) != 0)
-    {
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    off_t copyLen;
-    copyLen = pSourceEntry->getCompressedLen();
-    if ((pSourceEntry->mLFH.mGPBitFlag & ZipEntry::kUsesDataDescr) != 0)
-        copyLen += ZipEntry::kDataDescriptorLen;
-
-    if (copyPartialFpToFp(mZipFp, pSourceZip->mZipFp, copyLen, NULL)
-        != NO_ERROR)
-    {
-        LOGW("copy of '%s' failed\n", pEntry->mCDE.mFileName);
-        result = UNKNOWN_ERROR;
-        goto bail;
-    }
-
-    /*
-     * Update file offsets.
-     */
-    endPosn = ftell(mZipFp);
-
-    /*
-     * Success!  Fill out new values.
-     */
-    pEntry->setLFHOffset(lfhPosn);      // sets mCDE.mLocalHeaderRelOffset
-    mEOCD.mNumEntries++;
-    mEOCD.mTotalNumEntries++;
-    mEOCD.mCentralDirSize = 0;      // mark invalid; set by flush()
-    mEOCD.mCentralDirOffset = endPosn;
-
-    /*
-     * Add pEntry to the list.
-     */
-    mEntries.add(pEntry);
-    if (ppEntry != NULL)
-        *ppEntry = pEntry;
-    pEntry = NULL;
-
-    result = NO_ERROR;
-
-bail:
-    delete pEntry;
-    return result;
-}
-
-/*
- * Copy all of the bytes in "src" to "dst".
- *
- * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
- * will be seeked immediately past the data.
- */
-status_t ZipFile::copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32)
-{
-    unsigned char tmpBuf[32768];
-    size_t count;
-
-    *pCRC32 = crc32(0L, Z_NULL, 0);
-
-    while (1) {
-        count = fread(tmpBuf, 1, sizeof(tmpBuf), srcFp);
-        if (ferror(srcFp) || ferror(dstFp))
-            return errnoToStatus(errno);
-        if (count == 0)
-            break;
-
-        *pCRC32 = crc32(*pCRC32, tmpBuf, count);
-
-        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
-            LOGD("fwrite %d bytes failed\n", (int) count);
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Copy all of the bytes in "src" to "dst".
- *
- * On exit, "dstFp" will be seeked immediately past the data.
- */
-status_t ZipFile::copyDataToFp(FILE* dstFp,
-    const void* data, size_t size, unsigned long* pCRC32)
-{
-    size_t count;
-
-    *pCRC32 = crc32(0L, Z_NULL, 0);
-    if (size > 0) {
-        *pCRC32 = crc32(*pCRC32, (const unsigned char*)data, size);
-        if (fwrite(data, 1, size, dstFp) != size) {
-            LOGD("fwrite %d bytes failed\n", (int) size);
-            return UNKNOWN_ERROR;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Copy some of the bytes in "src" to "dst".
- *
- * If "pCRC32" is NULL, the CRC will not be computed.
- *
- * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
- * will be seeked immediately past the data just written.
- */
-status_t ZipFile::copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
-    unsigned long* pCRC32)
-{
-    unsigned char tmpBuf[32768];
-    size_t count;
-
-    if (pCRC32 != NULL)
-        *pCRC32 = crc32(0L, Z_NULL, 0);
-
-    while (length) {
-        long readSize;
-        
-        readSize = sizeof(tmpBuf);
-        if (readSize > length)
-            readSize = length;
-
-        count = fread(tmpBuf, 1, readSize, srcFp);
-        if ((long) count != readSize) {     // error or unexpected EOF
-            LOGD("fread %d bytes failed\n", (int) readSize);
-            return UNKNOWN_ERROR;
-        }
-
-        if (pCRC32 != NULL)
-            *pCRC32 = crc32(*pCRC32, tmpBuf, count);
-
-        if (fwrite(tmpBuf, 1, count, dstFp) != count) {
-            LOGD("fwrite %d bytes failed\n", (int) count);
-            return UNKNOWN_ERROR;
-        }
-
-        length -= readSize;
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Compress all of the data in "srcFp" and write it to "dstFp".
- *
- * On exit, "srcFp" will be seeked to the end of the file, and "dstFp"
- * will be seeked immediately past the compressed data.
- */
-status_t ZipFile::compressFpToFp(FILE* dstFp, FILE* srcFp,
-    const void* data, size_t size, unsigned long* pCRC32)
-{
-    status_t result = NO_ERROR;
-	const size_t kBufSize = 32768;
-	unsigned char* inBuf = NULL;
-	unsigned char* outBuf = NULL;
-	z_stream zstream;
-    bool atEof = false;     // no feof() aviailable yet
-	unsigned long crc;
-	int zerr;
-
-	/*
-	 * Create an input buffer and an output buffer.
-	 */
-	inBuf = new unsigned char[kBufSize];
-	outBuf = new unsigned char[kBufSize];
-	if (inBuf == NULL || outBuf == NULL) {
-		result = NO_MEMORY;
-		goto bail;
-	}
-
-	/*
-	 * Initialize the zlib stream.
-	 */
-	memset(&zstream, 0, sizeof(zstream));
-	zstream.zalloc = Z_NULL;
-	zstream.zfree = Z_NULL;
-	zstream.opaque = Z_NULL;
-	zstream.next_in = NULL;
-	zstream.avail_in = 0;
-	zstream.next_out = outBuf;
-	zstream.avail_out = kBufSize;
-	zstream.data_type = Z_UNKNOWN;
-
-	zerr = deflateInit2(&zstream, Z_BEST_COMPRESSION,
-		Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-	if (zerr != Z_OK) {
-		result = UNKNOWN_ERROR;
-		if (zerr == Z_VERSION_ERROR) {
-			LOGE("Installed zlib is not compatible with linked version (%s)\n",
-				ZLIB_VERSION);
-		} else {
-			LOGD("Call to deflateInit2 failed (zerr=%d)\n", zerr);
-		}
-		goto bail;
-	}
-
- 	crc = crc32(0L, Z_NULL, 0);
-
-	/*
-	 * Loop while we have data.
-	 */
-	do {
-		size_t getSize;
-		int flush;
-
-		/* only read if the input buffer is empty */
-		if (zstream.avail_in == 0 && !atEof) {
-            LOGV("+++ reading %d bytes\n", (int)kBufSize);
-            if (data) {
-                getSize = size > kBufSize ? kBufSize : size;
-                memcpy(inBuf, data, getSize);
-                data = ((const char*)data) + getSize;
-                size -= getSize;
-            } else {
-                getSize = fread(inBuf, 1, kBufSize, srcFp);
-                if (ferror(srcFp)) {
-                    LOGD("deflate read failed (errno=%d)\n", errno);
-                    goto z_bail;
-                }
-            }
-            if (getSize < kBufSize) {
-                LOGV("+++  got %d bytes, EOF reached\n",
-                    (int)getSize);
-                atEof = true;
-            }
-
-			crc = crc32(crc, inBuf, getSize);
-
-			zstream.next_in = inBuf;
-			zstream.avail_in = getSize;
-		}
-
-		if (atEof)
-			flush = Z_FINISH;       /* tell zlib that we're done */
-		else
-			flush = Z_NO_FLUSH;     /* more to come! */
-
-		zerr = deflate(&zstream, flush);
-		if (zerr != Z_OK && zerr != Z_STREAM_END) {
-			LOGD("zlib deflate call failed (zerr=%d)\n", zerr);
-			result = UNKNOWN_ERROR;
-			goto z_bail;
-		}
-
-		/* write when we're full or when we're done */
-		if (zstream.avail_out == 0 ||
-			(zerr == Z_STREAM_END && zstream.avail_out != (uInt) kBufSize))
-		{
-			LOGV("+++ writing %d bytes\n", (int) (zstream.next_out - outBuf));
-            if (fwrite(outBuf, 1, zstream.next_out - outBuf, dstFp) !=
-                (size_t)(zstream.next_out - outBuf))
-            {
-				LOGD("write %d failed in deflate\n",
-                    (int) (zstream.next_out - outBuf));
-				goto z_bail;
-			}
-
-			zstream.next_out = outBuf;
-			zstream.avail_out = kBufSize;
-		}
-	} while (zerr == Z_OK);
-
-	assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
-
-	*pCRC32 = crc;
-
-z_bail:
-	deflateEnd(&zstream);        /* free up any allocated structures */
-
-bail:
-	delete[] inBuf;
-	delete[] outBuf;
-
-	return result;
-}
-
-/*
- * Mark an entry as deleted.
- *
- * We will eventually need to crunch the file down, but if several files
- * are being removed (perhaps as part of an "update" process) we can make
- * things considerably faster by deferring the removal to "flush" time.
- */
-status_t ZipFile::remove(ZipEntry* pEntry)
-{
-    /*
-     * Should verify that pEntry is actually part of this archive, and
-     * not some stray ZipEntry from a different file.
-     */
-
-    /* mark entry as deleted, and mark archive as dirty */
-    pEntry->setDeleted();
-    mNeedCDRewrite = true;
-    return NO_ERROR;
-}
-
-/*
- * Flush any pending writes.
- *
- * In particular, this will crunch out deleted entries, and write the
- * Central Directory and EOCD if we have stomped on them.
- */
-status_t ZipFile::flush(void)
-{
-    status_t result = NO_ERROR;
-    long eocdPosn;
-    int i, count;
-
-    if (mReadOnly)
-        return INVALID_OPERATION;
-    if (!mNeedCDRewrite)
-        return NO_ERROR;
-
-    assert(mZipFp != NULL);
-
-    result = crunchArchive();
-    if (result != NO_ERROR)
-        return result;
-
-    if (fseek(mZipFp, mEOCD.mCentralDirOffset, SEEK_SET) != 0)
-        return UNKNOWN_ERROR;
-
-    count = mEntries.size();
-    for (i = 0; i < count; i++) {
-        ZipEntry* pEntry = mEntries[i];
-        pEntry->mCDE.write(mZipFp);
-    }
-
-    eocdPosn = ftell(mZipFp);
-    mEOCD.mCentralDirSize = eocdPosn - mEOCD.mCentralDirOffset;
-
-    mEOCD.write(mZipFp);
-
-    /*
-     * If we had some stuff bloat up during compression and get replaced
-     * with plain files, or if we deleted some entries, there's a lot
-     * of wasted space at the end of the file.  Remove it now.
-     */
-    if (ftruncate(fileno(mZipFp), ftell(mZipFp)) != 0) {
-        LOGW("ftruncate failed %ld: %s\n", ftell(mZipFp), strerror(errno));
-        // not fatal
-    }
-
-    /* should we clear the "newly added" flag in all entries now? */
-
-    mNeedCDRewrite = false;
-    return NO_ERROR;
-}
-
-/*
- * Crunch deleted files out of an archive by shifting the later files down.
- *
- * Because we're not using a temp file, we do the operation inside the
- * current file.
- */
-status_t ZipFile::crunchArchive(void)
-{
-    status_t result = NO_ERROR;
-    int i, count;
-    long delCount, adjust;
-
-#if 0
-    printf("CONTENTS:\n");
-    for (i = 0; i < (int) mEntries.size(); i++) {
-        printf(" %d: lfhOff=%ld del=%d\n",
-            i, mEntries[i]->getLFHOffset(), mEntries[i]->getDeleted());
-    }
-    printf("  END is %ld\n", (long) mEOCD.mCentralDirOffset);
-#endif
-
-    /*
-     * Roll through the set of files, shifting them as appropriate.  We
-     * could probably get a slight performance improvement by sliding
-     * multiple files down at once (because we could use larger reads
-     * when operating on batches of small files), but it's not that useful.
-     */
-    count = mEntries.size();
-    delCount = adjust = 0;
-    for (i = 0; i < count; i++) {
-        ZipEntry* pEntry = mEntries[i];
-        long span;
-
-        if (pEntry->getLFHOffset() != 0) {
-            long nextOffset;
-
-            /* Get the length of this entry by finding the offset
-             * of the next entry.  Directory entries don't have
-             * file offsets, so we need to find the next non-directory
-             * entry.
-             */
-            nextOffset = 0;
-            for (int ii = i+1; nextOffset == 0 && ii < count; ii++)
-                nextOffset = mEntries[ii]->getLFHOffset();
-            if (nextOffset == 0)
-                nextOffset = mEOCD.mCentralDirOffset;
-            span = nextOffset - pEntry->getLFHOffset();
-
-            assert(span >= ZipEntry::LocalFileHeader::kLFHLen);
-        } else {
-            /* This is a directory entry.  It doesn't have
-             * any actual file contents, so there's no need to
-             * move anything.
-             */
-            span = 0;
-        }
-
-        //printf("+++ %d: off=%ld span=%ld del=%d [count=%d]\n",
-        //    i, pEntry->getLFHOffset(), span, pEntry->getDeleted(), count);
-
-        if (pEntry->getDeleted()) {
-            adjust += span;
-            delCount++;
-
-            delete pEntry;
-            mEntries.removeAt(i);
-
-            /* adjust loop control */
-            count--;
-            i--;
-        } else if (span != 0 && adjust > 0) {
-            /* shuffle this entry back */
-            //printf("+++ Shuffling '%s' back %ld\n",
-            //    pEntry->getFileName(), adjust);
-            result = filemove(mZipFp, pEntry->getLFHOffset() - adjust,
-                        pEntry->getLFHOffset(), span);
-            if (result != NO_ERROR) {
-                /* this is why you use a temp file */
-                LOGE("error during crunch - archive is toast\n");
-                return result;
-            }
-
-            pEntry->setLFHOffset(pEntry->getLFHOffset() - adjust);
-        }
-    }
-
-    /*
-     * Fix EOCD info.  We have to wait until the end to do some of this
-     * because we use mCentralDirOffset to determine "span" for the
-     * last entry.
-     */
-    mEOCD.mCentralDirOffset -= adjust;
-    mEOCD.mNumEntries -= delCount;
-    mEOCD.mTotalNumEntries -= delCount;
-    mEOCD.mCentralDirSize = 0;  // mark invalid; set by flush()
-
-    assert(mEOCD.mNumEntries == mEOCD.mTotalNumEntries);
-    assert(mEOCD.mNumEntries == count);
-
-    return result;
-}
-
-/*
- * Works like memmove(), but on pieces of a file.
- */
-status_t ZipFile::filemove(FILE* fp, off_t dst, off_t src, size_t n)
-{
-    if (dst == src || n <= 0)
-        return NO_ERROR;
-
-    unsigned char readBuf[32768];
-
-    if (dst < src) {
-        /* shift stuff toward start of file; must read from start */
-        while (n != 0) {
-            size_t getSize = sizeof(readBuf);
-            if (getSize > n)
-                getSize = n;
-
-            if (fseek(fp, (long) src, SEEK_SET) != 0) {
-                LOGD("filemove src seek %ld failed\n", (long) src);
-                return UNKNOWN_ERROR;
-            }
-
-            if (fread(readBuf, 1, getSize, fp) != getSize) {
-                LOGD("filemove read %ld off=%ld failed\n",
-                    (long) getSize, (long) src);
-                return UNKNOWN_ERROR;
-            }
-
-            if (fseek(fp, (long) dst, SEEK_SET) != 0) {
-                LOGD("filemove dst seek %ld failed\n", (long) dst);
-                return UNKNOWN_ERROR;
-            }
-
-            if (fwrite(readBuf, 1, getSize, fp) != getSize) {
-                LOGD("filemove write %ld off=%ld failed\n",
-                    (long) getSize, (long) dst);
-                return UNKNOWN_ERROR;
-            }
-
-            src += getSize;
-            dst += getSize;
-            n -= getSize;
-        }
-    } else {
-        /* shift stuff toward end of file; must read from end */
-        assert(false);      // write this someday, maybe
-        return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-
-/*
- * Get the modification time from a file descriptor.
- */
-time_t ZipFile::getModTime(int fd)
-{
-    struct stat sb;
-
-    if (fstat(fd, &sb) < 0) {
-        LOGD("HEY: fstat on fd %d failed\n", fd);
-        return (time_t) -1;
-    }
-
-    return sb.st_mtime;
-}
-
-
-#if 0       /* this is a bad idea */
-/*
- * Get a copy of the Zip file descriptor.
- *
- * We don't allow this if the file was opened read-write because we tend
- * to leave the file contents in an uncertain state between calls to
- * flush().  The duplicated file descriptor should only be valid for reads.
- */
-int ZipFile::getZipFd(void) const
-{
-    if (!mReadOnly)
-        return INVALID_OPERATION;
-    assert(mZipFp != NULL);
-
-    int fd;
-    fd = dup(fileno(mZipFp));
-    if (fd < 0) {
-        LOGD("didn't work, errno=%d\n", errno);
-    }
-
-    return fd;
-}
-#endif
-
-
-#if 0
-/*
- * Expand data.
- */
-bool ZipFile::uncompress(const ZipEntry* pEntry, void* buf) const
-{
-    return false;
-}
-#endif
-
-// free the memory when you're done
-void* ZipFile::uncompress(const ZipEntry* entry)
-{
-    size_t unlen = entry->getUncompressedLen();
-    size_t clen = entry->getCompressedLen();
-
-    void* buf = malloc(unlen);
-    if (buf == NULL) {
-        return NULL;
-    }
-
-    fseek(mZipFp, 0, SEEK_SET);
-
-    off_t offset = entry->getFileOffset();
-    if (fseek(mZipFp, offset, SEEK_SET) != 0) {
-        goto bail;
-    }
-
-    switch (entry->getCompressionMethod())
-    {
-        case ZipEntry::kCompressStored: {
-            ssize_t amt = fread(buf, 1, unlen, mZipFp);
-            if (amt != (ssize_t)unlen) {
-                goto bail;
-            }
-#if 0
-            printf("data...\n");
-            const unsigned char* p = (unsigned char*)buf;
-            const unsigned char* end = p+unlen;
-            for (int i=0; i<32 && p < end; i++) {
-                printf("0x%08x ", (int)(offset+(i*0x10)));
-                for (int j=0; j<0x10 && p < end; j++) {
-                    printf(" %02x", *p);
-                    p++;
-                }
-                printf("\n");
-            }
-#endif
-
-            }
-            break;
-        case ZipEntry::kCompressDeflated: {
-            if (!ZipUtils::inflateToBuffer(mZipFp, buf, unlen, clen)) {
-                goto bail;
-            }
-            }
-            break;
-        default:
-            goto bail;
-    }
-    return buf;
-
-bail:
-    free(buf);
-    return NULL;
-}
-
-
-/*
- * ===========================================================================
- *		ZipFile::EndOfCentralDir
- * ===========================================================================
- */
-
-/*
- * Read the end-of-central-dir fields.
- *
- * "buf" should be positioned at the EOCD signature, and should contain
- * the entire EOCD area including the comment.
- */
-status_t ZipFile::EndOfCentralDir::readBuf(const unsigned char* buf, int len)
-{
-    /* don't allow re-use */
-    assert(mComment == NULL);
-
-    if (len < kEOCDLen) {
-        /* looks like ZIP file got truncated */
-        LOGD(" Zip EOCD: expected >= %d bytes, found %d\n",
-            kEOCDLen, len);
-        return INVALID_OPERATION;
-    }
-
-    /* this should probably be an assert() */
-    if (ZipEntry::getLongLE(&buf[0x00]) != kSignature)
-        return UNKNOWN_ERROR;
-
-    mDiskNumber = ZipEntry::getShortLE(&buf[0x04]);
-    mDiskWithCentralDir = ZipEntry::getShortLE(&buf[0x06]);
-    mNumEntries = ZipEntry::getShortLE(&buf[0x08]);
-    mTotalNumEntries = ZipEntry::getShortLE(&buf[0x0a]);
-    mCentralDirSize = ZipEntry::getLongLE(&buf[0x0c]);
-    mCentralDirOffset = ZipEntry::getLongLE(&buf[0x10]);
-    mCommentLen = ZipEntry::getShortLE(&buf[0x14]);
-
-    // TODO: validate mCentralDirOffset
-
-    if (mCommentLen > 0) {
-        if (kEOCDLen + mCommentLen > len) {
-            LOGD("EOCD(%d) + comment(%d) exceeds len (%d)\n",
-                kEOCDLen, mCommentLen, len);
-            return UNKNOWN_ERROR;
-        }
-        mComment = new unsigned char[mCommentLen];
-        memcpy(mComment, buf + kEOCDLen, mCommentLen);
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Write an end-of-central-directory section.
- */
-status_t ZipFile::EndOfCentralDir::write(FILE* fp)
-{
-    unsigned char buf[kEOCDLen];
-
-    ZipEntry::putLongLE(&buf[0x00], kSignature);
-    ZipEntry::putShortLE(&buf[0x04], mDiskNumber);
-    ZipEntry::putShortLE(&buf[0x06], mDiskWithCentralDir);
-    ZipEntry::putShortLE(&buf[0x08], mNumEntries);
-    ZipEntry::putShortLE(&buf[0x0a], mTotalNumEntries);
-    ZipEntry::putLongLE(&buf[0x0c], mCentralDirSize);
-    ZipEntry::putLongLE(&buf[0x10], mCentralDirOffset);
-    ZipEntry::putShortLE(&buf[0x14], mCommentLen);
-
-    if (fwrite(buf, 1, kEOCDLen, fp) != kEOCDLen)
-        return UNKNOWN_ERROR;
-    if (mCommentLen > 0) {
-        assert(mComment != NULL);
-        if (fwrite(mComment, mCommentLen, 1, fp) != mCommentLen)
-            return UNKNOWN_ERROR;
-    }
-
-    return NO_ERROR;
-}
-
-/*
- * Dump the contents of an EndOfCentralDir object.
- */
-void ZipFile::EndOfCentralDir::dump(void) const
-{
-    LOGD(" EndOfCentralDir contents:\n");
-    LOGD("  diskNum=%u diskWCD=%u numEnt=%u totalNumEnt=%u\n",
-        mDiskNumber, mDiskWithCentralDir, mNumEntries, mTotalNumEntries);
-    LOGD("  centDirSize=%lu centDirOff=%lu commentLen=%u\n",
-        mCentralDirSize, mCentralDirOffset, mCommentLen);
-}
-
diff --git a/libs/utils/executablepath_darwin.cpp b/libs/utils/executablepath_darwin.cpp
deleted file mode 100644
index 2e3c3a0..0000000
--- a/libs/utils/executablepath_darwin.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/executablepath.h>
-#import <Carbon/Carbon.h>
-#include <unistd.h>
-
-void executablepath(char s[PATH_MAX])
-{
-    ProcessSerialNumber psn;
-    GetCurrentProcess(&psn);
-    CFDictionaryRef dict;
-    dict = ProcessInformationCopyDictionary(&psn, 0xffffffff);
-    CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict,
-                CFSTR("CFBundleExecutable"));
-    CFStringGetCString(value, s, PATH_MAX+1, kCFStringEncodingUTF8);
-}
-
diff --git a/libs/utils/executablepath_linux.cpp b/libs/utils/executablepath_linux.cpp
deleted file mode 100644
index b8d2a3d..0000000
--- a/libs/utils/executablepath_linux.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <utils/executablepath.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <limits.h>
-#include <stdio.h>
-
-void executablepath(char exe[PATH_MAX])
-{
-    char proc[100];
-    sprintf(proc, "/proc/%d/exe", getpid());
-    
-    int err = readlink(proc, exe, PATH_MAX);
-}
-
diff --git a/libs/utils/ported.cpp b/libs/utils/ported.cpp
deleted file mode 100644
index 656e46f..0000000
--- a/libs/utils/ported.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2005 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.
- */
-
-//
-// Ports of standard functions that don't exist on a specific platform.
-//
-// Note these are NOT in the "android" namespace.
-//
-#include <utils/ported.h>
-
-#if defined(NEED_GETTIMEOFDAY) || defined(NEED_USLEEP)
-# include <sys/time.h>
-# include <windows.h>
-#endif
-
-
-#if defined(NEED_GETTIMEOFDAY)
-/*
- * Replacement gettimeofday() for Windows environments (primarily MinGW).
- *
- * Ignores "tz".
- */
-int gettimeofday(struct timeval* ptv, struct timezone* tz)
-{
-    long long nsTime;   // time in 100ns units since Jan 1 1601
-    FILETIME ft;
-
-    if (tz != NULL) {
-        // oh well
-    }
-
-    ::GetSystemTimeAsFileTime(&ft);
-    nsTime = (long long) ft.dwHighDateTime << 32 |
-             (long long) ft.dwLowDateTime;
-    // convert to time in usec since Jan 1 1970
-    ptv->tv_usec = (long) ((nsTime / 10LL) % 1000000LL);
-    ptv->tv_sec = (long) ((nsTime - 116444736000000000LL) / 10000000LL);
-
-    return 0;
-}
-#endif
-
-#if defined(NEED_USLEEP)
-//
-// Replacement usleep for Windows environments (primarily MinGW).
-//
-void usleep(unsigned long usec)
-{
-    // Win32 API function Sleep() takes milliseconds
-    ::Sleep((usec + 500) / 1000);
-}
-#endif
-
-#if 0 //defined(NEED_PIPE)
-//
-// Replacement pipe() command for MinGW
-//
-// The _O_NOINHERIT flag sets bInheritHandle to FALSE in the
-// SecurityAttributes argument to CreatePipe().  This means the handles
-// aren't inherited when a new process is created.  The examples I've seen
-// use it, possibly because there's a lot of junk going on behind the
-// scenes.  (I'm assuming "process" and "thread" are different here, so
-// we should be okay spinning up a thread.)  The recommended practice is
-// to dup() the descriptor you want the child to have.
-//
-// It appears that unnamed pipes can't do non-blocking ("overlapped") I/O.
-// You can't use select() either, since that only works on sockets.  The
-// Windows API calls that are useful here all operate on a HANDLE, not
-// an integer file descriptor, and I don't think you can get there from
-// here.  The "named pipe" stuff is insane.
-//
-int pipe(int filedes[2])
-{
-    return _pipe(filedes, 0, _O_BINARY | _O_NOINHERIT);
-}
-#endif
-
-#if defined(NEED_SETENV)
-/*
- * MinGW lacks these.  For now, just stub them out so the code compiles.
- */
-int setenv(const char* name, const char* value, int overwrite)
-{
-    return 0;
-}
-void unsetenv(const char* name)
-{
-}
-char* getenv(const char* name)
-{
-    return NULL;
-}
-#endif
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 25cfcb8..545fd0e 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -131,6 +131,30 @@
 /* Interfaces defined by EGL_KHR_image above */
 #endif
 
+
+#ifndef EGL_ANDROID_image_native_buffer
+#define EGL_ANDROID_image_native_buffer 1
+struct android_native_buffer_t;
+#define EGL_NATIVE_BUFFER_ANDROID       0x3140  /* eglCreateImageKHR target */
+#endif
+
+#ifndef EGL_ANDROID_get_render_buffer
+#define EGL_ANDROID_get_render_buffer 1
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLClientBuffer EGLAPIENTRY eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw);
+#endif
+typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETRENDERBUFFERANDROIDPROC) (EGLDisplay dpy, EGLSurface draw);
+#endif
+
+#ifndef EGL_ANDROID_swap_rectangle
+#define EGL_ANDROID_swap_rectangle 1
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglSetSwapRectangleANDROID (EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSWAPRECTANGLEANDROIDPROC) (EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height);
+#endif
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h
index ac00901..53e9e61 100644
--- a/opengl/include/EGL/eglplatform.h
+++ b/opengl/include/EGL/eglplatform.h
@@ -89,9 +89,10 @@
 
 #elif defined(ANDROID)
 
-#include <EGL/eglnatives.h>
+struct android_native_window_t;
+struct egl_native_pixmap_t;
 
-typedef struct egl_native_window_t*     EGLNativeWindowType;
+typedef struct android_native_window_t* EGLNativeWindowType;
 typedef struct egl_native_pixmap_t*     EGLNativePixmapType;
 typedef void*                           EGLNativeDisplayType;
 
diff --git a/opengl/include/GLES/glplatform.h b/opengl/include/GLES/glplatform.h
index 0924cae..198e679 100644
--- a/opengl/include/GLES/glplatform.h
+++ b/opengl/include/GLES/glplatform.h
@@ -28,12 +28,6 @@
 
 #define GL_APIENTRY KHRONOS_APIENTRY
 
-// XXX: this should probably not be here
-#define GL_DIRECT_TEXTURE_2D_QUALCOMM               0x7E80
-
-// XXX: not sure how this is intended to be used
-#define GL_GLEXT_PROTOTYPES
-
 #endif
 
 #endif /* __glplatform_h_ */
diff --git a/opengl/include/GLES2/gl2.h b/opengl/include/GLES2/gl2.h
new file mode 100644
index 0000000..0182a67
--- /dev/null
+++ b/opengl/include/GLES2/gl2.h
@@ -0,0 +1,620 @@
+#ifndef __gl2_h_
+#define __gl2_h_
+
+/* $Revision: 7173 $ on $Date:: 2009-01-09 11:18:21 -0800 #$ */
+
+#include <GLES2/gl2platform.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+/*-------------------------------------------------------------------------
+ * Data type definitions
+ *-----------------------------------------------------------------------*/
+
+typedef void             GLvoid;
+typedef unsigned int     GLenum;
+typedef unsigned char    GLboolean;
+typedef unsigned int     GLbitfield;
+typedef khronos_int8_t   GLbyte;
+typedef short            GLshort;
+typedef int              GLint;
+typedef int              GLsizei;
+typedef khronos_uint8_t  GLubyte;
+typedef unsigned short   GLushort;
+typedef unsigned int     GLuint;
+typedef khronos_float_t  GLfloat;
+typedef khronos_float_t  GLclampf;
+typedef khronos_int32_t  GLfixed;
+
+/* GL types for handling large vertex buffer objects */
+typedef khronos_intptr_t GLintptr;
+typedef khronos_ssize_t  GLsizeiptr;
+
+/* OpenGL ES core versions */
+#define GL_ES_VERSION_2_0                 1
+
+/* ClearBufferMask */
+#define GL_DEPTH_BUFFER_BIT               0x00000100
+#define GL_STENCIL_BUFFER_BIT             0x00000400
+#define GL_COLOR_BUFFER_BIT               0x00004000
+
+/* Boolean */
+#define GL_FALSE                          0
+#define GL_TRUE                           1
+
+/* BeginMode */
+#define GL_POINTS                         0x0000
+#define GL_LINES                          0x0001
+#define GL_LINE_LOOP                      0x0002
+#define GL_LINE_STRIP                     0x0003
+#define GL_TRIANGLES                      0x0004
+#define GL_TRIANGLE_STRIP                 0x0005
+#define GL_TRIANGLE_FAN                   0x0006
+
+/* AlphaFunction (not supported in ES20) */
+/*      GL_NEVER */
+/*      GL_LESS */
+/*      GL_EQUAL */
+/*      GL_LEQUAL */
+/*      GL_GREATER */
+/*      GL_NOTEQUAL */
+/*      GL_GEQUAL */
+/*      GL_ALWAYS */
+
+/* BlendingFactorDest */
+#define GL_ZERO                           0
+#define GL_ONE                            1
+#define GL_SRC_COLOR                      0x0300
+#define GL_ONE_MINUS_SRC_COLOR            0x0301
+#define GL_SRC_ALPHA                      0x0302
+#define GL_ONE_MINUS_SRC_ALPHA            0x0303
+#define GL_DST_ALPHA                      0x0304
+#define GL_ONE_MINUS_DST_ALPHA            0x0305
+
+/* BlendingFactorSrc */
+/*      GL_ZERO */
+/*      GL_ONE */
+#define GL_DST_COLOR                      0x0306
+#define GL_ONE_MINUS_DST_COLOR            0x0307
+#define GL_SRC_ALPHA_SATURATE             0x0308
+/*      GL_SRC_ALPHA */
+/*      GL_ONE_MINUS_SRC_ALPHA */
+/*      GL_DST_ALPHA */
+/*      GL_ONE_MINUS_DST_ALPHA */
+
+/* BlendEquationSeparate */
+#define GL_FUNC_ADD                       0x8006
+#define GL_BLEND_EQUATION                 0x8009
+#define GL_BLEND_EQUATION_RGB             0x8009    /* same as BLEND_EQUATION */
+#define GL_BLEND_EQUATION_ALPHA           0x883D
+
+/* BlendSubtract */
+#define GL_FUNC_SUBTRACT                  0x800A
+#define GL_FUNC_REVERSE_SUBTRACT          0x800B
+
+/* Separate Blend Functions */
+#define GL_BLEND_DST_RGB                  0x80C8
+#define GL_BLEND_SRC_RGB                  0x80C9
+#define GL_BLEND_DST_ALPHA                0x80CA
+#define GL_BLEND_SRC_ALPHA                0x80CB
+#define GL_CONSTANT_COLOR                 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR       0x8002
+#define GL_CONSTANT_ALPHA                 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA       0x8004
+#define GL_BLEND_COLOR                    0x8005
+
+/* Buffer Objects */
+#define GL_ARRAY_BUFFER                   0x8892
+#define GL_ELEMENT_ARRAY_BUFFER           0x8893
+#define GL_ARRAY_BUFFER_BINDING           0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING   0x8895
+
+#define GL_STREAM_DRAW                    0x88E0
+#define GL_STATIC_DRAW                    0x88E4
+#define GL_DYNAMIC_DRAW                   0x88E8
+
+#define GL_BUFFER_SIZE                    0x8764
+#define GL_BUFFER_USAGE                   0x8765
+
+#define GL_CURRENT_VERTEX_ATTRIB          0x8626
+
+/* CullFaceMode */
+#define GL_FRONT                          0x0404
+#define GL_BACK                           0x0405
+#define GL_FRONT_AND_BACK                 0x0408
+
+/* DepthFunction */
+/*      GL_NEVER */
+/*      GL_LESS */
+/*      GL_EQUAL */
+/*      GL_LEQUAL */
+/*      GL_GREATER */
+/*      GL_NOTEQUAL */
+/*      GL_GEQUAL */
+/*      GL_ALWAYS */
+
+/* EnableCap */
+#define GL_TEXTURE_2D                     0x0DE1
+#define GL_CULL_FACE                      0x0B44
+#define GL_BLEND                          0x0BE2
+#define GL_DITHER                         0x0BD0
+#define GL_STENCIL_TEST                   0x0B90
+#define GL_DEPTH_TEST                     0x0B71
+#define GL_SCISSOR_TEST                   0x0C11
+#define GL_POLYGON_OFFSET_FILL            0x8037
+#define GL_SAMPLE_ALPHA_TO_COVERAGE       0x809E
+#define GL_SAMPLE_COVERAGE                0x80A0
+
+/* ErrorCode */
+#define GL_NO_ERROR                       0
+#define GL_INVALID_ENUM                   0x0500
+#define GL_INVALID_VALUE                  0x0501
+#define GL_INVALID_OPERATION              0x0502
+#define GL_OUT_OF_MEMORY                  0x0505
+
+/* FrontFaceDirection */
+#define GL_CW                             0x0900
+#define GL_CCW                            0x0901
+
+/* GetPName */
+#define GL_LINE_WIDTH                     0x0B21
+#define GL_ALIASED_POINT_SIZE_RANGE       0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE       0x846E
+#define GL_CULL_FACE_MODE                 0x0B45
+#define GL_FRONT_FACE                     0x0B46
+#define GL_DEPTH_RANGE                    0x0B70
+#define GL_DEPTH_WRITEMASK                0x0B72
+#define GL_DEPTH_CLEAR_VALUE              0x0B73
+#define GL_DEPTH_FUNC                     0x0B74
+#define GL_STENCIL_CLEAR_VALUE            0x0B91
+#define GL_STENCIL_FUNC                   0x0B92
+#define GL_STENCIL_FAIL                   0x0B94
+#define GL_STENCIL_PASS_DEPTH_FAIL        0x0B95
+#define GL_STENCIL_PASS_DEPTH_PASS        0x0B96
+#define GL_STENCIL_REF                    0x0B97
+#define GL_STENCIL_VALUE_MASK             0x0B93
+#define GL_STENCIL_WRITEMASK              0x0B98
+#define GL_STENCIL_BACK_FUNC              0x8800
+#define GL_STENCIL_BACK_FAIL              0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL   0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS   0x8803
+#define GL_STENCIL_BACK_REF               0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK        0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK         0x8CA5
+#define GL_VIEWPORT                       0x0BA2
+#define GL_SCISSOR_BOX                    0x0C10
+/*      GL_SCISSOR_TEST */
+#define GL_COLOR_CLEAR_VALUE              0x0C22
+#define GL_COLOR_WRITEMASK                0x0C23
+#define GL_UNPACK_ALIGNMENT               0x0CF5
+#define GL_PACK_ALIGNMENT                 0x0D05
+#define GL_MAX_TEXTURE_SIZE               0x0D33
+#define GL_MAX_VIEWPORT_DIMS              0x0D3A
+#define GL_SUBPIXEL_BITS                  0x0D50
+#define GL_RED_BITS                       0x0D52
+#define GL_GREEN_BITS                     0x0D53
+#define GL_BLUE_BITS                      0x0D54
+#define GL_ALPHA_BITS                     0x0D55
+#define GL_DEPTH_BITS                     0x0D56
+#define GL_STENCIL_BITS                   0x0D57
+#define GL_POLYGON_OFFSET_UNITS           0x2A00
+/*      GL_POLYGON_OFFSET_FILL */
+#define GL_POLYGON_OFFSET_FACTOR          0x8038
+#define GL_TEXTURE_BINDING_2D             0x8069
+#define GL_SAMPLE_BUFFERS                 0x80A8
+#define GL_SAMPLES                        0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE          0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT         0x80AB
+
+/* GetTextureParameter */
+/*      GL_TEXTURE_MAG_FILTER */
+/*      GL_TEXTURE_MIN_FILTER */
+/*      GL_TEXTURE_WRAP_S */
+/*      GL_TEXTURE_WRAP_T */
+
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS     0x86A3
+
+/* HintMode */
+#define GL_DONT_CARE                      0x1100
+#define GL_FASTEST                        0x1101
+#define GL_NICEST                         0x1102
+
+/* HintTarget */
+#define GL_GENERATE_MIPMAP_HINT            0x8192
+
+/* DataType */
+#define GL_BYTE                           0x1400
+#define GL_UNSIGNED_BYTE                  0x1401
+#define GL_SHORT                          0x1402
+#define GL_UNSIGNED_SHORT                 0x1403
+#define GL_INT                            0x1404
+#define GL_UNSIGNED_INT                   0x1405
+#define GL_FLOAT                          0x1406
+#define GL_FIXED                          0x140C
+
+/* PixelFormat */
+#define GL_DEPTH_COMPONENT                0x1902
+#define GL_ALPHA                          0x1906
+#define GL_RGB                            0x1907
+#define GL_RGBA                           0x1908
+#define GL_LUMINANCE                      0x1909
+#define GL_LUMINANCE_ALPHA                0x190A
+
+/* PixelType */
+/*      GL_UNSIGNED_BYTE */
+#define GL_UNSIGNED_SHORT_4_4_4_4         0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1         0x8034
+#define GL_UNSIGNED_SHORT_5_6_5           0x8363
+
+/* Shaders */
+#define GL_FRAGMENT_SHADER                  0x8B30
+#define GL_VERTEX_SHADER                    0x8B31
+#define GL_MAX_VERTEX_ATTRIBS               0x8869
+#define GL_MAX_VERTEX_UNIFORM_VECTORS       0x8DFB
+#define GL_MAX_VARYING_VECTORS              0x8DFC
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS   0x8B4C
+#define GL_MAX_TEXTURE_IMAGE_UNITS          0x8872
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS     0x8DFD
+#define GL_SHADER_TYPE                      0x8B4F
+#define GL_DELETE_STATUS                    0x8B80
+#define GL_LINK_STATUS                      0x8B82
+#define GL_VALIDATE_STATUS                  0x8B83
+#define GL_ATTACHED_SHADERS                 0x8B85
+#define GL_ACTIVE_UNIFORMS                  0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH        0x8B87
+#define GL_ACTIVE_ATTRIBUTES                0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH      0x8B8A
+#define GL_SHADING_LANGUAGE_VERSION         0x8B8C
+#define GL_CURRENT_PROGRAM                  0x8B8D
+
+/* StencilFunction */
+#define GL_NEVER                          0x0200
+#define GL_LESS                           0x0201
+#define GL_EQUAL                          0x0202
+#define GL_LEQUAL                         0x0203
+#define GL_GREATER                        0x0204
+#define GL_NOTEQUAL                       0x0205
+#define GL_GEQUAL                         0x0206
+#define GL_ALWAYS                         0x0207
+
+/* StencilOp */
+/*      GL_ZERO */
+#define GL_KEEP                           0x1E00
+#define GL_REPLACE                        0x1E01
+#define GL_INCR                           0x1E02
+#define GL_DECR                           0x1E03
+#define GL_INVERT                         0x150A
+#define GL_INCR_WRAP                      0x8507
+#define GL_DECR_WRAP                      0x8508
+
+/* StringName */
+#define GL_VENDOR                         0x1F00
+#define GL_RENDERER                       0x1F01
+#define GL_VERSION                        0x1F02
+#define GL_EXTENSIONS                     0x1F03
+
+/* TextureMagFilter */
+#define GL_NEAREST                        0x2600
+#define GL_LINEAR                         0x2601
+
+/* TextureMinFilter */
+/*      GL_NEAREST */
+/*      GL_LINEAR */
+#define GL_NEAREST_MIPMAP_NEAREST         0x2700
+#define GL_LINEAR_MIPMAP_NEAREST          0x2701
+#define GL_NEAREST_MIPMAP_LINEAR          0x2702
+#define GL_LINEAR_MIPMAP_LINEAR           0x2703
+
+/* TextureParameterName */
+#define GL_TEXTURE_MAG_FILTER             0x2800
+#define GL_TEXTURE_MIN_FILTER             0x2801
+#define GL_TEXTURE_WRAP_S                 0x2802
+#define GL_TEXTURE_WRAP_T                 0x2803
+
+/* TextureTarget */
+/*      GL_TEXTURE_2D */
+#define GL_TEXTURE                        0x1702
+
+#define GL_TEXTURE_CUBE_MAP               0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP       0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X    0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X    0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y    0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y    0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z    0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z    0x851A
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE      0x851C
+
+/* TextureUnit */
+#define GL_TEXTURE0                       0x84C0
+#define GL_TEXTURE1                       0x84C1
+#define GL_TEXTURE2                       0x84C2
+#define GL_TEXTURE3                       0x84C3
+#define GL_TEXTURE4                       0x84C4
+#define GL_TEXTURE5                       0x84C5
+#define GL_TEXTURE6                       0x84C6
+#define GL_TEXTURE7                       0x84C7
+#define GL_TEXTURE8                       0x84C8
+#define GL_TEXTURE9                       0x84C9
+#define GL_TEXTURE10                      0x84CA
+#define GL_TEXTURE11                      0x84CB
+#define GL_TEXTURE12                      0x84CC
+#define GL_TEXTURE13                      0x84CD
+#define GL_TEXTURE14                      0x84CE
+#define GL_TEXTURE15                      0x84CF
+#define GL_TEXTURE16                      0x84D0
+#define GL_TEXTURE17                      0x84D1
+#define GL_TEXTURE18                      0x84D2
+#define GL_TEXTURE19                      0x84D3
+#define GL_TEXTURE20                      0x84D4
+#define GL_TEXTURE21                      0x84D5
+#define GL_TEXTURE22                      0x84D6
+#define GL_TEXTURE23                      0x84D7
+#define GL_TEXTURE24                      0x84D8
+#define GL_TEXTURE25                      0x84D9
+#define GL_TEXTURE26                      0x84DA
+#define GL_TEXTURE27                      0x84DB
+#define GL_TEXTURE28                      0x84DC
+#define GL_TEXTURE29                      0x84DD
+#define GL_TEXTURE30                      0x84DE
+#define GL_TEXTURE31                      0x84DF
+#define GL_ACTIVE_TEXTURE                 0x84E0
+
+/* TextureWrapMode */
+#define GL_REPEAT                         0x2901
+#define GL_CLAMP_TO_EDGE                  0x812F
+#define GL_MIRRORED_REPEAT                0x8370
+
+/* Uniform Types */
+#define GL_FLOAT_VEC2                     0x8B50
+#define GL_FLOAT_VEC3                     0x8B51
+#define GL_FLOAT_VEC4                     0x8B52
+#define GL_INT_VEC2                       0x8B53
+#define GL_INT_VEC3                       0x8B54
+#define GL_INT_VEC4                       0x8B55
+#define GL_BOOL                           0x8B56
+#define GL_BOOL_VEC2                      0x8B57
+#define GL_BOOL_VEC3                      0x8B58
+#define GL_BOOL_VEC4                      0x8B59
+#define GL_FLOAT_MAT2                     0x8B5A
+#define GL_FLOAT_MAT3                     0x8B5B
+#define GL_FLOAT_MAT4                     0x8B5C
+#define GL_SAMPLER_2D                     0x8B5E
+#define GL_SAMPLER_CUBE                   0x8B60
+
+/* Vertex Arrays */
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED        0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE           0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE         0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE           0x8625
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED     0x886A
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER        0x8645
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+
+/* Read Format */
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE   0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
+
+/* Shader Source */
+#define GL_COMPILE_STATUS                 0x8B81
+#define GL_INFO_LOG_LENGTH                0x8B84
+#define GL_SHADER_SOURCE_LENGTH           0x8B88
+#define GL_SHADER_COMPILER                0x8DFA
+
+/* Shader Binary */
+#define GL_SHADER_BINARY_FORMATS          0x8DF8
+#define GL_NUM_SHADER_BINARY_FORMATS      0x8DF9
+
+/* Shader Precision-Specified Types */
+#define GL_LOW_FLOAT                      0x8DF0
+#define GL_MEDIUM_FLOAT                   0x8DF1
+#define GL_HIGH_FLOAT                     0x8DF2
+#define GL_LOW_INT                        0x8DF3
+#define GL_MEDIUM_INT                     0x8DF4
+#define GL_HIGH_INT                       0x8DF5
+
+/* Framebuffer Object. */
+#define GL_FRAMEBUFFER                    0x8D40
+#define GL_RENDERBUFFER                   0x8D41
+
+#define GL_RGBA4                          0x8056
+#define GL_RGB5_A1                        0x8057
+#define GL_RGB565                         0x8D62
+#define GL_DEPTH_COMPONENT16              0x81A5
+#define GL_STENCIL_INDEX                  0x1901
+#define GL_STENCIL_INDEX8                 0x8D48
+
+#define GL_RENDERBUFFER_WIDTH             0x8D42
+#define GL_RENDERBUFFER_HEIGHT            0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT   0x8D44
+#define GL_RENDERBUFFER_RED_SIZE          0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE        0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE         0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE        0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE        0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE      0x8D55
+
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE           0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME           0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL         0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
+
+#define GL_COLOR_ATTACHMENT0              0x8CE0
+#define GL_DEPTH_ATTACHMENT               0x8D00
+#define GL_STENCIL_ATTACHMENT             0x8D20
+
+#define GL_NONE                           0
+
+#define GL_FRAMEBUFFER_COMPLETE                      0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT         0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS         0x8CD9
+#define GL_FRAMEBUFFER_UNSUPPORTED                   0x8CDD
+
+#define GL_FRAMEBUFFER_BINDING            0x8CA6
+#define GL_RENDERBUFFER_BINDING           0x8CA7
+#define GL_MAX_RENDERBUFFER_SIZE          0x84E8
+
+#define GL_INVALID_FRAMEBUFFER_OPERATION  0x0506
+
+/*-------------------------------------------------------------------------
+ * GL core functions.
+ *-----------------------------------------------------------------------*/
+
+GL_APICALL void         GL_APIENTRY glActiveTexture (GLenum texture);
+GL_APICALL void         GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
+GL_APICALL void         GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const char* name);
+GL_APICALL void         GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
+GL_APICALL void         GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
+GL_APICALL void         GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
+GL_APICALL void         GL_APIENTRY glBindTexture (GLenum target, GLuint texture);
+GL_APICALL void         GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GL_APICALL void         GL_APIENTRY glBlendEquation ( GLenum mode );
+GL_APICALL void         GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
+GL_APICALL void         GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
+GL_APICALL void         GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+GL_APICALL void         GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void* data, GLenum usage);
+GL_APICALL void         GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
+GL_APICALL GLenum       GL_APIENTRY glCheckFramebufferStatus (GLenum target);
+GL_APICALL void         GL_APIENTRY glClear (GLbitfield mask);
+GL_APICALL void         GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GL_APICALL void         GL_APIENTRY glClearDepthf (GLclampf depth);
+GL_APICALL void         GL_APIENTRY glClearStencil (GLint s);
+GL_APICALL void         GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+GL_APICALL void         GL_APIENTRY glCompileShader (GLuint shader);
+GL_APICALL void         GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
+GL_APICALL void         GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+GL_APICALL void         GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+GL_APICALL void         GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL GLuint       GL_APIENTRY glCreateProgram (void);
+GL_APICALL GLuint       GL_APIENTRY glCreateShader (GLenum type);
+GL_APICALL void         GL_APIENTRY glCullFace (GLenum mode);
+GL_APICALL void         GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers);
+GL_APICALL void         GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers);
+GL_APICALL void         GL_APIENTRY glDeleteProgram (GLuint program);
+GL_APICALL void         GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers);
+GL_APICALL void         GL_APIENTRY glDeleteShader (GLuint shader);
+GL_APICALL void         GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures);
+GL_APICALL void         GL_APIENTRY glDepthFunc (GLenum func);
+GL_APICALL void         GL_APIENTRY glDepthMask (GLboolean flag);
+GL_APICALL void         GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar);
+GL_APICALL void         GL_APIENTRY glDetachShader (GLuint program, GLuint shader);
+GL_APICALL void         GL_APIENTRY glDisable (GLenum cap);
+GL_APICALL void         GL_APIENTRY glDisableVertexAttribArray (GLuint index);
+GL_APICALL void         GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
+GL_APICALL void         GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void* indices);
+GL_APICALL void         GL_APIENTRY glEnable (GLenum cap);
+GL_APICALL void         GL_APIENTRY glEnableVertexAttribArray (GLuint index);
+GL_APICALL void         GL_APIENTRY glFinish (void);
+GL_APICALL void         GL_APIENTRY glFlush (void);
+GL_APICALL void         GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GL_APICALL void         GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GL_APICALL void         GL_APIENTRY glFrontFace (GLenum mode);
+GL_APICALL void         GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers);
+GL_APICALL void         GL_APIENTRY glGenerateMipmap (GLenum target);
+GL_APICALL void         GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers);
+GL_APICALL void         GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers);
+GL_APICALL void         GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures);
+GL_APICALL void         GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+GL_APICALL void         GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+GL_APICALL void         GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+GL_APICALL int          GL_APIENTRY glGetAttribLocation (GLuint program, const char* name);
+GL_APICALL void         GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params);
+GL_APICALL void         GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL GLenum       GL_APIENTRY glGetError (void);
+GL_APICALL void         GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params);
+GL_APICALL void         GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params);
+GL_APICALL void         GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params);
+GL_APICALL void         GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params);
+GL_APICALL void         GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+GL_APICALL void         GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void         GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params);
+GL_APICALL void         GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+GL_APICALL void         GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+GL_APICALL void         GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
+GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name);
+GL_APICALL void         GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params);
+GL_APICALL void         GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void         GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params);
+GL_APICALL void         GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params);
+GL_APICALL int          GL_APIENTRY glGetUniformLocation (GLuint program, const char* name);
+GL_APICALL void         GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params);
+GL_APICALL void         GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params);
+GL_APICALL void         GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void** pointer);
+GL_APICALL void         GL_APIENTRY glHint (GLenum target, GLenum mode);
+GL_APICALL GLboolean    GL_APIENTRY glIsBuffer (GLuint buffer);
+GL_APICALL GLboolean    GL_APIENTRY glIsEnabled (GLenum cap);
+GL_APICALL GLboolean    GL_APIENTRY glIsFramebuffer (GLuint framebuffer);
+GL_APICALL GLboolean    GL_APIENTRY glIsProgram (GLuint program);
+GL_APICALL GLboolean    GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer);
+GL_APICALL GLboolean    GL_APIENTRY glIsShader (GLuint shader);
+GL_APICALL GLboolean    GL_APIENTRY glIsTexture (GLuint texture);
+GL_APICALL void         GL_APIENTRY glLineWidth (GLfloat width);
+GL_APICALL void         GL_APIENTRY glLinkProgram (GLuint program);
+GL_APICALL void         GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
+GL_APICALL void         GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
+GL_APICALL void         GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
+GL_APICALL void         GL_APIENTRY glReleaseShaderCompiler (void);
+GL_APICALL void         GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void         GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
+GL_APICALL void         GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void         GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length);
+GL_APICALL void         GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const char** string, const GLint* length);
+GL_APICALL void         GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
+GL_APICALL void         GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
+GL_APICALL void         GL_APIENTRY glStencilMask (GLuint mask);
+GL_APICALL void         GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
+GL_APICALL void         GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void         GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+GL_APICALL void         GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat,  GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void         GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
+GL_APICALL void         GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params);
+GL_APICALL void         GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
+GL_APICALL void         GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params);
+GL_APICALL void         GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
+GL_APICALL void         GL_APIENTRY glUniform1f (GLint location, GLfloat x);
+GL_APICALL void         GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void         GL_APIENTRY glUniform1i (GLint location, GLint x);
+GL_APICALL void         GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void         GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y);
+GL_APICALL void         GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void         GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y);
+GL_APICALL void         GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void         GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void         GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void         GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z);
+GL_APICALL void         GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void         GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void         GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v);
+GL_APICALL void         GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void         GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v);
+GL_APICALL void         GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void         GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void         GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void         GL_APIENTRY glUseProgram (GLuint program);
+GL_APICALL void         GL_APIENTRY glValidateProgram (GLuint program);
+GL_APICALL void         GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x);
+GL_APICALL void         GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values);
+GL_APICALL void         GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y);
+GL_APICALL void         GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values);
+GL_APICALL void         GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void         GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values);
+GL_APICALL void         GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+GL_APICALL void         GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values);
+GL_APICALL void         GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+GL_APICALL void         GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gl2_h_ */
diff --git a/opengl/include/GLES2/gl2ext.h b/opengl/include/GLES2/gl2ext.h
new file mode 100644
index 0000000..72f1ae7
--- /dev/null
+++ b/opengl/include/GLES2/gl2ext.h
@@ -0,0 +1,518 @@
+#ifndef __gl2ext_h_
+#define __gl2ext_h_
+
+/* $Revision: 8271 $ on $Date:: 2009-05-21 09:33:40 -0700 #$ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+#ifndef GL_APIENTRYP
+#   define GL_APIENTRYP GL_APIENTRY*
+#endif
+
+/*------------------------------------------------------------------------*
+ * OES extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_OES_compressed_ETC1_RGB8_texture */
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_ETC1_RGB8_OES                                        0x8D64
+#endif
+
+/* GL_OES_compressed_paletted_texture */
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_PALETTE4_RGB8_OES                                    0x8B90
+#define GL_PALETTE4_RGBA8_OES                                   0x8B91
+#define GL_PALETTE4_R5_G6_B5_OES                                0x8B92
+#define GL_PALETTE4_RGBA4_OES                                   0x8B93
+#define GL_PALETTE4_RGB5_A1_OES                                 0x8B94
+#define GL_PALETTE8_RGB8_OES                                    0x8B95
+#define GL_PALETTE8_RGBA8_OES                                   0x8B96
+#define GL_PALETTE8_R5_G6_B5_OES                                0x8B97
+#define GL_PALETTE8_RGBA4_OES                                   0x8B98
+#define GL_PALETTE8_RGB5_A1_OES                                 0x8B99
+#endif
+
+/* GL_OES_depth24 */
+#ifndef GL_OES_depth24
+#define GL_DEPTH_COMPONENT24_OES                                0x81A6
+#endif
+
+/* GL_OES_depth32 */
+#ifndef GL_OES_depth32
+#define GL_DEPTH_COMPONENT32_OES                                0x81A7
+#endif
+
+/* GL_OES_depth_texture */
+/* No new tokens introduced by this extension. */
+
+/* GL_OES_EGL_image */
+#ifndef GL_OES_EGL_image
+typedef void* GLeglImageOES;
+#endif
+
+/* GL_OES_get_program_binary */
+#ifndef GL_OES_get_program_binary
+#define GL_PROGRAM_BINARY_LENGTH_OES                            0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS_OES                       0x87FE
+#define GL_PROGRAM_BINARY_FORMATS_OES                           0x87FF
+#endif
+
+/* GL_OES_mapbuffer */
+#ifndef GL_OES_mapbuffer
+#define GL_WRITE_ONLY_OES                                       0x88B9
+#define GL_BUFFER_ACCESS_OES                                    0x88BB
+#define GL_BUFFER_MAPPED_OES                                    0x88BC
+#define GL_BUFFER_MAP_POINTER_OES                               0x88BD
+#endif
+
+/* GL_OES_packed_depth_stencil */
+#ifndef GL_OES_packed_depth_stencil
+#define GL_DEPTH_STENCIL_OES                                    0x84F9
+#define GL_UNSIGNED_INT_24_8_OES                                0x84FA
+#define GL_DEPTH24_STENCIL8_OES                                 0x88F0
+#endif
+
+/* GL_OES_rgb8_rgba8 */
+#ifndef GL_OES_rgb8_rgba8
+#define GL_RGB8_OES                                             0x8051
+#define GL_RGBA8_OES                                            0x8058
+#endif
+
+/* GL_OES_standard_derivatives */
+#ifndef GL_OES_standard_derivatives
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES                  0x8B8B
+#endif
+
+/* GL_OES_stencil1 */
+#ifndef GL_OES_stencil1
+#define GL_STENCIL_INDEX1_OES                                   0x8D46
+#endif
+
+/* GL_OES_stencil4 */
+#ifndef GL_OES_stencil4
+#define GL_STENCIL_INDEX4_OES                                   0x8D47
+#endif
+
+/* GL_OES_texture3D */
+#ifndef GL_OES_texture3D
+#define GL_TEXTURE_WRAP_R_OES                                   0x8072
+#define GL_TEXTURE_3D_OES                                       0x806F
+#define GL_TEXTURE_BINDING_3D_OES                               0x806A
+#define GL_MAX_3D_TEXTURE_SIZE_OES                              0x8073
+#define GL_SAMPLER_3D_OES                                       0x8B5F
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES        0x8CD4
+#endif
+
+/* GL_OES_texture_half_float */
+#ifndef GL_OES_texture_half_float
+#define GL_HALF_FLOAT_OES                                       0x8D61
+#endif
+
+/* GL_OES_vertex_half_float */
+/* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */
+
+/* GL_OES_vertex_type_10_10_10_2 */
+#ifndef GL_OES_vertex_type_10_10_10_2
+#define GL_UNSIGNED_INT_10_10_10_2_OES                          0x8DF6
+#define GL_INT_10_10_10_2_OES                                   0x8DF7
+#endif
+
+/*------------------------------------------------------------------------*
+ * AMD extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_AMD_compressed_3DC_texture */
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_3DC_X_AMD                                            0x87F9
+#define GL_3DC_XY_AMD                                           0x87FA
+#endif
+
+/* GL_AMD_compressed_ATC_texture */
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_ATC_RGB_AMD                                          0x8C92
+#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD                          0x8C93
+#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD                      0x87EE
+#endif
+
+/* GL_AMD_program_binary_Z400 */
+#ifndef GL_AMD_program_binary_Z400
+#define GL_Z400_BINARY_AMD                                      0x8740
+#endif
+
+/* GL_AMD_performance_monitor */
+#ifndef GL_AMD_performance_monitor
+#define GL_COUNTER_TYPE_AMD                                     0x8BC0
+#define GL_COUNTER_RANGE_AMD                                    0x8BC1
+#define GL_UNSIGNED_INT64_AMD                                   0x8BC2
+#define GL_PERCENTAGE_AMD                                       0x8BC3
+#define GL_PERFMON_RESULT_AVAILABLE_AMD                         0x8BC4
+#define GL_PERFMON_RESULT_SIZE_AMD                              0x8BC5
+#define GL_PERFMON_RESULT_AMD                                   0x8BC6
+#endif
+
+/*------------------------------------------------------------------------*
+ * EXT extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_EXT_texture_filter_anisotropic */
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT                           0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT                       0x84FF
+#endif
+
+/* GL_EXT_texture_type_2_10_10_10_REV */
+#ifndef GL_EXT_texture_type_2_10_10_10_REV
+#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT                      0x8368
+#endif
+
+/* GL_EXT_texture_format_BGRA8888 */
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_BGRA                                                 0x80E1
+#endif
+
+/*------------------------------------------------------------------------*
+ * IMG extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_IMG_read_format */
+#ifndef GL_IMG_read_format
+#define GL_BGRA                                                 0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV                           0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV                           0x8366
+#endif
+
+/* GL_IMG_texture_compression_pvrtc */
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG                      0x8C00
+#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG                      0x8C01
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG                     0x8C02
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG                     0x8C03
+#endif
+
+/*------------------------------------------------------------------------*
+ * NV extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_NV_fence */
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV                                     0x84F2
+#define GL_FENCE_STATUS_NV                                      0x84F3
+#define GL_FENCE_CONDITION_NV                                   0x84F4
+#endif
+
+/*------------------------------------------------------------------------*
+ * QCOM extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_QCOM_driver_control */
+/* No new tokens introduced by this extension. */
+
+/* GL_QCOM_perfmon_global_mode */
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_PERFMON_GLOBAL_MODE_QCOM                             0x8FA0
+#endif
+
+/*------------------------------------------------------------------------*
+ * End of extension tokens, start of corresponding extension functions
+ *------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------*
+ * OES extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_OES_compressed_ETC1_RGB8_texture */
+#ifndef GL_OES_compressed_ETC1_RGB8_texture
+#define GL_OES_compressed_ETC1_RGB8_texture 1
+#endif
+
+/* GL_OES_compressed_paletted_texture */
+#ifndef GL_OES_compressed_paletted_texture
+#define GL_OES_compressed_paletted_texture 1
+#endif
+
+/* GL_OES_EGL_image */
+#ifndef GL_OES_EGL_image
+#define GL_OES_EGL_image 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image);
+GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image);
+#endif
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
+#endif
+
+/* GL_OES_depth24 */
+#ifndef GL_OES_depth24
+#define GL_OES_depth24 1
+#endif
+
+/* GL_OES_depth32 */
+#ifndef GL_OES_depth32
+#define GL_OES_depth32 1
+#endif
+
+/* GL_OES_depth_texture */
+#ifndef GL_OES_depth_texture
+#define GL_OES_depth_texture 1
+#endif
+
+/* GL_OES_element_index_uint */
+#ifndef GL_OES_element_index_uint
+#define GL_OES_element_index_uint 1
+#endif
+
+/* GL_OES_fbo_render_mipmap */
+#ifndef GL_OES_fbo_render_mipmap
+#define GL_OES_fbo_render_mipmap 1
+#endif
+
+/* GL_OES_fragment_precision_high */
+#ifndef GL_OES_fragment_precision_high
+#define GL_OES_fragment_precision_high 1
+#endif
+
+/* GL_OES_get_program_binary */
+#ifndef GL_OES_get_program_binary
+#define GL_OES_get_program_binary 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+#endif
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
+typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+#endif
+
+/* GL_OES_mapbuffer */
+#ifndef GL_OES_mapbuffer
+#define GL_OES_mapbuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access);
+GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target);
+GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void** params);
+#endif
+typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access);
+typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void** params);
+#endif
+
+/* GL_OES_packed_depth_stencil */
+#ifndef GL_OES_packed_depth_stencil
+#define GL_OES_packed_depth_stencil 1
+#endif
+
+/* GL_OES_rgb8_rgba8 */
+#ifndef GL_OES_rgb8_rgba8
+#define GL_OES_rgb8_rgba8 1
+#endif
+
+/* GL_OES_standard_derivatives */
+#ifndef GL_OES_standard_derivatives
+#define GL_OES_standard_derivatives 1
+#endif
+
+/* GL_OES_stencil1 */
+#ifndef GL_OES_stencil1
+#define GL_OES_stencil1 1
+#endif
+
+/* GL_OES_stencil4 */
+#ifndef GL_OES_stencil4
+#define GL_OES_stencil4 1
+#endif
+
+/* GL_OES_texture_3D */
+#ifndef GL_OES_texture_3D
+#define GL_OES_texture_3D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels);
+GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
+GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data);
+GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+#endif
+typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
+typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+#endif
+
+/* GL_OES_texture_float_linear */
+#ifndef GL_OES_texture_float_linear
+#define GL_OES_texture_float_linear 1
+#endif
+
+/* GL_OES_texture_half_float_linear */
+#ifndef GL_OES_texture_half_float_linear
+#define GL_OES_texture_half_float_linear 1
+#endif
+
+/* GL_OES_texture_float */
+#ifndef GL_OES_texture_float
+#define GL_OES_texture_float 1
+#endif
+
+/* GL_OES_texture_half_float */
+#ifndef GL_OES_texture_half_float
+#define GL_OES_texture_half_float 1
+#endif
+
+/* GL_OES_texture_npot */
+#ifndef GL_OES_texture_npot
+#define GL_OES_texture_npot 1
+#endif
+
+/* GL_OES_vertex_half_float */
+#ifndef GL_OES_vertex_half_float
+#define GL_OES_vertex_half_float 1
+#endif
+
+/* GL_OES_vertex_type_10_10_10_2 */
+#ifndef GL_OES_vertex_type_10_10_10_2
+#define GL_OES_vertex_type_10_10_10_2 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * AMD extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_AMD_compressed_3DC_texture */
+#ifndef GL_AMD_compressed_3DC_texture
+#define GL_AMD_compressed_3DC_texture 1
+#endif
+
+/* GL_AMD_compressed_ATC_texture */
+#ifndef GL_AMD_compressed_ATC_texture
+#define GL_AMD_compressed_ATC_texture 1
+#endif
+
+/* GL_AMD_program_binary_Z400 */
+#ifndef GL_AMD_program_binary_Z400
+#define GL_AMD_program_binary_Z400 1
+#endif
+
+/* AMD_performance_monitor */
+#ifndef GL_AMD_performance_monitor
+#define GL_AMD_performance_monitor 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, char *groupString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data);
+GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);
+GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList);
+GL_APICALL void GL_APIENTRY glBeginPerfMonitorAMD (GLuint monitor);
+GL_APICALL void GL_APIENTRY glEndPerfMonitorAMD (GLuint monitor);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, char *groupString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data);
+typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
+typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList);
+typedef void (GL_APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GL_APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
+#endif
+
+/*------------------------------------------------------------------------*
+ * EXT extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_EXT_texture_filter_anisotropic */
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#endif
+
+/* GL_EXT_texture_type_2_10_10_10_REV */
+#ifndef GL_EXT_texture_type_2_10_10_10_REV
+#define GL_EXT_texture_type_2_10_10_10_REV 1
+#endif
+
+/* GL_EXT_texture_format_BGRA8888 */
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_EXT_texture_format_BGRA8888 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * IMG extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_IMG_read_format */
+#ifndef GL_IMG_read_format
+#define GL_IMG_read_format 1
+#endif
+
+/* GL_IMG_texture_compression_pvrtc */
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_IMG_texture_compression_pvrtc 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * NV extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_NV_fence */
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences);
+GL_APICALL void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences);
+GL_APICALL GLboolean GL_APIENTRY glIsFenceNV (GLuint fence);
+GL_APICALL GLboolean GL_APIENTRY glTestFenceNV (GLuint fence);
+GL_APICALL void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glFinishFenceNV (GLuint fence);
+GL_APICALL void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
+#endif
+typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#endif
+
+/*------------------------------------------------------------------------*
+ * QCOM extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_QCOM_driver_control */
+#ifndef GL_QCOM_driver_control
+#define GL_QCOM_driver_control 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls);
+GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString);
+GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl);
+GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl);
+#endif
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls);
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString);
+typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+#endif
+
+/* GL_QCOM_perfmon_global_mode */
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_QCOM_perfmon_global_mode 1
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gl2ext_h_ */
diff --git a/opengl/include/GLES2/gl2platform.h b/opengl/include/GLES2/gl2platform.h
new file mode 100644
index 0000000..3e9036c
--- /dev/null
+++ b/opengl/include/GLES2/gl2platform.h
@@ -0,0 +1,29 @@
+#ifndef __gl2platform_h_
+#define __gl2platform_h_
+
+/* $Revision: 7173 $ on $Date:: 2009-01-09 11:18:21 -0800 #$ */
+
+/*
+ * This document is licensed under the SGI Free Software B License Version
+ * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ .
+ */
+
+/* Platform-specific types and definitions for OpenGL ES 2.X  gl2.h
+ * Last modified on 2008/12/19
+ *
+ * Adopters may modify khrplatform.h and this file to suit their platform.
+ * You are encouraged to submit all modifications to the Khronos group so that
+ * they can be included in future versions of this file.  Please submit changes
+ * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
+ * by filing a bug against product "OpenGL-ES" component "Registry".
+ */
+
+#include <KHR/khrplatform.h>
+
+#ifndef GL_APICALL
+#define GL_APICALL  KHRONOS_APICALL
+#endif
+
+#define GL_APIENTRY KHRONOS_APIENTRY
+
+#endif /* __gl2platform_h_ */
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
index 3ce0414..d1ed82e 100644
--- a/opengl/libagl/Android.mk
+++ b/opengl/libagl/Android.mk
@@ -6,6 +6,9 @@
 
 include $(CLEAR_VARS)
 
+# Set to 1 to use gralloc and copybits
+LIBAGL_USE_GRALLOC_COPYBITS := 1
+
 LOCAL_SRC_FILES:= \
 	egl.cpp                     \
 	state.cpp		            \
@@ -29,13 +32,24 @@
 
 ifneq ($(TARGET_SIMULATOR),true)
     # we need to access the private Bionic header <bionic_tls.h>
-    LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
+    LOCAL_C_INCLUDES += bionic/libc/private
 endif
 
-LOCAL_SHARED_LIBRARIES := libcutils libutils libpixelflinger
+ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1)
+    LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS
+    LOCAL_SRC_FILES += copybit.cpp
+    LOCAL_C_INCLUDES += hardware/libhardware/modules/gralloc
+endif
+
+LOCAL_CFLAGS += -DLOG_TAG=\"libagl\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+LOCAL_SHARED_LIBRARIES := libcutils libhardware libutils libpixelflinger
 LOCAL_CFLAGS += -fvisibility=hidden
 
 LOCAL_LDLIBS := -lpthread -ldl
-LOCAL_MODULE:= libagl
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
+LOCAL_MODULE:= libGLES_android
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
index ce31854..255ccac 100644
--- a/opengl/libagl/TextureObjectManager.cpp
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -1,16 +1,16 @@
 /*
  ** Copyright 2006, 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 
+ ** 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 
+ **     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 
+ ** 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.
  */
 
@@ -19,11 +19,13 @@
 #include "context.h"
 #include "TextureObjectManager.h"
 
+#include <private/ui/android_natives_priv.h>
+
 namespace android {
 // ----------------------------------------------------------------------------
 
 EGLTextureObject::EGLTextureObject()
-    : mCount(0), mSize(0)
+    : mSize(0)
 {
     init();
 }
@@ -53,6 +55,10 @@
     memset(crop_rect, 0, sizeof(crop_rect));
     generate_mipmap = GL_FALSE;
     direct = GL_FALSE;
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    try_copybit = false;
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+    buffer = 0;
 }
 
 void EGLTextureObject::copyParameters(const sp<EGLTextureObject>& old)
@@ -123,6 +129,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.
@@ -141,12 +148,26 @@
     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)
 {
     const size_t size = h * bpr;
-    if (level == 0) 
+    if (level == 0)
     {
         if (size!=mSize || !surface.data) {
             if (mSize && surface.data) {
@@ -177,9 +198,9 @@
                 return NO_MEMORY;
         }
 
-        LOGW_IF(level-1 >= mNumExtraLod, 
+        LOGW_IF(level-1 >= mNumExtraLod,
                 "specifying mipmap level %d, but # of level is %d",
-                level, mNumExtraLod+1);        
+                level, mNumExtraLod+1);
 
         GGLSurface& mipmap = editMip(level);
         if (mipmap.data)
@@ -224,7 +245,7 @@
 // ----------------------------------------------------------------------------
 
 EGLSurfaceManager::EGLSurfaceManager()
-    : TokenManager(), mCount(0)
+    : TokenManager()
 {
 }
 
diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h
index 74ed1a4..279e040 100644
--- a/opengl/libagl/TextureObjectManager.h
+++ b/opengl/libagl/TextureObjectManager.h
@@ -1,16 +1,16 @@
 /*
 ** Copyright 2006, 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 
+** 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 
+**     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 
+** 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.
 */
 
@@ -30,6 +30,8 @@
 #include <private/pixelflinger/ggl_context.h>
 
 #include <GLES/gl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
 
 #include "Tokenizer.h"
 #include "TokenManager.h"
@@ -39,22 +41,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 +65,6 @@
         status_t        allocateMipmaps();
             void        freeMipmaps();
             void        init();
-    mutable int32_t     mCount;
     size_t              mSize;
     GGLSurface          *mMipmaps;
     int                 mNumExtraLod;
@@ -81,36 +80,22 @@
     GLint               crop_rect[4];
     GLint               generate_mipmap;
     GLint               direct;
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    bool                try_copybit;
+#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);
@@ -118,21 +103,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 3e9c6a5..f414ee5 100644
--- a/opengl/libagl/array.cpp
+++ b/opengl/libagl/array.cpp
@@ -1,16 +1,16 @@
-/* 
+/*
 ** Copyright 2006, 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 
+** 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 
+**     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 
+** 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.
 */
 
@@ -26,6 +26,9 @@
 #include "primitives.h"
 #include "texture.h"
 #include "BufferObjectManager.h"
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+#include "copybit.h"
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
 
 // ----------------------------------------------------------------------------
 
@@ -250,7 +253,7 @@
     v[2] = GGL_S_TO_X(p[2]);
 }
 
-typedef array_t::fetcher_t fn_t; 
+typedef array_t::fetcher_t fn_t;
 
 static const fn_t color_fct[2][16] = { // size={3,4}, type={ub,f,x}
     { 0, (fn_t)fetchExpand3ub, 0, 0, 0, 0,
@@ -334,7 +337,7 @@
     this->bounds = count;
 }
 
-inline void array_t::resolve() 
+inline void array_t::resolve()
 {
     physical_pointer = (bo) ? (bo->data + uintptr_t(pointer)) : pointer;
 }
@@ -465,7 +468,7 @@
         // We compute directly the index of a "free" entry from the locked
         // state of v[2] and v[3].
         v = c->vc.vBuffer + 2;
-        v += v[0].locked | (v[1].locked<<1);       
+        v += v[0].locked | (v[1].locked<<1);
     }
     // note: compileElement clears v->flags
     c->arrays.compileElement(c, v, index);
@@ -480,7 +483,7 @@
 
 #if VC_CACHE_TYPE == VC_CACHE_TYPE_INDEXED
 
-    vertex_t* const v = c->vc.vCache + 
+    vertex_t* const v = c->vc.vCache +
             (index & (vertex_cache_t::VERTEX_CACHE_SIZE-1));
 
     if (ggl_likely(v->index == index)) {
@@ -491,7 +494,7 @@
 
 #elif VC_CACHE_TYPE == VC_CACHE_TYPE_LRU
 
-    vertex_t* v = c->vc.vCache + 
+    vertex_t* v = c->vc.vCache +
             (index & ((vertex_cache_t::VERTEX_CACHE_SIZE-1)>>1))*2;
 
     // always record LRU in v[0]
@@ -532,12 +535,12 @@
         return;
 
     // vertex cache size must be multiple of 1
-    const GLsizei vcs = 
+    const GLsizei vcs =
             (vertex_cache_t::VERTEX_BUFFER_SIZE +
              vertex_cache_t::VERTEX_CACHE_SIZE);
     do {
         vertex_t* v = c->vc.vBuffer;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.cull = vertex_t::CLIP_ALL;
         c->arrays.compileElements(c, v, first, num);
         first += num;
@@ -569,13 +572,13 @@
     count -= 1;
 
     // vertex cache size must be multiple of 1
-    const GLsizei vcs = 
+    const GLsizei vcs =
         (vertex_cache_t::VERTEX_BUFFER_SIZE +
          vertex_cache_t::VERTEX_CACHE_SIZE - 1);
     do {
-        v0 = c->vc.vBuffer + 0; 
+        v0 = c->vc.vBuffer + 0;
         v  = c->vc.vBuffer + 1;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.compileElements(c, v, first, num);
         first += num;
         count -= num;
@@ -602,7 +605,7 @@
         return;
     drawPrimitivesLineStrip(c, first, count);
     if (ggl_likely(count >= 3)) {
-        vertex_t* v0 = c->vc.vBuffer; 
+        vertex_t* v0 = c->vc.vBuffer;
         vertex_t* v1 = c->vc.vBuffer + 1;
         c->arrays.compileElement(c, v1, first);
         const uint32_t cc = v0->flags & v1->flags;
@@ -617,12 +620,12 @@
         return;
 
     // vertex cache size must be multiple of 2
-    const GLsizei vcs = 
+    const GLsizei vcs =
         ((vertex_cache_t::VERTEX_BUFFER_SIZE +
         vertex_cache_t::VERTEX_CACHE_SIZE) / 2) * 2;
     do {
         vertex_t* v = c->vc.vBuffer;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.cull = vertex_t::CLIP_ALL;
         c->arrays.compileElements(c, v, first, num);
         first += num;
@@ -662,14 +665,14 @@
     // because it allows us to preserve the same winding when the whole
     // batch is culled. We also need 2 extra vertices in the array, because
     // we always keep the two first ones.
-    const GLsizei vcs = 
+    const GLsizei vcs =
         ((vertex_cache_t::VERTEX_BUFFER_SIZE +
           vertex_cache_t::VERTEX_CACHE_SIZE - 2) / 2) * 2;
     do {
-        v0 = c->vc.vBuffer + 0; 
-        v1 = c->vc.vBuffer + 1; 
+        v0 = c->vc.vBuffer + 0;
+        v1 = c->vc.vBuffer + 1;
         v  = c->vc.vBuffer + 2;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.compileElements(c, v, first, num);
         first += num;
         count -= num;
@@ -697,13 +700,19 @@
     } while (count > 0);
 }
 
-void drawPrimitivesTriangleStrip(ogles_context_t* c, 
+void drawPrimitivesTriangleStrip(ogles_context_t* c,
         GLint first, GLsizei count) {
     drawPrimitivesTriangleFanOrStrip(c, first, count, 1);
 }
 
 void drawPrimitivesTriangleFan(ogles_context_t* c,
         GLint first, GLsizei count) {
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    if (drawTriangleFanWithCopybit(c, first, count)) {
+        return;
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
     drawPrimitivesTriangleFanOrStrip(c, first, count, 2);
 }
 
@@ -713,12 +722,12 @@
         return;
 
     // vertex cache size must be multiple of 3
-    const GLsizei vcs = 
+    const GLsizei vcs =
         ((vertex_cache_t::VERTEX_BUFFER_SIZE +
         vertex_cache_t::VERTEX_CACHE_SIZE) / 3) * 3;
     do {
         vertex_t* v = c->vc.vBuffer;
-        GLsizei num = count > vcs ? vcs : count; 
+        GLsizei num = count > vcs ? vcs : count;
         c->arrays.cull = vertex_t::CLIP_ALL;
         c->arrays.compileElements(c, v, first, num);
         first += num;
@@ -779,11 +788,11 @@
 {
     if (ggl_unlikely(count < 2))
         return;
-    
+
     vertex_t * const v = c->vc.vBuffer;
     vertex_t* v0 = v;
     vertex_t* v1;
-    
+
     const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
     c->arrays.compileElement(c, v0, read_index(type, indices));
     count -= 1;
@@ -806,11 +815,11 @@
         drawIndexedPrimitivesLines(c, count, indices);
         return;
     }
- 
+
     vertex_t * const v = c->vc.vBuffer;
     vertex_t* v0 = v;
     vertex_t* v1;
-    
+
     const int type = (c->arrays.indicesType == GL_UNSIGNED_BYTE);
     c->arrays.compileElement(c, v0, read_index(type, indices));
     count -= 1;
@@ -825,7 +834,7 @@
     } while (count);
     v1->locked = 0;
 
-    v1 = c->vc.vBuffer; 
+    v1 = c->vc.vBuffer;
     const uint32_t cc = v0->flags & v1->flags;
     if (ggl_likely(!(cc & vertex_t::CLIP_ALL)))
         c->prims.renderLine(c, v0, v1);
@@ -861,7 +870,7 @@
 
     if (ggl_unlikely(count < 3))
         return;
-    
+
     vertex_t * const v = c->vc.vBuffer;
     vertex_t* v0 = v;
     vertex_t* v1 = v+1;
@@ -985,17 +994,17 @@
     const GLfixed* vp = (const GLfixed*)c->arrays.vertex.element(first);
     const size_t stride = c->arrays.vertex.stride / 4;
 //    const GLfixed* const& m = c->transforms.mvp.matrix.m;
-    
+
     GLfixed m[16];
     memcpy(&m, c->transforms.mvp.matrix.m, sizeof(m));
-    
+
     do {
         const GLfixed rx = vp[0];
         const GLfixed ry = vp[1];
         const GLfixed rz = vp[2];
         vp += stride;
         v->index = first++;
-        v->clip.x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]); 
+        v->clip.x = mla3a(rx, m[ 0], ry, m[ 4], rz, m[ 8], m[12]);
         v->clip.y = mla3a(rx, m[ 1], ry, m[ 5], rz, m[ 9], m[13]);
         v->clip.z = mla3a(rx, m[ 2], ry, m[ 6], rz, m[10], m[14]);
         v->clip.w = mla3a(rx, m[ 3], ry, m[ 7], rz, m[11], m[15]);
@@ -1023,7 +1032,7 @@
 #pragma mark clippers
 #endif
 
-static void clipVec4(vec4_t& nv, 
+static void clipVec4(vec4_t& nv,
         GLfixed t, const vec4_t& s, const vec4_t& p)
 {
     for (int i=0; i<4 ; i++)
@@ -1086,10 +1095,10 @@
     // automatically turn it off (in fact we could when the 4th coordinate
     // is not spcified in the vertex array).
     // W interpolation is never needed for points.
-    GLboolean perspective = 
+    GLboolean perspective =
         c->perspective && mode!=GL_POINTS && (enables & GGL_ENABLE_TMUS);
     c->rasterizer.procs.enableDisable(c, GGL_W_LERP, perspective);
-    
+
     // set anti-aliasing
     GLboolean smooth = GL_FALSE;
     switch (mode) {
@@ -1120,7 +1129,7 @@
     if (enables & GGL_ENABLE_TMUS) { // needs texture transforms
         want |= transform_state_t::TEXTURE;
     }
-    if (c->clipPlanes.enable || (enables & GGL_ENABLE_FOG)) { 
+    if (c->clipPlanes.enable || (enables & GGL_ENABLE_FOG)) {
         want |= transform_state_t::MODELVIEW; // needs eye coords
     }
     ogles_validate_transform(c, want);
@@ -1139,18 +1148,18 @@
 
     c->arrays.mv_transform =
         c->transforms.modelview.transform.pointv[c->arrays.vertex.size - 2];
-    
+
     /*
      * ***********************************************************************
      *  pick fetchers
      * ***********************************************************************
      */
-    
+
     array_machine_t& am = c->arrays;
     am.vertex.fetch = fetchNop;
     am.normal.fetch = currentNormal;
     am.color.fetch = currentColor;
-    
+
     if (am.vertex.enable) {
         am.vertex.resolve();
         if (am.vertex.bo || am.vertex.pointer) {
@@ -1366,9 +1375,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);
@@ -1413,15 +1431,23 @@
     // clear the vertex-cache
     c->vc.clear();
     validate_arrays(c, mode);
-    
+
     // if indices are in a buffer object, the pointer is treated as an
     // offset in that buffer.
     if (c->arrays.element_array_buffer) {
         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);
@@ -1448,7 +1474,7 @@
             return;
         }
     }
-    ((target == GL_ARRAY_BUFFER) ? 
+    ((target == GL_ARRAY_BUFFER) ?
             c->arrays.array_buffer : c->arrays.element_array_buffer) = bo;
 }
 
@@ -1467,7 +1493,7 @@
         ogles_error(c, GL_INVALID_ENUM);
         return;
     }
-    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? 
+    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ?
             c->arrays.array_buffer : c->arrays.element_array_buffer);
 
     if (bo == 0) {
@@ -1497,7 +1523,7 @@
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
-    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ? 
+    buffer_t const* bo = ((target == GL_ARRAY_BUFFER) ?
             c->arrays.array_buffer : c->arrays.element_array_buffer);
 
     if (bo == 0) {
@@ -1545,7 +1571,7 @@
                 }
             }
         }
-    }    
+    }
     c->bufferObjectManager->deleteBuffers(n, buffers);
     c->bufferObjectManager->recycleTokens(n, buffers);
 }
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
new file mode 100644
index 0000000..3331026
--- /dev/null
+++ b/opengl/libagl/copybit.cpp
@@ -0,0 +1,455 @@
+/*
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "context.h"
+#include "fp.h"
+#include "state.h"
+#include "matrix.h"
+#include "vertex.h"
+#include "light.h"
+#include "primitives.h"
+#include "texture.h"
+#include "BufferObjectManager.h"
+#include "TextureObjectManager.h"
+
+#include <hardware/gralloc.h>
+#include <hardware/copybit.h>
+#include <private/ui/android_natives_priv.h>
+
+
+#define DEBUG_COPYBIT true
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+static void textureToCopyBitImage(
+        const GGLSurface* surface, buffer_handle_t buffer, copybit_image_t* img) 
+{
+    img->w      = surface->stride;
+    img->h      = surface->height;
+    img->format = surface->format;
+    img->base   = surface->data;
+    img->handle = (native_handle_t *)buffer;
+}
+
+struct clipRectRegion : public copybit_region_t {
+    clipRectRegion(ogles_context_t* c) 
+    {
+        scissor_t const* scissor = &c->rasterizer.state.scissor;
+        r.l = scissor->left;
+        r.t = scissor->top;
+        r.r = scissor->right;
+        r.b = scissor->bottom;
+        next = iterate; 
+    }
+private:
+    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
+        *rect = static_cast<clipRectRegion const*>(self)->r;
+        const_cast<copybit_region_t *>(self)->next = iterate_done;
+        return 1;
+    }
+    static int iterate_done(copybit_region_t const *, copybit_rect_t*) {
+        return 0;
+    }
+    copybit_rect_t r;
+};
+
+static bool supportedCopybitsFormat(int format) {
+    switch (format) {
+    case COPYBIT_FORMAT_RGBA_8888:
+    case COPYBIT_FORMAT_RGB_565:
+    case COPYBIT_FORMAT_BGRA_8888:
+    case COPYBIT_FORMAT_RGBA_5551:
+    case COPYBIT_FORMAT_RGBA_4444:
+    case COPYBIT_FORMAT_YCbCr_422_SP:
+    case COPYBIT_FORMAT_YCbCr_420_SP:
+        return true;
+    default:
+        return false;
+    }
+}
+
+static bool hasAlpha(int format) {
+    switch (format) {
+    case COPYBIT_FORMAT_RGBA_8888:
+    case COPYBIT_FORMAT_BGRA_8888:
+    case COPYBIT_FORMAT_RGBA_5551:
+    case COPYBIT_FORMAT_RGBA_4444:
+        return true;
+    default:
+        return false;
+    }
+}
+
+static inline int fixedToByte(GGLfixed val) {
+    return (val - (val >> 8)) >> 8;
+}
+
+/**
+ * Performs a quick check of the rendering state. If this function returns
+ * false we cannot use the copybit driver.
+ */
+
+static bool checkContext(ogles_context_t* c) {
+
+	// By convention copybitQuickCheckContext() has already returned true.
+	// avoid checking the same information again.
+	
+    if (c->copybits.blitEngine == NULL) {
+        LOGD_IF(DEBUG_COPYBIT, "no copybit hal");
+        return false;
+    }
+
+    if (c->rasterizer.state.enables
+                    & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) {
+        LOGD_IF(DEBUG_COPYBIT, "depth test and/or fog");
+        return false;
+    }
+
+    // Note: The drawSurfaceBuffer is only set for destination
+    // surfaces types that are supported by the hardware and
+    // do not have an alpha channel. So we don't have to re-check that here.
+
+    static const int tmu = 0;
+    texture_unit_t& u(c->textures.tmu[tmu]);
+    EGLTextureObject* textureObject = u.texture;
+
+    if (!supportedCopybitsFormat(textureObject->surface.format)) {
+        LOGD_IF(DEBUG_COPYBIT, "texture format not supported");
+        return false;
+    }
+    return true;
+}
+
+
+static bool copybit(GLint x, GLint y,
+        GLint w, GLint h,
+        EGLTextureObject* textureObject,
+        const GLint* crop_rect,
+        int transform,
+        ogles_context_t* c)
+{
+    // We assume checkContext has already been called and has already
+    // returned true.
+
+    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+
+    y = cbSurface.height - (y + h);
+
+    const GLint Ucr = crop_rect[0];
+    const GLint Vcr = crop_rect[1];
+    const GLint Wcr = crop_rect[2];
+    const GLint Hcr = crop_rect[3];
+
+    GLint screen_w = w;
+    GLint screen_h = h;
+    int32_t dsdx = Wcr << 16;   // dsdx =  ((Wcr/screen_w)/Wt)*Wt
+    int32_t dtdy = Hcr << 16;   // dtdy = -((Hcr/screen_h)/Ht)*Ht
+    if (transform & COPYBIT_TRANSFORM_ROT_90) {
+        swap(screen_w, screen_h);
+    }
+    if (dsdx!=screen_w || dtdy!=screen_h) {
+        // in most cases the divide is not needed
+        dsdx /= screen_w;
+        dtdy /= screen_h;
+    }
+    dtdy = -dtdy; // see equation of dtdy above
+    if (dsdx < c->copybits.minScale || dsdx > c->copybits.maxScale
+            || dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) {
+        // The requested scale is out of the range the hardware
+        // can support.
+        LOGD_IF(DEBUG_COPYBIT,
+                "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
+                "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d", 
+                dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
+        return false;
+    }
+
+    // copybit doesn't say anything about filtering, so we can't
+    // discriminate. On msm7k, copybit will always filter.
+    // the code below handles min/mag filters, we keep it as a reference.
+    
+#ifdef MIN_MAG_FILTER
+    int32_t texelArea = gglMulx(dtdy, dsdx);
+    if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) {
+        // Non-linear filtering on a texture enlargement.
+        LOGD_IF(DEBUG_COPYBIT, "mag filter is not GL_LINEAR");
+        return false;
+    }
+    if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) {
+        // Non-linear filtering on an texture shrink.
+        LOGD_IF(DEBUG_COPYBIT, "min filter is not GL_LINEAR");
+        return false;
+    }
+#endif
+    
+    const uint32_t enables = c->rasterizer.state.enables;
+    int planeAlpha = 255;
+    static const int tmu = 0;
+    texture_t& tev(c->rasterizer.state.texture[tmu]);
+    bool srcTextureHasAlpha = hasAlpha(textureObject->surface.format);
+    if (!srcTextureHasAlpha) {
+        planeAlpha = fixedToByte(c->currentColorClamped.a);
+    }
+
+    switch (tev.env) {
+    case GGL_REPLACE:
+        break;
+    case GGL_MODULATE:
+        if (! (c->currentColorClamped.r == FIXED_ONE &&
+               c->currentColorClamped.g == FIXED_ONE &&
+               c->currentColorClamped.b == FIXED_ONE)) {
+            LOGD_IF(DEBUG_COPYBIT, 
+                    "MODULATE and non white color (%08x, %08x, %08x)",
+                    c->currentColorClamped.r,
+                    c->currentColorClamped.g,
+                    c->currentColorClamped.b);
+            return false;
+        }
+        if (srcTextureHasAlpha && c->currentColorClamped.a < FIXED_ONE) {
+            LOGD_IF(DEBUG_COPYBIT, 
+                    "MODULATE and texture w/alpha and alpha=%08x)",
+                    c->currentColorClamped.a);
+            return false;
+        }
+        break;
+
+    default:
+        // Incompatible texture environment.
+        LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment");
+        return false;
+    }
+
+    bool blending = false;
+    if ((enables & GGL_ENABLE_BLENDING)
+            && !(c->rasterizer.state.blend.src == GL_ONE
+                    && c->rasterizer.state.blend.dst == GL_ZERO)) {
+        // Blending is OK if it is
+        // the exact kind of blending that the copybits hardware supports.
+        // Note: The hardware only supports
+        // GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA,
+        // But the surface flinger uses GL_ONE / GL_ONE_MINUS_SRC_ALPHA.
+        // We substitute GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA in that case,
+        // because the performance is worth it, even if the results are
+        // not correct.
+        if (!((c->rasterizer.state.blend.src == GL_SRC_ALPHA
+                || c->rasterizer.state.blend.src == GL_ONE)
+                && c->rasterizer.state.blend.dst == GL_ONE_MINUS_SRC_ALPHA
+                && c->rasterizer.state.blend.alpha_separate == 0)) {
+            // Incompatible blend mode.
+            LOGD_IF(DEBUG_COPYBIT, "incompatible blend mode");
+            return false;
+        }
+        blending = true;
+    } else {
+        // No blending is OK if we are not using alpha.
+        if (srcTextureHasAlpha || planeAlpha != 255) {
+            // Incompatible alpha
+            LOGD_IF(DEBUG_COPYBIT, "incompatible alpha");
+            return false;
+        }
+    }
+
+    if (srcTextureHasAlpha && planeAlpha != 255) {
+        // Can't do two types of alpha at once.
+        LOGD_IF(DEBUG_COPYBIT, "src alpha and plane alpha");
+        return false;
+    }
+
+    // LOGW("calling copybits");
+
+    copybit_device_t* copybit = c->copybits.blitEngine;
+
+    copybit_image_t dst;
+    buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer;
+    textureToCopyBitImage(&cbSurface, target_hnd, &dst);
+    copybit_rect_t drect = {x, y, x+w, y+h};
+
+    copybit_image_t src;
+    buffer_handle_t source_hnd = textureObject->buffer->handle;
+    textureToCopyBitImage(&textureObject->surface, source_hnd, &src);
+    copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
+
+    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
+    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha);
+    copybit->set_parameter(copybit, COPYBIT_DITHER,
+            (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE);
+
+    clipRectRegion it(c);
+    status_t err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
+    return err == NO_ERROR ? true : false;
+}
+
+/*
+ * Try to draw a triangle fan with copybit, return false if we fail.
+ */
+bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count)
+{
+    if (!checkContext(c)) {
+        return false;
+    }
+
+    // FIXME: we should handle culling  here
+    c->arrays.compileElements(c, c->vc.vBuffer, 0, 4);
+
+    // we detect if we're dealing with a rectangle, by comparing the
+    // rectangles {v0,v2} and {v1,v3} which should be identical.
+    
+    // NOTE: we should check that the rectangle is window aligned, however
+    // if we do that, the optimization won't be taken in a lot of cases.
+    // Since this code is intended to be used with SurfaceFlinger only,
+    // so it's okay...
+    
+    const vec4_t& v0 = c->vc.vBuffer[0].window;
+    const vec4_t& v1 = c->vc.vBuffer[1].window;
+    const vec4_t& v2 = c->vc.vBuffer[2].window;
+    const vec4_t& v3 = c->vc.vBuffer[3].window;
+    int l = min(v0.x, v2.x);
+    int b = min(v0.y, v2.y);
+    int r = max(v0.x, v2.x);
+    int t = max(v0.y, v2.y);
+    if ((l != min(v1.x, v3.x)) || (b != min(v1.y, v3.y)) ||
+        (r != max(v1.x, v3.x)) || (t != max(v1.y, v3.y))) {
+        LOGD_IF(DEBUG_COPYBIT, "geometry not a rectangle");
+        return false;
+    }
+
+    // fetch and transform texture coordinates
+    // NOTE: maybe it would be better to have a "compileElementsAll" method
+    // that would ensure all vertex data are fetched and transformed
+    const transform_t& tr = c->transforms.texture[0].transform; 
+    for (size_t i=0 ; i<4 ; i++) {
+        const GLubyte* tp = c->arrays.texture[0].element(i);
+        vertex_t* const v = &c->vc.vBuffer[i];
+        c->arrays.texture[0].fetch(c, v->texture[0].v, tp);
+        // FIXME: we should bail if q!=1
+        c->arrays.tex_transform[0](&tr, &v->texture[0], &v->texture[0]);
+    }
+    
+    const vec4_t& t0 = c->vc.vBuffer[0].texture[0];
+    const vec4_t& t1 = c->vc.vBuffer[1].texture[0];
+    const vec4_t& t2 = c->vc.vBuffer[2].texture[0];
+    const vec4_t& t3 = c->vc.vBuffer[3].texture[0];
+    int txl = min(t0.x, t2.x);
+    int txb = min(t0.y, t2.y);
+    int txr = max(t0.x, t2.x);
+    int txt = max(t0.y, t2.y);
+    if ((txl != min(t1.x, t3.x)) || (txb != min(t1.y, t3.y)) ||
+        (txr != max(t1.x, t3.x)) || (txt != max(t1.y, t3.y))) {
+        LOGD_IF(DEBUG_COPYBIT, "texcoord not a rectangle");
+        return false;
+    }
+    if ((txl != 0) || (txb != 0) ||
+        (txr != FIXED_ONE) || (txt != FIXED_ONE)) {
+        // we could probably handle this case, if we wanted to
+        LOGD_IF(DEBUG_COPYBIT, "texture is cropped: %08x,%08x,%08x,%08x",
+                txl, txb, txr, txt);
+        return false;
+    }
+
+    // at this point, we know we are dealing with a rectangle, so we 
+    // only need to consider 3 vertices for computing the jacobians
+    
+    const int dx01 = v1.x - v0.x;
+    const int dx02 = v2.x - v0.x;
+    const int dy01 = v1.y - v0.y;
+    const int dy02 = v2.y - v0.y;
+    const int ds01 = t1.S - t0.S;
+    const int ds02 = t2.S - t0.S;
+    const int dt01 = t1.T - t0.T;
+    const int dt02 = t2.T - t0.T;
+    const int area = dx01*dy02 - dy01*dx02;
+    int dsdx, dsdy, dtdx, dtdy;
+    if (area >= 0) {
+        dsdx = ds01*dy02 - ds02*dy01;
+        dtdx = dt01*dy02 - dt02*dy01;
+        dsdy = ds02*dx01 - ds01*dx02;
+        dtdy = dt02*dx01 - dt01*dx02;
+    } else {
+        dsdx = ds02*dy01 - ds01*dy02;
+        dtdx = dt02*dy01 - dt01*dy02;
+        dsdy = ds01*dx02 - ds02*dx01;
+        dtdy = dt01*dx02 - dt02*dx01;
+    }
+
+    // here we rely on the fact that we know the transform is
+    // a rigid-body transform AND that it can only rotate in 90 degrees
+    // increments
+
+    int transform = 0;
+    if (dsdx == 0) {
+        // 90 deg rotation case
+        // [ 0    dtdx  ]
+        // [ dsdx    0  ]
+        transform |= COPYBIT_TRANSFORM_ROT_90;
+        // FIXME: not sure if FLIP_H and FLIP_V shouldn't be inverted
+        if (dtdx > 0)
+            transform |= COPYBIT_TRANSFORM_FLIP_H;
+        if (dsdy < 0)
+            transform |= COPYBIT_TRANSFORM_FLIP_V;
+    } else {
+        // [ dsdx    0  ]
+        // [ 0     dtdy ]
+        if (dsdx < 0)
+            transform |= COPYBIT_TRANSFORM_FLIP_H;
+        if (dtdy < 0)
+            transform |= COPYBIT_TRANSFORM_FLIP_V;
+    }
+
+    //LOGD("l=%d, b=%d, w=%d, h=%d, tr=%d", x, y, w, h, transform);
+    //LOGD("A=%f\tB=%f\nC=%f\tD=%f",
+    //      dsdx/65536.0, dtdx/65536.0, dsdy/65536.0, dtdy/65536.0);
+
+    int x = l >> 4;
+    int y = b >> 4;
+    int w = (r-l) >> 4;
+    int h = (t-b) >> 4;
+    texture_unit_t& u(c->textures.tmu[0]);
+    EGLTextureObject* textureObject = u.texture;
+    GLint tWidth = textureObject->surface.width;
+    GLint tHeight = textureObject->surface.height;
+    GLint crop_rect[4] = {0, tHeight, tWidth, -tHeight};
+    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
+    y = cbSurface.height - (y + h);
+    return copybit(x, y, w, h, textureObject, crop_rect, transform, c);
+}
+
+/*
+ * Try to drawTexiOESWithCopybit, return false if we fail.
+ */
+
+bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
+        GLint w, GLint h, ogles_context_t* c)
+{
+    // quickly process empty rects
+    if ((w|h) <= 0) {
+        return true;
+    }
+    if (!checkContext(c)) {
+        return false;
+    }
+    texture_unit_t& u(c->textures.tmu[0]);
+    EGLTextureObject* textureObject = u.texture;
+    return copybit(x, y, w, h, textureObject, textureObject->crop_rect, 0, c);
+}
+
+} // namespace android
+
diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h
new file mode 100644
index 0000000..b8b5afd
--- /dev/null
+++ b/opengl/libagl/copybit.h
@@ -0,0 +1,75 @@
+/*
+**
+** Copyright 2009, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef ANDROID_OPENGLES_COPYBIT_H
+#define ANDROID_OPENGLES_COPYBIT_H
+
+#include <stdlib.h>
+
+#include <GLES/gl.h>
+
+#include "TextureObjectManager.h"
+namespace android {
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+
+bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
+        GLint w, GLint h, ogles_context_t* c);
+
+bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first,
+        GLsizei count);
+
+inline bool copybitQuickCheckContext(ogles_context_t* c) {
+        return  c->copybits.drawSurfaceBuffer != 0
+            && c->rasterizer.state.enabled_tmu == 1
+            && c->textures.tmu[0].texture->try_copybit;
+}
+
+/*
+ * Tries to draw a drawTexiOES using copybit hardware.
+ * Returns true if successful.
+ */
+inline bool drawTexiOESWithCopybit(GLint x, GLint y, GLint z,
+        GLint w, GLint h, ogles_context_t* c) {
+    if (!copybitQuickCheckContext(c)) {
+    	return false;
+   	}
+   	
+   	return drawTexiOESWithCopybit_impl(x, y, z, w, h, c);
+}
+
+/*
+ * Tries to draw a triangle fan using copybit hardware.
+ * Returns true if successful.
+ */
+inline bool drawTriangleFanWithCopybit(ogles_context_t* c, GLint first,
+        GLsizei count) {
+    /*
+     * We are looking for the glDrawArrays call made by SurfaceFlinger.
+     */
+
+    if ((count!=4) || first || !copybitQuickCheckContext(c))
+        return false;
+    
+    return drawTriangleFanWithCopybit_impl(c, first, count);
+}
+
+
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
+} // namespace android
+
+#endif // ANDROID_OPENGLES_COPYBIT_H
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 4461567..6f6656a 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -15,8 +15,6 @@
 ** limitations under the License.
 */
 
-#define LOG_TAG "EGL"
-
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -41,11 +39,19 @@
 #include <pixelflinger/format.h>
 #include <pixelflinger/pixelflinger.h>
 
+#include <private/ui/android_natives_priv.h>
+
+#include <hardware/copybit.h>
+
 #include "context.h"
 #include "state.h"
 #include "texture.h"
 #include "matrix.h"
 
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+#include "gralloc_priv.h"
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
 #undef NELEM
 #define NELEM(x) (sizeof(x)/sizeof(*(x)))
 
@@ -89,9 +95,9 @@
 struct egl_display_t
 {
     egl_display_t() : type(0), initialized(0) { }
-    
+
     static egl_display_t& get_display(EGLDisplay dpy);
-    
+
     static EGLBoolean is_valid(EGLDisplay dpy) {
         return ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS) ? EGL_FALSE : EGL_TRUE;
     }
@@ -140,18 +146,21 @@
                 egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat);
     virtual     ~egl_surface_t();
     virtual     bool    isValid() const = 0;
-    
+
     virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl) = 0;
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl) = 0;
+    virtual     void        connect() {}
+    virtual     void        disconnect() {}
     virtual     EGLint      getWidth() const = 0;
     virtual     EGLint      getHeight() const = 0;
-    virtual     void*       getBits() const = 0;
 
     virtual     EGLint      getHorizontalResolution() const;
     virtual     EGLint      getVerticalResolution() const;
     virtual     EGLint      getRefreshRate() const;
     virtual     EGLint      getSwapBehavior() const;
     virtual     EGLBoolean  swapBuffers();
+    virtual     EGLBoolean  setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
+    virtual     EGLClientBuffer getRenderBuffer() const;
 protected:
     GGLSurface              depth;
 };
@@ -185,42 +194,191 @@
 EGLint egl_surface_t::getSwapBehavior() const {
     return EGL_BUFFER_PRESERVED;
 }
+EGLBoolean egl_surface_t::setSwapRectangle(
+        EGLint l, EGLint t, EGLint w, EGLint h)
+{
+    return EGL_FALSE;
+}
+EGLClientBuffer egl_surface_t::getRenderBuffer() const {
+    return 0;
+}
 
 // ----------------------------------------------------------------------------
 
-struct egl_window_surface_t : public egl_surface_t
+struct egl_window_surface_v2_t : public egl_surface_t
 {
-    egl_window_surface_t(
+    egl_window_surface_v2_t(
             EGLDisplay dpy, EGLConfig config,
             int32_t depthFormat,
-            egl_native_window_t* window);
+            android_native_window_t* window);
 
-     ~egl_window_surface_t();
+     ~egl_window_surface_v2_t();
 
-    virtual     bool        isValid() const { return nativeWindow->magic == 0x600913; }    
+    virtual     bool        isValid() const { return nativeWindow->common.magic == ANDROID_NATIVE_WINDOW_MAGIC; }
     virtual     EGLBoolean  swapBuffers();
     virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
-    virtual     EGLint      getWidth() const    { return nativeWindow->width;  }
-    virtual     EGLint      getHeight() const   { return nativeWindow->height; }
-    virtual     void*       getBits() const;
+    virtual     void        connect();
+    virtual     void        disconnect();
+    virtual     EGLint      getWidth() const    { return buffer->width;  }
+    virtual     EGLint      getHeight() const   { return buffer->height; }
     virtual     EGLint      getHorizontalResolution() const;
     virtual     EGLint      getVerticalResolution() const;
     virtual     EGLint      getRefreshRate() const;
     virtual     EGLint      getSwapBehavior() const;
+    virtual     EGLBoolean  setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
+    virtual     EGLClientBuffer  getRenderBuffer() const;
+    
 private:
-    egl_native_window_t*    nativeWindow;
+    status_t lock(android_native_buffer_t* buf, int usage, void** vaddr);
+    status_t unlock(android_native_buffer_t* buf);
+    android_native_window_t*   nativeWindow;
+    android_native_buffer_t*   buffer;
+    android_native_buffer_t*   previousBuffer;
+    gralloc_module_t const*    module;
+    copybit_device_t*          blitengine;
+    int width;
+    int height;
+    void* bits;
+    GGLFormat const* pixelFormatTable;
+    
+    struct Rect {
+        inline Rect() { };
+        inline Rect(int32_t w, int32_t h)
+            : left(0), top(0), right(w), bottom(h) { }
+        inline Rect(int32_t l, int32_t t, int32_t r, int32_t b)
+            : left(l), top(t), right(r), bottom(b) { }
+        Rect& andSelf(const Rect& r) {
+            left   = max(left, r.left);
+            top    = max(top, r.top);
+            right  = min(right, r.right);
+            bottom = min(bottom, r.bottom);
+            return *this;
+        }
+        bool isEmpty() const {
+            return (left>=right || top>=bottom);
+        }
+        void dump(char const* what) {
+            LOGD("%s { %5d, %5d, w=%5d, h=%5d }", 
+                    what, left, top, right-left, bottom-top);
+        }
+        
+        int32_t left;
+        int32_t top;
+        int32_t right;
+        int32_t bottom;
+    };
+
+    struct Region {
+        inline Region() : count(0) { }
+        typedef Rect const* const_iterator;
+        const_iterator begin() const { return storage; }
+        const_iterator end() const { return storage+count; }
+        static Region subtract(const Rect& lhs, const Rect& rhs) {
+            Region reg;
+            Rect* storage = reg.storage;
+            if (!lhs.isEmpty()) {
+                if (lhs.top < rhs.top) { // top rect
+                    storage->left   = lhs.left;
+                    storage->top    = lhs.top;
+                    storage->right  = lhs.right;
+                    storage->bottom = rhs.top;
+                    storage++;
+                }
+                const int32_t top = max(lhs.top, rhs.top);
+                const int32_t bot = min(lhs.bottom, rhs.bottom);
+                if (top < bot) {
+                    if (lhs.left < rhs.left) { // left-side rect
+                        storage->left   = lhs.left;
+                        storage->top    = top;
+                        storage->right  = rhs.left;
+                        storage->bottom = bot;
+                        storage++;
+                    }
+                    if (lhs.right > rhs.right) { // right-side rect
+                        storage->left   = rhs.right;
+                        storage->top    = top;
+                        storage->right  = lhs.right;
+                        storage->bottom = bot;
+                        storage++;
+                    }
+                }
+                if (lhs.bottom > rhs.bottom) { // bottom rect
+                    storage->left   = lhs.left;
+                    storage->top    = rhs.bottom;
+                    storage->right  = lhs.right;
+                    storage->bottom = lhs.bottom;
+                    storage++;
+                }
+                reg.count = storage - reg.storage;
+            }
+            return reg;
+        }
+        bool isEmpty() const {
+            return count<=0;
+        }
+    private:
+        Rect storage[4];
+        ssize_t count;
+    };
+    
+    struct region_iterator : public copybit_region_t {
+        region_iterator(const Region& region)
+            : b(region.begin()), e(region.end()) {
+            this->next = iterate;
+        }
+    private:
+        static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
+            region_iterator const* me = static_cast<region_iterator const*>(self);
+            if (me->b != me->e) {
+                *reinterpret_cast<Rect*>(rect) = *me->b++;
+                return 1;
+            }
+            return 0;
+        }
+        mutable Region::const_iterator b;
+        Region::const_iterator const e;
+    };
+
+    void copyBlt(
+            android_native_buffer_t* dst, void* dst_vaddr,
+            android_native_buffer_t* src, void const* src_vaddr,
+            const Region& clip);
+
+    Rect dirtyRegion;
+    Rect oldDirtyRegion;
 };
 
-egl_window_surface_t::egl_window_surface_t(EGLDisplay dpy,
+egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
         EGLConfig config,
         int32_t depthFormat,
-        egl_native_window_t* window)
-    : egl_surface_t(dpy, config, depthFormat), nativeWindow(window)
+        android_native_window_t* window)
+    : egl_surface_t(dpy, config, depthFormat), 
+    nativeWindow(window), buffer(0), previousBuffer(0), module(0),
+    blitengine(0), bits(NULL)
 {
+    hw_module_t const* pModule;
+    hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule);
+    module = reinterpret_cast<gralloc_module_t const*>(pModule);
+
+    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &pModule) == 0) {
+        copybit_open(pModule, &blitengine);
+    }
+
+    pixelFormatTable = gglGetPixelFormatTable();
+    
+    // keep a reference on the window
+    nativeWindow->common.incRef(&nativeWindow->common);
+
+    // dequeue a buffer
+    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
+
+    // allocate a corresponding depth-buffer
+    width = buffer->width;
+    height = buffer->height;
     if (depthFormat) {
-        depth.width   = window->width;
-        depth.height  = window->height;
+        depth.width   = width;
+        depth.height  = height;
         depth.stride  = depth.width; // use the width here
         depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
         if (depth.data == 0) {
@@ -228,76 +386,293 @@
             return;
         }
     }
-    nativeWindow->incRef(nativeWindow);
-}
-egl_window_surface_t::~egl_window_surface_t() {
-    nativeWindow->decRef(nativeWindow);
+
+    // keep a reference on the buffer
+    buffer->common.incRef(&buffer->common);
 }
 
-EGLBoolean egl_window_surface_t::swapBuffers()
+egl_window_surface_v2_t::~egl_window_surface_v2_t() {
+    if (buffer) {
+        buffer->common.decRef(&buffer->common);
+    }
+    if (previousBuffer) {
+        previousBuffer->common.decRef(&previousBuffer->common); 
+    }
+    nativeWindow->common.decRef(&nativeWindow->common);
+    if (blitengine) {
+        copybit_close(blitengine);
+    }
+}
+
+void egl_window_surface_v2_t::connect() 
 {
-    uint32_t flags = nativeWindow->swapBuffers(nativeWindow);
-    if (flags & EGL_NATIVES_FLAG_SIZE_CHANGED) {
+    // Lock the buffer
+    nativeWindow->lockBuffer(nativeWindow, buffer);
+    // pin the buffer down
+    if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | 
+            GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
+        LOGE("connect() failed to lock buffer %p (%ux%u)",
+                buffer, buffer->width, buffer->height);
+        setError(EGL_BAD_ACCESS, EGL_NO_SURFACE);
+        // FIXME: we should make sure we're not accessing the buffer anymore
+    }
+}
+
+void egl_window_surface_v2_t::disconnect() 
+{
+    if (buffer && bits) {
+        bits = NULL;
+        unlock(buffer);
+    }
+}
+
+status_t egl_window_surface_v2_t::lock(
+        android_native_buffer_t* buf, int usage, void** vaddr)
+{
+    int err = module->lock(module, buf->handle, 
+            usage, 0, 0, buf->width, buf->height, vaddr);
+    return err;
+}
+
+status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf)
+{
+    int err = module->unlock(module, buf->handle);
+    return err;
+}
+
+void egl_window_surface_v2_t::copyBlt(
+        android_native_buffer_t* dst, void* dst_vaddr,
+        android_native_buffer_t* src, void const* src_vaddr,
+        const Region& clip)
+{
+    // FIXME: use copybit if possible
+    // NOTE: dst and src must be the same format
+    
+    status_t err = NO_ERROR;
+    copybit_device_t* const copybit = blitengine;
+    if (copybit)  {
+        copybit_image_t simg;
+        simg.w = src->width;
+        simg.h = src->height;
+        simg.format = src->format;
+        simg.handle = const_cast<native_handle_t*>(src->handle);
+
+        copybit_image_t dimg;
+        dimg.w = dst->width;
+        dimg.h = dst->height;
+        dimg.format = dst->format;
+        dimg.handle = const_cast<native_handle_t*>(dst->handle);
+        
+        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
+        copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
+        region_iterator it(clip);
+        err = copybit->blit(copybit, &dimg, &simg, &it);
+        if (err != NO_ERROR) {
+            LOGE("copybit failed (%s)", strerror(err));
+        }
+    }
+
+    if (!copybit || err) {
+        Region::const_iterator cur = clip.begin();
+        Region::const_iterator end = clip.end();
+        
+        const size_t bpp = pixelFormatTable[src->format].size;
+        const size_t dbpr = dst->stride * bpp;
+        const size_t sbpr = src->stride * bpp;
+
+        uint8_t const * const src_bits = (uint8_t const *)src_vaddr;
+        uint8_t       * const dst_bits = (uint8_t       *)dst_vaddr;
+
+        while (cur != end) {
+            const Rect& r(*cur++);
+            ssize_t w = r.right - r.left;
+            ssize_t h = r.bottom - r.top;
+            if (w <= 0 || h<=0) continue;
+            size_t size = w * 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);
+        }
+    }
+}
+
+EGLBoolean egl_window_surface_v2_t::swapBuffers()
+{
+    /*
+     * Handle eglSetSwapRectangleANDROID()
+     * We copyback from the front buffer 
+     */
+    if (!dirtyRegion.isEmpty()) {
+        dirtyRegion.andSelf(Rect(buffer->width, buffer->height));
+        if (previousBuffer) {
+            const Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion));
+            if (!copyBack.isEmpty()) {
+                void* prevBits;
+                if (lock(previousBuffer, 
+                        GRALLOC_USAGE_SW_READ_OFTEN, &prevBits) == NO_ERROR) {
+                    // copy from previousBuffer to buffer
+                    copyBlt(buffer, bits, previousBuffer, prevBits, copyBack);
+                    unlock(previousBuffer);
+                }
+            }
+        }
+        oldDirtyRegion = dirtyRegion;
+    }
+
+    if (previousBuffer) {
+        previousBuffer->common.decRef(&previousBuffer->common); 
+        previousBuffer = 0;
+    }
+    
+    unlock(buffer);
+    previousBuffer = buffer;
+    nativeWindow->queueBuffer(nativeWindow, buffer);
+    buffer = 0;
+
+    // dequeue a new buffer
+    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
+    
+    // TODO: lockBuffer should rather be executed when the very first
+    // direct rendering occurs.
+    nativeWindow->lockBuffer(nativeWindow, buffer);
+    
+    // reallocate the depth-buffer if needed
+    if ((width != buffer->width) || (height != buffer->height)) {
         // TODO: we probably should reset the swap rect here
         // if the window size has changed
+        width = buffer->width;
+        height = buffer->height;
         if (depth.data) {
             free(depth.data);
-            depth.width   = nativeWindow->width;
-            depth.height  = nativeWindow->height;
-            depth.stride  = nativeWindow->stride;
+            depth.width   = width;
+            depth.height  = height;
+            depth.stride  = buffer->stride;
             depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
             if (depth.data == 0) {
-                setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+                setError(EGL_BAD_ALLOC, EGL_FALSE);
                 return EGL_FALSE;
             }
         }
     }
+    
+    // keep a reference on the buffer
+    buffer->common.incRef(&buffer->common);
+
+    // finally pin the buffer down
+    if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | 
+            GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
+        LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)",
+                buffer, buffer->width, buffer->height);
+        setError(EGL_BAD_ACCESS, EGL_NO_SURFACE);
+        // FIXME: we should make sure we're not accessing the buffer anymore
+    }
+
     return EGL_TRUE;
 }
 
-EGLBoolean egl_window_surface_t::bindDrawSurface(ogles_context_t* gl)
+EGLBoolean egl_window_surface_v2_t::setSwapRectangle(
+        EGLint l, EGLint t, EGLint w, EGLint h)
+{
+    dirtyRegion = Rect(l, t, l+w, t+h);
+    return EGL_TRUE;
+}
+
+EGLClientBuffer egl_window_surface_v2_t::getRenderBuffer() const
+{
+    return buffer;
+}
+
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+
+static bool supportedCopybitsDestinationFormat(int format) {
+    // Hardware supported
+    switch (format) {
+    case HAL_PIXEL_FORMAT_RGB_565:
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBA_4444:
+    case HAL_PIXEL_FORMAT_RGBA_5551:
+    case HAL_PIXEL_FORMAT_BGRA_8888:
+        return true;
+    }
+    return false;
+}
+#endif
+
+EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl)
 {
     GGLSurface buffer;
     buffer.version = sizeof(GGLSurface);
-    buffer.width   = nativeWindow->width;
-    buffer.height  = nativeWindow->height;
-    buffer.stride  = nativeWindow->stride;
-    buffer.data    = (GGLubyte*)nativeWindow->base + nativeWindow->offset;
-    buffer.format  = nativeWindow->format;
+    buffer.width   = this->buffer->width;
+    buffer.height  = this->buffer->height;
+    buffer.stride  = this->buffer->stride;
+    buffer.data    = (GGLubyte*)bits;
+    buffer.format  = this->buffer->format;
     gl->rasterizer.procs.colorBuffer(gl, &buffer);
     if (depth.data != gl->rasterizer.state.buffers.depth.data)
         gl->rasterizer.procs.depthBuffer(gl, &depth);
+
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    gl->copybits.drawSurfaceBuffer = 0;
+    if (supportedCopybitsDestinationFormat(buffer.format)) {
+        buffer_handle_t handle = this->buffer->handle;
+        if (handle != NULL) {
+            private_handle_t* hand = private_handle_t::dynamicCast(handle);
+            if (hand != NULL && hand->usesPhysicallyContiguousMemory()) {
+                gl->copybits.drawSurfaceBuffer = handle;
+            }
+        }
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
     return EGL_TRUE;
 }
-EGLBoolean egl_window_surface_t::bindReadSurface(ogles_context_t* gl)
+EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl)
 {
     GGLSurface buffer;
     buffer.version = sizeof(GGLSurface);
-    buffer.width   = nativeWindow->width;
-    buffer.height  = nativeWindow->height;
-    buffer.stride  = nativeWindow->stride;
-    buffer.data    = (GGLubyte*)nativeWindow->base + nativeWindow->offset;
-    buffer.format  = nativeWindow->format;
+    buffer.width   = this->buffer->width;
+    buffer.height  = this->buffer->height;
+    buffer.stride  = this->buffer->stride;
+    buffer.data    = (GGLubyte*)bits; // FIXME: hopefully is is LOCKED!!!
+    buffer.format  = this->buffer->format;
     gl->rasterizer.procs.readBuffer(gl, &buffer);
     return EGL_TRUE;
 }
-void* egl_window_surface_t::getBits() const {
-    return (GGLubyte*)nativeWindow->base + nativeWindow->offset;
-}
-EGLint egl_window_surface_t::getHorizontalResolution() const {
+EGLint egl_window_surface_v2_t::getHorizontalResolution() const {
     return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
 }
-EGLint egl_window_surface_t::getVerticalResolution() const {
+EGLint egl_window_surface_v2_t::getVerticalResolution() const {
     return (nativeWindow->ydpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
 }
-EGLint egl_window_surface_t::getRefreshRate() const {
-    return (nativeWindow->fps * EGL_DISPLAY_SCALING);
+EGLint egl_window_surface_v2_t::getRefreshRate() const {
+    return (60 * EGL_DISPLAY_SCALING); // FIXME
 }
-EGLint egl_window_surface_t::getSwapBehavior() const {
-    uint32_t flags = nativeWindow->flags;
-    if (flags & EGL_NATIVES_FLAG_DESTROY_BACKBUFFER)
-        return EGL_BUFFER_DESTROYED;
-    return EGL_BUFFER_PRESERVED;
+EGLint egl_window_surface_v2_t::getSwapBehavior() const 
+{
+    /*
+     * EGL_BUFFER_PRESERVED means that eglSwapBuffers() completely preserves
+     * the content of the swapped buffer.
+     * 
+     * EGL_BUFFER_DESTROYED means that the content of the buffer is lost.
+     * 
+     * However when ANDROID_swap_retcangle is supported, EGL_BUFFER_DESTROYED
+     * only applies to the area specified by eglSetSwapRectangleANDROID(), that
+     * is, everything outside of this area is preserved.
+     * 
+     * This implementation of EGL assumes the later case.
+     * 
+     */
+
+    return EGL_BUFFER_DESTROYED;
 }
 
 // ----------------------------------------------------------------------------
@@ -311,12 +686,11 @@
 
     virtual ~egl_pixmap_surface_t() { }
 
-    virtual     bool        isValid() const { return nativePixmap.version == sizeof(egl_native_pixmap_t); }    
+    virtual     bool        isValid() const { return nativePixmap.version == sizeof(egl_native_pixmap_t); }
     virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
     virtual     EGLint      getWidth() const    { return nativePixmap.width;  }
     virtual     EGLint      getHeight() const   { return nativePixmap.height; }
-    virtual     void*       getBits() const     { return nativePixmap.data; }
 private:
     egl_native_pixmap_t     nativePixmap;
 };
@@ -347,7 +721,7 @@
     buffer.stride  = nativePixmap.stride;
     buffer.data    = nativePixmap.data;
     buffer.format  = nativePixmap.format;
-    
+
     gl->rasterizer.procs.colorBuffer(gl, &buffer);
     if (depth.data != gl->rasterizer.state.buffers.depth.data)
         gl->rasterizer.procs.depthBuffer(gl, &depth);
@@ -376,12 +750,11 @@
 
     virtual ~egl_pbuffer_surface_t();
 
-    virtual     bool        isValid() const { return pbuffer.data != 0; }    
+    virtual     bool        isValid() const { return pbuffer.data != 0; }
     virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
     virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
     virtual     EGLint      getWidth() const    { return pbuffer.width;  }
     virtual     EGLint      getHeight() const   { return pbuffer.height; }
-    virtual     void*       getBits() const     { return pbuffer.data; }
 private:
     GGLSurface  pbuffer;
 };
@@ -407,7 +780,7 @@
     pbuffer.stride  = w;
     pbuffer.data    = (GGLubyte*)malloc(size);
     pbuffer.format  = f;
-    
+
     if (depthFormat) {
         depth.width   = pbuffer.width;
         depth.height  = pbuffer.height;
@@ -468,7 +841,13 @@
 static char const * const gVendorString     = "Google Inc.";
 static char const * const gVersionString    = "1.2 Android Driver";
 static char const * const gClientApiString  = "OpenGL ES";
-static char const * const gExtensionsString = "";
+static char const * const gExtensionsString =
+        "EGL_KHR_image_base "
+        // "KHR_image_pixmap "
+        "EGL_ANDROID_image_native_buffer "
+        "EGL_ANDROID_swap_rectangle "
+        "EGL_ANDROID_get_render_buffer "
+        ;
 
 // ----------------------------------------------------------------------------
 
@@ -496,6 +875,10 @@
             (__eglMustCastToProperFunctionPointerType)&glDrawTexxvOES },
     { "glQueryMatrixxOES",
             (__eglMustCastToProperFunctionPointerType)&glQueryMatrixxOES },
+    { "glEGLImageTargetTexture2DOES",
+            (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetTexture2DOES },
+    { "glEGLImageTargetRenderbufferStorageOES",
+            (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetRenderbufferStorageOES },
     { "glClipPlanef",
             (__eglMustCastToProperFunctionPointerType)&glClipPlanef },
     { "glClipPlanex",
@@ -510,9 +893,17 @@
             (__eglMustCastToProperFunctionPointerType)&glDeleteBuffers },
     { "glGenBuffers",
             (__eglMustCastToProperFunctionPointerType)&glGenBuffers },
+    { "eglCreateImageKHR",  
+            (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR }, 
+    { "eglDestroyImageKHR", 
+            (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
+    { "eglSetSwapRectangleANDROID", 
+            (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
+    { "eglGetRenderBufferANDROID", 
+            (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, 
 };
 
-/* 
+/*
  * In the lists below, attributes names MUST be sorted.
  * Additionally, all configs must be sorted according to
  * the EGL specification.
@@ -523,7 +914,7 @@
         { EGL_CONFIG_CAVEAT,              EGL_SLOW_CONFIG                   },
         { EGL_LEVEL,                      0                                 },
         { EGL_MAX_PBUFFER_HEIGHT,         GGL_MAX_VIEWPORT_DIMS             },
-        { EGL_MAX_PBUFFER_PIXELS,         
+        { EGL_MAX_PBUFFER_PIXELS,
                 GGL_MAX_VIEWPORT_DIMS*GGL_MAX_VIEWPORT_DIMS                 },
         { EGL_MAX_PBUFFER_WIDTH,          GGL_MAX_VIEWPORT_DIMS             },
         { EGL_NATIVE_RENDERABLE,          EGL_TRUE                          },
@@ -660,9 +1051,9 @@
 {
    while (first <= last) {
        int mid = (first + last) / 2;
-       if (key > sortedArray[mid].key) { 
+       if (key > sortedArray[mid].key) {
            first = mid + 1;
-       } else if (key < sortedArray[mid].key) { 
+       } else if (key < sortedArray[mid].key) {
            last = mid - 1;
        } else {
            return mid;
@@ -674,13 +1065,13 @@
 static int isAttributeMatching(int i, EGLint attr, EGLint val)
 {
     // look for the attribute in all of our configs
-    config_pair_t const* configFound = gConfigs[i].array; 
+    config_pair_t const* configFound = gConfigs[i].array;
     int index = binarySearch<config_pair_t>(
             gConfigs[i].array,
             0, gConfigs[i].size-1,
             attr);
     if (index < 0) {
-        configFound = config_base_attribute_list; 
+        configFound = config_base_attribute_list;
         index = binarySearch<config_pair_t>(
                 config_base_attribute_list,
                 0, NELEM(config_base_attribute_list)-1,
@@ -794,28 +1185,28 @@
     int32_t depthFormat;
     int32_t pixelFormat;
     switch(configID) {
-    case 0: 
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+    case 0:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = 0;
         break;
     case 1:
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 2:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = 0;
         break;
     case 3:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 4:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = 0;
         break;
     case 5:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     default:
@@ -828,9 +1219,9 @@
     //if (EGLint(info.format) != pixelFormat)
     //    return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
 
-    egl_surface_t* surface =
-        new egl_window_surface_t(dpy, config, depthFormat,
-                static_cast<egl_native_window_t*>(window));
+    egl_surface_t* surface;
+    surface = new egl_window_surface_v2_t(dpy, config, depthFormat,
+            static_cast<android_native_window_t*>(window));
 
     if (!surface->isValid()) {
         // there was a problem in the ctor, the error
@@ -863,28 +1254,28 @@
     int32_t depthFormat;
     int32_t pixelFormat;
     switch(configID) {
-    case 0: 
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+    case 0:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = 0;
         break;
     case 1:
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 2:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = 0;
         break;
     case 3:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 4:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = 0;
         break;
     case 5:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     default:
@@ -916,10 +1307,10 @@
     EGLint surfaceType;
     if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
         return EGL_FALSE;
-    
+
     if (!(surfaceType & EGL_PBUFFER_BIT))
         return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
-        
+
     EGLint configID;
     if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
         return EGL_FALSE;
@@ -927,28 +1318,28 @@
     int32_t depthFormat;
     int32_t pixelFormat;
     switch(configID) {
-    case 0: 
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+    case 0:
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = 0;
         break;
     case 1:
-        pixelFormat = GGL_PIXEL_FORMAT_RGB_565; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 2:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = 0;
         break;
     case 3:
-        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888; 
+        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     case 4:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = 0;
         break;
     case 5:
-        pixelFormat = GGL_PIXEL_FORMAT_A_8; 
+        pixelFormat = GGL_PIXEL_FORMAT_A_8;
         depthFormat = GGL_PIXEL_FORMAT_Z_16;
         break;
     default:
@@ -1001,7 +1392,7 @@
         egl_display_t& d = egl_display_t::get_display(dpy);
         d.type = display;
         return dpy;
-    }    
+    }
     return EGL_NO_DISPLAY;
 }
 
@@ -1009,10 +1400,10 @@
 {
     if (egl_display_t::is_valid(dpy) == EGL_FALSE)
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    
+
     EGLBoolean res = EGL_TRUE;
     egl_display_t& d = egl_display_t::get_display(dpy);
-    
+
     if (android_atomic_inc(&d.initialized) == 0) {
         // initialize stuff here if needed
         //pthread_mutex_lock(&gInitMutex);
@@ -1080,7 +1471,7 @@
         *num_config = 0;
         return EGL_TRUE;
     }
-    
+
     int numAttributes = 0;
     int numConfigs =  NELEM(gConfigs);
     uint32_t possibleMatch = (1<<numConfigs)-1;
@@ -1161,7 +1552,7 @@
 {
     return createWindowSurface(dpy, config, window, attrib_list);
 }
-    
+
 EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
                                     NativePixmapType pixmap,
                                     const EGLint *attrib_list)
@@ -1174,7 +1565,7 @@
 {
     return createPbufferSurface(dpy, config, attrib_list);
 }
-                                    
+
 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
 {
     if (egl_display_t::is_valid(dpy) == EGL_FALSE)
@@ -1185,6 +1576,11 @@
             return setError(EGL_BAD_SURFACE, EGL_FALSE);
         if (surface->dpy != dpy)
             return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+        if (surface->ctx) {
+            // FIXME: this surface is current check what the spec says
+            surface->disconnect();
+            surface->ctx = 0;
+        }
         delete surface;
     }
     return EGL_TRUE;
@@ -1244,7 +1640,7 @@
             *value = (wr * EGL_DISPLAY_SCALING) / hr;
         } break;
         case EGL_SWAP_BEHAVIOR:
-            *value = surface->getSwapBehavior(); 
+            *value = surface->getSwapBehavior();
             break;
         default:
             ret = setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
@@ -1294,7 +1690,7 @@
     }
 
     EGLContext current_ctx = EGL_NO_CONTEXT;
-    
+
     if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))
         return setError(EGL_BAD_MATCH, EGL_FALSE);
 
@@ -1310,21 +1706,28 @@
         egl_surface_t* r = (egl_surface_t*)read;
         if ((d && d->ctx && d->ctx != ctx) ||
             (r && r->ctx && r->ctx != ctx)) {
-            // once of the surface is bound to a context in another thread
+            // one of the surface is bound to a context in another thread
             return setError(EGL_BAD_ACCESS, EGL_FALSE);
         }
     }
 
-    // TODO: call connect / disconnect on the surface
-
     ogles_context_t* gl = (ogles_context_t*)ctx;
     if (makeCurrent(gl) == 0) {
         if (ctx) {
             egl_context_t* c = egl_context_t::context(ctx);
             egl_surface_t* d = (egl_surface_t*)draw;
             egl_surface_t* r = (egl_surface_t*)read;
-            c->read = read;
+            
+            if (c->draw) {
+                reinterpret_cast<egl_surface_t*>(c->draw)->disconnect();
+            }
+            if (c->read) {
+                // FIXME: unlock/disconnect the read surface too 
+            }
+            
             c->draw = draw;
+            c->read = read;
+
             if (c->flags & egl_context_t::NEVER_CURRENT) {
                 c->flags &= ~egl_context_t::NEVER_CURRENT;
                 GLint w = 0;
@@ -1338,10 +1741,12 @@
                 ogles_scissor(gl, 0, 0, w, h);
             }
             if (d) {
+                d->connect();
                 d->ctx = ctx;
                 d->bindDrawSurface(gl);
             }
             if (r) {
+                // FIXME: lock/connect the read surface too 
                 r->ctx = ctx;
                 r->bindReadSurface(gl);
             }
@@ -1352,8 +1757,16 @@
                 egl_context_t* c = egl_context_t::context(current_ctx);
                 egl_surface_t* d = (egl_surface_t*)c->draw;
                 egl_surface_t* r = (egl_surface_t*)c->read;
-                if (d) d->ctx = EGL_NO_CONTEXT;
-                if (r) r->ctx = EGL_NO_CONTEXT;
+                if (d) {
+                    c->draw = 0;
+                    d->ctx = EGL_NO_CONTEXT;
+                    d->disconnect();
+                }
+                if (r) {
+                    c->read = 0;
+                    r->ctx = EGL_NO_CONTEXT;
+                    // FIXME: unlock/disconnect the read surface too 
+                }
             }
         }
         return EGL_TRUE;
@@ -1425,7 +1838,7 @@
 {
     if (egl_display_t::is_valid(dpy) == EGL_FALSE)
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
-    
+
     egl_surface_t* d = static_cast<egl_surface_t*>(draw);
     if (d->dpy != dpy)
         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
@@ -1558,7 +1971,7 @@
 }
 
 // ----------------------------------------------------------------------------
-// Android extensions
+// EGL_EGLEXT_VERSION 3
 // ----------------------------------------------------------------------------
 
 void (*eglGetProcAddress (const char *procname))()
@@ -1571,3 +1984,93 @@
     }
     return NULL;
 }
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
+        const EGLint *attrib_list)
+{
+    EGLBoolean result = EGL_FALSE;
+    return result;
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
+{
+    EGLBoolean result = EGL_FALSE;
+    return result;
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+        EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE) {
+        return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
+    }
+    if (ctx != EGL_NO_CONTEXT) {
+        return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
+    }
+    if (target != EGL_NATIVE_BUFFER_ANDROID) {
+        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+    }
+
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+    
+    native_buffer->common.incRef(&native_buffer->common);
+    return (EGLImageKHR)native_buffer;
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE) {
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+    }
+
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+
+    native_buffer->common.decRef(&native_buffer->common);
+
+    return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// ANDROID extensions
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
+        EGLint left, EGLint top, EGLint width, EGLint height)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    egl_surface_t* d = static_cast<egl_surface_t*>(draw);
+    if (d->dpy != dpy)
+        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    // post the surface
+    d->setSwapRectangle(left, top, width, height);
+
+    return EGL_TRUE;
+}
+
+EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw)
+{
+    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
+        return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0);
+
+    egl_surface_t* d = static_cast<egl_surface_t*>(draw);
+    if (d->dpy != dpy)
+        return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0);
+
+    // post the surface
+    return d->getRenderBuffer();
+}
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
index 5cbabea..a59b3b0 100644
--- a/opengl/libagl/state.cpp
+++ b/opengl/libagl/state.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, 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 
+** 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 
+**     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 
+** 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.
 */
 
@@ -28,12 +28,16 @@
 #include "BufferObjectManager.h"
 #include "TextureObjectManager.h"
 
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+#include <hardware/copybit.h>
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
 namespace android {
 
 // ----------------------------------------------------------------------------
 
 static char const * const gVendorString     = "Android";
-static char const * const gRendererString   = "Android PixelFlinger 1.0";
+static char const * const gRendererString   = "Android PixelFlinger 1.1";
 static char const * const gVersionString    = "OpenGL ES-CM 1.0";
 static char const * const gExtensionsString =
     "GL_OES_byte_coordinates "              // OK
@@ -46,9 +50,9 @@
     "GL_OES_query_matrix "                  // OK
     //        "GL_OES_point_size_array "              // TODO
     //        "GL_OES_point_sprite "                  // TODO
+    "GL_OES_EGL_image "                     // OK
     "GL_ARB_texture_compression "           // OK
     "GL_ARB_texture_non_power_of_two "      // OK
-    "GL_ANDROID_direct_texture "            // OK
     "GL_ANDROID_user_clip_plane "           // OK
     "GL_ANDROID_vertex_buffer_object "      // OK
     "GL_ANDROID_generate_mipmap "           // OK
@@ -62,13 +66,13 @@
 ogles_context_t *ogles_init(size_t extra)
 {
     void* const base = malloc(extra + sizeof(ogles_context_t) + 32);
-	if (!base) return 0;
+    if (!base) return 0;
 
     ogles_context_t *c =
             (ogles_context_t *)((ptrdiff_t(base) + extra + 31) & ~0x1FL);
     memset(c, 0, sizeof(ogles_context_t));
     ggl_init_context(&(c->rasterizer));
-    
+
     // XXX: this should be passed as an argument
     sp<EGLSurfaceManager> smgr(new EGLSurfaceManager());
     c->surfaceManager = smgr.get();
@@ -87,13 +91,42 @@
     c->rasterizer.base = base;
     c->point.size = TRI_ONE;
     c->line.width = TRI_ONE;
-            
+
     // in OpenGL, writing to the depth buffer is enabled by default.
     c->rasterizer.procs.depthMask(c, 1);
-    
+
     // OpenGL enables dithering by default
     c->rasterizer.procs.enable(c, GL_DITHER);
 
+    c->copybits.blitEngine = NULL;
+    c->copybits.minScale = 0;
+    c->copybits.maxScale = 0;
+    c->copybits.drawSurfaceBuffer = 0;
+
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    hw_module_t const* module;
+    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
+        struct copybit_device_t* copyBits;
+        if (copybit_open(module, &copyBits) == 0) {
+            c->copybits.blitEngine = copyBits;
+            {
+                int minLim = copyBits->get(copyBits,
+                        COPYBIT_MINIFICATION_LIMIT);
+                if (minLim != -EINVAL && minLim > 0) {
+                    c->copybits.minScale = (1 << 16) / minLim;
+                }
+            }
+            {
+                int magLim = copyBits->get(copyBits,
+                        COPYBIT_MAGNIFICATION_LIMIT);
+                if (magLim != -EINVAL && magLim > 0) {
+                    c->copybits.maxScale = min(32*1024-1, magLim) << 16;
+                }
+            }
+        }
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
     return c;
 }
 
@@ -107,7 +140,12 @@
     c->surfaceManager->decStrong(c);
     c->bufferObjectManager->decStrong(c);
     ggl_uninit_context(&(c->rasterizer));
-	free(c->rasterizer.base);
+    free(c->rasterizer.base);
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    if (c->copybits.blitEngine != NULL) {
+        copybit_close((struct copybit_device_t*) c->copybits.blitEngine);
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void _ogles_error(ogles_context_t* c, GLenum error)
@@ -188,7 +226,7 @@
         // these need to fall through into the rasterizer
         c->rasterizer.procs.enableDisable(c, cap, enabled);
         break;
-        
+
     case GL_MULTISAMPLE:
     case GL_SAMPLE_ALPHA_TO_COVERAGE:
     case GL_SAMPLE_ALPHA_TO_ONE:
@@ -281,7 +319,7 @@
     case GL_LINE_SMOOTH_HINT:
         break;
     case GL_POINT_SMOOTH_HINT:
-        c->rasterizer.procs.enableDisable(c, 
+        c->rasterizer.procs.enableDisable(c,
                 GGL_POINT_SMOOTH_NICE, mode==GL_NICEST);
         break;
     case GL_PERSPECTIVE_CORRECTION_HINT:
@@ -323,7 +361,7 @@
         c->error = 0;
         return ret;
     }
-    
+
     if (c->rasterizer.error) {
         const GLenum ret(c->rasterizer.error);
         c->rasterizer.error = 0;
@@ -362,25 +400,25 @@
         int index = c->rasterizer.state.buffers.color.format;
         GGLFormat const * formats = gglGetPixelFormatTable();
         params[0] = formats[index].ah - formats[index].al;
-        break; 
+        break;
         }
     case GL_RED_BITS: {
         int index = c->rasterizer.state.buffers.color.format;
         GGLFormat const * formats = gglGetPixelFormatTable();
         params[0] = formats[index].rh - formats[index].rl;
-        break; 
+        break;
         }
     case GL_GREEN_BITS: {
         int index = c->rasterizer.state.buffers.color.format;
         GGLFormat const * formats = gglGetPixelFormatTable();
         params[0] = formats[index].gh - formats[index].gl;
-        break; 
+        break;
         }
     case GL_BLUE_BITS: {
         int index = c->rasterizer.state.buffers.color.format;
         GGLFormat const * formats = gglGetPixelFormatTable();
         params[0] = formats[index].bh - formats[index].bl;
-        break; 
+        break;
         }
     case GL_COMPRESSED_TEXTURE_FORMATS:
         params[ 0] = GL_PALETTE4_RGB8_OES;
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 14a910c..d767c31 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -2,16 +2,16 @@
 **
 ** Copyright 2006, 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 
+** 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 
+**     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 
+** 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.
 */
 
@@ -23,6 +23,13 @@
 #include "texture.h"
 #include "TextureObjectManager.h"
 
+#include <private/ui/android_natives_priv.h>
+
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+#include "copybit.h"
+#include "gralloc_priv.h"
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -48,7 +55,7 @@
     // each context has a default named (0) texture (not shared)
     c->textures.defaultTexture = new EGLTextureObject();
     c->textures.defaultTexture->incStrong(c);
-    
+
     // bind the default texture to each texture unit
     for (int i=0; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
         bindTextureTmu(c, i, 0, c->textures.defaultTexture);
@@ -96,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)
@@ -110,6 +117,66 @@
     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);
+
+                void* vaddr;
+                int err = module->lock(module, native_buffer->handle,
+                        GRALLOC_USAGE_SW_READ_OFTEN,
+                        0, 0, native_buffer->width, native_buffer->height,
+                        &vaddr);
+
+                u.texture->setImageBits(vaddr);
+                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);
+
+                module->unlock(module, native_buffer->handle);
+                u.texture->setImageBits(NULL);
+                c->rasterizer.procs.bindTexture(c, &(u.texture->surface));
+            }
+        }
+    }
+    c->rasterizer.procs.activeTexture(c, c->textures.active);
+}
+
 // ----------------------------------------------------------------------------
 #if 0
 #pragma mark -
@@ -255,7 +322,7 @@
         u.texture->decStrong(c);
 
     if (name == 0) {
-        // 0 is our local texture object, not shared with anyone. 
+        // 0 is our local texture object, not shared with anyone.
         // But it affects all bound TMUs immediately.
         // (we need to invalidate all units bound to this texture object)
         tex = c->textures.defaultTexture;
@@ -273,7 +340,7 @@
     u.texture = tex.get();
     u.texture->incStrong(c);
     u.name = name;
-    invalidate_texture(c, active);    
+    invalidate_texture(c, active);
     return tex;
 }
 
@@ -282,7 +349,7 @@
 {
     if (tex.get() == c->textures.tmu[tmu].texture)
         return;
-    
+
     // free the reference to the previously bound object
     texture_unit_t& u(c->textures.tmu[tmu]);
     if (u.texture)
@@ -310,7 +377,7 @@
     if (formatIdx == 0) { // we don't know what to do with this
         return GL_INVALID_OPERATION;
     }
-    
+
     // figure out the size we need as well as the stride
     const GGLFormat& pixelFormat(c->rasterizer.formats[formatIdx]);
     const int32_t align = c->textures.unpackAlignment-1;
@@ -530,8 +597,8 @@
         ogles_error(c, GL_INVALID_ENUM);
         return;
     }
-    
-    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;    
+
+    EGLTextureObject* textureObject = c->textures.tmu[c->textures.active].texture;
     switch (pname) {
     case GL_TEXTURE_WRAP_S:
         if ((param == GL_REPEAT) ||
@@ -581,13 +648,12 @@
 }
 
 
-static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
+
+static void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
         ogles_context_t* c)
 {
-    // quickly reject empty rects
-    if ((w|h) <= 0)
-        return;                
-
+    ogles_lock_textures(c);
+    
     const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
     y = gglIntToFixed(cbSurface.height) - (y + h);
     w >>= FIXED_BITS;
@@ -610,7 +676,7 @@
                 GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
         u.dirty = 0xFF; // XXX: should be more subtle
 
-        EGLTextureObject* textureObject = u.texture;  
+        EGLTextureObject* textureObject = u.texture;
         const GLint Ucr = textureObject->crop_rect[0] << 16;
         const GLint Vcr = textureObject->crop_rect[1] << 16;
         const GLint Wcr = textureObject->crop_rect[2] << 16;
@@ -641,11 +707,30 @@
     c->rasterizer.procs.disable(c, GGL_W_LERP);
     c->rasterizer.procs.disable(c, GGL_AA);
     c->rasterizer.procs.shadeModel(c, GL_FLAT);
-    c->rasterizer.procs.recti(c, 
+    c->rasterizer.procs.recti(c,
             gglFixedToIntRound(x),
             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,
+        ogles_context_t* c)
+{
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    if (drawTexiOESWithCopybit(gglFixedToIntRound(x),
+            gglFixedToIntRound(y), gglFixedToIntRound(z),
+            gglFixedToIntRound(w), gglFixedToIntRound(h), c)) {
+        return;
+    }
+#else
+    // quickly reject empty rects
+    if ((w|h) <= 0)
+        return;
+#endif
+    drawTexxOESImp(x, y, z, w, h, c);
 }
 
 static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_context_t* c)
@@ -656,14 +741,21 @@
     // which is a lot faster.
 
     if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+        if (drawTexiOESWithCopybit(x, y, z, w, h, c)) {
+            return;
+        }
+#endif
         const int tmu = 0;
         texture_unit_t& u(c->textures.tmu[tmu]);
-        EGLTextureObject* textureObject = u.texture;  
+        EGLTextureObject* textureObject = u.texture;
         const GLint Wcr = textureObject->crop_rect[2];
         const GLint Hcr = textureObject->crop_rect[3];
 
         if ((w == Wcr) && (h == -Hcr)) {
+#ifndef LIBAGL_USE_GRALLOC_COPYBITS
             if ((w|h) <= 0) return; // quickly reject empty rects
+#endif
 
             if (u.dirty) {
                 c->rasterizer.procs.activeTexture(c, tmu);
@@ -679,14 +771,14 @@
                     GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
             u.dirty = 0xFF; // XXX: should be more subtle
             c->rasterizer.procs.activeTexture(c, c->textures.active);
-            
+
             const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
             y = cbSurface.height - (y + h);
             const GLint Ucr = textureObject->crop_rect[0];
             const GLint Vcr = textureObject->crop_rect[1];
             const GLint s0  = Ucr - x;
             const GLint t0  = (Vcr + Hcr) - y;
-            
+
             const GLuint tw = textureObject->surface.width;
             const GLuint th = textureObject->surface.height;
             if ((uint32_t(s0+x+w) > tw) || (uint32_t(t0+y+h) > th)) {
@@ -694,7 +786,9 @@
                 // in this case, so we just use the slow case, which
                 // at least won't crash
                 goto slow_case;
-            } 
+            }
+
+            ogles_lock_textures(c);
 
             c->rasterizer.procs.texCoord2i(c, s0, t0);
             const uint32_t enables = c->rasterizer.state.enables;
@@ -706,12 +800,15 @@
             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;
         }
     }
 
 slow_case:
-    drawTexxOES(
+    drawTexxOESImp(
             gglIntToFixed(x), gglIntToFixed(y), gglIntToFixed(z),
             gglIntToFixed(w), gglIntToFixed(h),
             c);
@@ -749,7 +846,7 @@
     }
 
     // Bind or create a texture
-    sp<EGLTextureObject> tex;    
+    sp<EGLTextureObject> tex;
     if (texture == 0) {
         // 0 is our local texture object
         tex = c->textures.defaultTexture;
@@ -837,7 +934,7 @@
     if ((pname != GL_PACK_ALIGNMENT) && (pname != GL_UNPACK_ALIGNMENT)) {
         ogles_error(c, GL_INVALID_ENUM);
         return;
-    }    
+    }
     if ((param<=0 || param>8) || (param & (param-1))) {
         ogles_error(c, GL_INVALID_VALUE);
         return;
@@ -952,7 +1049,7 @@
     }
 
     // "uncompress" the texture since pixelflinger doesn't support
-    // any compressed texture format natively. 
+    // any compressed texture format natively.
     GLenum format;
     GLenum type;
     switch (internalformat) {
@@ -1016,7 +1113,7 @@
         GLenum format, GLenum type, const GLvoid *pixels)
 {
     ogles_context_t* c = ogles_context_t::get();
-    if (target != GL_TEXTURE_2D && target != GL_DIRECT_TEXTURE_2D_QUALCOMM) {
+    if (target != GL_TEXTURE_2D) {
         ogles_error(c, GL_INVALID_ENUM);
         return;
     }
@@ -1024,7 +1121,7 @@
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
-    if (format != internalformat) {
+    if (format != (GLenum)internalformat) {
         ogles_error(c, GL_INVALID_OPERATION);
         return;
     }
@@ -1034,16 +1131,10 @@
 
     int32_t size = 0;
     GGLSurface* surface = 0;
-    if (target != GL_DIRECT_TEXTURE_2D_QUALCOMM) {
-        int error = createTextureSurface(c, &surface, &size,
-                level, format, type, width, height);
-        if (error) {
-            ogles_error(c, error);
-            return;
-        }
-    } else if (pixels == 0 || level != 0) {
-        // pixel can't be null for direct texture
-        ogles_error(c, GL_INVALID_OPERATION);
+    int error = createTextureSurface(c, &surface, &size,
+            level, format, type, width, height);
+    if (error) {
+        ogles_error(c, error);
         return;
     }
 
@@ -1064,18 +1155,12 @@
         userSurface.compressedFormat = 0;
         userSurface.data = (GLubyte*)pixels;
 
-        if (target != GL_DIRECT_TEXTURE_2D_QUALCOMM) {
-            int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height); 
-            if (err) {
-                ogles_error(c, err);
-                return;
-            }
-            generateMipmap(c, level);
-        } else {
-            // bind it to the texture unit
-            sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
-            tex->setSurface(&userSurface);
+        int err = copyPixels(c, *surface, 0, 0, userSurface, 0, 0, width, height);
+        if (err) {
+            ogles_error(c, err);
+            return;
         }
+        generateMipmap(c, level);
     }
 }
 
@@ -1150,7 +1235,7 @@
 
     int err = copyPixels(c,
             surface, xoffset, yoffset,
-            userSurface, 0, 0, width, height); 
+            userSurface, 0, 0, width, height);
     if (err) {
         ogles_error(c, err);
         return;
@@ -1203,7 +1288,7 @@
     case GL_LUMINANCE_ALPHA:
     case GL_LUMINANCE:
         type = GL_UNSIGNED_BYTE;
-        break;    
+        break;
     }
 
     // figure out the format to use for the new texture
@@ -1213,7 +1298,7 @@
     case GGL_PIXEL_FORMAT_RGBA_5551:
     case GGL_PIXEL_FORMAT_RGBA_4444:
         format = internalformat;
-        break;    
+        break;
     case GGL_PIXEL_FORMAT_RGBX_8888:
     case GGL_PIXEL_FORMAT_RGB_888:
     case GGL_PIXEL_FORMAT_RGB_565:
@@ -1222,7 +1307,7 @@
         case GL_LUMINANCE:
         case GL_RGB:
             format = internalformat;
-            break;    
+            break;
         }
         break;
     }
@@ -1242,7 +1327,7 @@
         ogles_error(c, error);
         return;
     }
-    
+
     // The bottom row is stored first in textures
     GGLSurface txSurface(*surface);
     txSurface.stride = -txSurface.stride;
@@ -1252,7 +1337,7 @@
 
     int err = copyPixels(c,
             txSurface, 0, 0,
-            cbSurface, x, y, cbSurface.width, cbSurface.height);  
+            cbSurface, x, y, cbSurface.width, cbSurface.height);
     if (err) {
         ogles_error(c, err);
     }
@@ -1302,7 +1387,7 @@
 
     int err = copyPixels(c,
             surface, xoffset, yoffset,
-            cbSurface, x, y, width, height);  
+            cbSurface, x, y, width, height);
     if (err) {
         ogles_error(c, err);
         return;
@@ -1372,7 +1457,7 @@
         return;
     }
 
-    ggl->colorBuffer(ggl, &userSurface);  // destination is user buffer 
+    ggl->colorBuffer(ggl, &userSurface);  // destination is user buffer
     ggl->bindTexture(ggl, &readSurface);  // source is read-buffer
     ggl->texCoord2i(ggl, x, readSurface.height - (y + height));
     ggl->recti(ggl, 0, 0, width, height);
@@ -1426,3 +1511,54 @@
     ogles_context_t* c = ogles_context_t::get();
     drawTexxOES(x, y, z, w, h, c);
 }
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark EGL Image Extension
+#endif
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+    ogles_context_t* c = ogles_context_t::get();
+    if (target != GL_TEXTURE_2D) {
+        ogles_error(c, GL_INVALID_ENUM);
+        return;
+    }
+
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)image;
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+    if (native_buffer->common.version != sizeof(android_native_buffer_t)) {
+        ogles_error(c, GL_INVALID_VALUE);
+        return;
+    }
+
+    // bind it to the texture unit
+    sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
+    tex->setImage(native_buffer);
+
+    /*
+     * Here an implementation can retrieve the buffer_handle_t of this buffer
+     * which gives it access to an arbitrary-defined kernel resource
+     * (or anything else for that matter).
+     * There needs to be an intimate knowledge between GLES and buffer_handle_t,
+     * so make sure to validate the handle before using it.
+     * Typically, buffer_handle_t comes from the gralloc HAL which is provided
+     * by the implementor of GLES.
+     *
+     */
+#ifdef LIBAGL_USE_GRALLOC_COPYBITS
+    tex->try_copybit = false;
+    private_handle_t* hnd = private_handle_t::dynamicCast(native_buffer->handle);
+    if (hnd && hnd->usesPhysicallyContiguousMemory()) {
+        tex->try_copybit = true;
+    }
+#endif // LIBAGL_USE_GRALLOC_COPYBITS
+}
+
+void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+}
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/libs/Android.mk b/opengl/libs/Android.mk
index 23304d5..e1fd48b 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -1,17 +1,18 @@
 LOCAL_PATH:= $(call my-dir)
 
-#
+###############################################################################
 # Build META EGL library
 #
 
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= 	\
-	EGL/egl.cpp 		\
-	EGL/gpu.cpp			\
+	EGL/egl.cpp 	\
+	EGL/hooks.cpp 	\
+	EGL/Loader.cpp 	\
 #
 
-LOCAL_SHARED_LIBRARIES += libcutils libutils libui
+LOCAL_SHARED_LIBRARIES += libcutils libutils
 LOCAL_LDLIBS := -lpthread -ldl
 LOCAL_MODULE:= libEGL
 
@@ -19,24 +20,42 @@
 ifeq ($(TARGET_SIMULATOR),true)
 else
     LOCAL_SHARED_LIBRARIES += libdl
-    # we need to access the Bionic private header <bionic_tls.h>
-    LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
+    # we need to access the private Bionic header <bionic_tls.h>
+    LOCAL_C_INCLUDES += bionic/libc/private
 endif
 
+LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
 LOCAL_CFLAGS += -fvisibility=hidden
 
 include $(BUILD_SHARED_LIBRARY)
+installed_libEGL := $(LOCAL_INSTALLED_MODULE)
 
 
+# OpenGL drivers config file
+ifneq ($(BOARD_EGL_CFG),)
 
-#
-# Build the wrapper OpenGL ES library
+include $(CLEAR_VARS)
+LOCAL_MODULE := egl.cfg
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl
+LOCAL_SRC_FILES := ../../../../$(BOARD_EGL_CFG)
+include $(BUILD_PREBUILT)
+
+# make sure we depend on egl.cfg, so it gets installed
+$(installed_libEGL): | egl.cfg
+
+endif
+
+###############################################################################
+# Build the wrapper OpenGL ES 1.x library
 #
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= 	\
-	GLES_CM/gl.cpp.arm 		\
+LOCAL_SRC_FILES:= 		\
+	GLES_CM/gl.cpp.arm 	\
 #
 
 LOCAL_SHARED_LIBRARIES += libcutils libEGL
@@ -47,10 +66,41 @@
 ifeq ($(TARGET_SIMULATOR),true)
 else
     LOCAL_SHARED_LIBRARIES += libdl
-    # we need to access the Bionic private header <bionic_tls.h>
-    LOCAL_CFLAGS += -I$(LOCAL_PATH)/../../../../bionic/libc/private
+    # we need to access the private Bionic header <bionic_tls.h>
+    LOCAL_C_INCLUDES += bionic/libc/private
 endif
 
+LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv1\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+LOCAL_CFLAGS += -fvisibility=hidden
+
+include $(BUILD_SHARED_LIBRARY)
+
+
+###############################################################################
+# Build the wrapper OpenGL ES 2.x library
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= 		\
+	GLES2/gl2.cpp.arm 	\
+#
+
+LOCAL_SHARED_LIBRARIES += libcutils libEGL
+LOCAL_LDLIBS := -lpthread -ldl
+LOCAL_MODULE:= libGLESv2
+
+# needed on sim build because of weird logging issues
+ifeq ($(TARGET_SIMULATOR),true)
+else
+    LOCAL_SHARED_LIBRARIES += libdl
+    # we need to access the private Bionic header <bionic_tls.h>
+    LOCAL_C_INCLUDES += bionic/libc/private
+endif
+
+LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv2\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
 LOCAL_CFLAGS += -fvisibility=hidden
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
new file mode 100644
index 0000000..7f3f114
--- /dev/null
+++ b/opengl/libs/EGL/Loader.cpp
@@ -0,0 +1,276 @@
+/* 
+ ** Copyright 2007, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License"); 
+ ** you may not use this file except in compliance with the License. 
+ ** You may obtain a copy of the License at 
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0 
+ **
+ ** Unless required by applicable law or agreed to in writing, software 
+ ** distributed under the License is distributed on an "AS IS" BASIS, 
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ ** See the License for the specific language governing permissions and 
+ ** limitations under the License.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <limits.h>
+
+#include <cutils/log.h>
+
+#include <EGL/egl.h>
+
+#include "hooks.h"
+#include "egl_impl.h"
+
+#include "Loader.h"
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+
+/*
+ * EGL drivers are called
+ * 
+ * /system/lib/egl/lib{[EGL|GLESv1_CM|GLESv2] | GLES}_$TAG.so 
+ * 
+ */
+
+ANDROID_SINGLETON_STATIC_INSTANCE( Loader )
+
+// ----------------------------------------------------------------------------
+
+Loader::driver_t::driver_t(void* gles) 
+{
+    dso[0] = gles;
+    for (size_t i=1 ; i<NELEM(dso) ; i++)
+        dso[i] = 0;
+}
+
+Loader::driver_t::~driver_t() 
+{
+    for (size_t i=0 ; i<NELEM(dso) ; i++) {
+        if (dso[i]) {
+            dlclose(dso[i]);
+            dso[i] = 0;
+        }
+    }
+}
+
+status_t Loader::driver_t::set(void* hnd, int32_t api)
+{
+    switch (api) {
+        case EGL:
+            dso[0] = hnd;
+            break;
+        case GLESv1_CM:
+            dso[1] = hnd;
+            break;
+        case GLESv2:
+            dso[2] = hnd;
+            break;
+        default:
+            return BAD_INDEX;
+    }
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+
+Loader::entry_t::entry_t(int dpy, int impl, const char* tag)
+    : dpy(dpy), impl(impl), tag(tag) {
+}
+
+// ----------------------------------------------------------------------------
+
+Loader::Loader()
+{
+    char line[256];
+    char tag[256];
+    FILE* cfg = fopen("/system/lib/egl/egl.cfg", "r");
+    if (cfg == NULL) {
+        // default config
+        LOGD("egl.cfg not found, using default config");
+        gConfig.add( entry_t(0, 0, "android") );
+    } else {
+        while (fgets(line, 256, cfg)) {
+            int dpy;
+            int impl;
+            if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) {
+                //LOGD(">>> %u %u %s", dpy, impl, tag);
+                gConfig.add( entry_t(dpy, impl, tag) );
+            }
+        }
+        fclose(cfg);
+    }
+}
+
+Loader::~Loader()
+{
+}
+
+const char* Loader::getTag(int dpy, int impl)
+{
+    const Vector<entry_t>& cfgs(gConfig);    
+    const size_t c = cfgs.size();
+    for (size_t i=0 ; i<c ; i++) {
+        if (dpy == cfgs[i].dpy)
+            if (impl == cfgs[i].impl)
+                return cfgs[i].tag.string();
+    }
+    return 0;
+}
+
+void* Loader::open(EGLNativeDisplayType display, int impl, gl_hooks_t* hooks)
+{
+    /*
+     * TODO: if we don't find display/0, then use 0/0
+     * (0/0 should always work)
+     */
+    
+    void* dso;
+    char path[PATH_MAX];
+    int index = int(display);
+    driver_t* hnd = 0;
+    const char* const format = "/system/lib/egl/lib%s_%s.so";
+    
+    char const* tag = getTag(index, impl);
+    if (tag) {
+        snprintf(path, PATH_MAX, format, "GLES", tag);
+        dso = load_driver(path, hooks, EGL | GLESv1_CM | GLESv2);
+        if (dso) {
+            hnd = new driver_t(dso);
+        } else {
+            // Always load EGL first
+            snprintf(path, PATH_MAX, "lib%s_%s.so", "EGL", tag);
+            dso = load_driver(path, hooks, EGL);
+            if (dso) {
+                hnd = new driver_t(dso);
+
+                // TODO: make this more automated
+                snprintf(path, PATH_MAX, format, "GLESv1_CM", tag);
+                hnd->set( load_driver(path, hooks, GLESv1_CM), GLESv1_CM );
+
+                snprintf(path, PATH_MAX, format, "GLESv2", tag);
+                hnd->set( load_driver(path, hooks, GLESv2), GLESv2 );
+            }
+        }
+    }
+
+    LOG_FATAL_IF(!index && !impl && !hnd, 
+            "couldn't find the default OpenGL ES implementation "
+            "for default display");
+    
+    return (void*)hnd;
+}
+
+status_t Loader::close(void* driver)
+{
+    driver_t* hnd = (driver_t*)driver;
+    delete hnd;
+    return NO_ERROR;
+}
+
+void Loader::init_api(void* dso, 
+        char const * const * api, 
+        __eglMustCastToProperFunctionPointerType* curr, 
+        getProcAddressType getProcAddress) 
+{
+    char scrap[256];
+    while (*api) {
+        char const * name = *api;
+        __eglMustCastToProperFunctionPointerType f = 
+            (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
+        if (f == NULL) {
+            // couldn't find the entry-point, use eglGetProcAddress()
+            f = getProcAddress(name);
+        }
+        if (f == NULL) {
+            // Try without the OES postfix
+            ssize_t index = ssize_t(strlen(name)) - 3;
+            if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) {
+                strncpy(scrap, name, index);
+                scrap[index] = 0;
+                f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap);
+                //LOGD_IF(f, "found <%s> instead", scrap);
+            }
+        }
+        if (f == NULL) {
+            // Try with the OES postfix
+            ssize_t index = ssize_t(strlen(name)) - 3;
+            if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) {
+                strncpy(scrap, name, index);
+                scrap[index] = 0;
+                strcat(scrap, "OES");
+                f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap);
+                //LOGD_IF(f, "found <%s> instead", scrap);
+            }
+        }
+        if (f == NULL) {
+            //LOGD("%s", name);
+            f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented;
+        }
+        *curr++ = f;
+        api++;
+    }
+}
+
+void *Loader::load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask)
+{
+    //LOGD("%s", driver);
+    void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL);
+    LOGE_IF(!dso, "%s", dlerror());
+    if (dso == 0)
+        return 0;
+
+    if (mask & EGL) {
+        getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
+
+        LOGE_IF(!getProcAddress, 
+                "can't find eglGetProcAddress() in %s", driver);        
+
+        gl_hooks_t::egl_t* egl = &hooks->egl;
+        __eglMustCastToProperFunctionPointerType* curr =
+            (__eglMustCastToProperFunctionPointerType*)egl;
+        char const * const * api = egl_names;
+        while (*api) {
+            char const * name = *api;
+            __eglMustCastToProperFunctionPointerType f = 
+                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
+            if (f == NULL) {
+                // couldn't find the entry-point, use eglGetProcAddress()
+                f = getProcAddress(name);
+                if (f == NULL) {
+                    f = (__eglMustCastToProperFunctionPointerType)0;
+                }
+            }
+            *curr++ = f;
+            api++;
+        }
+    }
+    
+    if (mask & GLESv1_CM) {
+        init_api(dso, gl_names,  
+                (__eglMustCastToProperFunctionPointerType*)&hooks->gl, 
+                getProcAddress);
+    }
+
+    if (mask & GLESv2) {
+      init_api(dso, gl2_names, 
+            (__eglMustCastToProperFunctionPointerType*)&hooks->gl2, 
+            getProcAddress);
+    }
+    
+    return dso;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
new file mode 100644
index 0000000..69f6dd5
--- /dev/null
+++ b/opengl/libs/EGL/Loader.h
@@ -0,0 +1,90 @@
+/* 
+ ** Copyright 2009, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License"); 
+ ** you may not use this file except in compliance with the License. 
+ ** You may obtain a copy of the License at 
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0 
+ **
+ ** Unless required by applicable law or agreed to in writing, software 
+ ** distributed under the License is distributed on an "AS IS" BASIS, 
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ ** See the License for the specific language governing permissions and 
+ ** limitations under the License.
+ */
+
+#ifndef ANDROID_EGL_LOADER_H
+#define ANDROID_EGL_LOADER_H
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include <utils/Errors.h>
+#include <utils/Singleton.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include <EGL/egl.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+struct gl_hooks_t;
+
+class Loader : public Singleton<Loader>
+{
+    friend class Singleton<Loader>;
+
+    typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)(
+            const char*);
+   
+    enum {
+        EGL         = 0x01,
+        GLESv1_CM   = 0x02,
+        GLESv2      = 0x04
+    };
+    struct driver_t {
+        driver_t(void* gles);
+        ~driver_t();
+        status_t set(void* hnd, int32_t api);
+        void* dso[3];
+    };
+    
+    struct entry_t {
+        entry_t() { }
+        entry_t(int dpy, int impl, const char* tag);
+        int dpy;
+        int impl;
+        String8 tag;
+    };
+
+    Vector<entry_t> gConfig;    
+    getProcAddressType getProcAddress;
+    
+    const char* getTag(int dpy, int impl);
+
+public:
+    ~Loader();
+    
+    void* open(EGLNativeDisplayType display, int impl, gl_hooks_t* hooks);
+    status_t close(void* driver);
+    
+private:
+    Loader();
+    void *load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask);
+
+    static __attribute__((noinline))
+    void init_api(void* dso, 
+            char const * const * api, 
+            __eglMustCastToProperFunctionPointerType* curr, 
+            getProcAddressType getProcAddress); 
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+#endif /* ANDROID_EGL_LOADER_H */
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index c6e0f50..c2003dd 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -14,9 +14,8 @@
  ** limitations under the License.
  */
 
-#define LOG_TAG "libEGL"
-
 #include <ctype.h>
+#include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <dlfcn.h>
@@ -37,11 +36,9 @@
 #include <cutils/properties.h>
 #include <cutils/memory.h>
 
-#include <utils/RefBase.h>
-
 #include "hooks.h"
 #include "egl_impl.h"
-
+#include "Loader.h"
 
 #define MAKE_CONFIG(_impl, _index)  ((EGLConfig)(((_impl)<<24) | (_index)))
 #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r)
@@ -55,7 +52,16 @@
 static char const * const gVendorString     = "Android";
 static char const * const gVersionString    = "1.31 Android META-EGL";
 static char const * const gClientApiString  = "OpenGL ES";
-static char const * const gExtensionString  = "";
+static char const * const gExtensionString  = 
+        "EGL_KHR_image "
+        "EGL_KHR_image_base "
+        "EGL_KHR_image_pixmap "
+        "EGL_ANDROID_image_native_buffer "
+        "EGL_ANDROID_swap_rectangle "
+        "EGL_ANDROID_get_render_buffer "
+        ;
+
+// ----------------------------------------------------------------------------
 
 template <int MAGIC>
 struct egl_object_t
@@ -87,21 +93,15 @@
 struct egl_surface_t : public egl_object_t<'_srf'>
 {
     egl_surface_t(EGLDisplay dpy, EGLSurface surface,
-            NativeWindowType window, int impl, egl_connection_t const* cnx) 
-    : dpy(dpy), surface(surface), window(window), impl(impl), cnx(cnx)
+            int impl, egl_connection_t const* cnx) 
+    : dpy(dpy), surface(surface), impl(impl), cnx(cnx)
     {
         // NOTE: window must be incRef'ed and connected already
     }
     ~egl_surface_t() {
-        if (window) {
-            if (window->disconnect)
-                window->disconnect(window);
-            window->decRef(window);
-        }
     }
     EGLDisplay                  dpy;
     EGLSurface                  surface;
-    NativeWindowType            window;
     int                         impl;
     egl_connection_t const*     cnx;
 };
@@ -121,6 +121,18 @@
     egl_connection_t const*     cnx;
 };
 
+struct egl_image_t : public egl_object_t<'_img'>
+{
+    egl_image_t(EGLDisplay dpy, EGLContext context)
+        : dpy(dpy), context(context)
+    {
+        memset(images, 0, sizeof(images));
+    }
+    EGLDisplay dpy;
+    EGLConfig context;
+    EGLImageKHR images[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
+};
+
 struct tls_t
 {
     tls_t() : error(EGL_SUCCESS), ctx(0) { }
@@ -128,32 +140,6 @@
     EGLContext  ctx;
 };
 
-static void gl_unimplemented() {
-    LOGE("called unimplemented OpenGL ES API");
-}
-
-// ----------------------------------------------------------------------------
-// GL / EGL hooks
-// ----------------------------------------------------------------------------
-
-#undef GL_ENTRY
-#undef EGL_ENTRY
-#define GL_ENTRY(_r, _api, ...) #_api,
-#define EGL_ENTRY(_r, _api, ...) #_api,
-
-static char const * const gl_names[] = {
-    #include "gl_entries.in"
-    #include "glext_entries.in"
-    NULL
-};
-
-static char const * const egl_names[] = {
-    #include "egl_entries.in"
-    NULL
-};
-
-#undef GL_ENTRY
-#undef EGL_ENTRY
 
 // ----------------------------------------------------------------------------
 
@@ -262,110 +248,8 @@
     return tls->ctx;
 }
 
-
 /*****************************************************************************/
 
-class ISurfaceComposer;
-const sp<ISurfaceComposer>& getSurfaceFlinger();
-request_gpu_t* gpu_acquire(void* user);
-int gpu_release(void*, request_gpu_t* gpu);
-
-static __attribute__((noinline))
-void *load_driver(const char* driver, gl_hooks_t* hooks)
-{
-    //LOGD("%s", driver);
-    char scrap[256];
-    void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL);
-    LOGE_IF(!dso,
-            "couldn't load <%s> library (%s)",
-            driver, dlerror());
-
-    if (dso) {
-        // first find the symbol for eglGetProcAddress
-        
-        typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)(
-                const char*);
-        
-        getProcAddressType getProcAddress = 
-            (getProcAddressType)dlsym(dso, "eglGetProcAddress");
-        
-        LOGE_IF(!getProcAddress, 
-                "can't find eglGetProcAddress() in %s", driver);        
-        
-        __eglMustCastToProperFunctionPointerType* curr;
-        char const * const * api;
-
-        gl_hooks_t::egl_t* egl = &hooks->egl;
-        curr = (__eglMustCastToProperFunctionPointerType*)egl;
-        api = egl_names;
-        while (*api) {
-            char const * name = *api;
-            __eglMustCastToProperFunctionPointerType f = 
-                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
-            if (f == NULL) {
-                // couldn't find the entry-point, use eglGetProcAddress()
-                f = getProcAddress(name);
-                if (f == NULL) {
-                    f = (__eglMustCastToProperFunctionPointerType)0;
-                }
-            }
-            *curr++ = f;
-            api++;
-        }
-
-        gl_hooks_t::gl_t* gl = &hooks->gl;
-        curr = (__eglMustCastToProperFunctionPointerType*)gl;
-        api = gl_names;
-        while (*api) {
-            char const * name = *api;
-            __eglMustCastToProperFunctionPointerType f = 
-                (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
-            if (f == NULL) {
-                // couldn't find the entry-point, use eglGetProcAddress()
-                f = getProcAddress(name);
-            }
-            if (f == NULL) {
-                // Try without the OES postfix
-                ssize_t index = ssize_t(strlen(name)) - 3;
-                if ((index>0 && (index<255)) && (!strcmp(name+index, "OES"))) {
-                    strncpy(scrap, name, index);
-                    scrap[index] = 0;
-                    f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap);
-                    //LOGD_IF(f, "found <%s> instead", scrap);
-                }
-            }
-            if (f == NULL) {
-                // Try with the OES postfix
-                ssize_t index = ssize_t(strlen(name)) - 3;
-                if ((index>0 && (index<252)) && (strcmp(name+index, "OES"))) {
-                    strncpy(scrap, name, index);
-                    scrap[index] = 0;
-                    strcat(scrap, "OES");
-                    f = (__eglMustCastToProperFunctionPointerType)dlsym(dso, scrap);
-                    //LOGD_IF(f, "found <%s> instead", scrap);
-                }
-            }
-            if (f == NULL) {
-                //LOGD("%s", name);
-                f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented;
-            }
-            *curr++ = f;
-            api++;
-        }
-
-        // hook this driver up with surfaceflinger if needed
-        register_gpu_t register_gpu = 
-            (register_gpu_t)dlsym(dso, "oem_register_gpu");
-
-        if (register_gpu != NULL) {
-            if (getSurfaceFlinger() != 0) {
-                register_gpu(dso, gpu_acquire, gpu_release);
-            }
-        }
-    }
-    return dso;
-}
-
 template<typename T>
 static __attribute__((noinline))
 int binarySearch(
@@ -412,6 +296,18 @@
 };
 
 static const extention_map_t gExtentionMap[] = {
+    { "eglLockSurfaceKHR",  
+            (__eglMustCastToProperFunctionPointerType)&eglLockSurfaceKHR }, 
+    { "eglUnlockSurfaceKHR", 
+            (__eglMustCastToProperFunctionPointerType)&eglUnlockSurfaceKHR }, 
+    { "eglCreateImageKHR",  
+            (__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR }, 
+    { "eglDestroyImageKHR", 
+            (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
+    { "eglSetSwapRectangleANDROID", 
+            (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
+    { "eglGetRenderBufferANDROID", 
+            (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, 
 };
 
 static extention_map_t gGLExtentionMap[MAX_NUMBER_OF_GL_EXTENSIONS];
@@ -429,6 +325,12 @@
 
 // ----------------------------------------------------------------------------
 
+/*
+ * To "loose" the GPU, use something like
+ *    gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_CONTEXT_LOST];
+ * 
+ */
+
 static int gl_context_lost() {
     setGlThreadSpecific(&gHooks[IMPL_CONTEXT_LOST]);
     return 0;
@@ -491,6 +393,11 @@
     return egl_to_native_cast<egl_context_t>(context);
 }
 
+static inline
+egl_image_t* get_image(EGLImageKHR image) {
+    return egl_to_native_cast<egl_image_t>(image);
+}
+
 static egl_connection_t* validate_display_config(
         EGLDisplay dpy, EGLConfig config,
         egl_display_t const*& dp, int& impl, int& index)
@@ -540,6 +447,24 @@
 }
 
 
+EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image)
+{
+    EGLContext context = getContext();
+    if (context == EGL_NO_CONTEXT || image == EGL_NO_IMAGE_KHR)
+        return EGL_NO_IMAGE_KHR;
+    
+    egl_context_t const * const c = get_context(context);
+    if (!c->isValid())
+        return EGL_NO_IMAGE_KHR;
+
+    egl_image_t const * const i = get_image(image);
+    if (!i->isValid())
+        return EGL_NO_IMAGE_KHR;
+
+    return i->images[c->impl];
+}
+
+
 EGLDisplay egl_init_displays(NativeDisplayType display)
 {
     if (sEarlyInitState) {
@@ -554,12 +479,15 @@
     EGLDisplay dpy = EGLDisplay(uintptr_t(display) + 1LU);
     egl_display_t* d = &gDisplay[index];
 
+    // get our driver loader
+    Loader& loader(Loader::getInstance());    
+    
     // dynamically load all our EGL implementations for that display
     // and call into the real eglGetGisplay()
     egl_connection_t* cnx = &gEGLImpl[IMPL_SOFTWARE];
     if (cnx->dso == 0) {
         cnx->hooks = &gHooks[IMPL_SOFTWARE];
-        cnx->dso = load_driver("libagl.so", cnx->hooks);
+        cnx->dso = loader.open(display, 0, cnx->hooks);
     }
     if (cnx->dso && d->dpys[IMPL_SOFTWARE]==EGL_NO_DISPLAY) {
         d->dpys[IMPL_SOFTWARE] = cnx->hooks->egl.eglGetDisplay(display);
@@ -573,7 +501,7 @@
         property_get("debug.egl.hw", value, "1");
         if (atoi(value) != 0) {
             cnx->hooks = &gHooks[IMPL_HARDWARE];
-            cnx->dso = load_driver("libhgl.so", cnx->hooks);
+            cnx->dso = loader.open(display, 1, cnx->hooks);
         } else {
             LOGD("3D hardware acceleration is disabled");
         }
@@ -605,7 +533,8 @@
         if (d->dpys[IMPL_HARDWARE] == EGL_NO_DISPLAY) {
             LOGE("h/w accelerated eglGetDisplay() failed (%s)",
                     egl_strerror(cnx->hooks->egl.eglGetError()));
-            dlclose((void*)cnx->dso);
+            
+            loader.close(cnx->dso);
             cnx->dso = 0;
             // in case of failure, we want to make sure we don't try again
             // as it's expensive.
@@ -717,6 +646,8 @@
     if (android_atomic_dec(&dp->refs) != 1)
         return EGL_TRUE;
         
+    Loader& loader(Loader::getInstance());    
+
     EGLBoolean res = EGL_FALSE;
     for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
@@ -732,7 +663,8 @@
             free((void*)dp->queryString[i].extensions);
             dp->numConfigs[i] = 0;
             dp->dpys[i] = EGL_NO_DISPLAY;
-            dlclose((void*)cnx->dso);
+
+            loader.close(cnx->dso);
             cnx->dso = 0;
             res = EGL_TRUE;
         }
@@ -909,26 +841,12 @@
     int i=0, index=0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
     if (cnx) {
-        // window must be connected upon calling underlying
-        // eglCreateWindowSurface
-        if (window) {
-            window->incRef(window);
-            if (window->connect)
-                window->connect(window);
-        }
-
         EGLSurface surface = cnx->hooks->egl.eglCreateWindowSurface(
                 dp->dpys[i], dp->configs[i][index], window, attrib_list);       
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, window, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
             return s;
         }
-        
-        // something went wrong, disconnect and free window
-        // (will disconnect() automatically)
-        if (window) {
-            window->decRef(window);
-        }        
     }
     return EGL_NO_SURFACE;
 }
@@ -944,7 +862,7 @@
         EGLSurface surface = cnx->hooks->egl.eglCreatePixmapSurface(
                 dp->dpys[i], dp->configs[i][index], pixmap, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, NULL, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
             return s;
         }
     }
@@ -961,7 +879,7 @@
         EGLSurface surface = cnx->hooks->egl.eglCreatePbufferSurface(
                 dp->dpys[i], dp->configs[i][index], attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, NULL, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
             return s;
         }
     }
@@ -1430,3 +1348,156 @@
     }
     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
 }
+
+// ----------------------------------------------------------------------------
+// EGL_EGLEXT_VERSION 3
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
+        const EGLint *attrib_list)
+{
+    EGLBoolean result = EGL_FALSE;
+    if (!validate_display_surface(dpy, surface))
+        return result;
+
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+
+    if (s->cnx->hooks->egl.eglLockSurfaceKHR) {
+        result = s->cnx->hooks->egl.eglLockSurfaceKHR(
+                dp->dpys[s->impl], s->surface, attrib_list);
+    }
+    return result;
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
+{
+    EGLBoolean result = EGL_FALSE;
+    if (!validate_display_surface(dpy, surface))
+        return result;
+
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(surface);
+
+    if (s->cnx->hooks->egl.eglUnlockSurfaceKHR) {
+        result = s->cnx->hooks->egl.eglUnlockSurfaceKHR(
+                dp->dpys[s->impl], s->surface);
+    }
+    return result;
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+        EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+    if (ctx != EGL_NO_CONTEXT) {
+        if (!validate_display_context(dpy, ctx))
+            return EGL_NO_IMAGE_KHR;
+        egl_display_t const * const dp = get_display(dpy);
+        egl_context_t * const c = get_context(ctx);
+        // since we have an EGLContext, we know which implementation to use
+        EGLImageKHR image = c->cnx->hooks->egl.eglCreateImageKHR(
+                dp->dpys[c->impl], c->context, target, buffer, attrib_list);
+        if (image == EGL_NO_IMAGE_KHR)
+            return image;
+            
+        egl_image_t* result = new egl_image_t(dpy, ctx);
+        result->images[c->impl] = image;
+        return (EGLImageKHR)result;
+    } else {
+        // EGL_NO_CONTEXT is a valid parameter
+        egl_display_t const * const dp = get_display(dpy);
+        if (dp == 0) {
+            return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
+        }
+        // since we don't have a way to know which implementation to call,
+        // we're calling all of them
+
+        EGLImageKHR implImages[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
+        bool success = false;
+        for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
+            egl_connection_t* const cnx = &gEGLImpl[i];
+            implImages[i] = EGL_NO_IMAGE_KHR;
+            if (cnx->dso) {
+                if (cnx->hooks->egl.eglCreateImageKHR) {
+                    implImages[i] = cnx->hooks->egl.eglCreateImageKHR(
+                            dp->dpys[i], ctx, target, buffer, attrib_list);
+                    if (implImages[i] != EGL_NO_IMAGE_KHR) {
+                        success = true;
+                    }
+                }
+            }
+        }
+        if (!success)
+            return EGL_NO_IMAGE_KHR;
+        
+        egl_image_t* result = new egl_image_t(dpy, ctx);
+        memcpy(result->images, implImages, sizeof(implImages));
+        return (EGLImageKHR)result;
+    }
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
+{
+     egl_display_t const * const dp = get_display(dpy);
+     if (dp == 0) {
+         return setError(EGL_BAD_DISPLAY, EGL_FALSE);
+     }
+
+     egl_image_t* image = get_image(img);
+     if (!image->isValid()) {
+         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+     }
+
+     bool success = false;
+     for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
+         egl_connection_t* const cnx = &gEGLImpl[i];
+         if (image->images[i] != EGL_NO_IMAGE_KHR) {
+             if (cnx->dso) {
+                 if (cnx->hooks->egl.eglCreateImageKHR) {
+                     if (cnx->hooks->egl.eglDestroyImageKHR(
+                             dp->dpys[i], image->images[i])) {
+                         success = true;
+                     }
+                 }
+             }
+         }
+     }
+     if (!success)
+         return EGL_FALSE;
+
+     delete image;
+
+     return EGL_FALSE;
+}
+
+
+// ----------------------------------------------------------------------------
+// ANDROID extensions
+// ----------------------------------------------------------------------------
+
+EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
+        EGLint left, EGLint top, EGLint width, EGLint height)
+{
+    if (!validate_display_surface(dpy, draw))
+        return EGL_FALSE;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(draw);
+    if (s->cnx->hooks->egl.eglSetSwapRectangleANDROID) {
+        return s->cnx->hooks->egl.eglSetSwapRectangleANDROID(dp->dpys[s->impl],
+                s->surface, left, top, width, height);
+    }
+    return EGL_FALSE;
+}
+
+EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw)
+{
+    if (!validate_display_surface(dpy, draw))
+        return 0;    
+    egl_display_t const * const dp = get_display(dpy);
+    egl_surface_t const * const s = get_surface(draw);
+    if (s->cnx->hooks->egl.eglGetRenderBufferANDROID) {
+        return s->cnx->hooks->egl.eglGetRenderBufferANDROID(dp->dpys[s->impl],
+                s->surface);
+    }
+    return 0;
+}
diff --git a/opengl/libs/egl_entries.in b/opengl/libs/EGL/egl_entries.in
similarity index 92%
rename from opengl/libs/egl_entries.in
rename to opengl/libs/EGL/egl_entries.in
index 3b4551b..5d89287 100644
--- a/opengl/libs/egl_entries.in
+++ b/opengl/libs/EGL/egl_entries.in
@@ -50,3 +50,8 @@
 EGL_ENTRY(EGLBoolean,  eglUnlockSurfaceKHR, EGLDisplay, EGLSurface)
 EGL_ENTRY(EGLImageKHR, eglCreateImageKHR,   EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *)
 EGL_ENTRY(EGLBoolean,  eglDestroyImageKHR,  EGLDisplay, EGLImageKHR)
+
+/* ANDROID extensions */
+
+EGL_ENTRY(EGLBoolean, eglSetSwapRectangleANDROID, EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint)
+EGL_ENTRY(EGLClientBuffer, eglGetRenderBufferANDROID, EGLDisplay, EGLSurface)
diff --git a/opengl/libs/EGL/gpu.cpp b/opengl/libs/EGL/gpu.cpp
deleted file mode 100644
index 4c902c8..0000000
--- a/opengl/libs/EGL/gpu.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/* 
- ** Copyright 2007, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License"); 
- ** you may not use this file except in compliance with the License. 
- ** You may obtain a copy of the License at 
- **
- **     http://www.apache.org/licenses/LICENSE-2.0 
- **
- ** Unless required by applicable law or agreed to in writing, software 
- ** distributed under the License is distributed on an "AS IS" BASIS, 
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
- ** See the License for the specific language governing permissions and 
- ** limitations under the License.
- */
-
-#define LOG_TAG "EGL"
-
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-
-#include <sys/ioctl.h>
-
-#if HAVE_ANDROID_OS
-#include <linux/android_pmem.h>
-#endif
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-#include <utils/IMemory.h>
-#include <utils/threads.h>
-#include <utils/IServiceManager.h>
-#include <utils/IPCThreadState.h>
-#include <utils/Parcel.h>
-
-#include <ui/EGLDisplaySurface.h>
-#include <ui/ISurfaceComposer.h>
-
-#include "hooks.h"
-#include "egl_impl.h"
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-/*
- * we provide our own allocators for the GPU regions, these
- * allocators go through surfaceflinger 
- */
-
-static Mutex                            gRegionsLock;
-static request_gpu_t                    gRegions;
-static sp<ISurfaceComposer>             gSurfaceManager;
-GL_API ISurfaceComposer*                GLES_localSurfaceManager = 0;
-
-extern egl_connection_t gEGLImpl[2];
-
-const sp<ISurfaceComposer>& getSurfaceFlinger()
-{
-    Mutex::Autolock _l(gRegionsLock);
-
-    /*
-     * There is a little bit of voodoo magic here. We want to access
-     * surfaceflinger for allocating GPU regions, however, when we are
-     * running as part of surfaceflinger, we want to bypass the
-     * service manager because surfaceflinger might not be registered yet.
-     * SurfaceFlinger will populate "GLES_localSurfaceManager" with its
-     * own address, so we can just use that.
-     */
-    if (gSurfaceManager == 0) {
-        if (GLES_localSurfaceManager) {
-            // we're running in SurfaceFlinger's context
-            gSurfaceManager =  GLES_localSurfaceManager;
-        } else {
-            // we're a remote process or not part of surfaceflinger,
-            // go through the service manager
-            sp<IServiceManager> sm = defaultServiceManager();
-            if (sm != NULL) {
-                sp<IBinder> binder = sm->getService(String16("SurfaceFlinger"));
-                gSurfaceManager = interface_cast<ISurfaceComposer>(binder);
-            }
-        }
-    }
-    return gSurfaceManager;
-}
-
-class GPURevokeRequester : public BnGPUCallback
-{
-public:
-    virtual void gpuLost() {
-        LOGD("CONTEXT_LOST: Releasing GPU upon request from SurfaceFlinger.");
-        gEGLImpl[IMPL_HARDWARE].hooks = &gHooks[IMPL_CONTEXT_LOST];
-    }
-};
-
-static sp<GPURevokeRequester> gRevokerCallback;
-
-
-request_gpu_t* gpu_acquire(void* user)
-{
-    sp<ISurfaceComposer> server( getSurfaceFlinger() );
-
-    Mutex::Autolock _l(gRegionsLock);
-    if (server == NULL) {
-        return 0;
-    }
-    
-    ISurfaceComposer::gpu_info_t info;
-    
-    if (gRevokerCallback == 0)
-        gRevokerCallback = new GPURevokeRequester();
-
-    status_t err = server->requestGPU(gRevokerCallback, &info);
-    if (err != NO_ERROR) {
-        LOGD("requestGPU returned %d", err);
-        return 0;
-    }
-
-    if (info.regs == 0) {
-        LOGD("requestGPU() failed");
-        return 0;
-    }
-
-    bool failed = false;
-    request_gpu_t* gpu = &gRegions;
-    memset(gpu, 0, sizeof(*gpu));
-    
-    if (info.regs != 0) {
-        sp<IMemoryHeap> heap(info.regs->getMemory());
-        if (heap != 0) {
-            int fd = heap->heapID();
-            gpu->regs.fd = fd;
-            gpu->regs.base = info.regs->pointer(); 
-            gpu->regs.size = info.regs->size(); 
-            gpu->regs.user = info.regs.get();
-#if HAVE_ANDROID_OS
-            struct pmem_region region;
-            if (ioctl(fd, PMEM_GET_PHYS, &region) >= 0)
-                gpu->regs.phys = (void*)region.offset;
-#endif
-            info.regs->incStrong(gpu);
-        } else {
-            LOGE("GPU register handle %p is invalid!", info.regs.get());
-            failed = true;
-        }
-    }
-
-    for (size_t i=0 ; i<info.count && !failed ; i++) {
-        sp<IMemory>& region(info.regions[i].region);
-        if (region != 0) {
-            sp<IMemoryHeap> heap(region->getMemory());
-            if (heap != 0) {
-                const int fd = heap->heapID();
-                gpu->gpu[i].fd = fd;
-                gpu->gpu[i].base = region->pointer(); 
-                gpu->gpu[i].size = region->size(); 
-                gpu->gpu[i].user = region.get();
-                gpu->gpu[i].offset = info.regions[i].reserved;
-#if HAVE_ANDROID_OS
-                struct pmem_region reg;
-                if (ioctl(fd, PMEM_GET_PHYS, &reg) >= 0)
-                    gpu->gpu[i].phys = (void*)reg.offset;
-#endif
-                region->incStrong(gpu);
-            } else {
-                LOGE("GPU region handle [%d, %p] is invalid!", i, region.get());
-                failed = true;
-            }
-        }
-    }
-    
-    if (failed) {
-        // something went wrong, clean up everything!
-        if (gpu->regs.user) {
-            static_cast<IMemory*>(gpu->regs.user)->decStrong(gpu);
-            for (size_t i=0 ; i<info.count ; i++) {
-                if (gpu->gpu[i].user) {
-                    static_cast<IMemory*>(gpu->gpu[i].user)->decStrong(gpu);
-                }
-            }
-        }
-    }
-    
-    gpu->count = info.count;
-    return gpu;
-}
-
-int gpu_release(void*, request_gpu_t* gpu)
-{
-    sp<IMemory> regs;
-
-    { // scope for lock
-        Mutex::Autolock _l(gRegionsLock);
-        regs = static_cast<IMemory*>(gpu->regs.user);   
-        gpu->regs.user = 0;
-        if (regs != 0) regs->decStrong(gpu);
-        
-        for (int i=0 ; i<gpu->count ; i++) {
-            sp<IMemory> r(static_cast<IMemory*>(gpu->gpu[i].user));
-            gpu->gpu[i].user = 0;
-            if (r != 0) r->decStrong(gpu);
-        }
-    }
-    
-    // there is a special transaction to relinquish the GPU
-    // (it will happen automatically anyway if we don't do this)
-    Parcel data, reply;
-    // NOTE: this transaction does not require an interface token
-    regs->asBinder()->transact(1000, data, &reply);
-    return 1;
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/hooks.cpp b/opengl/libs/EGL/hooks.cpp
new file mode 100644
index 0000000..2246366
--- /dev/null
+++ b/opengl/libs/EGL/hooks.cpp
@@ -0,0 +1,67 @@
+/* 
+ ** Copyright 2009, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License"); 
+ ** you may not use this file except in compliance with the License. 
+ ** You may obtain a copy of the License at 
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0 
+ **
+ ** Unless required by applicable law or agreed to in writing, software 
+ ** distributed under the License is distributed on an "AS IS" BASIS, 
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ ** See the License for the specific language governing permissions and 
+ ** limitations under the License.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <cutils/log.h>
+
+#include "hooks.h"
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+void gl_unimplemented() {
+    LOGE("called unimplemented OpenGL ES API");
+}
+
+
+// ----------------------------------------------------------------------------
+// GL / EGL hooks
+// ----------------------------------------------------------------------------
+
+#undef GL_ENTRY
+#undef EGL_ENTRY
+#define GL_ENTRY(_r, _api, ...) #_api,
+#define EGL_ENTRY(_r, _api, ...) #_api,
+
+char const * const gl_names[] = {
+    #include "GLES_CM/gl_entries.in"
+    #include "GLES_CM/glext_entries.in"
+    NULL
+};
+
+char const * const gl2_names[] = {
+    #include "GLES2/gl2_entries.in"
+    #include "GLES2/gl2ext_entries.in"
+    NULL
+};
+
+char const * const egl_names[] = {
+    #include "egl_entries.in"
+    NULL
+};
+
+#undef GL_ENTRY
+#undef EGL_ENTRY
+
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
new file mode 100644
index 0000000..e5358c3
--- /dev/null
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -0,0 +1,111 @@
+/* 
+ ** Copyright 2007, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License"); 
+ ** you may not use this file except in compliance with the License. 
+ ** You may obtain a copy of the License at 
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0 
+ **
+ ** Unless required by applicable law or agreed to in writing, software 
+ ** distributed under the License is distributed on an "AS IS" BASIS, 
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ ** See the License for the specific language governing permissions and 
+ ** limitations under the License.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/ioctl.h>
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include "hooks.h"
+#include "egl_impl.h"
+
+using namespace android;
+
+// ----------------------------------------------------------------------------
+// Actual GL entry-points
+// ----------------------------------------------------------------------------
+
+#undef API_ENTRY
+#undef CALL_GL_API
+#undef CALL_GL_API_RETURN
+
+#if USE_FAST_TLS_KEY
+
+    #define API_ENTRY(_api) __attribute__((naked)) _api
+
+    #define CALL_GL_API(_api, ...)                              \
+         asm volatile(                                          \
+            "mov   r12, #0xFFFF0FFF   \n"                       \
+            "ldr   r12, [r12, #-15]   \n"                       \
+            "ldr   r12, [r12, %[tls]] \n"                       \
+            "cmp   r12, #0            \n"                       \
+            "ldrne pc,  [r12, %[api]] \n"                       \
+            "bx    lr                 \n"                       \
+            :                                                   \
+            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
+              [api] "J"(__builtin_offsetof(gl_hooks_t, gl2._api))    \
+            :                                                   \
+            );
+    
+    #define CALL_GL_API_RETURN(_api, ...) \
+        CALL_GL_API(_api, __VA_ARGS__) \
+        return 0; // placate gcc's warnings. never reached.
+
+#else
+
+    #define API_ENTRY(_api) _api
+
+    #define CALL_GL_API(_api, ...)                                       \
+        gl_hooks_t::gl2_t const * const _c = &getGlThreadSpecific()->gl2; \
+        _c->_api(__VA_ARGS__)
+    
+    #define CALL_GL_API_RETURN(_api, ...)                                \
+        gl_hooks_t::gl2_t const * const _c = &getGlThreadSpecific()->gl2; \
+        return _c->_api(__VA_ARGS__)
+
+#endif
+
+
+extern "C" {
+#include "gl2_api.in"
+#include "gl2ext_api.in"
+}
+
+#undef API_ENTRY
+#undef CALL_GL_API
+#undef CALL_GL_API_RETURN
+
+
+/*
+ * These GL calls are special because they need to EGL to retrieve some
+ * informations before they can execute.
+ */
+
+extern "C" void __glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+extern "C" void __glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+    GLeglImageOES implImage = 
+        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
+    __glEGLImageTargetTexture2DOES(target, implImage);
+}
+
+void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+    GLeglImageOES implImage = 
+        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
+    __glEGLImageTargetRenderbufferStorageOES(target, image);
+}
+
diff --git a/opengl/libs/GLES2/gl2_api.in b/opengl/libs/GLES2/gl2_api.in
new file mode 100644
index 0000000..9c2e69a
--- /dev/null
+++ b/opengl/libs/GLES2/gl2_api.in
@@ -0,0 +1,426 @@
+void API_ENTRY(glActiveTexture)(GLenum texture) {
+    CALL_GL_API(glActiveTexture, texture);
+}
+void API_ENTRY(glAttachShader)(GLuint program, GLuint shader) {
+    CALL_GL_API(glAttachShader, program, shader);
+}
+void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const char* name) {
+    CALL_GL_API(glBindAttribLocation, program, index, name);
+}
+void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
+    CALL_GL_API(glBindBuffer, target, buffer);
+}
+void API_ENTRY(glBindFramebuffer)(GLenum target, GLuint framebuffer) {
+    CALL_GL_API(glBindFramebuffer, target, framebuffer);
+}
+void API_ENTRY(glBindRenderbuffer)(GLenum target, GLuint renderbuffer) {
+    CALL_GL_API(glBindRenderbuffer, target, renderbuffer);
+}
+void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
+    CALL_GL_API(glBindTexture, target, texture);
+}
+void API_ENTRY(glBlendColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+    CALL_GL_API(glBlendColor, red, green, blue, alpha);
+}
+void API_ENTRY(glBlendEquation)( GLenum mode ) {
+    CALL_GL_API(glBlendEquation, mode);
+}
+void API_ENTRY(glBlendEquationSeparate)(GLenum modeRGB, GLenum modeAlpha) {
+    CALL_GL_API(glBlendEquationSeparate, modeRGB, modeAlpha);
+}
+void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
+    CALL_GL_API(glBlendFunc, sfactor, dfactor);
+}
+void API_ENTRY(glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
+    CALL_GL_API(glBlendFuncSeparate, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
+    CALL_GL_API(glBufferData, target, size, data, usage);
+}
+void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
+    CALL_GL_API(glBufferSubData, target, offset, size, data);
+}
+GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target) {
+    CALL_GL_API_RETURN(glCheckFramebufferStatus, target);
+}
+void API_ENTRY(glClear)(GLbitfield mask) {
+    CALL_GL_API(glClear, mask);
+}
+void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+    CALL_GL_API(glClearColor, red, green, blue, alpha);
+}
+void API_ENTRY(glClearDepthf)(GLclampf depth) {
+    CALL_GL_API(glClearDepthf, depth);
+}
+void API_ENTRY(glClearStencil)(GLint s) {
+    CALL_GL_API(glClearStencil, s);
+}
+void API_ENTRY(glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
+    CALL_GL_API(glColorMask, red, green, blue, alpha);
+}
+void API_ENTRY(glCompileShader)(GLuint shader) {
+    CALL_GL_API(glCompileShader, shader);
+}
+void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) {
+    CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
+}
+void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) {
+    CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+void API_ENTRY(glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
+    CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y, width, height, border);
+}
+void API_ENTRY(glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
+    CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y, width, height);
+}
+GLuint API_ENTRY(glCreateProgram)(void) {
+    CALL_GL_API_RETURN(glCreateProgram);
+}
+GLuint API_ENTRY(glCreateShader)(GLenum type) {
+    CALL_GL_API_RETURN(glCreateShader, type);
+}
+void API_ENTRY(glCullFace)(GLenum mode) {
+    CALL_GL_API(glCullFace, mode);
+}
+void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint* buffers) {
+    CALL_GL_API(glDeleteBuffers, n, buffers);
+}
+void API_ENTRY(glDeleteFramebuffers)(GLsizei n, const GLuint* framebuffers) {
+    CALL_GL_API(glDeleteFramebuffers, n, framebuffers);
+}
+void API_ENTRY(glDeleteProgram)(GLuint program) {
+    CALL_GL_API(glDeleteProgram, program);
+}
+void API_ENTRY(glDeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers) {
+    CALL_GL_API(glDeleteRenderbuffers, n, renderbuffers);
+}
+void API_ENTRY(glDeleteShader)(GLuint shader) {
+    CALL_GL_API(glDeleteShader, shader);
+}
+void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint* textures) {
+    CALL_GL_API(glDeleteTextures, n, textures);
+}
+void API_ENTRY(glDepthFunc)(GLenum func) {
+    CALL_GL_API(glDepthFunc, func);
+}
+void API_ENTRY(glDepthMask)(GLboolean flag) {
+    CALL_GL_API(glDepthMask, flag);
+}
+void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) {
+    CALL_GL_API(glDepthRangef, zNear, zFar);
+}
+void API_ENTRY(glDetachShader)(GLuint program, GLuint shader) {
+    CALL_GL_API(glDetachShader, program, shader);
+}
+void API_ENTRY(glDisable)(GLenum cap) {
+    CALL_GL_API(glDisable, cap);
+}
+void API_ENTRY(glDisableVertexAttribArray)(GLuint index) {
+    CALL_GL_API(glDisableVertexAttribArray, index);
+}
+void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
+    CALL_GL_API(glDrawArrays, mode, first, count);
+}
+void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const void* indices) {
+    CALL_GL_API(glDrawElements, mode, count, type, indices);
+}
+void API_ENTRY(glEnable)(GLenum cap) {
+    CALL_GL_API(glEnable, cap);
+}
+void API_ENTRY(glEnableVertexAttribArray)(GLuint index) {
+    CALL_GL_API(glEnableVertexAttribArray, index);
+}
+void API_ENTRY(glFinish)(void) {
+    CALL_GL_API(glFinish);
+}
+void API_ENTRY(glFlush)(void) {
+    CALL_GL_API(glFlush);
+}
+void API_ENTRY(glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
+    CALL_GL_API(glFramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer);
+}
+void API_ENTRY(glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
+    CALL_GL_API(glFramebufferTexture2D, target, attachment, textarget, texture, level);
+}
+void API_ENTRY(glFrontFace)(GLenum mode) {
+    CALL_GL_API(glFrontFace, mode);
+}
+void API_ENTRY(glGenBuffers)(GLsizei n, GLuint* buffers) {
+    CALL_GL_API(glGenBuffers, n, buffers);
+}
+void API_ENTRY(glGenerateMipmap)(GLenum target) {
+    CALL_GL_API(glGenerateMipmap, target);
+}
+void API_ENTRY(glGenFramebuffers)(GLsizei n, GLuint* framebuffers) {
+    CALL_GL_API(glGenFramebuffers, n, framebuffers);
+}
+void API_ENTRY(glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers) {
+    CALL_GL_API(glGenRenderbuffers, n, renderbuffers);
+}
+void API_ENTRY(glGenTextures)(GLsizei n, GLuint* textures) {
+    CALL_GL_API(glGenTextures, n, textures);
+}
+void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) {
+    CALL_GL_API(glGetActiveAttrib, program, index, bufsize, length, size, type, name);
+}
+void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) {
+    CALL_GL_API(glGetActiveUniform, program, index, bufsize, length, size, type, name);
+}
+void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) {
+    CALL_GL_API(glGetAttachedShaders, program, maxcount, count, shaders);
+}
+int API_ENTRY(glGetAttribLocation)(GLuint program, const char* name) {
+    CALL_GL_API_RETURN(glGetAttribLocation, program, name);
+}
+void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean* params) {
+    CALL_GL_API(glGetBooleanv, pname, params);
+}
+void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params) {
+    CALL_GL_API(glGetBufferParameteriv, target, pname, params);
+}
+GLenum API_ENTRY(glGetError)(void) {
+    CALL_GL_API_RETURN(glGetError);
+}
+void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat* params) {
+    CALL_GL_API(glGetFloatv, pname, params);
+}
+void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params) {
+    CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params);
+}
+void API_ENTRY(glGetIntegerv)(GLenum pname, GLint* params) {
+    CALL_GL_API(glGetIntegerv, pname, params);
+}
+void API_ENTRY(glGetProgramiv)(GLuint program, GLenum pname, GLint* params) {
+    CALL_GL_API(glGetProgramiv, program, pname, params);
+}
+void API_ENTRY(glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) {
+    CALL_GL_API(glGetProgramInfoLog, program, bufsize, length, infolog);
+}
+void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params) {
+    CALL_GL_API(glGetRenderbufferParameteriv, target, pname, params);
+}
+void API_ENTRY(glGetShaderiv)(GLuint shader, GLenum pname, GLint* params) {
+    CALL_GL_API(glGetShaderiv, shader, pname, params);
+}
+void API_ENTRY(glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) {
+    CALL_GL_API(glGetShaderInfoLog, shader, bufsize, length, infolog);
+}
+void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
+    CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision);
+}
+void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source) {
+    CALL_GL_API(glGetShaderSource, shader, bufsize, length, source);
+}
+const GLubyte* API_ENTRY(glGetString)(GLenum name) {
+    CALL_GL_API_RETURN(glGetString, name);
+}
+void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params) {
+    CALL_GL_API(glGetTexParameterfv, target, pname, params);
+}
+void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint* params) {
+    CALL_GL_API(glGetTexParameteriv, target, pname, params);
+}
+void API_ENTRY(glGetUniformfv)(GLuint program, GLint location, GLfloat* params) {
+    CALL_GL_API(glGetUniformfv, program, location, params);
+}
+void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint* params) {
+    CALL_GL_API(glGetUniformiv, program, location, params);
+}
+int API_ENTRY(glGetUniformLocation)(GLuint program, const char* name) {
+    CALL_GL_API_RETURN(glGetUniformLocation, program, name);
+}
+void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params) {
+    CALL_GL_API(glGetVertexAttribfv, index, pname, params);
+}
+void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params) {
+    CALL_GL_API(glGetVertexAttribiv, index, pname, params);
+}
+void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer) {
+    CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer);
+}
+void API_ENTRY(glHint)(GLenum target, GLenum mode) {
+    CALL_GL_API(glHint, target, mode);
+}
+GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) {
+    CALL_GL_API_RETURN(glIsBuffer, buffer);
+}
+GLboolean API_ENTRY(glIsEnabled)(GLenum cap) {
+    CALL_GL_API_RETURN(glIsEnabled, cap);
+}
+GLboolean API_ENTRY(glIsFramebuffer)(GLuint framebuffer) {
+    CALL_GL_API_RETURN(glIsFramebuffer, framebuffer);
+}
+GLboolean API_ENTRY(glIsProgram)(GLuint program) {
+    CALL_GL_API_RETURN(glIsProgram, program);
+}
+GLboolean API_ENTRY(glIsRenderbuffer)(GLuint renderbuffer) {
+    CALL_GL_API_RETURN(glIsRenderbuffer, renderbuffer);
+}
+GLboolean API_ENTRY(glIsShader)(GLuint shader) {
+    CALL_GL_API_RETURN(glIsShader, shader);
+}
+GLboolean API_ENTRY(glIsTexture)(GLuint texture) {
+    CALL_GL_API_RETURN(glIsTexture, texture);
+}
+void API_ENTRY(glLineWidth)(GLfloat width) {
+    CALL_GL_API(glLineWidth, width);
+}
+void API_ENTRY(glLinkProgram)(GLuint program) {
+    CALL_GL_API(glLinkProgram, program);
+}
+void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
+    CALL_GL_API(glPixelStorei, pname, param);
+}
+void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
+    CALL_GL_API(glPolygonOffset, factor, units);
+}
+void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
+    CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
+}
+void API_ENTRY(glReleaseShaderCompiler)(void) {
+    CALL_GL_API(glReleaseShaderCompiler);
+}
+void API_ENTRY(glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
+    CALL_GL_API(glRenderbufferStorage, target, internalformat, width, height);
+}
+void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) {
+    CALL_GL_API(glSampleCoverage, value, invert);
+}
+void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
+    CALL_GL_API(glScissor, x, y, width, height);
+}
+void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) {
+    CALL_GL_API(glShaderBinary, n, shaders, binaryformat, binary, length);
+}
+void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length) {
+    CALL_GL_API(glShaderSource, shader, count, string, length);
+}
+void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
+    CALL_GL_API(glStencilFunc, func, ref, mask);
+}
+void API_ENTRY(glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask) {
+    CALL_GL_API(glStencilFuncSeparate, face, func, ref, mask);
+}
+void API_ENTRY(glStencilMask)(GLuint mask) {
+    CALL_GL_API(glStencilMask, mask);
+}
+void API_ENTRY(glStencilMaskSeparate)(GLenum face, GLuint mask) {
+    CALL_GL_API(glStencilMaskSeparate, face, mask);
+}
+void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
+    CALL_GL_API(glStencilOp, fail, zfail, zpass);
+}
+void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
+    CALL_GL_API(glStencilOpSeparate, face, fail, zfail, zpass);
+}
+void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat,  GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
+    CALL_GL_API(glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels);
+}
+void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
+    CALL_GL_API(glTexParameterf, target, pname, param);
+}
+void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat* params) {
+    CALL_GL_API(glTexParameterfv, target, pname, params);
+}
+void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) {
+    CALL_GL_API(glTexParameteri, target, pname, param);
+}
+void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint* params) {
+    CALL_GL_API(glTexParameteriv, target, pname, params);
+}
+void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) {
+    CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+void API_ENTRY(glUniform1f)(GLint location, GLfloat x) {
+    CALL_GL_API(glUniform1f, location, x);
+}
+void API_ENTRY(glUniform1fv)(GLint location, GLsizei count, const GLfloat* v) {
+    CALL_GL_API(glUniform1fv, location, count, v);
+}
+void API_ENTRY(glUniform1i)(GLint location, GLint x) {
+    CALL_GL_API(glUniform1i, location, x);
+}
+void API_ENTRY(glUniform1iv)(GLint location, GLsizei count, const GLint* v) {
+    CALL_GL_API(glUniform1iv, location, count, v);
+}
+void API_ENTRY(glUniform2f)(GLint location, GLfloat x, GLfloat y) {
+    CALL_GL_API(glUniform2f, location, x, y);
+}
+void API_ENTRY(glUniform2fv)(GLint location, GLsizei count, const GLfloat* v) {
+    CALL_GL_API(glUniform2fv, location, count, v);
+}
+void API_ENTRY(glUniform2i)(GLint location, GLint x, GLint y) {
+    CALL_GL_API(glUniform2i, location, x, y);
+}
+void API_ENTRY(glUniform2iv)(GLint location, GLsizei count, const GLint* v) {
+    CALL_GL_API(glUniform2iv, location, count, v);
+}
+void API_ENTRY(glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z) {
+    CALL_GL_API(glUniform3f, location, x, y, z);
+}
+void API_ENTRY(glUniform3fv)(GLint location, GLsizei count, const GLfloat* v) {
+    CALL_GL_API(glUniform3fv, location, count, v);
+}
+void API_ENTRY(glUniform3i)(GLint location, GLint x, GLint y, GLint z) {
+    CALL_GL_API(glUniform3i, location, x, y, z);
+}
+void API_ENTRY(glUniform3iv)(GLint location, GLsizei count, const GLint* v) {
+    CALL_GL_API(glUniform3iv, location, count, v);
+}
+void API_ENTRY(glUniform4f)(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+    CALL_GL_API(glUniform4f, location, x, y, z, w);
+}
+void API_ENTRY(glUniform4fv)(GLint location, GLsizei count, const GLfloat* v) {
+    CALL_GL_API(glUniform4fv, location, count, v);
+}
+void API_ENTRY(glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w) {
+    CALL_GL_API(glUniform4i, location, x, y, z, w);
+}
+void API_ENTRY(glUniform4iv)(GLint location, GLsizei count, const GLint* v) {
+    CALL_GL_API(glUniform4iv, location, count, v);
+}
+void API_ENTRY(glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
+    CALL_GL_API(glUniformMatrix2fv, location, count, transpose, value);
+}
+void API_ENTRY(glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
+    CALL_GL_API(glUniformMatrix3fv, location, count, transpose, value);
+}
+void API_ENTRY(glUniformMatrix4fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
+    CALL_GL_API(glUniformMatrix4fv, location, count, transpose, value);
+}
+void API_ENTRY(glUseProgram)(GLuint program) {
+    CALL_GL_API(glUseProgram, program);
+}
+void API_ENTRY(glValidateProgram)(GLuint program) {
+    CALL_GL_API(glValidateProgram, program);
+}
+void API_ENTRY(glVertexAttrib1f)(GLuint indx, GLfloat x) {
+    CALL_GL_API(glVertexAttrib1f, indx, x);
+}
+void API_ENTRY(glVertexAttrib1fv)(GLuint indx, const GLfloat* values) {
+    CALL_GL_API(glVertexAttrib1fv, indx, values);
+}
+void API_ENTRY(glVertexAttrib2f)(GLuint indx, GLfloat x, GLfloat y) {
+    CALL_GL_API(glVertexAttrib2f, indx, x, y);
+}
+void API_ENTRY(glVertexAttrib2fv)(GLuint indx, const GLfloat* values) {
+    CALL_GL_API(glVertexAttrib2fv, indx, values);
+}
+void API_ENTRY(glVertexAttrib3f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z) {
+    CALL_GL_API(glVertexAttrib3f, indx, x, y, z);
+}
+void API_ENTRY(glVertexAttrib3fv)(GLuint indx, const GLfloat* values) {
+    CALL_GL_API(glVertexAttrib3fv, indx, values);
+}
+void API_ENTRY(glVertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+    CALL_GL_API(glVertexAttrib4f, indx, x, y, z, w);
+}
+void API_ENTRY(glVertexAttrib4fv)(GLuint indx, const GLfloat* values) {
+    CALL_GL_API(glVertexAttrib4fv, indx, values);
+}
+void API_ENTRY(glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) {
+    CALL_GL_API(glVertexAttribPointer, indx, size, type, normalized, stride, ptr);
+}
+void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
+    CALL_GL_API(glViewport, x, y, width, height);
+}
diff --git a/opengl/libs/GLES2/gl2_entries.in b/opengl/libs/GLES2/gl2_entries.in
new file mode 100644
index 0000000..6a41b94
--- /dev/null
+++ b/opengl/libs/GLES2/gl2_entries.in
@@ -0,0 +1,142 @@
+GL_ENTRY(void, glActiveTexture, GLenum texture)
+GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader)
+GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const char* name)
+GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer)
+GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer)
+GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer)
+GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture)
+GL_ENTRY(void, glBlendColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+GL_ENTRY(void, glBlendEquation,  GLenum mode )
+GL_ENTRY(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha)
+GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
+GL_ENTRY(void, glBlendFuncSeparate, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const void* data, GLenum usage)
+GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void* data)
+GL_ENTRY(GLenum, glCheckFramebufferStatus, GLenum target)
+GL_ENTRY(void, glClear, GLbitfield mask)
+GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+GL_ENTRY(void, glClearDepthf, GLclampf depth)
+GL_ENTRY(void, glClearStencil, GLint s)
+GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+GL_ENTRY(void, glCompileShader, GLuint shader)
+GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
+GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
+GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(GLuint, glCreateProgram, void)
+GL_ENTRY(GLuint, glCreateShader, GLenum type)
+GL_ENTRY(void, glCullFace, GLenum mode)
+GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint* buffers)
+GL_ENTRY(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers)
+GL_ENTRY(void, glDeleteProgram, GLuint program)
+GL_ENTRY(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers)
+GL_ENTRY(void, glDeleteShader, GLuint shader)
+GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint* textures)
+GL_ENTRY(void, glDepthFunc, GLenum func)
+GL_ENTRY(void, glDepthMask, GLboolean flag)
+GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar)
+GL_ENTRY(void, glDetachShader, GLuint program, GLuint shader)
+GL_ENTRY(void, glDisable, GLenum cap)
+GL_ENTRY(void, glDisableVertexAttribArray, GLuint index)
+GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count)
+GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const void* indices)
+GL_ENTRY(void, glEnable, GLenum cap)
+GL_ENTRY(void, glEnableVertexAttribArray, GLuint index)
+GL_ENTRY(void, glFinish, void)
+GL_ENTRY(void, glFlush, void)
+GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+GL_ENTRY(void, glFrontFace, GLenum mode)
+GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint* buffers)
+GL_ENTRY(void, glGenerateMipmap, GLenum target)
+GL_ENTRY(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers)
+GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers)
+GL_ENTRY(void, glGenTextures, GLsizei n, GLuint* textures)
+GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
+GL_ENTRY(int, glGetAttribLocation, GLuint program, const char* name)
+GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean* params)
+GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint* params)
+GL_ENTRY(GLenum, glGetError, void)
+GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat* params)
+GL_ENTRY(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
+GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+GL_ENTRY(const GLubyte*, glGetString, GLenum name)
+GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat* params)
+GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params)
+GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params)
+GL_ENTRY(int, glGetUniformLocation, GLuint program, const char* name)
+GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params)
+GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params)
+GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, void** pointer)
+GL_ENTRY(void, glHint, GLenum target, GLenum mode)
+GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer)
+GL_ENTRY(GLboolean, glIsEnabled, GLenum cap)
+GL_ENTRY(GLboolean, glIsFramebuffer, GLuint framebuffer)
+GL_ENTRY(GLboolean, glIsProgram, GLuint program)
+GL_ENTRY(GLboolean, glIsRenderbuffer, GLuint renderbuffer)
+GL_ENTRY(GLboolean, glIsShader, GLuint shader)
+GL_ENTRY(GLboolean, glIsTexture, GLuint texture)
+GL_ENTRY(void, glLineWidth, GLfloat width)
+GL_ENTRY(void, glLinkProgram, GLuint program)
+GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param)
+GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units)
+GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
+GL_ENTRY(void, glReleaseShaderCompiler, void)
+GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert)
+GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
+GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const char** string, const GLint* length)
+GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
+GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask)
+GL_ENTRY(void, glStencilMask, GLuint mask)
+GL_ENTRY(void, glStencilMaskSeparate, GLenum face, GLuint mask)
+GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass)
+GL_ENTRY(void, glStencilOpSeparate, GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat,  GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
+GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param)
+GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat* params)
+GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param)
+GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint* params)
+GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels)
+GL_ENTRY(void, glUniform1f, GLint location, GLfloat x)
+GL_ENTRY(void, glUniform1fv, GLint location, GLsizei count, const GLfloat* v)
+GL_ENTRY(void, glUniform1i, GLint location, GLint x)
+GL_ENTRY(void, glUniform1iv, GLint location, GLsizei count, const GLint* v)
+GL_ENTRY(void, glUniform2f, GLint location, GLfloat x, GLfloat y)
+GL_ENTRY(void, glUniform2fv, GLint location, GLsizei count, const GLfloat* v)
+GL_ENTRY(void, glUniform2i, GLint location, GLint x, GLint y)
+GL_ENTRY(void, glUniform2iv, GLint location, GLsizei count, const GLint* v)
+GL_ENTRY(void, glUniform3f, GLint location, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glUniform3fv, GLint location, GLsizei count, const GLfloat* v)
+GL_ENTRY(void, glUniform3i, GLint location, GLint x, GLint y, GLint z)
+GL_ENTRY(void, glUniform3iv, GLint location, GLsizei count, const GLint* v)
+GL_ENTRY(void, glUniform4f, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+GL_ENTRY(void, glUniform4fv, GLint location, GLsizei count, const GLfloat* v)
+GL_ENTRY(void, glUniform4i, GLint location, GLint x, GLint y, GLint z, GLint w)
+GL_ENTRY(void, glUniform4iv, GLint location, GLsizei count, const GLint* v)
+GL_ENTRY(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+GL_ENTRY(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+GL_ENTRY(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
+GL_ENTRY(void, glUseProgram, GLuint program)
+GL_ENTRY(void, glValidateProgram, GLuint program)
+GL_ENTRY(void, glVertexAttrib1f, GLuint indx, GLfloat x)
+GL_ENTRY(void, glVertexAttrib1fv, GLuint indx, const GLfloat* values)
+GL_ENTRY(void, glVertexAttrib2f, GLuint indx, GLfloat x, GLfloat y)
+GL_ENTRY(void, glVertexAttrib2fv, GLuint indx, const GLfloat* values)
+GL_ENTRY(void, glVertexAttrib3f, GLuint indx, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glVertexAttrib3fv, GLuint indx, const GLfloat* values)
+GL_ENTRY(void, glVertexAttrib4f, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+GL_ENTRY(void, glVertexAttrib4fv, GLuint indx, const GLfloat* values)
+GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height)
diff --git a/opengl/libs/GLES2/gl2ext_api.in b/opengl/libs/GLES2/gl2ext_api.in
new file mode 100644
index 0000000..6eeecb3
--- /dev/null
+++ b/opengl/libs/GLES2/gl2ext_api.in
@@ -0,0 +1,105 @@
+void API_ENTRY(__glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image) {
+    CALL_GL_API(glEGLImageTargetTexture2DOES, target, image);
+}
+void API_ENTRY(__glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) {
+    CALL_GL_API(glEGLImageTargetRenderbufferStorageOES, target, image);
+}
+void API_ENTRY(glGetProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) {
+    CALL_GL_API(glGetProgramBinaryOES, program, bufSize, length, binaryFormat, binary);
+}
+void API_ENTRY(glProgramBinaryOES)(GLuint program, GLenum binaryFormat, const void *binary, GLint length) {
+    CALL_GL_API(glProgramBinaryOES, program, binaryFormat, binary, length);
+}
+void* API_ENTRY(glMapBufferOES)(GLenum target, GLenum access) {
+    CALL_GL_API_RETURN(glMapBufferOES, target, access);
+}
+GLboolean API_ENTRY(glUnmapBufferOES)(GLenum target) {
+    CALL_GL_API_RETURN(glUnmapBufferOES, target);
+}
+void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, void** params) {
+    CALL_GL_API(glGetBufferPointervOES, target, pname, params);
+}
+void API_ENTRY(glTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) {
+    CALL_GL_API(glTexImage3DOES, target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+void API_ENTRY(glTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) {
+    CALL_GL_API(glTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
+}
+void API_ENTRY(glCopyTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
+    CALL_GL_API(glCopyTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, x, y, width, height);
+}
+void API_ENTRY(glCompressedTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) {
+    CALL_GL_API(glCompressedTexImage3DOES, target, level, internalformat, width, height, depth, border, imageSize, data);
+}
+void API_ENTRY(glCompressedTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) {
+    CALL_GL_API(glCompressedTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
+}
+void API_ENTRY(glFramebufferTexture3DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
+    CALL_GL_API(glFramebufferTexture3DOES, target, attachment, textarget, texture, level, zoffset);
+}
+void API_ENTRY(glGetPerfMonitorGroupsAMD)(GLint *numGroups, GLsizei groupsSize, GLuint *groups) {
+    CALL_GL_API(glGetPerfMonitorGroupsAMD, numGroups, groupsSize, groups);
+}
+void API_ENTRY(glGetPerfMonitorCountersAMD)(GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) {
+    CALL_GL_API(glGetPerfMonitorCountersAMD, group, numCounters, maxActiveCounters, counterSize, counters);
+}
+void API_ENTRY(glGetPerfMonitorGroupStringAMD)(GLuint group, GLsizei bufSize, GLsizei *length, char *groupString) {
+    CALL_GL_API(glGetPerfMonitorGroupStringAMD, group, bufSize, length, groupString);
+}
+void API_ENTRY(glGetPerfMonitorCounterStringAMD)(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString) {
+    CALL_GL_API(glGetPerfMonitorCounterStringAMD, group, counter, bufSize, length, counterString);
+}
+void API_ENTRY(glGetPerfMonitorCounterInfoAMD)(GLuint group, GLuint counter, GLenum pname, void *data) {
+    CALL_GL_API(glGetPerfMonitorCounterInfoAMD, group, counter, pname, data);
+}
+void API_ENTRY(glGenPerfMonitorsAMD)(GLsizei n, GLuint *monitors) {
+    CALL_GL_API(glGenPerfMonitorsAMD, n, monitors);
+}
+void API_ENTRY(glDeletePerfMonitorsAMD)(GLsizei n, GLuint *monitors) {
+    CALL_GL_API(glDeletePerfMonitorsAMD, n, monitors);
+}
+void API_ENTRY(glSelectPerfMonitorCountersAMD)(GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList) {
+    CALL_GL_API(glSelectPerfMonitorCountersAMD, monitor, enable, group, numCounters, countersList);
+}
+void API_ENTRY(glBeginPerfMonitorAMD)(GLuint monitor) {
+    CALL_GL_API(glBeginPerfMonitorAMD, monitor);
+}
+void API_ENTRY(glEndPerfMonitorAMD)(GLuint monitor) {
+    CALL_GL_API(glEndPerfMonitorAMD, monitor);
+}
+void API_ENTRY(glGetPerfMonitorCounterDataAMD)(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) {
+    CALL_GL_API(glGetPerfMonitorCounterDataAMD, monitor, pname, dataSize, data, bytesWritten);
+}
+void API_ENTRY(glDeleteFencesNV)(GLsizei n, const GLuint *fences) {
+    CALL_GL_API(glDeleteFencesNV, n, fences);
+}
+void API_ENTRY(glGenFencesNV)(GLsizei n, GLuint *fences) {
+    CALL_GL_API(glGenFencesNV, n, fences);
+}
+GLboolean API_ENTRY(glIsFenceNV)(GLuint fence) {
+    CALL_GL_API_RETURN(glIsFenceNV, fence);
+}
+GLboolean API_ENTRY(glTestFenceNV)(GLuint fence) {
+    CALL_GL_API_RETURN(glTestFenceNV, fence);
+}
+void API_ENTRY(glGetFenceivNV)(GLuint fence, GLenum pname, GLint *params) {
+    CALL_GL_API(glGetFenceivNV, fence, pname, params);
+}
+void API_ENTRY(glFinishFenceNV)(GLuint fence) {
+    CALL_GL_API(glFinishFenceNV, fence);
+}
+void API_ENTRY(glSetFenceNV)(GLuint fence, GLenum condition) {
+    CALL_GL_API(glSetFenceNV, fence, condition);
+}
+void API_ENTRY(glGetDriverControlsQCOM)(GLint *num, GLsizei size, GLuint *driverControls) {
+    CALL_GL_API(glGetDriverControlsQCOM, num, size, driverControls);
+}
+void API_ENTRY(glGetDriverControlStringQCOM)(GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString) {
+    CALL_GL_API(glGetDriverControlStringQCOM, driverControl, bufSize, length, driverControlString);
+}
+void API_ENTRY(glEnableDriverControlQCOM)(GLuint driverControl) {
+    CALL_GL_API(glEnableDriverControlQCOM, driverControl);
+}
+void API_ENTRY(glDisableDriverControlQCOM)(GLuint driverControl) {
+    CALL_GL_API(glDisableDriverControlQCOM, driverControl);
+}
diff --git a/opengl/libs/GLES2/gl2ext_entries.in b/opengl/libs/GLES2/gl2ext_entries.in
new file mode 100644
index 0000000..e608f5d
--- /dev/null
+++ b/opengl/libs/GLES2/gl2ext_entries.in
@@ -0,0 +1,35 @@
+GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image)
+GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image)
+GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)
+GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const void *binary, GLint length)
+GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access)
+GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target)
+GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, void** params)
+GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels)
+GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels)
+GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data)
+GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data)
+GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize, GLuint *groups)
+GL_ENTRY(void, glGetPerfMonitorCountersAMD, GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters)
+GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, char *groupString)
+GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString)
+GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, void *data)
+GL_ENTRY(void, glGenPerfMonitorsAMD, GLsizei n, GLuint *monitors)
+GL_ENTRY(void, glDeletePerfMonitorsAMD, GLsizei n, GLuint *monitors)
+GL_ENTRY(void, glSelectPerfMonitorCountersAMD, GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList)
+GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor)
+GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor)
+GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten)
+GL_ENTRY(void, glDeleteFencesNV, GLsizei n, const GLuint *fences)
+GL_ENTRY(void, glGenFencesNV, GLsizei n, GLuint *fences)
+GL_ENTRY(GLboolean, glIsFenceNV, GLuint fence)
+GL_ENTRY(GLboolean, glTestFenceNV, GLuint fence)
+GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params)
+GL_ENTRY(void, glFinishFenceNV, GLuint fence)
+GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition)
+GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls)
+GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString)
+GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl)
+GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl)
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index 384b59a..3204d9a 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -14,8 +14,6 @@
  ** limitations under the License.
  */
 
-#define LOG_TAG "GLES_CM"
-
 #include <ctype.h>
 #include <string.h>
 #include <errno.h>
@@ -121,16 +119,25 @@
 
 
 /*
- * These GL calls are special because they need to call into EGL to retrieve
- * some informations before they can execute.
+ * These GL calls are special because they need to EGL to retrieve some
+ * informations before they can execute.
  */
 
+extern "C" void __glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
+extern "C" void __glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
+
 
 void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
 {
+    GLeglImageOES implImage = 
+        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
+    __glEGLImageTargetTexture2DOES(target, implImage);
 }
 
 void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
 {
+    GLeglImageOES implImage = 
+        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
+    __glEGLImageTargetRenderbufferStorageOES(target, image);
 }
 
diff --git a/opengl/libs/gl_entries.in b/opengl/libs/GLES_CM/gl_entries.in
similarity index 100%
rename from opengl/libs/gl_entries.in
rename to opengl/libs/GLES_CM/gl_entries.in
diff --git a/opengl/libs/glext_entries.in b/opengl/libs/GLES_CM/glext_entries.in
similarity index 100%
rename from opengl/libs/glext_entries.in
rename to opengl/libs/GLES_CM/glext_entries.in
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index 312b176..c5f753d 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -31,13 +31,15 @@
 
 struct egl_connection_t
 {
-    void volatile *     dso;
+    void *              dso;
     gl_hooks_t *        hooks;
     EGLint              major;
     EGLint              minor;
     int                 unavailable;
 };
 
+EGLAPI EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image);
+
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/gl_enums.in b/opengl/libs/gl_enums.in
deleted file mode 100644
index ffc2fad..0000000
--- a/opengl/libs/gl_enums.in
+++ /dev/null
@@ -1,261 +0,0 @@
-GLENUM(GL_POINTS, 0x0000)
-GLENUM(GL_LINES, 0x0001)
-GLENUM(GL_LINE_LOOP, 0x0002)
-GLENUM(GL_LINE_STRIP, 0x0003)
-GLENUM(GL_TRIANGLES, 0x0004)
-GLENUM(GL_TRIANGLE_STRIP, 0x0005)
-GLENUM(GL_TRIANGLE_FAN, 0x0006)
-GLENUM(GL_ADD, 0x0104)
-GLENUM(GL_NEVER, 0x0200)
-GLENUM(GL_LESS, 0x0201)
-GLENUM(GL_EQUAL, 0x0202)
-GLENUM(GL_LEQUAL, 0x0203)
-GLENUM(GL_GREATER, 0x0204)
-GLENUM(GL_NOTEQUAL, 0x0205)
-GLENUM(GL_GEQUAL, 0x0206)
-GLENUM(GL_ALWAYS, 0x0207)
-GLENUM(GL_SRC_COLOR, 0x0300)
-GLENUM(GL_ONE_MINUS_SRC_COLOR, 0x0301)
-GLENUM(GL_SRC_ALPHA, 0x0302)
-GLENUM(GL_ONE_MINUS_SRC_ALPHA, 0x0303)
-GLENUM(GL_DST_ALPHA, 0x0304)
-GLENUM(GL_ONE_MINUS_DST_ALPHA, 0x0305)
-GLENUM(GL_DST_COLOR, 0x0306)
-GLENUM(GL_ONE_MINUS_DST_COLOR, 0x0307)
-GLENUM(GL_SRC_ALPHA_SATURATE, 0x0308)
-GLENUM(GL_FRONT, 0x0404)
-GLENUM(GL_BACK, 0x0405)
-GLENUM(GL_FRONT_AND_BACK, 0x0408)
-GLENUM(GL_INVALID_ENUM, 0x0500)
-GLENUM(GL_INVALID_VALUE, 0x0501)
-GLENUM(GL_INVALID_OPERATION, 0x0502)
-GLENUM(GL_STACK_OVERFLOW, 0x0503)
-GLENUM(GL_STACK_UNDERFLOW, 0x0504)
-GLENUM(GL_OUT_OF_MEMORY, 0x0505)
-GLENUM(GL_EXP, 0x0800)
-GLENUM(GL_EXP2, 0x0801)
-GLENUM(GL_CW, 0x0900)
-GLENUM(GL_CCW, 0x0901)
-GLENUM(GL_POINT_SMOOTH, 0x0B10)
-GLENUM(GL_SMOOTH_POINT_SIZE_RANGE, 0x0B12)
-GLENUM(GL_LINE_SMOOTH, 0x0B20)
-GLENUM(GL_SMOOTH_LINE_WIDTH_RANGE, 0x0B22)
-GLENUM(GL_CULL_FACE, 0x0B44)
-GLENUM(GL_LIGHTING, 0x0B50)
-GLENUM(GL_LIGHT_MODEL_TWO_SIDE, 0x0B52)
-GLENUM(GL_LIGHT_MODEL_AMBIENT, 0x0B53)
-GLENUM(GL_COLOR_MATERIAL, 0x0B57)
-GLENUM(GL_FOG, 0x0B60)
-GLENUM(GL_FOG_DENSITY, 0x0B62)
-GLENUM(GL_FOG_START, 0x0B63)
-GLENUM(GL_FOG_END, 0x0B64)
-GLENUM(GL_FOG_MODE, 0x0B65)
-GLENUM(GL_FOG_COLOR, 0x0B66)
-GLENUM(GL_DEPTH_TEST, 0x0B71)
-GLENUM(GL_STENCIL_TEST, 0x0B90)
-GLENUM(GL_NORMALIZE, 0x0BA1)
-GLENUM(GL_ALPHA_TEST, 0x0BC0)
-GLENUM(GL_DITHER, 0x0BD0)
-GLENUM(GL_BLEND, 0x0BE2)
-GLENUM(GL_COLOR_LOGIC_OP, 0x0BF2)
-GLENUM(GL_SCISSOR_TEST, 0x0C11)
-GLENUM(GL_PERSPECTIVE_CORRECTION_HINT, 0x0C50)
-GLENUM(GL_POINT_SMOOTH_HINT, 0x0C51)
-GLENUM(GL_LINE_SMOOTH_HINT, 0x0C52)
-GLENUM(GL_POLYGON_SMOOTH_HINT, 0x0C53)
-GLENUM(GL_FOG_HINT, 0x0C54)
-GLENUM(GL_UNPACK_ALIGNMENT, 0x0CF5)
-GLENUM(GL_PACK_ALIGNMENT, 0x0D05)
-GLENUM(GL_MAX_LIGHTS, 0x0D31)
-GLENUM(GL_MAX_CLIP_PLANES, 0x0D32)
-GLENUM(GL_MAX_TEXTURE_SIZE, 0x0D33)
-GLENUM(GL_MAX_MODELVIEW_STACK_DEPTH, 0x0D36)
-GLENUM(GL_MAX_PROJECTION_STACK_DEPTH, 0x0D38)
-GLENUM(GL_MAX_TEXTURE_STACK_DEPTH, 0x0D39)
-GLENUM(GL_MAX_VIEWPORT_DIMS, 0x0D3A)
-GLENUM(GL_RED_BITS, 0x0D52)
-GLENUM(GL_GREEN_BITS, 0x0D53)
-GLENUM(GL_BLUE_BITS, 0x0D54)
-GLENUM(GL_ALPHA_BITS, 0x0D55)
-GLENUM(GL_DEPTH_BITS, 0x0D56)
-GLENUM(GL_STENCIL_BITS, 0x0D57)
-GLENUM(GL_TEXTURE_2D, 0x0DE1)
-GLENUM(GL_DONT_CARE, 0x1100)
-GLENUM(GL_FASTEST, 0x1101)
-GLENUM(GL_NICEST, 0x1102)
-GLENUM(GL_AMBIENT, 0x1200)
-GLENUM(GL_DIFFUSE, 0x1201)
-GLENUM(GL_SPECULAR, 0x1202)
-GLENUM(GL_POSITION, 0x1203)
-GLENUM(GL_SPOT_DIRECTION, 0x1204)
-GLENUM(GL_SPOT_EXPONENT, 0x1205)
-GLENUM(GL_SPOT_CUTOFF, 0x1206)
-GLENUM(GL_CONSTANT_ATTENUATION, 0x1207)
-GLENUM(GL_LINEAR_ATTENUATION, 0x1208)
-GLENUM(GL_QUADRATIC_ATTENUATION, 0x1209)
-GLENUM(GL_BYTE, 0x1400)
-GLENUM(GL_UNSIGNED_BYTE, 0x1401)
-GLENUM(GL_SHORT, 0x1402)
-GLENUM(GL_UNSIGNED_SHORT, 0x1403)
-GLENUM(GL_FLOAT, 0x1406)
-GLENUM(GL_FIXED, 0x140C)
-GLENUM(GL_CLEAR, 0x1500)
-GLENUM(GL_AND, 0x1501)
-GLENUM(GL_AND_REVERSE, 0x1502)
-GLENUM(GL_COPY, 0x1503)
-GLENUM(GL_AND_INVERTED, 0x1504)
-GLENUM(GL_NOOP, 0x1505)
-GLENUM(GL_XOR, 0x1506)
-GLENUM(GL_OR, 0x1507)
-GLENUM(GL_NOR, 0x1508)
-GLENUM(GL_EQUIV, 0x1509)
-GLENUM(GL_INVERT, 0x150A)
-GLENUM(GL_OR_REVERSE, 0x150B)
-GLENUM(GL_COPY_INVERTED, 0x150C)
-GLENUM(GL_OR_INVERTED, 0x150D)
-GLENUM(GL_NAND, 0x150E)
-GLENUM(GL_SET, 0x150F)
-GLENUM(GL_EMISSION, 0x1600)
-GLENUM(GL_SHININESS, 0x1601)
-GLENUM(GL_AMBIENT_AND_DIFFUSE, 0x1602)
-GLENUM(GL_MODELVIEW, 0x1700)
-GLENUM(GL_PROJECTION, 0x1701)
-GLENUM(GL_TEXTURE, 0x1702)
-GLENUM(GL_ALPHA, 0x1906)
-GLENUM(GL_RGB, 0x1907)
-GLENUM(GL_RGBA, 0x1908)
-GLENUM(GL_LUMINANCE, 0x1909)
-GLENUM(GL_LUMINANCE_ALPHA, 0x190A)
-GLENUM(GL_FLAT, 0x1D00)
-GLENUM(GL_SMOOTH, 0x1D01)
-GLENUM(GL_KEEP, 0x1E00)
-GLENUM(GL_REPLACE, 0x1E01)
-GLENUM(GL_REPLACE, 0x1E01)
-GLENUM(GL_INCR, 0x1E02)
-GLENUM(GL_DECR, 0x1E03)
-GLENUM(GL_VENDOR, 0x1F00)
-GLENUM(GL_RENDERER, 0x1F01)
-GLENUM(GL_VERSION, 0x1F02)
-GLENUM(GL_EXTENSIONS, 0x1F03)
-GLENUM(GL_MODULATE, 0x2100)
-GLENUM(GL_DECAL, 0x2101)
-GLENUM(GL_TEXTURE_ENV_MODE, 0x2200)
-GLENUM(GL_TEXTURE_ENV_COLOR, 0x2201)
-GLENUM(GL_TEXTURE_ENV, 0x2300)
-GLENUM(GL_NEAREST, 0x2600)
-GLENUM(GL_LINEAR, 0x2601)
-GLENUM(GL_NEAREST_MIPMAP_NEAREST, 0x2700)
-GLENUM(GL_LINEAR_MIPMAP_NEAREST, 0x2701)
-GLENUM(GL_NEAREST_MIPMAP_LINEAR, 0x2702)
-GLENUM(GL_LINEAR_MIPMAP_LINEAR, 0x2703)
-GLENUM(GL_TEXTURE_MAG_FILTER, 0x2800)
-GLENUM(GL_TEXTURE_MIN_FILTER, 0x2801)
-GLENUM(GL_TEXTURE_WRAP_S, 0x2802)
-GLENUM(GL_TEXTURE_WRAP_T, 0x2803)
-GLENUM(GL_CLAMP, 0x2900)
-GLENUM(GL_REPEAT, 0x2901)
-GLENUM(GL_CLIP_PLANE0, 0x3000)
-GLENUM(GL_CLIP_PLANE1, 0x3001)
-GLENUM(GL_CLIP_PLANE2, 0x3002)
-GLENUM(GL_CLIP_PLANE3, 0x3003)
-GLENUM(GL_CLIP_PLANE4, 0x3004)
-GLENUM(GL_CLIP_PLANE5, 0x3005)
-GLENUM(GL_LIGHT0, 0x4000)
-GLENUM(GL_LIGHT1, 0x4001)
-GLENUM(GL_LIGHT2, 0x4002)
-GLENUM(GL_LIGHT3, 0x4003)
-GLENUM(GL_LIGHT4, 0x4004)
-GLENUM(GL_LIGHT5, 0x4005)
-GLENUM(GL_LIGHT6, 0x4006)
-GLENUM(GL_LIGHT7, 0x4007)
-GLENUM(GL_DIRECT_TEXTURE_2D_QUALCOMM, 0x7E80)
-GLENUM(GL_UNSIGNED_SHORT_4_4_4_4, 0x8033)
-GLENUM(GL_UNSIGNED_SHORT_5_5_5_1, 0x8034)
-GLENUM(GL_POLYGON_OFFSET_FILL, 0x8037)
-GLENUM(GL_RESCALE_NORMAL, 0x803A)
-GLENUM(GL_VERTEX_ARRAY, 0x8074)
-GLENUM(GL_NORMAL_ARRAY, 0x8075)
-GLENUM(GL_COLOR_ARRAY, 0x8076)
-GLENUM(GL_TEXTURE_COORD_ARRAY, 0x8078)
-GLENUM(GL_MULTISAMPLE, 0x809D)
-GLENUM(GL_SAMPLE_ALPHA_TO_COVERAGE, 0x809E)
-GLENUM(GL_SAMPLE_ALPHA_TO_ONE, 0x809F)
-GLENUM(GL_SAMPLE_COVERAGE, 0x80A0)
-GLENUM(GL_MAX_ELEMENTS_VERTICES, 0x80E8)
-GLENUM(GL_MAX_ELEMENTS_INDICES, 0x80E9)
-GLENUM(GL_CLAMP_TO_EDGE, 0x812F)
-GLENUM(GL_GENERATE_MIPMAP, 0x8191)
-GLENUM(GL_GENERATE_MIPMAP_HINT, 0x8192)
-GLENUM(GL_UNSIGNED_SHORT_5_6_5, 0x8363)
-GLENUM(GL_ALIASED_POINT_SIZE_RANGE, 0x846D)
-GLENUM(GL_ALIASED_LINE_WIDTH_RANGE, 0x846E)
-GLENUM(GL_TEXTURE0, 0x84C0)
-GLENUM(GL_TEXTURE1, 0x84C1)
-GLENUM(GL_TEXTURE2, 0x84C2)
-GLENUM(GL_TEXTURE3, 0x84C3)
-GLENUM(GL_TEXTURE4, 0x84C4)
-GLENUM(GL_TEXTURE5, 0x84C5)
-GLENUM(GL_TEXTURE6, 0x84C6)
-GLENUM(GL_TEXTURE7, 0x84C7)
-GLENUM(GL_TEXTURE8, 0x84C8)
-GLENUM(GL_TEXTURE9, 0x84C9)
-GLENUM(GL_TEXTURE10, 0x84CA)
-GLENUM(GL_TEXTURE11, 0x84CB)
-GLENUM(GL_TEXTURE12, 0x84CC)
-GLENUM(GL_TEXTURE13, 0x84CD)
-GLENUM(GL_TEXTURE14, 0x84CE)
-GLENUM(GL_TEXTURE15, 0x84CF)
-GLENUM(GL_TEXTURE16, 0x84D0)
-GLENUM(GL_TEXTURE17, 0x84D1)
-GLENUM(GL_TEXTURE18, 0x84D2)
-GLENUM(GL_TEXTURE19, 0x84D3)
-GLENUM(GL_TEXTURE20, 0x84D4)
-GLENUM(GL_TEXTURE21, 0x84D5)
-GLENUM(GL_TEXTURE22, 0x84D6)
-GLENUM(GL_TEXTURE23, 0x84D7)
-GLENUM(GL_TEXTURE24, 0x84D8)
-GLENUM(GL_TEXTURE25, 0x84D9)
-GLENUM(GL_TEXTURE26, 0x84DA)
-GLENUM(GL_TEXTURE27, 0x84DB)
-GLENUM(GL_TEXTURE28, 0x84DC)
-GLENUM(GL_TEXTURE29, 0x84DD)
-GLENUM(GL_TEXTURE30, 0x84DE)
-GLENUM(GL_TEXTURE31, 0x84DF)
-GLENUM(GL_MAX_TEXTURE_UNITS, 0x84E2)
-GLENUM(GL_NUM_COMPRESSED_TEXTURE_FORMATS, 0x86A2)
-GLENUM(GL_COMPRESSED_TEXTURE_FORMATS, 0x86A3)
-GLENUM(GL_BUFFER_SIZE, 0x8764)
-GLENUM(GL_BUFFER_USAGE, 0x8765)
-GLENUM(GL_POINT_SPRITE_OES, 0x8861)
-GLENUM(GL_COORD_REPLACE_OES, 0x8862)
-GLENUM(GL_ARRAY_BUFFER, 0x8892)
-GLENUM(GL_ELEMENT_ARRAY_BUFFER, 0x8893)
-GLENUM(GL_ARRAY_BUFFER_BINDING, 0x8894)
-GLENUM(GL_ELEMENT_ARRAY_BUFFER_BINDING, 0x8895)
-GLENUM(GL_VERTEX_ARRAY_BUFFER_BINDING, 0x8896)
-GLENUM(GL_NORMAL_ARRAY_BUFFER_BINDING, 0x8897)
-GLENUM(GL_COLOR_ARRAY_BUFFER_BINDING, 0x8898)
-GLENUM(GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING, 0x889A)
-GLENUM(GL_STATIC_DRAW, 0x88E4)
-GLENUM(GL_DYNAMIC_DRAW, 0x88E8)
-GLENUM(GL_POINT_SIZE_ARRAY_TYPE_OES, 0x898A)
-GLENUM(GL_POINT_SIZE_ARRAY_STRIDE_OES, 0x898B)
-GLENUM(GL_POINT_SIZE_ARRAY_POINTER_OES, 0x898C)
-GLENUM(GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES, 0x898D)
-GLENUM(GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES, 0x898E)
-GLENUM(GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES, 0x898F)
-GLENUM(GL_PALETTE4_RGB8_OES, 0x8B90)
-GLENUM(GL_PALETTE4_RGBA8_OES, 0x8B91)
-GLENUM(GL_PALETTE4_R5_G6_B5_OES, 0x8B92)
-GLENUM(GL_PALETTE4_RGBA4_OES, 0x8B93)
-GLENUM(GL_PALETTE4_RGB5_A1_OES, 0x8B94)
-GLENUM(GL_PALETTE8_RGB8_OES, 0x8B95)
-GLENUM(GL_PALETTE8_RGBA8_OES, 0x8B96)
-GLENUM(GL_PALETTE8_R5_G6_B5_OES, 0x8B97)
-GLENUM(GL_PALETTE8_RGBA4_OES, 0x8B98)
-GLENUM(GL_PALETTE8_RGB5_A1_OES, 0x8B99)
-GLENUM(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, 0x8B9A)
-GLENUM(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, 0x8B9B)
-GLENUM(GL_POINT_SIZE_ARRAY_OES, 0x8B9C)
-GLENUM(GL_TEXTURE_CROP_RECT_OES, 0x8B9D)
-GLENUM(GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES, 0x8B9F)
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
index fd97254..37292ee 100644
--- a/opengl/libs/hooks.h
+++ b/opengl/libs/hooks.h
@@ -21,10 +21,14 @@
 #include <string.h>
 #include <errno.h>
 
+#include <pthread.h>
+
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <GLES/gl.h>
 #include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 
 #if !defined(__arm__)
 #define USE_SLOW_BINDING            1
@@ -76,11 +80,15 @@
 
 struct gl_hooks_t {
     struct gl_t {
-        #include "gl_entries.in"
-        #include "glext_entries.in"
+        #include "GLES_CM/gl_entries.in"
+        #include "GLES_CM/glext_entries.in"
     } gl;
+    struct gl2_t {
+        #include "GLES2/gl2_entries.in"
+        #include "GLES2/gl2ext_entries.in"
+    } gl2;
     struct egl_t {
-        #include "egl_entries.in"
+        #include "EGL/egl_entries.in"
     } egl;
     struct gl_ext_t {
         void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void);
@@ -94,6 +102,13 @@
 
 extern gl_hooks_t gHooks[IMPL_NUM_IMPLEMENTATIONS];
 extern pthread_key_t gGLWrapperKey;
+extern "C" void gl_unimplemented();
+
+extern char const * const gl_names[];
+extern char const * const gl2_names[];
+extern char const * const egl_names[];
+
+// ----------------------------------------------------------------------------
 
 #if USE_FAST_TLS_KEY
 
diff --git a/opengl/libs/tools/enumextract.sh b/opengl/libs/tools/enumextract.sh
deleted file mode 100644
index 5707302..0000000
--- a/opengl/libs/tools/enumextract.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/sh
-
-awk '
-/^#define GL_/ {
-    names[count] = $2;
-    values[count] = $3;
-    sort[count] = $3 + 0;
-    count++;
-}
-END {
-    for (i = 1; i < count; i++) {
-        for (j = 0; j < i; j++) {
-            if (sort[i] < sort[j]) {
-                tn = names[i];
-                tv = values[i];
-                ts = sort[i];
-                names[i] = names[j];
-                values[i] = values[j];
-                sort[i] = sort[j];
-                names[j] = tn;
-                values[j] = tv;
-                sort[j] = ts;
-            }
-        }
-    }
- 
-    for (i = 0; i < count; i++) {
-        printf("GLENUM(%s, %s)\n", names[i], values[i]);
-    }
-}
-' < $1
-
diff --git a/opengl/libs/tools/genfiles b/opengl/libs/tools/genfiles
index 107768b..4f8eda4 100755
--- a/opengl/libs/tools/genfiles
+++ b/opengl/libs/tools/genfiles
@@ -15,6 +15,13 @@
 # limitations under the License.
 
 ./glapigen ../../include/GLES/gl.h > ../GLES_CM/gl_api.in 
-./glentrygen ../../include/GLES/gl.h > ../gl_entries.in 
+./glentrygen ../../include/GLES/gl.h > ../GLES_CM/gl_entries.in 
+
 ./glapigen ../../include/GLES/glext.h > ../GLES_CM/glext_api.in 
-./glentrygen ../../include/GLES/glext.h > ../glext_entries.in 
+./glentrygen ../../include/GLES/glext.h > ../GLES_CM/glext_entries.in 
+
+./glapigen ../../include/GLES2/gl2.h > ../GLES2/gl2_api.in 
+./glentrygen ../../include/GLES2/gl2.h > ../GLES2/gl2_entries.in 
+
+./glapigen ../../include/GLES2/gl2ext.h > ../GLES2/gl2ext_api.in 
+./glentrygen ../../include/GLES2/gl2ext.h > ../GLES2/gl2ext_entries.in 
diff --git a/opengl/libs/tools/glapigen b/opengl/libs/tools/glapigen
index a2c3a7b..bd8dda3 100755
--- a/opengl/libs/tools/glapigen
+++ b/opengl/libs/tools/glapigen
@@ -16,16 +16,23 @@
 
 use strict;
 
+sub rtrim($)
+{
+    my $string = shift;
+    $string =~ s/\s+$//;
+    return $string;
+}
+
 while (my $line = <>) {
   next if $line =~ /^\//;
   next if $line =~ /^#/;
   next if $line =~ /^\s*$/;
-  if ($line !~ /^GL_API\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) {
+  if ($line !~ /^GL_API(CALL)?\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) {
     next;
   }
-  my $type = $1;
-  my $name = $2;
-  my $args = $3;
+  my $type = rtrim($2);
+  my $name = $3;
+  my $args = $4;
 
   #printf("%s", $line);
   
diff --git a/opengl/libs/tools/glentrygen b/opengl/libs/tools/glentrygen
index 5e0f7b6..170f041 100755
--- a/opengl/libs/tools/glentrygen
+++ b/opengl/libs/tools/glentrygen
@@ -16,16 +16,23 @@
 
 use strict;
 
+sub rtrim($)
+{
+    my $string = shift;
+    $string =~ s/\s+$//;
+    return $string;
+}
+
 while (my $line = <>) {
   next if $line =~ /^\//;
   next if $line =~ /^#/;
   next if $line =~ /^\s*$/;
-  if ($line !~ /^GL_API\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) {
+  if ($line !~ /^GL_API(CALL)?\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) {
     next;
   }
-  my $type = $1;
-  my $name = $2;
-  my $args = $3;
+  my $type = rtrim($2);
+  my $name = $3;
+  my $args = $4;
 
   printf("GL_ENTRY(%s, %s, %s)\n", $type, $name, $args);
 }
diff --git a/opengl/tests/copybits/Android.mk b/opengl/tests/copybits/Android.mk
new file mode 100644
index 0000000..d5ded42
--- /dev/null
+++ b/opengl/tests/copybits/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	copybits.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv1_CM \
+    libui
+
+LOCAL_MODULE:= test-opengl-copybits
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
+
diff --git a/opengl/tests/copybits/copybits.cpp b/opengl/tests/copybits/copybits.cpp
new file mode 100644
index 0000000..f8ca9b2
--- /dev/null
+++ b/opengl/tests/copybits/copybits.cpp
@@ -0,0 +1,722 @@
+// Test software OpenGL hardware accelleration using copybits.
+
+#define LOG_TAG "copybits_test"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include <ui/PixelFormat.h>
+
+#include <cutils/log.h>
+#include <cutils/native_handle.h>
+
+#include <utils/Atomic.h>
+
+#include <private/ui/SurfaceBuffer.h>
+#include <pixelflinger/pixelflinger.h>
+
+#include <hardware/gralloc.h>
+#include <hardware/hardware.h>
+
+#define EGL_EGLEXT_PROTOTYPES
+#define GL_GLEXT_PROTOTYPES
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+extern "C" EGLNativeWindowType android_createDisplaySurface(void);
+
+using namespace android;
+
+EGLDisplay eglDisplay;
+EGLSurface eglSurface;
+EGLContext eglContext;
+GLuint texture;
+
+hw_module_t const* gralloc_module;
+alloc_device_t  *sAllocDev;
+
+#define FIXED_ONE 0x10000 /* 1.0 in 16.16 fixed point. */
+
+int init_gl_surface();
+void free_gl_surface();
+void init_scene();
+
+int create_physical_texture();
+int readTimer();
+
+// ===========================================================================
+// Buffer an implementation of android_native_buffer_t
+// ===========================================================================
+
+class NativeBuffer;
+
+class Buffer : public android::SurfaceBuffer
+{
+public:
+    // creates w * h buffer
+    Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage);
+
+    // return status
+    status_t initCheck() const;
+
+    uint32_t getWidth() const           { return width; }
+    uint32_t getHeight() const          { return height; }
+    uint32_t getStride() const          { return stride; }
+    uint32_t getUsage() const           { return usage; }
+    PixelFormat getPixelFormat() const  { return format; }
+    
+    
+    android_native_buffer_t* getNativeBuffer() const;
+
+    void setPixel(int x, int y, int r, int g, int b, int a);
+
+    status_t lock(GGLSurface* surface, uint32_t usage);
+    void lock() {
+        GGLSurface s;
+        lock(&s, GRALLOC_USAGE_SW_WRITE_OFTEN);
+        mData = (void*)s.data;
+    }
+
+private:
+    friend class LightRefBase<Buffer>;
+    Buffer(const Buffer& rhs);
+    virtual ~Buffer();
+    Buffer& operator = (const Buffer& rhs);
+    const Buffer& operator = (const Buffer& rhs) const;
+
+    status_t initSize(uint32_t w, uint32_t h);
+
+    ssize_t                 mInitCheck;
+    void*                   mData;
+};
+
+Buffer::Buffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage)
+    : SurfaceBuffer(), mInitCheck(NO_INIT)
+{
+    this->usage = usage;
+    this->format = format;
+    if (w>0 && h>0) {
+        mInitCheck = initSize(w, h);
+    }
+}
+
+Buffer::~Buffer()
+{
+    if (handle) {
+        sAllocDev->free(sAllocDev, handle);
+    }
+}
+
+status_t Buffer::initCheck() const {
+    return mInitCheck;
+}
+
+android_native_buffer_t* Buffer::getNativeBuffer() const
+{
+    return static_cast<android_native_buffer_t*>(const_cast<Buffer*>(this));
+}
+
+status_t Buffer::initSize(uint32_t w, uint32_t h)
+{
+    status_t err = NO_ERROR;
+
+    err = sAllocDev->alloc(sAllocDev, w, h, format, usage, &handle, &stride);
+    
+    if (err == NO_ERROR) {
+        if (err == NO_ERROR) {
+            width  = w;
+            height = h;
+        }
+    }
+
+    return err;
+}
+
+status_t Buffer::lock(GGLSurface* sur, uint32_t usage) 
+{
+    void* vaddr;
+    status_t res = SurfaceBuffer::lock(usage, &vaddr);
+    if (res == NO_ERROR && sur) {
+        sur->version = sizeof(GGLSurface);
+        sur->width = width;
+        sur->height = height;
+        sur->stride = stride;
+        sur->format = format;
+        sur->data = static_cast<GGLubyte*>(vaddr);
+    }
+    return res;
+}
+
+
+void Buffer::setPixel(int x, int y, int r, int g, int b, int a) {
+    if (x < 0 || (unsigned int) x >= width
+            || y < 0 || (unsigned int) y >= height) {
+        // clipped
+        return;
+    }
+    int index = stride * y + x;
+    switch (format) {
+    case HAL_PIXEL_FORMAT_RGB_565: {
+            unsigned short val = (unsigned short) (
+                    ((0x1f & (r >> 3)) << 11)
+                    | ((0x3f & (g >> 2)) << 5)
+                    | (0x1f & (b >> 3)));
+            ((unsigned short*) mData)[index]= val;
+        }
+        break;
+    case HAL_PIXEL_FORMAT_RGBA_8888: { // ABGR
+        unsigned int val = (unsigned int)
+            (((a & 0xff) << 24)
+                    | ((b & 0xff) << 16)
+                    | ((g & 0xff) << 8)
+                    | (r & 0xff));
+            ((unsigned int*) mData)[index] = val;
+        }
+        break;
+    default:
+        // Unsupported pixel format
+        break;
+    }
+}
+
+
+static void gluLookAt(float eyeX, float eyeY, float eyeZ,
+        float centerX, float centerY, float centerZ, float upX, float upY,
+        float upZ)
+{
+    // See the OpenGL GLUT documentation for gluLookAt for a description
+    // of the algorithm. We implement it in a straightforward way:
+
+    float fx = centerX - eyeX;
+    float fy = centerY - eyeY;
+    float fz = centerZ - eyeZ;
+
+    // Normalize f
+    float rlf = 1.0f / sqrtf(fx*fx + fy*fy + fz*fz);
+    fx *= rlf;
+    fy *= rlf;
+    fz *= rlf;
+
+    // Normalize up
+    float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
+    upX *= rlup;
+    upY *= rlup;
+    upZ *= rlup;
+
+    // compute s = f x up (x means "cross product")
+
+    float sx = fy * upZ - fz * upY;
+    float sy = fz * upX - fx * upZ;
+    float sz = fx * upY - fy * upX;
+
+    // compute u = s x f
+    float ux = sy * fz - sz * fy;
+    float uy = sz * fx - sx * fz;
+    float uz = sx * fy - sy * fx;
+
+    float m[16] ;
+    m[0] = sx;
+    m[1] = ux;
+    m[2] = -fx;
+    m[3] = 0.0f;
+
+    m[4] = sy;
+    m[5] = uy;
+    m[6] = -fy;
+    m[7] = 0.0f;
+
+    m[8] = sz;
+    m[9] = uz;
+    m[10] = -fz;
+    m[11] = 0.0f;
+
+    m[12] = 0.0f;
+    m[13] = 0.0f;
+    m[14] = 0.0f;
+    m[15] = 1.0f;
+
+    glMultMatrixf(m);
+    glTranslatef(-eyeX, -eyeY, -eyeZ);
+}
+
+int init_gralloc() {
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &gralloc_module);
+    LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
+
+    if (err == 0) {
+        gralloc_open(gralloc_module, &sAllocDev);
+    }
+    return err;
+}
+
+int init_gl_surface(void)
+{
+    EGLint numConfigs = 1;
+    EGLConfig myConfig = {0};
+    EGLint attrib[] =
+    {
+            EGL_DEPTH_SIZE,     16,
+            EGL_NONE
+    };
+
+    printf("init_gl_surface\n");
+    if ( (eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY )
+    {
+        printf("eglGetDisplay failed\n");
+        return 0;
+    }
+
+    if ( eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE )
+    {
+        printf("eglInitialize failed\n");
+        return 0;
+    }
+
+    if ( eglChooseConfig(eglDisplay, attrib, &myConfig, 1, &numConfigs) != EGL_TRUE )
+    {
+        printf("eglChooseConfig failed\n");
+        return 0;
+    }
+
+    if ( (eglSurface = eglCreateWindowSurface(eglDisplay, myConfig,
+            android_createDisplaySurface(), 0)) == EGL_NO_SURFACE )
+    {
+        printf("eglCreateWindowSurface failed\n");
+        return 0;
+    }
+
+    if ( (eglContext = eglCreateContext(eglDisplay, myConfig, 0, 0)) == EGL_NO_CONTEXT )
+    {
+        printf("eglCreateContext failed\n");
+        return 0;
+    }
+
+    if ( eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) != EGL_TRUE )
+    {
+        printf("eglMakeCurrent failed\n");
+        return 0;
+    }
+
+#if EGL_ANDROID_swap_rectangle
+    eglSetSwapRectangleANDROID(eglDisplay, eglSurface, 0, 0, 320, 480);
+#endif
+    
+    return 1;
+}
+
+void free_gl_surface(void)
+{
+    if (eglDisplay != EGL_NO_DISPLAY)
+    {
+        eglMakeCurrent( eglDisplay, EGL_NO_SURFACE,
+                EGL_NO_SURFACE, EGL_NO_CONTEXT );
+        eglDestroyContext( eglDisplay, eglContext );
+        eglDestroySurface( eglDisplay, eglSurface );
+        eglTerminate( eglDisplay );
+        eglDisplay = EGL_NO_DISPLAY;
+    }
+}
+
+void init_scene(void)
+{
+    glDisable(GL_DITHER);
+    glEnable(GL_CULL_FACE);
+    float ratio = 320.0f /  480.0f;
+    glViewport(0, 0, 320, 480);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+
+    glMatrixMode(GL_MODELVIEW);
+
+    glLoadIdentity();
+    gluLookAt(
+            0, 0, 3,  // eye
+            0, 0, 0,  // center
+            0, 1, 0); // up
+
+    glEnable(GL_TEXTURE_2D);
+}
+
+// #define USE_ALPHA_COLOR
+
+#define USE_GL_REPLACE
+//#define USE_GL_MODULATE
+
+// #define USE_BLEND
+
+#define USE_565
+// #define USE_8888
+
+// #define USE_NEAREST
+#define USE_LINEAR
+
+#define USE_SCALE
+
+void setSmoothGradient(Buffer* bufferObject) {
+    int pixels = bufferObject->getHeight() * bufferObject->getWidth();
+    int step = 0;
+    for (unsigned int y = 0; y < bufferObject->getHeight(); y++) {
+        for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
+            int grey = step * 255 / pixels;
+            bufferObject->setPixel(x, y, grey, grey, grey, 255);
+            ++step;
+        }
+    }
+}
+
+void setSmoothAlphaGradient(Buffer* bufferObject) {
+    int pixels = bufferObject->getHeight() * bufferObject->getWidth();
+    int step = 0;
+    for (unsigned int y = 0; y < bufferObject->getHeight(); y++) {
+        for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
+            int grey = step * 255 / pixels;
+            bufferObject->setPixel(x, y, 255, 255, 255, grey);
+            ++step;
+        }
+    }
+}
+
+void setOrientedCheckerboard(Buffer* bufferObject) {
+    bufferObject->setPixel(0, 0, 0, 0, 0, 255);
+    for(unsigned int x = 1; x < bufferObject->getWidth() ; x++) {
+        bufferObject->setPixel(x, 0, 0, 255, 0, 255);
+    }
+    for (unsigned int y = 1; y < bufferObject->getHeight(); y++) {
+        for(unsigned int x = 0; x < bufferObject->getWidth() ; x++) {
+            if ((x ^ y ) & 1) {
+                bufferObject->setPixel(x, y, 255, 255, 255, 255);
+            } else {
+                bufferObject->setPixel(x, y, 255, 0, 0, 255);
+            }
+        }
+    }
+}
+
+int create_physical_texture(unsigned int w, unsigned int h)
+{
+
+#ifdef USE_565
+    PixelFormat format = HAL_PIXEL_FORMAT_RGB_565;
+#else
+    PixelFormat format = HAL_PIXEL_FORMAT_RGBA_8888;
+#endif
+    int usage = GRALLOC_USAGE_SW_READ_OFTEN |
+        GRALLOC_USAGE_SW_WRITE_OFTEN |
+        GRALLOC_USAGE_HW_TEXTURE |
+        GRALLOC_USAGE_HW_2D; /* This is the key to allocating the texture in pmem. */
+    int32_t stride;
+    buffer_handle_t handle;
+
+    // Allocate the hardware buffer
+    Buffer* bufferObject = new Buffer(w, h, format, usage);
+
+    android_native_buffer_t* buffer = bufferObject->getNativeBuffer();
+
+    buffer->common.incRef(&buffer->common);
+
+    // create the new EGLImageKHR
+    EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_NONE };
+    EGLDisplay dpy = eglGetCurrentDisplay();
+    EGLImageKHR image = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+            (EGLClientBuffer)buffer, attrs);
+    if (image == EGL_NO_IMAGE_KHR) {
+        printf("Could not create an image %d\n", eglGetError());
+        return -1;
+    }
+
+    bufferObject->lock();
+    setOrientedCheckerboard(bufferObject);
+    // setSmoothGradient(bufferObject);
+    // setSmoothAlphaGradient(bufferObject);
+    bufferObject->unlock();
+
+    glGenTextures(1, &texture);
+    glBindTexture(GL_TEXTURE_2D, texture);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+#ifdef USE_LINEAR
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+#elif defined(USE_NEAREST)
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+#endif
+
+#ifdef USE_GL_REPLACE
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+#elif defined(USE_GL_MODULATE)
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+#endif
+
+#ifdef USE_ALPHA_COLOR
+    glColor4f(1.0f, 1.0f, 1.0f, 0.4f);
+#else
+    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+#endif
+
+#ifdef USE_BLEND
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+#endif
+    return 0;
+}
+
+static const int SCALE_COUNT = 12;
+
+int scale(int base, int factor) {
+    static const float kTable[SCALE_COUNT] = {
+            0.24f, 0.25f, 0.5f, 0.75f, 1.0f,
+            1.5f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 5.0f
+    };
+    return base * kTable[factor];
+}
+
+class Timer {
+    struct timeval  first;
+    double elapsedSeconds;
+
+public:
+    Timer() {}
+    void start() {
+        gettimeofday(&first, NULL);
+    }
+
+    void stop() {
+        struct timeval  second,
+                        elapsed;
+        gettimeofday(&second, NULL);
+
+        if (first.tv_usec > second.tv_usec) {
+           second.tv_usec += 1000000;
+           second.tv_sec--;
+        }
+
+        elapsedSeconds = (second.tv_sec  - first.tv_sec) +
+            (second.tv_usec - first.tv_usec) / 1000000.0;
+    }
+
+    double getElapsedSeconds() {
+        return elapsedSeconds;
+    }
+
+    double getElapsedMs() {
+        return elapsedSeconds* 1000.0f;
+    }
+};
+
+int testTime()
+{
+    static const int WIDTH = 320;
+    static const int HEIGHT = 480;
+    static const int SCALE = 8;
+
+    if (create_physical_texture(WIDTH, HEIGHT) != 0) {
+        return -1;
+    }
+    // Need to do a dummy eglSwapBuffers first. Don't know why.
+    glClearColor(0.4, 1.0, 0.4, 0.4);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(eglDisplay, eglSurface);
+
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+
+#if defined(USE_SCALE)
+    static const int scaleOffset = 0;
+#else
+    static const int scaleOffset = 1;
+#endif
+    printf("ms\n");
+    for(int j = 0; j < SCALE; j++) {
+        int w = WIDTH >> (j + scaleOffset);
+        int h = HEIGHT >> j;
+        int cropRect[4] = {0,h,w,-h}; // Left bottom width height. Width and Height can be neg to flip.
+        glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
+        Timer timer;
+        timer.start();
+
+        int copyCount = 1000;
+        for (int i = 0; i < copyCount; i++) {
+            glDrawTexiOES(0, 0, 0, w, h);
+        }
+
+        timer.stop();
+        printf("%g\n", timer.getElapsedMs() / copyCount);
+    }
+
+    eglSwapBuffers(eglDisplay, eglSurface);
+    return 0;
+}
+
+int testStretch()
+{
+    static const int WIDTH = 8;
+    static const int HEIGHT = 8;
+
+    if (create_physical_texture(WIDTH, HEIGHT) != 0) {
+        return -1;
+    }
+    // Need to do a dummy eglSwapBuffers first. Don't know why.
+    glClearColor(0.4, 1.0, 0.4, 1.0);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(eglDisplay, eglSurface);
+    
+    int cropRect[4] = {0,HEIGHT,WIDTH,-HEIGHT}; // Left bottom width height. Width and Height can be neg to flip.
+    glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
+
+    for(int frame = 0; frame < 2; frame++) {
+        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+        int baseX = 10;
+        for (int x = 0; x < SCALE_COUNT; x++) {
+            int baseY = 10;
+            int width = scale(WIDTH, x);
+            for (int y = 0; y < SCALE_COUNT; y++) {
+                int height = scale(HEIGHT, y);
+                glDrawTexxOES(baseX << 16, baseY << 16, 0, width << 16, height << 16);
+                baseY += height + 10;
+            }
+            baseX += width + 10;
+        }
+
+        eglSwapBuffers(eglDisplay, eglSurface);
+        LOGD("wait 1s");
+        usleep(1000000);
+    }
+    return 0;
+}
+
+int testRot90()
+{
+    static const int WIDTH = 8;
+    static const int HEIGHT = 8;
+
+    if (create_physical_texture(WIDTH, HEIGHT) != 0) {
+        return -1;
+    }
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrthof(0, 320, 480, 0, 0, 1);
+
+    glMatrixMode(GL_MODELVIEW);
+
+    glLoadIdentity();
+
+    // Need to do a dummy eglSwapBuffers first. Don't know why.
+    glClearColor(0.4, 0.4, 0.4, 0.4);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    eglSwapBuffers(eglDisplay, eglSurface);
+
+    glEnable(GL_TEXTURE_2D);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
+    glDisable(GL_BLEND);
+    glShadeModel(GL_FLAT);
+    glDisable(GL_DITHER);
+    glDisable(GL_CULL_FACE);
+
+    for(int frame = 0; frame < 2; frame++) {
+        LOGD("frame = %d", frame);
+        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+        int baseX = 10;
+        for (int x = 0; x < SCALE_COUNT; x++) {
+            int baseY = 10;
+            int width = scale(WIDTH, x);
+            for (int y = 0; y < SCALE_COUNT; y++) {
+                int height = scale(HEIGHT, y);
+
+                // Code copied from SurfaceFlinger LayerBase.cpp
+
+                const GLfixed texCoords[4][2] = {
+                        { 0,        0 },
+                        { 0,        0x10000 },
+                        { 0x10000,  0x10000 },
+                        { 0x10000,  0 }
+                };
+
+                GLfixed fx = baseX << 16;
+                GLfixed fy = baseY << 16;
+                GLfixed fw = width << 16;
+                GLfixed fh = height << 16;
+
+                /*
+                 * Vertex pattern:
+                 *    (2)--(3)
+                 *     |\   |
+                 *     | \  |
+                 *     |  \ |
+                 *     |   \|
+                 *    (1)--(0)
+                 *
+                 */
+
+                const GLfixed vertices[4][2] = {
+                        {fx + fw, fy},
+                        {fx,      fy},
+                        {fx,      fy + fh},
+                        {fx + fw, fy + fh}
+                };
+
+                static const bool rotate90 = true;
+
+                glMatrixMode(GL_TEXTURE);
+                glLoadIdentity();
+
+                glEnableClientState(GL_VERTEX_ARRAY);
+                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+                glVertexPointer(2, GL_FIXED, 0, vertices);
+                glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+                LOGD("testRot90 %d, %d %d, %d", baseX, baseY, width, height);
+                glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+                baseY += height + 10;
+            }
+            baseX += width + 10;
+        }
+
+        eglSwapBuffers(eglDisplay, eglSurface);
+    }
+    return 0;
+}
+
+int main(int argc, char **argv)
+{
+
+    int q;
+    int start, end;
+
+    if (init_gralloc()) {
+        printf("gralloc initialization failed - exiting\n");
+        return 0;
+    }
+
+    printf("Initializing EGL...\n");
+
+    if(!init_gl_surface())
+    {
+        printf("GL initialisation failed - exiting\n");
+        return 0;
+    }
+
+    init_scene();
+
+    printf("Start test...\n");
+    // testTime();
+     testStretch();
+    //testRot90();
+    free_gl_surface();
+
+    return 0;
+}