From 2bb8f5606d4a28549d95005304305b3aff1ce090 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Tue, 17 Feb 2015 16:42:02 -0800 Subject: Glop text shadows, clearLayerRegions, and rectangleList Change-Id: I83b36d1ee5d8f05f41acf244639019f9b8da79cd --- libs/hwui/FloatColor.h | 7 ++++ libs/hwui/GlopBuilder.cpp | 64 +++++++++++++++++++++++++----- libs/hwui/GlopBuilder.h | 6 ++- libs/hwui/OpenGLRenderer.cpp | 93 +++++++++++++++++++++++++++++++------------- 4 files changed, 131 insertions(+), 39 deletions(-) (limited to 'libs') diff --git a/libs/hwui/FloatColor.h b/libs/hwui/FloatColor.h index b3bd5fd..97dec88 100644 --- a/libs/hwui/FloatColor.h +++ b/libs/hwui/FloatColor.h @@ -31,6 +31,13 @@ struct FloatColor { b = a * ((color ) & 0xff) / 255.0f; } + bool isNotBlack() { + return a < 1.0f + || r > 0.0f + || g > 0.0f + || b > 0.0f; + } + float r; float g; float b; diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp index bdc5c5c..f133d42 100644 --- a/libs/hwui/GlopBuilder.cpp +++ b/libs/hwui/GlopBuilder.cpp @@ -271,10 +271,7 @@ GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, bool isAlphaMask } if (isAlphaMaskTexture) { - mDescription.modulate = mOutGlop->fill.color.a < 1.0f - || mOutGlop->fill.color.r > 0.0f - || mOutGlop->fill.color.g > 0.0f - || mOutGlop->fill.color.b > 0.0f; + mDescription.modulate = mOutGlop->fill.color.isNotBlack(); } else { mDescription.modulate = mOutGlop->fill.color.a < 1.0f; } @@ -295,27 +292,74 @@ GlopBuilder& GlopBuilder::setFillPaint(const SkPaint& paint, float alphaScale) { return *this; } -GlopBuilder& GlopBuilder::setFillPathTexturePaint(Texture& texture, +GlopBuilder& GlopBuilder::setFillPathTexturePaint(PathTexture& texture, const SkPaint& paint, float alphaScale) { TRIGGER_STAGE(kFillStage); REQUIRE_STAGES(kMeshStage); mOutGlop->fill.texture = &texture; - //specify invalid, since these are always static for path textures + //specify invalid, since these are always static for PathTextures mOutGlop->fill.textureFilter = GL_INVALID_ENUM; mOutGlop->fill.textureClamp = GL_INVALID_ENUM; setFill(paint.getColor(), alphaScale, PaintUtils::getXfermode(paint.getXfermode()), paint.getShader(), paint.getColorFilter()); - mDescription.modulate = mOutGlop->fill.color.a < 1.0f - || mOutGlop->fill.color.r > 0.0f - || mOutGlop->fill.color.g > 0.0f - || mOutGlop->fill.color.b > 0.0f; + mDescription.modulate = mOutGlop->fill.color.isNotBlack(); return *this; } +GlopBuilder& GlopBuilder::setFillShadowTexturePaint(ShadowTexture& texture, int shadowColor, + const SkPaint& paint, float alphaScale) { + TRIGGER_STAGE(kFillStage); + REQUIRE_STAGES(kMeshStage); + + mOutGlop->fill.texture = &texture; + + //specify invalid, since these are always static for ShadowTextures + mOutGlop->fill.textureFilter = GL_INVALID_ENUM; + mOutGlop->fill.textureClamp = GL_INVALID_ENUM; + + const int ALPHA_BITMASK = SK_ColorBLACK; + const int COLOR_BITMASK = ~ALPHA_BITMASK; + if ((shadowColor & ALPHA_BITMASK) == ALPHA_BITMASK) { + // shadow color is fully opaque: override its alpha with that of paint + shadowColor &= paint.getColor() | COLOR_BITMASK; + } + + setFill(shadowColor, alphaScale, PaintUtils::getXfermode(paint.getXfermode()), + paint.getShader(), paint.getColorFilter()); + + mDescription.modulate = mOutGlop->fill.color.isNotBlack(); + return *this; +} + +GlopBuilder& GlopBuilder::setFillBlack() { + TRIGGER_STAGE(kFillStage); + REQUIRE_STAGES(kMeshStage); + + mOutGlop->fill.texture = nullptr; + mOutGlop->fill.textureFilter = GL_INVALID_ENUM; + mOutGlop->fill.textureClamp = GL_INVALID_ENUM; + + setFill(SK_ColorBLACK, 1.0f, SkXfermode::kSrcOver_Mode, nullptr, nullptr); + + return *this; +} + +GlopBuilder& GlopBuilder::setFillClear() { + TRIGGER_STAGE(kFillStage); + REQUIRE_STAGES(kMeshStage); + + mOutGlop->fill.texture = nullptr; + mOutGlop->fill.textureFilter = GL_INVALID_ENUM; + mOutGlop->fill.textureClamp = GL_INVALID_ENUM; + + setFill(SK_ColorBLACK, 1.0f, SkXfermode::kClear_Mode, nullptr, nullptr); + + return *this; +} //////////////////////////////////////////////////////////////////////////////// // Transform //////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h index 657e642..546e6c5 100644 --- a/libs/hwui/GlopBuilder.h +++ b/libs/hwui/GlopBuilder.h @@ -46,8 +46,12 @@ public: GlopBuilder& setFillPaint(const SkPaint& paint, float alphaScale); GlopBuilder& setFillTexturePaint(Texture& texture, bool isAlphaMaskTexture, const SkPaint* paint, float alphaScale); - GlopBuilder& setFillPathTexturePaint(Texture& texture, + GlopBuilder& setFillPathTexturePaint(PathTexture& texture, const SkPaint& paint, float alphaScale); + GlopBuilder& setFillShadowTexturePaint(ShadowTexture& texture, int shadowColor, + const SkPaint& paint, float alphaScale); + GlopBuilder& setFillBlack(); + GlopBuilder& setFillClear(); GlopBuilder& setTransformClip(const Matrix4& ortho, const Matrix4& transform, bool fudgingOffset); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 4761ab4..3f79cef 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1198,8 +1198,8 @@ void OpenGLRenderer::issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount) { } void OpenGLRenderer::clearLayerRegions() { - const size_t count = mLayers.size(); - if (count == 0) return; + const size_t quadCount = mLayers.size(); + if (quadCount == 0) return; if (!mState.currentlyIgnored()) { EVENT_LOGD("clearLayerRegions"); @@ -1212,10 +1212,10 @@ void OpenGLRenderer::clearLayerRegions() { // is likely different so we need to disable clipping here bool scissorChanged = mRenderState.scissor().setEnabled(false); - Vertex mesh[count * 4]; + Vertex mesh[quadCount * 4]; Vertex* vertex = mesh; - for (uint32_t i = 0; i < count; i++) { + for (uint32_t i = 0; i < quadCount; i++) { const Rect& bounds = mLayers[i]; Vertex::set(vertex++, bounds.left, bounds.top); @@ -1228,18 +1228,30 @@ void OpenGLRenderer::clearLayerRegions() { // the same thing again mLayers.clear(); - SkPaint clearPaint; - clearPaint.setXfermodeMode(SkXfermode::kClear_Mode); + if (USE_GLOPS) { + Glop glop; + GlopBuilder aBuilder(mRenderState, mCaches, &glop); + aBuilder.setMeshIndexedQuads(&mesh[0], quadCount) + .setFillClear() + .setTransformClip(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) + .setModelViewOffsetRect(0, 0, currentSnapshot()->getClipRect()) + .setRoundRectClipState(currentSnapshot()->roundRectClipState) + .build(); + renderGlop(glop); + } else { + SkPaint clearPaint; + clearPaint.setXfermodeMode(SkXfermode::kClear_Mode); - setupDraw(false); - setupDrawColor(0.0f, 0.0f, 0.0f, 1.0f); - setupDrawBlending(&clearPaint, true); - setupDrawProgram(); - setupDrawPureColorUniforms(); - setupDrawModelView(kModelViewMode_Translate, false, - 0.0f, 0.0f, 0.0f, 0.0f, true); + setupDraw(false); + setupDrawColor(0.0f, 0.0f, 0.0f, 1.0f); + setupDrawBlending(&clearPaint, true); + setupDrawProgram(); + setupDrawPureColorUniforms(); + setupDrawModelView(kModelViewMode_Translate, false, + 0.0f, 0.0f, 0.0f, 0.0f, true); - issueIndexedQuadDraw(&mesh[0], count); + issueIndexedQuadDraw(&mesh[0], quadCount); + } if (scissorChanged) mRenderState.scissor().setEnabled(true); } else { @@ -1391,11 +1403,11 @@ static void handlePointNoTransform(std::vector& rectangleVertices, float } void OpenGLRenderer::drawRectangleList(const RectangleList& rectangleList) { - int count = rectangleList.getTransformedRectanglesCount(); - std::vector rectangleVertices(count * 4); + int quadCount = rectangleList.getTransformedRectanglesCount(); + std::vector rectangleVertices(quadCount * 4); Rect scissorBox = rectangleList.calculateBounds(); scissorBox.snapToPixelBoundaries(); - for (int i = 0; i < count; ++i) { + for (int i = 0; i < quadCount; ++i) { const TransformedRectangle& tr(rectangleList.getTransformedRectangle(i)); const Matrix4& transform = tr.getTransform(); Rect bounds = tr.getBounds(); @@ -1420,6 +1432,19 @@ void OpenGLRenderer::drawRectangleList(const RectangleList& rectangleList) { mRenderState.scissor().set(scissorBox.left, getViewportHeight() - scissorBox.bottom, scissorBox.getWidth(), scissorBox.getHeight()); + if (USE_GLOPS) { + Glop glop; + GlopBuilder aBuilder(mRenderState, mCaches, &glop); + aBuilder.setMeshIndexedQuads(&rectangleVertices[0], rectangleVertices.size() / 4) + .setFillBlack() + .setTransformClip(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) + .setModelViewOffsetRect(0, 0, scissorBox) + .setRoundRectClipState(currentSnapshot()->roundRectClipState) + .build(); + renderGlop(glop); + return; + } + const SkPaint* paint = nullptr; setupDraw(); setupDrawNoTexture(); @@ -2654,17 +2679,30 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, // NOTE: The drop shadow will not perform gamma correction // if shader-based correction is enabled mCaches.dropShadowCache.setFontRenderer(fontRenderer); - const ShadowTexture* shadow = mCaches.dropShadowCache.get( + ShadowTexture* texture = mCaches.dropShadowCache.get( paint, text, bytesCount, count, textShadow.radius, positions); // If the drop shadow exceeds the max texture size or couldn't be // allocated, skip drawing - if (!shadow) return; - const AutoTexture autoCleanup(shadow); + if (!texture) return; + const AutoTexture autoCleanup(texture); - const float sx = x - shadow->left + textShadow.dx; - const float sy = y - shadow->top + textShadow.dy; + const float sx = x - texture->left + textShadow.dx; + const float sy = y - texture->top + textShadow.dy; - const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * writableSnapshot()->alpha; + if (USE_GLOPS) { + Glop glop; + GlopBuilder aBuilder(mRenderState, mCaches, &glop); + aBuilder.setMeshTexturedUnitQuad(nullptr, true) + .setFillShadowTexturePaint(*texture, textShadow.color, *paint, currentSnapshot()->alpha) + .setTransformClip(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width, sy + texture->height)) + .setRoundRectClipState(currentSnapshot()->roundRectClipState) + .build(); + renderGlop(glop); + return; + } + + const int shadowAlpha = ((textShadow.color >> 24) & 0xFF) * currentSnapshot()->alpha; if (getShader(paint)) { textShadow.color = SK_ColorWHITE; } @@ -2677,8 +2715,8 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, setupDrawBlending(paint, true); setupDrawProgram(); setupDrawModelView(kModelViewMode_TranslateAndScale, false, - sx, sy, sx + shadow->width, sy + shadow->height); - setupDrawTexture(shadow->id); + sx, sy, sx + texture->width, sy + texture->height); + setupDrawTexture(texture->id); setupDrawPureColorUniforms(); setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawShaderUniforms(getShader(paint)); @@ -3010,7 +3048,6 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { DRAW_DOUBLE_STENCIL_IF(!layer->hasDrawnSinceUpdate, composeLayerRect(layer, layer->regionRect)); } else if (layer->mesh) { - const float a = getLayerAlpha(layer); setupDraw(); setupDrawWithTexture(); @@ -3093,8 +3130,8 @@ Texture* OpenGLRenderer::getTexture(const SkBitmap* bitmap) { return texture; } -void OpenGLRenderer::drawPathTexture(PathTexture* texture, - float x, float y, const SkPaint* paint) { +void OpenGLRenderer::drawPathTexture(PathTexture* texture, float x, float y, + const SkPaint* paint) { if (quickRejectSetupScissor(x, y, x + texture->width, y + texture->height)) { return; } -- cgit v1.1