diff options
author | Mathias Agopian <mathias@google.com> | 2009-10-27 23:33:48 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2009-10-28 14:49:44 -0700 |
commit | 2ad8ec50a5aa91ad4881602467d41c8a54cbf6e4 (patch) | |
tree | b4e55573b45d314a2b80998d2796fca7aaf45363 /opengl | |
parent | d5493f3f5e7e971a98dd508874613a6a68196cd2 (diff) | |
download | frameworks_native-2ad8ec50a5aa91ad4881602467d41c8a54cbf6e4.zip frameworks_native-2ad8ec50a5aa91ad4881602467d41c8a54cbf6e4.tar.gz frameworks_native-2ad8ec50a5aa91ad4881602467d41c8a54cbf6e4.tar.bz2 |
fix [2071412] work around mdp 32-bits fade limitation
in the case where we fade a 32-bits surface (ie: GL_MODULATE w/ a,a,a,a + blending),
we first make a copy of the background into a RGB buffer, then we blend the 32-bits
surface as usual (without the alpha component), and finally blend the copy of
the background on top with 1-a. This uses a lot of bandwidth, but no CPU time.
Diffstat (limited to 'opengl')
-rw-r--r-- | opengl/libagl/copybit.cpp | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp index 0c3d0ee..4b9e59b 100644 --- a/opengl/libagl/copybit.cpp +++ b/opengl/libagl/copybit.cpp @@ -154,6 +154,8 @@ static bool copybit(GLint x, GLint y, int transform, ogles_context_t* c) { + status_t err = NO_ERROR; + // We assume checkContext has already been called and has already // returned true. @@ -200,6 +202,7 @@ static bool copybit(GLint x, GLint y, const uint32_t enables = c->rasterizer.state.enables; int planeAlpha = 255; + bool alphaPlaneWorkaround = false; static const int tmu = 0; texture_t& tev(c->rasterizer.state.texture[tmu]); int32_t opFormat = textureObject->surface.format; @@ -259,9 +262,10 @@ static bool copybit(GLint x, GLint y, if (c->currentColorClamped.r == c->currentColorClamped.a && c->currentColorClamped.g == c->currentColorClamped.a && c->currentColorClamped.b == c->currentColorClamped.a) { - // TODO: Need to emulate: RGBA source, color={a,a,a,a} / premult - // and RGBA source, color={1,1,1,a} / regular-blending - // (both are equivalent) + // TODO: RGBA source, color={1,1,1,a} / regular-blending + // is equivalent + alphaPlaneWorkaround = true; + break; } } LOGD_IF(DEBUG_COPYBIT, "GGL_MODULATE"); @@ -331,13 +335,13 @@ static bool copybit(GLint x, GLint y, tmp_w, tmp_h, src.format, GraphicBuffer::USAGE_HW_2D); - status_t err = tempBitmap->initCheck(); + err = tempBitmap->initCheck(); if (err == NO_ERROR) { copybit_image_t tmp_dst; copybit_rect_t tmp_rect; tmp_dst.w = tmp_w; tmp_dst.h = tmp_h; - tmp_dst.format = src.format; + tmp_dst.format = tempBitmap->format; tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle; tmp_rect.l = 0; tmp_rect.t = 0; @@ -359,13 +363,66 @@ static bool copybit(GLint x, GLint y, textureToCopyBitImage(&cbSurface, cbSurface.format, target_hnd, &dst); copybit_rect_t drect = {x, y, x+w, y+h}; - 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); + /* and now the alpha-plane hack. This handles the "Fade" case of a + * texture with an alpha channel. + */ + if (alphaPlaneWorkaround) { + sp<GraphicBuffer> tempCb = new GraphicBuffer( + w, h, COPYBIT_FORMAT_RGB_565, + GraphicBuffer::USAGE_HW_2D); + + err = tempCb->initCheck(); + + copybit_image_t tmpCbImg; + copybit_rect_t tmpCbRect; + tmpCbImg.w = w; + tmpCbImg.h = h; + tmpCbImg.format = tempCb->format; + tmpCbImg.handle = (native_handle_t*)tempCb->getNativeBuffer()->handle; + tmpCbRect.l = 0; + tmpCbRect.t = 0; + tmpCbRect.r = w; + tmpCbRect.b = h; + + if (!err) { + // first make a copy of the destination buffer + region_iterator tmp_it(Region(Rect(w, h))); + 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, + &tmpCbImg, &dst, &tmpCbRect, &drect, &tmp_it); + } + if (!err) { + // then proceed as usual, but without the alpha plane + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); + copybit->set_parameter(copybit, COPYBIT_DITHER, + (enables & GGL_ENABLE_DITHER) ? + COPYBIT_ENABLE : COPYBIT_DISABLE); + clipRectRegion it(c); + err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + } + if (!err) { + // finally copy back the destination on top with 1-alphaplane + int invPlaneAlpha = 0xFF - fixedToByte(c->currentColorClamped.a); + clipRectRegion it(c); + copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); + copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, invPlaneAlpha); + copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); + err = copybit->stretch(copybit, + &dst, &tmpCbImg, &drect, &tmpCbRect, &it); + } + } else { + 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); + err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); + } if (err != NO_ERROR) { c->textures.tmu[0].texture->try_copybit = false; } |