diff options
author | Mathias Agopian <mathias@google.com> | 2009-06-18 18:48:39 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-06-18 18:48:39 -0700 |
commit | 945ebbfd3dc07c7168602a1603eeb76ea7425376 (patch) | |
tree | 84d870c92c75c4e01ce1da91de579342a75260ee /libs/surfaceflinger/LayerDim.cpp | |
parent | aa6e88b80854dbcaa12678e77ffd440006faf828 (diff) | |
download | frameworks_native-945ebbfd3dc07c7168602a1603eeb76ea7425376.zip frameworks_native-945ebbfd3dc07c7168602a1603eeb76ea7425376.tar.gz frameworks_native-945ebbfd3dc07c7168602a1603eeb76ea7425376.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.cpp | 96 |
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); } // --------------------------------------------------------------------------- |