Loading libs/hwui/OpenGLRenderer.cpp +48 −48 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ static const Blender gBlends[] = { /////////////////////////////////////////////////////////////////////////////// OpenGLRenderer::OpenGLRenderer(): mBlend(false), mLastSrcMode(GL_ZERO), mLastDstMode(GL_ZERO), mTextureCache(MB(DEFAULT_TEXTURE_CACHE_SIZE)), mLayerCache(MB(DEFAULT_LAYER_CACHE_SIZE)), mPatchCache(DEFAULT_PATCH_CACHE_SIZE) { Loading Loading @@ -242,7 +243,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { const Rect& rect = layer->layer; drawTextureRect(rect.left, rect.top, rect.right, rect.bottom, layer->texture, layer->alpha, layer->mode, layer->blend, true); layer->texture, layer->alpha, layer->mode, layer->blend); LayerSize size(rect.getWidth(), rect.getHeight()); // Failing to add the layer to the cache should happen only if the Loading Loading @@ -421,13 +422,7 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint) { const Texture* texture = mTextureCache.get(bitmap); int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); drawTextureRect(left, top, left + texture->width, top + texture->height, texture->id, alpha / 255.0f, mode, texture->blend, true); drawTextureRect(left, top, left + texture->width, top + texture->height, texture, paint); } void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint) { Loading @@ -436,13 +431,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const transform.mapRect(r); const Texture* texture = mTextureCache.get(bitmap); int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); drawTextureRect(r.left, r.top, r.right, r.bottom, texture->id, alpha / 255.0f, mode, texture->blend, true); drawTextureRect(r.left, r.top, r.right, r.bottom, texture, paint); } void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, Loading @@ -451,10 +440,6 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkPaint* paint) { const Texture* texture = mTextureCache.get(bitmap); int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); const float width = texture->width; const float height = texture->height; Loading @@ -465,8 +450,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, resetDrawTextureTexCoords(u1, v1, u2, v2); drawTextureRect(dstLeft, dstTop, dstRight, dstBottom, texture->id, alpha / 255.0f, mode, texture->blend, true); drawTextureRect(dstLeft, dstTop, dstRight, dstBottom, texture, paint); resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); } Loading Loading @@ -606,17 +590,12 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, 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); } chooseBlending(alpha < 255, mode, true); mModelView.loadTranslate(left, top, 0.0f); mModelView.scale(right - left, bottom - top, 1.0f); Loading @@ -633,10 +612,17 @@ 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, const Texture* texture, const SkPaint* paint, bool isPremultiplied) { int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode, texture->blend, isPremultiplied, &mDrawTextureVertices[0].position[0], &mDrawTextureVertices[0].texture[0], NULL); } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, Loading @@ -653,15 +639,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]); if (blend || alpha < 1.0f || mode != SkXfermode::kSrcOver_Mode) { GLenum sourceMode = gBlends[mode].src; if (!isPremultiplied && sourceMode == GL_ONE) { sourceMode = GL_SRC_ALPHA; } glEnable(GL_BLEND); glBlendFunc(sourceMode, gBlends[mode].dst); } chooseBlending(blend || alpha < 1.0f, mode, isPremultiplied); glBindTexture(GL_TEXTURE_2D, texture); Loading Loading @@ -690,18 +668,40 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b glDisableVertexAttribArray(mDrawTextureShader->texCoords); glBindTexture(GL_TEXTURE_2D, 0); } void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, bool isPremultiplied) { // In theory we should not blend if the mode is Src, but it's rare enough // that it's not worth it blend = blend || mode != SkXfermode::kSrcOver_Mode; if (blend) { if (!mBlend) { glEnable(GL_BLEND); } GLenum sourceMode = gBlends[mode].src; GLenum destMode = gBlends[mode].dst; if (!isPremultiplied && sourceMode == GL_ONE) { sourceMode = GL_SRC_ALPHA; } if (sourceMode != mLastSrcMode || destMode != mLastDstMode) { glBlendFunc(sourceMode, destMode); mLastSrcMode = sourceMode; mLastDstMode = destMode; } } else if (mBlend) { glDisable(GL_BLEND); } mBlend = blend; } void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) { mDrawTextureVertices[0].texture[0] = u1; mDrawTextureVertices[0].texture[1] = v1; mDrawTextureVertices[1].texture[0] = u2; mDrawTextureVertices[1].texture[1] = v1; mDrawTextureVertices[2].texture[0] = u1; mDrawTextureVertices[2].texture[1] = v2; mDrawTextureVertices[3].texture[0] = u2; mDrawTextureVertices[3].texture[1] = v2; TextureVertex* v = &mDrawTextureVertices[0]; TextureVertex::setUV(v++, u1, v1); TextureVertex::setUV(v++, u2, v1); TextureVertex::setUV(v++, u1, v2); TextureVertex::setUV(v++, u2, v2); } void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) { Loading libs/hwui/OpenGLRenderer.h +44 −2 Original line number Diff line number Diff line Loading @@ -179,10 +179,40 @@ private: * @param isPremultiplied Indicates whether the texture has premultiplied alpha */ void drawTextureRect(float left, float top, float right, float bottom, GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied = false); float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied = true); /** * TODO: documentation * Draws a textured rectangle with the specified texture. The specified coordinates * are transformed by the current snapshot's transform matrix. * * @param left The left coordinate of the rectangle * @param top The top coordinate of the rectangle * @param right The right coordinate of the rectangle * @param bottom The bottom coordinate of the rectangle * @param texture The texture to use * @param paint The paint containing the alpha, blending mode, etc. * @param isPremultiplied Indicates whether the texture has premultiplied alpha */ void drawTextureRect(float left, float top, float right, float bottom, const Texture* texture, const SkPaint* paint, bool isPremultiplied = true); /** * Draws a textured mesh with the specified texture. If the indices are omitted, the * mesh is drawn as a simple quad. * * @param left The left coordinate of the rectangle * @param top The top coordinate of the rectangle * @param right The right coordinate of the rectangle * @param bottom The bottom coordinate of the rectangle * @param texture The texture name to map onto the rectangle * @param alpha An additional translucency parameter, between 0.0f and 1.0f * @param mode The blending mode * @param blend True if the texture contains an alpha channel * @param isPremultiplied Indicates whether the texture has premultiplied alpha * @param vertices The vertices that define the mesh * @param texCoords The texture coordinates of each vertex * @param indices The indices of the vertices, can be NULL * @param elementsCount The number of elements in the mesh, required by indices */ void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied, Loading Loading @@ -217,6 +247,12 @@ private: inline void generateVertices(TextureVertex* vertex, float y, float v, const int32_t xDivs[], uint32_t xCount, float xStretch, float xStretchTex, float width, float widthTex); /** * Enable or disable blending as necessary. This function sets the appropriate * blend function based on the specified xfermode. */ inline void chooseBlending(bool blend, SkXfermode::Mode mode, bool isPremultiplied); // Dimensions of the drawing surface int mWidth, mHeight; Loading @@ -240,6 +276,12 @@ private: // Used to draw textured quads TextureVertex mDrawTextureVertices[4]; // Last known blend state bool mBlend; GLenum mLastSrcMode; GLenum mLastDstMode; // Various caches TextureCache mTextureCache; LayerCache mLayerCache; PatchCache mPatchCache; Loading libs/hwui/Vertex.h +5 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,11 @@ struct TextureVertex { vertex[0].texture[0] = u; vertex[0].texture[1] = v; } static inline void setUV(TextureVertex* vertex, float u, float v) { vertex[0].texture[0] = u; vertex[0].texture[1] = v; } }; // struct TextureVertex }; // namespace uirenderer Loading Loading
libs/hwui/OpenGLRenderer.cpp +48 −48 Original line number Diff line number Diff line Loading @@ -95,6 +95,7 @@ static const Blender gBlends[] = { /////////////////////////////////////////////////////////////////////////////// OpenGLRenderer::OpenGLRenderer(): mBlend(false), mLastSrcMode(GL_ZERO), mLastDstMode(GL_ZERO), mTextureCache(MB(DEFAULT_TEXTURE_CACHE_SIZE)), mLayerCache(MB(DEFAULT_LAYER_CACHE_SIZE)), mPatchCache(DEFAULT_PATCH_CACHE_SIZE) { Loading Loading @@ -242,7 +243,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { const Rect& rect = layer->layer; drawTextureRect(rect.left, rect.top, rect.right, rect.bottom, layer->texture, layer->alpha, layer->mode, layer->blend, true); layer->texture, layer->alpha, layer->mode, layer->blend); LayerSize size(rect.getWidth(), rect.getHeight()); // Failing to add the layer to the cache should happen only if the Loading Loading @@ -421,13 +422,7 @@ bool OpenGLRenderer::clipRect(float left, float top, float right, float bottom) void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, const SkPaint* paint) { const Texture* texture = mTextureCache.get(bitmap); int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); drawTextureRect(left, top, left + texture->width, top + texture->height, texture->id, alpha / 255.0f, mode, texture->blend, true); drawTextureRect(left, top, left + texture->width, top + texture->height, texture, paint); } void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const SkPaint* paint) { Loading @@ -436,13 +431,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix, const transform.mapRect(r); const Texture* texture = mTextureCache.get(bitmap); int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); drawTextureRect(r.left, r.top, r.right, r.bottom, texture->id, alpha / 255.0f, mode, texture->blend, true); drawTextureRect(r.left, r.top, r.right, r.bottom, texture, paint); } void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, Loading @@ -451,10 +440,6 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, const SkPaint* paint) { const Texture* texture = mTextureCache.get(bitmap); int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); const float width = texture->width; const float height = texture->height; Loading @@ -465,8 +450,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, resetDrawTextureTexCoords(u1, v1, u2, v2); drawTextureRect(dstLeft, dstTop, dstRight, dstBottom, texture->id, alpha / 255.0f, mode, texture->blend, true); drawTextureRect(dstLeft, dstTop, dstRight, dstBottom, texture, paint); resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f); } Loading Loading @@ -606,17 +590,12 @@ void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, 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); } chooseBlending(alpha < 255, mode, true); mModelView.loadTranslate(left, top, 0.0f); mModelView.scale(right - left, bottom - top, 1.0f); Loading @@ -633,10 +612,17 @@ 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, const Texture* texture, const SkPaint* paint, bool isPremultiplied) { int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode, texture->blend, isPremultiplied, &mDrawTextureVertices[0].position[0], &mDrawTextureVertices[0].texture[0], NULL); } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, Loading @@ -653,15 +639,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b mDrawTextureShader->use(&mOrthoMatrix[0], &mModelView.data[0], &mSnapshot->transform.data[0]); if (blend || alpha < 1.0f || mode != SkXfermode::kSrcOver_Mode) { GLenum sourceMode = gBlends[mode].src; if (!isPremultiplied && sourceMode == GL_ONE) { sourceMode = GL_SRC_ALPHA; } glEnable(GL_BLEND); glBlendFunc(sourceMode, gBlends[mode].dst); } chooseBlending(blend || alpha < 1.0f, mode, isPremultiplied); glBindTexture(GL_TEXTURE_2D, texture); Loading Loading @@ -690,18 +668,40 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b glDisableVertexAttribArray(mDrawTextureShader->texCoords); glBindTexture(GL_TEXTURE_2D, 0); } void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, bool isPremultiplied) { // In theory we should not blend if the mode is Src, but it's rare enough // that it's not worth it blend = blend || mode != SkXfermode::kSrcOver_Mode; if (blend) { if (!mBlend) { glEnable(GL_BLEND); } GLenum sourceMode = gBlends[mode].src; GLenum destMode = gBlends[mode].dst; if (!isPremultiplied && sourceMode == GL_ONE) { sourceMode = GL_SRC_ALPHA; } if (sourceMode != mLastSrcMode || destMode != mLastDstMode) { glBlendFunc(sourceMode, destMode); mLastSrcMode = sourceMode; mLastDstMode = destMode; } } else if (mBlend) { glDisable(GL_BLEND); } mBlend = blend; } void OpenGLRenderer::resetDrawTextureTexCoords(float u1, float v1, float u2, float v2) { mDrawTextureVertices[0].texture[0] = u1; mDrawTextureVertices[0].texture[1] = v1; mDrawTextureVertices[1].texture[0] = u2; mDrawTextureVertices[1].texture[1] = v1; mDrawTextureVertices[2].texture[0] = u1; mDrawTextureVertices[2].texture[1] = v2; mDrawTextureVertices[3].texture[0] = u2; mDrawTextureVertices[3].texture[1] = v2; TextureVertex* v = &mDrawTextureVertices[0]; TextureVertex::setUV(v++, u1, v1); TextureVertex::setUV(v++, u2, v1); TextureVertex::setUV(v++, u1, v2); TextureVertex::setUV(v++, u2, v2); } void OpenGLRenderer::getAlphaAndMode(const SkPaint* paint, int* alpha, SkXfermode::Mode* mode) { Loading
libs/hwui/OpenGLRenderer.h +44 −2 Original line number Diff line number Diff line Loading @@ -179,10 +179,40 @@ private: * @param isPremultiplied Indicates whether the texture has premultiplied alpha */ void drawTextureRect(float left, float top, float right, float bottom, GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied = false); float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied = true); /** * TODO: documentation * Draws a textured rectangle with the specified texture. The specified coordinates * are transformed by the current snapshot's transform matrix. * * @param left The left coordinate of the rectangle * @param top The top coordinate of the rectangle * @param right The right coordinate of the rectangle * @param bottom The bottom coordinate of the rectangle * @param texture The texture to use * @param paint The paint containing the alpha, blending mode, etc. * @param isPremultiplied Indicates whether the texture has premultiplied alpha */ void drawTextureRect(float left, float top, float right, float bottom, const Texture* texture, const SkPaint* paint, bool isPremultiplied = true); /** * Draws a textured mesh with the specified texture. If the indices are omitted, the * mesh is drawn as a simple quad. * * @param left The left coordinate of the rectangle * @param top The top coordinate of the rectangle * @param right The right coordinate of the rectangle * @param bottom The bottom coordinate of the rectangle * @param texture The texture name to map onto the rectangle * @param alpha An additional translucency parameter, between 0.0f and 1.0f * @param mode The blending mode * @param blend True if the texture contains an alpha channel * @param isPremultiplied Indicates whether the texture has premultiplied alpha * @param vertices The vertices that define the mesh * @param texCoords The texture coordinates of each vertex * @param indices The indices of the vertices, can be NULL * @param elementsCount The number of elements in the mesh, required by indices */ void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture, float alpha, SkXfermode::Mode mode, bool blend, bool isPremultiplied, Loading Loading @@ -217,6 +247,12 @@ private: inline void generateVertices(TextureVertex* vertex, float y, float v, const int32_t xDivs[], uint32_t xCount, float xStretch, float xStretchTex, float width, float widthTex); /** * Enable or disable blending as necessary. This function sets the appropriate * blend function based on the specified xfermode. */ inline void chooseBlending(bool blend, SkXfermode::Mode mode, bool isPremultiplied); // Dimensions of the drawing surface int mWidth, mHeight; Loading @@ -240,6 +276,12 @@ private: // Used to draw textured quads TextureVertex mDrawTextureVertices[4]; // Last known blend state bool mBlend; GLenum mLastSrcMode; GLenum mLastDstMode; // Various caches TextureCache mTextureCache; LayerCache mLayerCache; PatchCache mPatchCache; Loading
libs/hwui/Vertex.h +5 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,11 @@ struct TextureVertex { vertex[0].texture[0] = u; vertex[0].texture[1] = v; } static inline void setUV(TextureVertex* vertex, float u, float v) { vertex[0].texture[0] = u; vertex[0].texture[1] = v; } }; // struct TextureVertex }; // namespace uirenderer Loading