implement dimming with a texture on msm7k so it uses copybit
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);
 }
 
 // ---------------------------------------------------------------------------