implement dimming with a texture on msm7k so it uses copybit
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index 16936e3..29b88e9 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -21,6 +21,10 @@
 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)
 	ifeq ($(HOST_OS),linux)
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
index c1e8ad6..b95e184 100644
--- a/libs/surfaceflinger/LayerDim.cpp
+++ b/libs/surfaceflinger/LayerDim.cpp
@@ -31,16 +31,73 @@
 const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
 const char* const LayerDim::typeID = "LayerDim";
 
+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)
+    : LayerBaseClient(flinger, display, client, i)
 {
 }
 
 void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
 {
+    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.width * t.stride * 2);
+        buffer->unlock();
+        sUseTexture = true;
+    }
+#endif
 }
 
 LayerDim::~LayerDim()
@@ -49,8 +106,6 @@
 
 void LayerDim::onDraw(const Region& clip) const
 {
-    // FIXME: on some h/w (like msm7K, it will be faster to use a texture)
-    
     const State& s(drawingState());
     Region::const_iterator it = clip.begin();
     Region::const_iterator const end = clip.end();
@@ -58,12 +113,42 @@
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         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);
+        
+#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);
+        }
+
+        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());
@@ -71,6 +156,7 @@
             glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
         }
     }
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 }
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h
index 0d5bb98..d9b70b4 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;
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index ebe315a..ac13340 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -180,6 +180,7 @@
     friend class LayerBaseClient;
     friend class Layer;
     friend class LayerBlur;
+    friend class LayerDim;
 
     sp<ISurface> createSurface(ClientID client, int pid, 
             ISurfaceFlingerClient::surface_data_t* params,