diff options
-rw-r--r-- | libs/hwui/FontRenderer.cpp | 13 | ||||
-rw-r--r-- | libs/hwui/Glop.h | 47 | ||||
-rw-r--r-- | libs/hwui/GlopBuilder.cpp | 91 | ||||
-rw-r--r-- | libs/hwui/GlopBuilder.h | 24 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 97 | ||||
-rwxr-xr-x | libs/hwui/OpenGLRenderer.h | 17 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.cpp | 15 | ||||
-rw-r--r-- | libs/hwui/SkiaShader.h | 2 | ||||
-rw-r--r-- | libs/hwui/renderstate/RenderState.cpp | 16 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderProxy.cpp | 13 |
10 files changed, 203 insertions, 132 deletions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index c79ae77..9664f58 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -51,17 +51,20 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// void TextDrawFunctor::draw(CacheTexture& texture, bool linearFiltering) { - int textureFillFlags = static_cast<int>(texture.getFormat() == GL_ALPHA - ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); + int textureFillFlags = TextureFillFlags::None; + if (texture.getFormat() == GL_ALPHA) { + textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture; + } if (linearFiltering) { - textureFillFlags |= TextureFillFlags::kForceFilter; + textureFillFlags |= TextureFillFlags::ForceFilter; } - const Matrix4& transform = pureTranslate ? Matrix4::identity() : *(renderer->currentTransform()); + int transformFlags = pureTranslate + ? TransformFlags::MeshIgnoresCanvasTransform : TransformFlags::None; Glop glop; GlopBuilder(renderer->mRenderState, renderer->mCaches, &glop) .setMeshTexturedIndexedQuads(texture.mesh(), texture.meshElementCount()) .setFillTexturePaint(texture.getTexture(), textureFillFlags, paint, renderer->currentSnapshot()->alpha) - .setTransform(renderer->currentSnapshot()->getOrthoMatrix(), transform, false) + .setTransform(*(renderer->currentSnapshot()), transformFlags) .setModelViewOffsetRect(0, 0, Rect(0, 0, 0, 0)) .setRoundRectClipState(renderer->currentSnapshot()->roundRectClipState) .build(); diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h index 2c6f6c1..fa20b08 100644 --- a/libs/hwui/Glop.h +++ b/libs/hwui/Glop.h @@ -41,13 +41,32 @@ class Texture; * Position is always enabled by MeshState, these other attributes * are enabled/disabled dynamically based on mesh content. */ -enum class VertexAttribFlags { - kNone = 0, - kTextureCoord = 1 << 0, - kColor = 1 << 1, - kAlpha = 1 << 2, + +namespace VertexAttribFlags { + enum { + None = 0, + TextureCoord = 1 << 0, + Color = 1 << 1, + Alpha = 1 << 2, + }; +}; + +/* + * Enumerates transform features + */ +namespace TransformFlags { + enum { + None = 0, + + // offset the eventual drawing matrix by a tiny amount to + // disambiguate sampling patterns with non-AA rendering + OffsetByFudgeFactor = 1 << 0, + + // Canvas transform isn't applied to the mesh at draw time, + //since it's already built in. + MeshIgnoresCanvasTransform = 1 << 1, + }; }; -MAKE_FLAGS_ENUM(VertexAttribFlags) /** * Structure containing all data required to issue an OpenGL draw @@ -116,10 +135,22 @@ struct Glop { } fill; struct Transform { - Matrix4 ortho; // TODO: out of op, since this is static per FBO + // Orthographic projection matrix for current FBO + // TODO: move out of Glop, since this is static per FBO + Matrix4 ortho; + + // modelView transform, accounting for delta between mesh transform and content of the mesh + // often represents x/y offsets within command, or scaling for mesh unit size Matrix4 modelView; + + // Canvas transform of Glop - not necessarily applied to geometry (see flags) Matrix4 canvas; - bool fudgingOffset; + int transformFlags; + + const Matrix4& meshTransform() const { + return (transformFlags & TransformFlags::MeshIgnoresCanvasTransform) + ? Matrix4::identity() : canvas; + } } transform; const RoundRectClipState* roundRectClipState; diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp index e25f81e..b7cdaa2 100644 --- a/libs/hwui/GlopBuilder.cpp +++ b/libs/hwui/GlopBuilder.cpp @@ -66,7 +66,7 @@ GlopBuilder& GlopBuilder::setMeshUnitQuad() { mOutGlop->mesh.indices = { 0, nullptr }; mOutGlop->mesh.vertices = { mRenderState.meshState().getUnitQuadVBO(), - static_cast<int>(VertexAttribFlags::kNone), + VertexAttribFlags::None, nullptr, nullptr, nullptr, kTextureVertexStride }; mOutGlop->mesh.elementCount = 4; @@ -85,7 +85,7 @@ GlopBuilder& GlopBuilder::setMeshTexturedUnitQuad(const UvMapper* uvMapper) { mOutGlop->mesh.indices = { 0, nullptr }; mOutGlop->mesh.vertices = { mRenderState.meshState().getUnitQuadVBO(), - static_cast<int>(VertexAttribFlags::kTextureCoord), + VertexAttribFlags::TextureCoord, nullptr, (const void*) kMeshTextureOffset, nullptr, kTextureVertexStride }; mOutGlop->mesh.elementCount = 4; @@ -105,7 +105,7 @@ GlopBuilder& GlopBuilder::setMeshTexturedUvQuad(const UvMapper* uvMapper, Rect u mOutGlop->mesh.indices = { 0, nullptr }; mOutGlop->mesh.vertices = { 0, - static_cast<int>(VertexAttribFlags::kTextureCoord), + VertexAttribFlags::TextureCoord, &textureVertex[0].x, &textureVertex[0].u, nullptr, kTextureVertexStride }; mOutGlop->mesh.elementCount = 4; @@ -119,7 +119,7 @@ GlopBuilder& GlopBuilder::setMeshIndexedQuads(Vertex* vertexData, int quadCount) mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr }; mOutGlop->mesh.vertices = { 0, - static_cast<int>(VertexAttribFlags::kNone), + VertexAttribFlags::None, vertexData, nullptr, nullptr, kVertexStride }; mOutGlop->mesh.elementCount = 6 * quadCount; @@ -133,7 +133,7 @@ GlopBuilder& GlopBuilder::setMeshTexturedIndexedQuads(TextureVertex* vertexData, mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr }; mOutGlop->mesh.vertices = { 0, - static_cast<int>(VertexAttribFlags::kTextureCoord), + VertexAttribFlags::TextureCoord, &vertexData[0].x, &vertexData[0].u, nullptr, kTextureVertexStride }; mOutGlop->mesh.elementCount = elementCount; @@ -147,7 +147,7 @@ GlopBuilder& GlopBuilder::setMeshTexturedMesh(TextureVertex* vertexData, int ele mOutGlop->mesh.indices = { 0, nullptr }; mOutGlop->mesh.vertices = { 0, - static_cast<int>(VertexAttribFlags::kTextureCoord), + VertexAttribFlags::TextureCoord, &vertexData[0].x, &vertexData[0].u, nullptr, kTextureVertexStride }; mOutGlop->mesh.elementCount = elementCount; @@ -161,7 +161,7 @@ GlopBuilder& GlopBuilder::setMeshColoredTexturedMesh(ColorTextureVertex* vertexD mOutGlop->mesh.indices = { 0, nullptr }; mOutGlop->mesh.vertices = { 0, - VertexAttribFlags::kTextureCoord | VertexAttribFlags::kColor, + VertexAttribFlags::TextureCoord | VertexAttribFlags::Color, &vertexData[0].x, &vertexData[0].u, &vertexData[0].r, kColorTextureVertexStride }; mOutGlop->mesh.elementCount = elementCount; @@ -180,7 +180,7 @@ GlopBuilder& GlopBuilder::setMeshVertexBuffer(const VertexBuffer& vertexBuffer, mOutGlop->mesh.indices = { 0, vertexBuffer.getIndices() }; mOutGlop->mesh.vertices = { 0, - static_cast<int>(alphaVertex ? VertexAttribFlags::kAlpha : VertexAttribFlags::kNone), + alphaVertex ? VertexAttribFlags::Alpha : VertexAttribFlags::None, vertexBuffer.getBuffer(), nullptr, nullptr, alphaVertex ? kAlphaVertexStride : kVertexStride }; mOutGlop->mesh.elementCount = indices @@ -197,7 +197,7 @@ GlopBuilder& GlopBuilder::setMeshPatchQuads(const Patch& patch) { mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr }; mOutGlop->mesh.vertices = { mCaches.patchCache.getMeshBuffer(), - static_cast<int>(VertexAttribFlags::kTextureCoord), + VertexAttribFlags::TextureCoord, (void*)patch.positionOffset, (void*)patch.textureOffset, nullptr, kTextureVertexStride }; mOutGlop->mesh.elementCount = patch.indexCount; @@ -230,7 +230,7 @@ void GlopBuilder::setFill(int color, float alphaScale, mOutGlop->blend = { GL_ZERO, GL_ZERO }; if (mOutGlop->fill.color.a < 1.0f - || (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kAlpha) + || (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Alpha) || (mOutGlop->fill.texture.texture && mOutGlop->fill.texture.texture->blend) || mOutGlop->roundRectClipState || PaintUtils::isBlendedShader(shader) @@ -298,12 +298,12 @@ void GlopBuilder::setFill(int color, float alphaScale, } } -GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, int textureFillFlags, - const SkPaint* paint, float alphaScale) { +GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, + const int textureFillFlags, const SkPaint* paint, float alphaScale) { TRIGGER_STAGE(kFillStage); REQUIRE_STAGES(kMeshStage); - GLenum filter = (textureFillFlags & TextureFillFlags::kForceFilter) + GLenum filter = (textureFillFlags & TextureFillFlags::ForceFilter) ? GL_LINEAR : PaintUtils::getFilter(paint); mOutGlop->fill.texture = { &texture, GL_TEXTURE_2D, filter, GL_CLAMP_TO_EDGE, nullptr }; @@ -312,7 +312,7 @@ GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, int textureFillF int color = paint->getColor(); SkShader* shader = paint->getShader(); - if (!(textureFillFlags & TextureFillFlags::kIsAlphaMaskTexture)) { + if (!(textureFillFlags & TextureFillFlags::IsAlphaMaskTexture)) { // Texture defines color, so disable shaders, and reset all non-alpha color channels color |= 0x00FFFFFF; shader = nullptr; @@ -324,7 +324,7 @@ GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, int textureFillF mOutGlop->fill.color = { alphaScale, alphaScale, alphaScale, alphaScale }; if (alphaScale < 1.0f - || (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kAlpha) + || (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Alpha) || texture.blend || mOutGlop->roundRectClipState) { Blend::getFactors(SkXfermode::kSrcOver_Mode, Blend::ModeOrderSwap::NoSwap, @@ -334,7 +334,7 @@ GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, int textureFillF } } - if (textureFillFlags & TextureFillFlags::kIsAlphaMaskTexture) { + if (textureFillFlags & TextureFillFlags::IsAlphaMaskTexture) { mDescription.modulate = mOutGlop->fill.color.isNotBlack(); mDescription.hasAlpha8Texture = true; } else { @@ -452,14 +452,13 @@ GlopBuilder& GlopBuilder::setFillTextureLayer(Layer& layer, float alpha) { // Transform //////////////////////////////////////////////////////////////////////////////// -GlopBuilder& GlopBuilder::setTransform(const Matrix4& ortho, - const Matrix4& transform, bool fudgingOffset) { +void GlopBuilder::setTransform(const Matrix4& ortho, const Matrix4& canvas, + const int transformFlags) { TRIGGER_STAGE(kTransformStage); mOutGlop->transform.ortho.load(ortho); - mOutGlop->transform.canvas.load(transform); - mOutGlop->transform.fudgingOffset = fudgingOffset; - return *this; + mOutGlop->transform.canvas.load(canvas); + mOutGlop->transform.transformFlags = transformFlags; } //////////////////////////////////////////////////////////////////////////////// @@ -482,11 +481,11 @@ GlopBuilder& GlopBuilder::setModelViewMapUnitToRectSnap(const Rect destination) float left = destination.left; float top = destination.top; - const Matrix4& canvasTransform = mOutGlop->transform.canvas; - if (CC_LIKELY(canvasTransform.isPureTranslate())) { + const Matrix4& meshTransform = mOutGlop->transform.meshTransform(); + if (CC_LIKELY(meshTransform.isPureTranslate())) { // snap by adjusting the model view matrix - const float translateX = canvasTransform.getTranslateX(); - const float translateY = canvasTransform.getTranslateY(); + const float translateX = meshTransform.getTranslateX(); + const float translateY = meshTransform.getTranslateY(); left = (int) floorf(left + translateX + 0.5f) - translateX; top = (int) floorf(top + translateY + 0.5f) - translateY; @@ -512,11 +511,11 @@ GlopBuilder& GlopBuilder::setModelViewOffsetRectSnap(float offsetX, float offset TRIGGER_STAGE(kModelViewStage); REQUIRE_STAGES(kTransformStage | kFillStage); - const Matrix4& canvasTransform = mOutGlop->transform.canvas; - if (CC_LIKELY(canvasTransform.isPureTranslate())) { + const Matrix4& meshTransform = mOutGlop->transform.meshTransform(); + if (CC_LIKELY(meshTransform.isPureTranslate())) { // snap by adjusting the model view matrix - const float translateX = canvasTransform.getTranslateX(); - const float translateY = canvasTransform.getTranslateY(); + const float translateX = meshTransform.getTranslateX(); + const float translateY = meshTransform.getTranslateY(); offsetX = (int) floorf(offsetX + translateX + source.left + 0.5f) - translateX - source.left; offsetY = (int) floorf(offsetY + translateY + source.top + 0.5f) - translateY - source.top; @@ -549,7 +548,7 @@ void verify(const ProgramDescription& description, const Glop& glop) { if (glop.fill.texture.texture != nullptr) { LOG_ALWAYS_FATAL_IF(((description.hasTexture && description.hasExternalTexture) || (!description.hasTexture && !description.hasExternalTexture) - || ((glop.mesh.vertices.attribFlags & VertexAttribFlags::kTextureCoord) == 0)), + || ((glop.mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) == 0)), "Texture %p, hT%d, hET %d, attribFlags %x", glop.fill.texture.texture, description.hasTexture, description.hasExternalTexture, @@ -557,13 +556,13 @@ void verify(const ProgramDescription& description, const Glop& glop) { } else { LOG_ALWAYS_FATAL_IF((description.hasTexture || description.hasExternalTexture - || ((glop.mesh.vertices.attribFlags & VertexAttribFlags::kTextureCoord) != 0)), + || ((glop.mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) != 0)), "No texture, hT%d, hET %d, attribFlags %x", description.hasTexture, description.hasExternalTexture, glop.mesh.vertices.attribFlags); } - if ((glop.mesh.vertices.attribFlags & VertexAttribFlags::kAlpha) + if ((glop.mesh.vertices.attribFlags & VertexAttribFlags::Alpha) && glop.mesh.vertices.bufferObject) { LOG_ALWAYS_FATAL("VBO and alpha attributes are not currently compatible"); } @@ -575,16 +574,16 @@ void verify(const ProgramDescription& description, const Glop& glop) { void GlopBuilder::build() { REQUIRE_STAGES(kAllStages); - if (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kTextureCoord) { + if (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::TextureCoord) { if (mOutGlop->fill.texture.target == GL_TEXTURE_2D) { mDescription.hasTexture = true; } else { mDescription.hasExternalTexture = true; } - } - mDescription.hasColors = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kColor; - mDescription.hasVertexAlpha = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kAlpha; + + mDescription.hasColors = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Color; + mDescription.hasVertexAlpha = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::Alpha; // Enable debug highlight when what we're about to draw is tested against // the stencil buffer and if stencil highlight debugging is on @@ -594,8 +593,22 @@ void GlopBuilder::build() { // serialize shader info into ShaderData GLuint textureUnit = mOutGlop->fill.texture.texture ? 1 : 0; - SkiaShader::store(mCaches, mShader, mOutGlop->transform.modelView, - &textureUnit, &mDescription, &(mOutGlop->fill.skiaShaderData)); + + if (CC_LIKELY(!mShader)) { + mOutGlop->fill.skiaShaderData.skiaShaderType = kNone_SkiaShaderType; + } else { + Matrix4 shaderMatrix; + if (mOutGlop->transform.transformFlags & TransformFlags::MeshIgnoresCanvasTransform) { + // canvas level transform was built into the modelView and geometry, + // so the shader matrix must reverse this + shaderMatrix.loadInverse(mOutGlop->transform.canvas); + shaderMatrix.multiply(mOutGlop->transform.modelView); + } else { + shaderMatrix.load(mOutGlop->transform.modelView); + } + SkiaShader::store(mCaches, *mShader, shaderMatrix, + &textureUnit, &mDescription, &(mOutGlop->fill.skiaShaderData)); + } // duplicates ProgramCache's definition of color uniform presence const bool singleColor = !mDescription.hasTexture @@ -608,7 +621,7 @@ void GlopBuilder::build() { // Final step: populate program and map bounds into render target space mOutGlop->fill.program = mCaches.programCache.get(mDescription); - mOutGlop->transform.canvas.mapRect(mOutGlop->bounds); + mOutGlop->transform.meshTransform().mapRect(mOutGlop->bounds); } } /* namespace uirenderer */ diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h index b335a2c..549bb21 100644 --- a/libs/hwui/GlopBuilder.h +++ b/libs/hwui/GlopBuilder.h @@ -16,6 +16,7 @@ #ifndef RENDERSTATE_GLOPBUILDER_H #define RENDERSTATE_GLOPBUILDER_H +#include "Glop.h" #include "OpenGLRenderer.h" #include "Program.h" #include "renderstate/Blend.h" @@ -32,14 +33,14 @@ class Matrix4; class RenderState; class Texture; class VertexBuffer; -struct Glop; -enum class TextureFillFlags { - kNone = 0, - kIsAlphaMaskTexture = 1 << 0, - kForceFilter = 1 << 1, -}; -MAKE_FLAGS_ENUM(TextureFillFlags); +namespace TextureFillFlags { + enum { + None = 0, + IsAlphaMaskTexture = 1 << 0, + ForceFilter = 1 << 1, + }; +} class GlopBuilder { PREVENT_COPY_AND_ASSIGN(GlopBuilder); @@ -57,7 +58,7 @@ public: GlopBuilder& setMeshPatchQuads(const Patch& patch); GlopBuilder& setFillPaint(const SkPaint& paint, float alphaScale); - GlopBuilder& setFillTexturePaint(Texture& texture, int textureFillFlags, + GlopBuilder& setFillTexturePaint(Texture& texture, const int textureFillFlags, const SkPaint* paint, float alphaScale); GlopBuilder& setFillPathTexturePaint(PathTexture& texture, const SkPaint& paint, float alphaScale); @@ -69,7 +70,10 @@ public: float alpha, SkXfermode::Mode mode, Blend::ModeOrderSwap modeUsage); GlopBuilder& setFillTextureLayer(Layer& layer, float alpha); - GlopBuilder& setTransform(const Matrix4& ortho, const Matrix4& transform, bool fudgingOffset); + GlopBuilder& setTransform(const Snapshot& snapshot, const int transformFlags) { + setTransform(snapshot.getOrthoMatrix(), *snapshot.transform, transformFlags); + return *this; + } GlopBuilder& setModelViewMapUnitToRect(const Rect destination); GlopBuilder& setModelViewMapUnitToRectSnap(const Rect destination); @@ -98,6 +102,8 @@ private: void setFill(int color, float alphaScale, SkXfermode::Mode mode, Blend::ModeOrderSwap modeUsage, const SkShader* shader, const SkColorFilter* colorFilter); + void setTransform(const Matrix4& ortho, const Matrix4& canvas, + const int transformFlags); enum StageFlags { kInitialStage = 0, diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 8f91620..5769376 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -827,7 +827,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto // the layer contains screen buffer content that shouldn't be alpha modulated // (and any necessary alpha modulation was handled drawing into the layer) writableSnapshot()->alpha = 1.0f; - composeLayerRect(layer, rect, true); + composeLayerRectSwapped(layer, rect); restore(); } @@ -849,31 +849,40 @@ void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) { GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUvQuad(nullptr, Rect(0, 1, 1, 0)) // TODO: simplify with VBO .setFillTextureLayer(*layer, getLayerAlpha(layer)) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewMapUnitToRectOptionalSnap(tryToSnap, rect) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); renderGlop(glop); } -void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) { +void OpenGLRenderer::composeLayerRectSwapped(Layer* layer, const Rect& rect) { + Glop glop; + GlopBuilder(mRenderState, mCaches, &glop) + .setMeshTexturedUvQuad(nullptr, layer->texCoords) + .setFillLayer(layer->getTexture(), layer->getColorFilter(), + getLayerAlpha(layer), layer->getMode(), Blend::ModeOrderSwap::Swap) + .setTransform(*currentSnapshot(), TransformFlags::MeshIgnoresCanvasTransform) + .setModelViewMapUnitToRect(rect) + .setRoundRectClipState(currentSnapshot()->roundRectClipState) + .build(); + renderGlop(glop); +} + +void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect) { if (layer->isTextureLayer()) { EVENT_LOGD("composeTextureLayerRect"); drawTextureLayer(layer, rect); } else { EVENT_LOGD("composeHardwareLayerRect"); - Blend::ModeOrderSwap modeUsage = swap ? - Blend::ModeOrderSwap::Swap : Blend::ModeOrderSwap::NoSwap; - const Matrix4& transform = swap ? Matrix4::identity() : *currentTransform(); - const bool tryToSnap = !swap - && layer->getWidth() == static_cast<uint32_t>(rect.getWidth()) + const bool tryToSnap = layer->getWidth() == static_cast<uint32_t>(rect.getWidth()) && layer->getHeight() == static_cast<uint32_t>(rect.getHeight()); Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUvQuad(nullptr, layer->texCoords) - .setFillLayer(layer->getTexture(), layer->getColorFilter(), getLayerAlpha(layer), layer->getMode(), modeUsage) - .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false) + .setFillLayer(layer->getTexture(), layer->getColorFilter(), getLayerAlpha(layer), layer->getMode(), Blend::ModeOrderSwap::NoSwap) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewMapUnitToRectOptionalSnap(tryToSnap, rect) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1014,7 +1023,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) { GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedIndexedQuads(&quadVertices[0], count * 6) .setFillLayer(layer->getTexture(), layer->getColorFilter(), getLayerAlpha(layer), layer->getMode(), Blend::ModeOrderSwap::NoSwap) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewOffsetRectSnap(rect.left, rect.top, modelRect) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1128,11 +1137,12 @@ void OpenGLRenderer::clearLayerRegions() { // stencil setup from doing the same thing again mLayers.clear(); + const int transformFlags = TransformFlags::MeshIgnoresCanvasTransform; Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshIndexedQuads(&mesh[0], quadCount) .setFillClear() - .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) + .setTransform(*currentSnapshot(), transformFlags) .setModelViewOffsetRect(0, 0, Rect(currentSnapshot()->getClipRect())) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1316,13 +1326,13 @@ void OpenGLRenderer::drawRectangleList(const RectangleList& rectangleList) { mRenderState.scissor().set(scissorBox.left, getViewportHeight() - scissorBox.bottom, scissorBox.getWidth(), scissorBox.getHeight()); - + const int transformFlags = TransformFlags::MeshIgnoresCanvasTransform; Glop glop; Vertex* vertices = &rectangleVertices[0]; GlopBuilder(mRenderState, mCaches, &glop) .setMeshIndexedQuads(vertices, rectangleVertices.size() / 4) .setFillBlack() - .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) + .setTransform(*currentSnapshot(), transformFlags) .setModelViewOffsetRect(0, 0, scissorBox) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1518,13 +1528,15 @@ void OpenGLRenderer::drawBitmaps(const SkBitmap* bitmap, AssetAtlas::Entry* entr bool snap = pureTranslate; const float x = floorf(bounds.left + 0.5f); const float y = floorf(bounds.top + 0.5f); - int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType) - ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); + + const int textureFillFlags = (bitmap->colorType() == kAlpha_8_SkColorType) + ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None; + const int transformFlags = TransformFlags::MeshIgnoresCanvasTransform; Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedMesh(vertices, bitmapCount * 6) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) + .setTransform(*currentSnapshot(), transformFlags) .setModelViewOffsetRectOptionalSnap(snap, x, y, Rect(0, 0, bounds.getWidth(), bounds.getHeight())) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1541,13 +1553,13 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, const SkPaint* paint) { if (!texture) return; const AutoTexture autoCleanup(texture); - int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType) - ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); + const int textureFillFlags = (bitmap->colorType() == kAlpha_8_SkColorType) + ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None; Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUnitQuad(texture->uvMapper) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewMapUnitToRectSnap(Rect(0, 0, texture->width, texture->height)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1632,11 +1644,12 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m * TODO: handle alpha_8 textures correctly by applying paint color, but *not* * shader in that case to mimic the behavior in SkiaCanvas::drawBitmapMesh. */ + const int textureFillFlags = TextureFillFlags::None; Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshColoredTexturedMesh(mesh.get(), elementCount) - .setFillTexturePaint(*texture, static_cast<int>(TextureFillFlags::kNone), paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1657,16 +1670,15 @@ void OpenGLRenderer::drawBitmap(const SkBitmap* bitmap, Rect src, Rect dst, cons fmin(1.0f, src.right / texture->width), fmin(1.0f, src.bottom / texture->height)); - const int textureFillFlags = static_cast<int>((bitmap->colorType() == kAlpha_8_SkColorType) - ? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone); + const int textureFillFlags = (bitmap->colorType() == kAlpha_8_SkColorType) + ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None; const bool tryToSnap = MathUtils::areEqual(src.getWidth(), dst.getWidth()) && MathUtils::areEqual(src.getHeight(), dst.getHeight()); - Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUvQuad(texture->uvMapper, uv) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewMapUnitToRectOptionalSnap(tryToSnap, dst) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1684,15 +1696,15 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh, if (!texture) return; // 9 patches are built for stretching - always filter - int textureFillFlags = static_cast<int>(TextureFillFlags::kForceFilter); + int textureFillFlags = TextureFillFlags::ForceFilter; if (bitmap->colorType() == kAlpha_8_SkColorType) { - textureFillFlags |= TextureFillFlags::kIsAlphaMaskTexture; + textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture; } Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshPatchQuads(*mesh) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewOffsetRectSnap(left, top, Rect(0, 0, right - left, bottom - top)) // TODO: get minimal bounds from patch .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1712,16 +1724,17 @@ void OpenGLRenderer::drawPatches(const SkBitmap* bitmap, AssetAtlas::Entry* entr const AutoTexture autoCleanup(texture); // TODO: get correct bounds from caller + const int transformFlags = TransformFlags::MeshIgnoresCanvasTransform; // 9 patches are built for stretching - always filter - int textureFillFlags = static_cast<int>(TextureFillFlags::kForceFilter); + int textureFillFlags = TextureFillFlags::ForceFilter; if (bitmap->colorType() == kAlpha_8_SkColorType) { - textureFillFlags |= TextureFillFlags::kIsAlphaMaskTexture; + textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture; } Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedIndexedQuads(vertices, elementCount) .setFillTexturePaint(*texture, textureFillFlags, paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) + .setTransform(*currentSnapshot(), transformFlags) .setModelViewOffsetRect(0, 0, Rect(0, 0, 0, 0)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -1736,13 +1749,13 @@ void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, return; } - bool fudgeOffset = displayFlags & kVertexBuffer_Offset; bool shadowInterp = displayFlags & kVertexBuffer_ShadowInterp; + const int transformFlags = TransformFlags::OffsetByFudgeFactor; Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshVertexBuffer(vertexBuffer, shadowInterp) .setFillPaint(*paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), fudgeOffset) + .setTransform(*currentSnapshot(), transformFlags) .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds()) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -2028,7 +2041,7 @@ void OpenGLRenderer::drawTextShadow(const SkPaint* paint, const char* text, GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUnitQuad(nullptr) .setFillShadowTexturePaint(*texture, textShadow.color, *paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width, sy + texture->height)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -2353,7 +2366,7 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedIndexedQuads(layer->mesh, layer->meshElementCount) .setFillLayer(layer->getTexture(), layer->getColorFilter(), getLayerAlpha(layer), layer->getMode(), Blend::ModeOrderSwap::NoSwap) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewOffsetRectSnap(x, y, Rect(0, 0, layer->layer.getWidth(), layer->layer.getHeight())) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -2411,7 +2424,7 @@ void OpenGLRenderer::drawPathTexture(PathTexture* texture, float x, float y, GlopBuilder(mRenderState, mCaches, &glop) .setMeshTexturedUnitQuad(nullptr) .setFillPathTexturePaint(*texture, *paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setTransform(*currentSnapshot(), TransformFlags::None) .setModelViewMapUnitToRect(Rect(x, y, x + texture->width, y + texture->height)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -2543,12 +2556,13 @@ void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint return; } - const Matrix4& transform = ignoreTransform ? Matrix4::identity() : *currentTransform(); + const int transformFlags = ignoreTransform + ? TransformFlags::MeshIgnoresCanvasTransform : TransformFlags::None; Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshIndexedQuads(&mesh[0], count / 4) .setFillPaint(*paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false) + .setTransform(*currentSnapshot(), transformFlags) .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); @@ -2557,12 +2571,13 @@ void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint void OpenGLRenderer::drawColorRect(float left, float top, float right, float bottom, const SkPaint* paint, bool ignoreTransform) { - const Matrix4& transform = ignoreTransform ? Matrix4::identity() : *currentTransform(); + const int transformFlags = ignoreTransform + ? TransformFlags::MeshIgnoresCanvasTransform : TransformFlags::None; Glop glop; GlopBuilder(mRenderState, mCaches, &glop) .setMeshUnitQuad() .setFillPaint(*paint, currentSnapshot()->alpha) - .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false) + .setTransform(*currentSnapshot(), transformFlags) .setModelViewMapUnitToRect(Rect(left, top, right, bottom)) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 8dae82c..29fbf0c 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -640,13 +640,20 @@ private: void composeLayerRegion(Layer* layer, const Rect& rect); /** - * Compose the specified layer as a simple rectangle. + * Restores the content in layer to the screen, swapping the blend mode, + * specifically used in the restore() of a saveLayerAlpha(). * - * @param layer The layer to compose - * @param rect The layer's bounds - * @param swap If true, the source and destination are swapped + * This allows e.g. a layer that would have been drawn on top of existing content (with SrcOver) + * to be drawn underneath. + * + * This will always ignore the canvas transform. + */ + void composeLayerRectSwapped(Layer* layer, const Rect& rect); + + /** + * Draws the content in layer to the screen. */ - void composeLayerRect(Layer* layer, const Rect& rect, bool swap = false); + void composeLayerRect(Layer* layer, const Rect& rect); /** * Clears all the regions corresponding to the current list of layers. diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index ecf8b6b..2cfb9e1 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -346,33 +346,28 @@ void applyLayer(Caches& caches, const SkiaShaderData::LayerShaderData& data) { glUniform2fv(caches.program().getUniform("textureDimension"), 1, &data.textureDimension[0]); } -void SkiaShader::store(Caches& caches, const SkShader* shader, const Matrix4& modelViewMatrix, +void SkiaShader::store(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, GLuint* textureUnit, ProgramDescription* description, SkiaShaderData* outData) { - if (!shader) { - outData->skiaShaderType = kNone_SkiaShaderType; - return; - } - - if (tryStoreGradient(caches, *shader, modelViewMatrix, + if (tryStoreGradient(caches, shader, modelViewMatrix, textureUnit, description, &outData->gradientData)) { outData->skiaShaderType = kGradient_SkiaShaderType; return; } - if (tryStoreBitmap(caches, *shader, modelViewMatrix, + if (tryStoreBitmap(caches, shader, modelViewMatrix, textureUnit, description, &outData->bitmapData)) { outData->skiaShaderType = kBitmap_SkiaShaderType; return; } - if (tryStoreCompose(caches, *shader, modelViewMatrix, + if (tryStoreCompose(caches, shader, modelViewMatrix, textureUnit, description, outData)) { outData->skiaShaderType = kCompose_SkiaShaderType; return; } - if (tryStoreLayer(caches, *shader, modelViewMatrix, + if (tryStoreLayer(caches, shader, modelViewMatrix, textureUnit, description, &outData->layerData)) { outData->skiaShaderType = kLayer_SkiaShaderType; } diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 5b8aa86..884196d 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -87,7 +87,7 @@ struct SkiaShaderData { class SkiaShader { public: - static void store(Caches& caches, const SkShader* shader, const Matrix4& modelViewMatrix, + static void store(Caches& caches, const SkShader& shader, const Matrix4& modelViewMatrix, GLuint* textureUnit, ProgramDescription* description, SkiaShaderData* outData); static void apply(Caches& caches, const SkiaShaderData& data); diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp index df12e63..3ebd57b 100644 --- a/libs/hwui/renderstate/RenderState.cpp +++ b/libs/hwui/renderstate/RenderState.cpp @@ -217,8 +217,8 @@ void RenderState::render(const Glop& glop) { fill.program->set(glop.transform.ortho, glop.transform.modelView, - glop.transform.canvas, - glop.transform.fudgingOffset); + glop.transform.meshTransform(), + glop.transform.transformFlags & TransformFlags::OffsetByFudgeFactor); // Color filter uniforms if (fill.filterMode == ProgramDescription::kColorBlend) { @@ -260,7 +260,7 @@ void RenderState::render(const Glop& glop) { // indices meshState().bindIndicesBufferInternal(indices.bufferObject); - if (vertices.attribFlags & VertexAttribFlags::kTextureCoord) { + if (vertices.attribFlags & VertexAttribFlags::TextureCoord) { const Glop::Fill::TextureData& texture = fill.texture; // texture always takes slot 0, shader samplers increment from there mCaches->textureState().activateTexture(0); @@ -284,13 +284,13 @@ void RenderState::render(const Glop& glop) { meshState().disableTexCoordsVertexArray(); } int colorLocation = -1; - if (vertices.attribFlags & VertexAttribFlags::kColor) { + if (vertices.attribFlags & VertexAttribFlags::Color) { colorLocation = fill.program->getAttrib("colors"); glEnableVertexAttribArray(colorLocation); glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, vertices.stride, vertices.color); } int alphaLocation = -1; - if (vertices.attribFlags & VertexAttribFlags::kAlpha) { + if (vertices.attribFlags & VertexAttribFlags::Alpha) { // NOTE: alpha vertex position is computed assuming no VBO const void* alphaCoords = ((const GLbyte*) vertices.position) + kVertexAlphaOffset; alphaLocation = fill.program->getAttrib("vtxAlpha"); @@ -318,7 +318,7 @@ void RenderState::render(const Glop& glop) { // rebind pointers without forcing, since initial bind handled above meshState().bindPositionVertexPointer(false, vertexData, vertices.stride); - if (vertices.attribFlags & VertexAttribFlags::kTextureCoord) { + if (vertices.attribFlags & VertexAttribFlags::TextureCoord) { meshState().bindTexCoordsVertexPointer(false, vertexData + kMeshTextureOffset, vertices.stride); } @@ -336,10 +336,10 @@ void RenderState::render(const Glop& glop) { // ----------------------------------- // ---------- Mesh teardown ---------- // ----------------------------------- - if (vertices.attribFlags & VertexAttribFlags::kAlpha) { + if (vertices.attribFlags & VertexAttribFlags::Alpha) { glDisableVertexAttribArray(alphaLocation); } - if (vertices.attribFlags & VertexAttribFlags::kColor) { + if (vertices.attribFlags & VertexAttribFlags::Color) { glDisableVertexAttribArray(colorLocation); } } diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index d8a9921..6d9acd4 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -52,11 +52,12 @@ namespace renderthread { MethodInvokeRenderTask* task = new MethodInvokeRenderTask((RunnableMethod) Bridge_ ## method); \ ARGS(method) *args = (ARGS(method) *) task->payload() -enum class DumpFlags { - kFrameStats = 1 << 0, - kReset = 1 << 1, +namespace DumpFlags { + enum { + FrameStats = 1 << 0, + Reset = 1 << 1, + }; }; -MAKE_FLAGS_ENUM(DumpFlags) CREATE_BRIDGE4(createContext, RenderThread* thread, bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory) { @@ -409,10 +410,10 @@ CREATE_BRIDGE4(dumpProfileInfo, CanvasContext* context, RenderThread* thread, int fd, int dumpFlags) { args->context->profiler().dumpData(args->fd); args->thread->jankTracker().dump(args->fd); - if (args->dumpFlags & DumpFlags::kFrameStats) { + if (args->dumpFlags & DumpFlags::FrameStats) { args->context->dumpFrames(args->fd); } - if (args->dumpFlags & DumpFlags::kReset) { + if (args->dumpFlags & DumpFlags::Reset) { args->context->resetFrameStats(); } return nullptr; |