diff options
Diffstat (limited to 'libs/hwui/OpenGLRenderer.cpp')
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 107 |
1 files changed, 77 insertions, 30 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index e764778..305c8c5 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -40,34 +40,42 @@ namespace uirenderer { // Globals /////////////////////////////////////////////////////////////////////////////// -const SimpleVertex gDrawColorVertices[] = { +static const SimpleVertex gDrawColorVertices[] = { SV(0.0f, 0.0f), SV(1.0f, 0.0f), SV(0.0f, 1.0f), SV(1.0f, 1.0f) }; -const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex); -const GLsizei gDrawColorVertexCount = 4; +static const GLsizei gDrawColorVertexStride = sizeof(SimpleVertex); +static const GLsizei gDrawColorVertexCount = 4; -TextureVertex gDrawTextureVertices[] = { +// This array is never used directly but used as a memcpy source in the +// OpenGLRenderer constructor +static const TextureVertex gDrawTextureVertices[] = { FV(0.0f, 0.0f, 0.0f, 1.0f), FV(1.0f, 0.0f, 1.0f, 1.0f), FV(0.0f, 1.0f, 0.0f, 0.0f), FV(1.0f, 1.0f, 1.0f, 0.0f) }; -const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex); -const GLsizei gDrawTextureVertexCount = 4; - -static inline void resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) { - gDrawTextureVertices[0].texture[0] = u1; - gDrawTextureVertices[0].texture[1] = v2; - gDrawTextureVertices[1].texture[0] = u2; - gDrawTextureVertices[1].texture[1] = v2; - gDrawTextureVertices[2].texture[0] = u1; - gDrawTextureVertices[2].texture[1] = v1; - gDrawTextureVertices[3].texture[0] = u2; - gDrawTextureVertices[3].texture[1] = v1; -} +static const GLsizei gDrawTextureVertexStride = sizeof(TextureVertex); +static const GLsizei gDrawTextureVertexCount = 4; + +// In this array, the index of each Blender equals the value of the first +// entry. For instance, gBlends[1] == gBlends[SkXfermode::kSrc_Mode] +static const Blender gBlends[] = { + { SkXfermode::kClear_Mode, GL_ZERO, GL_ZERO }, + { SkXfermode::kSrc_Mode, GL_ONE, GL_ZERO }, + { SkXfermode::kDst_Mode, GL_ZERO, GL_ONE }, + { SkXfermode::kSrcOver_Mode, GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, + { SkXfermode::kDstOver_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ONE }, + { SkXfermode::kSrcIn_Mode, GL_DST_ALPHA, GL_ZERO }, + { SkXfermode::kDstIn_Mode, GL_ZERO, GL_SRC_ALPHA }, + { SkXfermode::kSrcOut_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, + { SkXfermode::kDstOut_Mode, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, + { SkXfermode::kSrcATop_Mode, GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, + { SkXfermode::kDstATop_Mode, GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, + { SkXfermode::kXor_Mode, GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA } +}; /////////////////////////////////////////////////////////////////////////////// // Constructors/destructor @@ -78,6 +86,8 @@ OpenGLRenderer::OpenGLRenderer() { mDrawColorShader = new DrawColorProgram; mDrawTextureShader = new DrawTextureProgram; + + memcpy(mDrawTextureVertices, gDrawTextureVertices, sizeof(gDrawTextureVertices)); } OpenGLRenderer::~OpenGLRenderer() { @@ -336,22 +346,43 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) /////////////////////////////////////////////////////////////////////////////// void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { - // TODO: Set the transfer mode const Rect& clip = mSnapshot->clipRect; - drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color); + drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode); } void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, const SkPaint* p) { - // TODO Support more than just color - // TODO: Set the transfer mode - drawColorRect(left, top, right, bottom, p->getColor()); + SkXfermode::Mode mode; + + const bool isMode = SkXfermode::IsMode(p->getXfermode(), &mode); + if (!isMode) { + // Assume SRC_OVER + mode = SkXfermode::kSrcOver_Mode; + } + + // Skia draws using the color's alpha channel if < 255 + // Otherwise, it uses the paint's alpha + int color = p->getColor(); + if (((color >> 24) & 0xFF) == 255) { + color |= p->getAlpha() << 24; + } + + drawColorRect(left, top, right, bottom, color, mode); } -void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, int color) { - GLfloat a = ((color >> 24) & 0xFF) / 255.0f; - GLfloat r = ((color >> 16) & 0xFF) / 255.0f; - GLfloat g = ((color >> 8) & 0xFF) / 255.0f; - GLfloat b = ((color ) & 0xFF) / 255.0f; +void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, + int color, SkXfermode::Mode mode) { + const int alpha = (color >> 24) & 0xFF; + const bool blend = alpha < 255 || mode != SkXfermode::kSrcOver_Mode; + + const GLfloat a = alpha / 255.0f; + const GLfloat r = ((color >> 16) & 0xFF) / 255.0f; + const GLfloat g = ((color >> 8) & 0xFF) / 255.0f; + const GLfloat b = ((color ) & 0xFF) / 255.0f; + + if (blend) { + glEnable(GL_BLEND); + glBlendFunc(gBlends[mode].src, gBlends[mode].dst); + } mModelView.loadTranslate(left, top, 0.0f); mModelView.scale(right - left, bottom - top, 1.0f); @@ -368,6 +399,10 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot glDrawArrays(GL_TRIANGLE_STRIP, 0, gDrawColorVertexCount); glDisableVertexAttribArray(mDrawColorShader->position); + + if (blend) { + glDisable(GL_BLEND); + } } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, @@ -379,15 +414,16 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b // TODO Correctly set the blend function, based on texture format and xfermode glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + // For not pre-multiplied sources + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBindTexture(GL_TEXTURE_2D, texture); glActiveTexture(GL_TEXTURE0); glUniform1i(mDrawTextureShader->sampler, 0); - const GLvoid* p = &gDrawTextureVertices[0].position[0]; - const GLvoid* t = &gDrawTextureVertices[0].texture[0]; + const GLvoid* p = &mDrawTextureVertices[0].position[0]; + const GLvoid* t = &mDrawTextureVertices[0].texture[0]; glEnableVertexAttribArray(mDrawTextureShader->position); glVertexAttribPointer(mDrawTextureShader->position, 2, GL_FLOAT, GL_FALSE, @@ -408,5 +444,16 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b glDisable(GL_BLEND); } +void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) { + mDrawTextureVertices[0].texture[0] = u1; + mDrawTextureVertices[0].texture[1] = v2; + mDrawTextureVertices[1].texture[0] = u2; + mDrawTextureVertices[1].texture[1] = v2; + mDrawTextureVertices[2].texture[0] = u1; + mDrawTextureVertices[2].texture[1] = v1; + mDrawTextureVertices[3].texture[0] = u2; + mDrawTextureVertices[3].texture[1] = v1; +} + }; // namespace uirenderer }; // namespace android |
