summaryrefslogtreecommitdiffstats
path: root/libs/surfaceflinger/LayerDim.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2009-06-18 18:48:39 -0700
committerMathias Agopian <mathias@google.com>2009-06-18 18:48:39 -0700
commit9cc88529e4cbf54df3eed968666472d3fa658d13 (patch)
treeffa17c58d80a5604dea2438658348ef405d06316 /libs/surfaceflinger/LayerDim.cpp
parent42bf621e801183028066e6947fdd22eae8693a02 (diff)
downloadframeworks_base-9cc88529e4cbf54df3eed968666472d3fa658d13.zip
frameworks_base-9cc88529e4cbf54df3eed968666472d3fa658d13.tar.gz
frameworks_base-9cc88529e4cbf54df3eed968666472d3fa658d13.tar.bz2
implement dimming with a texture on msm7k so it uses copybit
Diffstat (limited to 'libs/surfaceflinger/LayerDim.cpp')
-rw-r--r--libs/surfaceflinger/LayerDim.cpp96
1 files changed, 91 insertions, 5 deletions
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 @@ namespace android {
const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
const char* const LayerDim::typeID = "LayerDim";
+bool LayerDim::sUseTexture;
+GLuint LayerDim::sTexId;
+EGLImageKHR LayerDim::sImage;
+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 @@ LayerDim::~LayerDim()
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 @@ void LayerDim::onDraw(const Region& clip) const
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 @@ void LayerDim::onDraw(const Region& clip) const
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
}
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
// ---------------------------------------------------------------------------