Loading libs/hwui/Glop.h +1 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ struct Glop { * Stores mesh - vertex and index data. * * buffer objects and void*s are mutually exclusive * indices are optional * indices are optional, currently only GL_UNSIGNED_SHORT supported */ struct Mesh { VertexAttribFlags vertexFlags; Loading libs/hwui/GlopBuilder.cpp +44 −6 Original line number Diff line number Diff line Loading @@ -78,6 +78,21 @@ GlopBuilder& GlopBuilder::setMeshUnitQuad() { return *this; } GlopBuilder& GlopBuilder::setMeshIndexedQuads(void* vertexData, int quadCount) { TRIGGER_STAGE(kMeshStage); mOutGlop->mesh.vertexFlags = kNone_Attrib; mOutGlop->mesh.primitiveMode = GL_TRIANGLES; mOutGlop->mesh.vertexBufferObject = 0; mOutGlop->mesh.vertices = vertexData; mOutGlop->mesh.indexBufferObject = mRenderState.meshState().getQuadListIBO(); mOutGlop->mesh.indices = nullptr; mOutGlop->mesh.vertexCount = 6 * quadCount; mOutGlop->mesh.stride = kVertexStride; return *this; } GlopBuilder& GlopBuilder::setTransform(const Matrix4& ortho, const Matrix4& transform, bool fudgingOffset) { TRIGGER_STAGE(kTransformStage); Loading @@ -90,6 +105,7 @@ GlopBuilder& GlopBuilder::setTransform(const Matrix4& ortho, GlopBuilder& GlopBuilder::setModelViewMapUnitToRect(const Rect destination) { TRIGGER_STAGE(kModelViewStage); mOutGlop->transform.modelView.loadTranslate(destination.left, destination.top, 0.0f); mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f); mOutGlop->bounds = destination; Loading @@ -98,22 +114,42 @@ GlopBuilder& GlopBuilder::setModelViewMapUnitToRect(const Rect destination) { GlopBuilder& GlopBuilder::setModelViewOffsetRect(float offsetX, float offsetY, const Rect source) { TRIGGER_STAGE(kModelViewStage); mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f); mOutGlop->bounds = source; mOutGlop->bounds.translate(offsetX, offsetY); return *this; } GlopBuilder& GlopBuilder::setPaint(const SkPaint* paint, float alphaScale) { GlopBuilder& GlopBuilder::setOptionalPaint(const SkPaint* paint, float alphaScale) { if (paint) { return setPaint(*paint, alphaScale); } TRIGGER_STAGE(kFillStage); // TODO: support null paint const SkShader* shader = paint->getShader(); const SkColorFilter* colorFilter = paint->getColorFilter(); mOutGlop->fill.color = { alphaScale, alphaScale, alphaScale, alphaScale }; SkXfermode::Mode mode = PaintUtils::getXfermode(paint->getXfermode()); const bool SWAP_SRC_DST = false; // TODO: account for texture blend if (alphaScale < 1.0f) { Blend::getFactors(SkXfermode::kSrcOver_Mode, SWAP_SRC_DST, &mOutGlop->blend.src, &mOutGlop->blend.dst); } else { mOutGlop->blend = { GL_ZERO, GL_ZERO }; } return *this; } GlopBuilder& GlopBuilder::setPaint(const SkPaint& paint, float alphaScale) { TRIGGER_STAGE(kFillStage); const SkShader* shader = paint.getShader(); const SkColorFilter* colorFilter = paint.getColorFilter(); SkXfermode::Mode mode = PaintUtils::getXfermode(paint.getXfermode()); if (mode != SkXfermode::kClear_Mode) { int color = paint->getColor(); int color = paint.getColor(); float alpha = (SkColorGetA(color) / 255.0f) * alphaScale; if (!shader) { float colorScale = alpha / 255.0f; Loading Loading @@ -195,6 +231,8 @@ GlopBuilder& GlopBuilder::setPaint(const SkPaint* paint, float alphaScale) { colorVector[1] = srcColorMatrix[9] / 255.0f; colorVector[2] = srcColorMatrix[14] / 255.0f; colorVector[3] = srcColorMatrix[19] / 255.0f; } else { LOG_ALWAYS_FATAL("unsupported ColorFilter"); } } else { mOutGlop->fill.filterMode = ProgramDescription::kColorNone; Loading libs/hwui/GlopBuilder.h +4 −1 Original line number Diff line number Diff line Loading @@ -36,15 +36,18 @@ class GlopBuilder { PREVENT_COPY_AND_ASSIGN(GlopBuilder); public: GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop); GlopBuilder& setMeshUnitQuad(); GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp); GlopBuilder& setMeshIndexedQuads(void* vertexData, int quadCount); GlopBuilder& setTransform(const Matrix4& ortho, const Matrix4& transform, bool fudgingOffset); GlopBuilder& setModelViewMapUnitToRect(const Rect destination); GlopBuilder& setModelViewOffsetRect(float offsetX, float offsetY, const Rect source); GlopBuilder& setPaint(const SkPaint* paint, float alphaScale); GlopBuilder& setOptionalPaint(const SkPaint* paint, float alphaScale); GlopBuilder& setPaint(const SkPaint& paint, float alphaScale); void build(); private: enum StageFlags { Loading libs/hwui/OpenGLRenderer.cpp +27 −10 Original line number Diff line number Diff line Loading @@ -1581,8 +1581,13 @@ void OpenGLRenderer::renderGlop(const Glop& glop) { setStencilFromClip(); } mRenderState.render(glop); if (!mRenderState.stencil().isWriteEnabled()) { // TODO: specify more clearly when a draw should dirty the layer. // is writing to the stencil the only time we should ignore this? dirtyLayer(glop.bounds.left, glop.bounds.top, glop.bounds.right, glop.bounds.bottom); } } /////////////////////////////////////////////////////////////////////////////// // Drawing commands Loading Loading @@ -2353,13 +2358,12 @@ void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, aBuilder.setMeshVertexBuffer(vertexBuffer, shadowInterp) .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), fudgeOffset) .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds()) .setPaint(paint, currentSnapshot()->alpha) .setPaint(*paint, currentSnapshot()->alpha) .build(); renderGlop(glop); return; } const VertexBuffer::MeshFeatureFlags meshFeatureFlags = vertexBuffer.getMeshFeatureFlags(); Rect bounds(vertexBuffer.getBounds()); bounds.translate(translateX, translateY); Loading Loading @@ -3218,12 +3222,6 @@ void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint return; } int color = paint->getColor(); // If a shader is set, preserve only the alpha if (getShader(paint)) { color |= 0x00ffffff; } float left = FLT_MAX; float top = FLT_MAX; float right = FLT_MIN; Loading Loading @@ -3253,6 +3251,25 @@ void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint return; } if (!paint->getShader() && !currentSnapshot()->roundRectClipState) { const Matrix4& transform = ignoreTransform ? Matrix4::identity() : *currentTransform(); Glop glop; GlopBuilder aBuilder(mRenderState, mCaches, &glop); aBuilder.setMeshIndexedQuads(&mesh[0], count / 4) .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false) .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom)) .setPaint(*paint, currentSnapshot()->alpha) .build(); renderGlop(glop); return; } int color = paint->getColor(); // If a shader is set, preserve only the alpha if (getShader(paint)) { color |= 0x00ffffff; } setupDraw(); setupDrawNoTexture(); setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha); Loading Loading @@ -3286,7 +3303,7 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot aBuilder.setMeshUnitQuad() .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false) .setModelViewMapUnitToRect(Rect(left, top, right, bottom)) .setPaint(paint, currentSnapshot()->alpha) .setPaint(*paint, currentSnapshot()->alpha) .build(); renderGlop(glop); return; Loading libs/hwui/renderstate/MeshState.cpp +17 −21 Original line number Diff line number Diff line Loading @@ -31,13 +31,29 @@ MeshState::MeshState() , mCurrentTexCoordsStride(0) , mTexCoordsArrayEnabled(false) , mQuadListIndices(0) { glGenBuffers(1, &mUnitQuadBuffer); glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW); mCurrentBuffer = mUnitQuadBuffer; std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[kMaxNumberOfQuads * 6]); for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) { uint16_t quad = i * 4; int index = i * 6; regionIndices[index ] = quad; // top-left regionIndices[index + 1] = quad + 1; // top-right regionIndices[index + 2] = quad + 2; // bottom-left regionIndices[index + 3] = quad + 2; // bottom-left regionIndices[index + 4] = quad + 1; // top-right regionIndices[index + 5] = quad + 3; // bottom-right } glGenBuffers(1, &mQuadListIndices); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadListIndices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxNumberOfQuads * 6 * sizeof(uint16_t), regionIndices.get(), GL_STATIC_DRAW); mCurrentIndicesBuffer = mQuadListIndices; // position attribute always enabled glEnableVertexAttribArray(Program::kBindingPosition); } Loading Loading @@ -138,26 +154,6 @@ bool MeshState::bindIndicesBufferInternal(const GLuint buffer) { } bool MeshState::bindQuadIndicesBuffer() { if (!mQuadListIndices) { std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[kMaxNumberOfQuads * 6]); for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) { uint16_t quad = i * 4; int index = i * 6; regionIndices[index ] = quad; // top-left regionIndices[index + 1] = quad + 1; // top-right regionIndices[index + 2] = quad + 2; // bottom-left regionIndices[index + 3] = quad + 2; // bottom-left regionIndices[index + 4] = quad + 1; // top-right regionIndices[index + 5] = quad + 3; // bottom-right } glGenBuffers(1, &mQuadListIndices); bool force = bindIndicesBufferInternal(mQuadListIndices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxNumberOfQuads * 6 * sizeof(uint16_t), regionIndices.get(), GL_STATIC_DRAW); return force; } return bindIndicesBufferInternal(mQuadListIndices); } Loading Loading
libs/hwui/Glop.h +1 −1 Original line number Diff line number Diff line Loading @@ -65,7 +65,7 @@ struct Glop { * Stores mesh - vertex and index data. * * buffer objects and void*s are mutually exclusive * indices are optional * indices are optional, currently only GL_UNSIGNED_SHORT supported */ struct Mesh { VertexAttribFlags vertexFlags; Loading
libs/hwui/GlopBuilder.cpp +44 −6 Original line number Diff line number Diff line Loading @@ -78,6 +78,21 @@ GlopBuilder& GlopBuilder::setMeshUnitQuad() { return *this; } GlopBuilder& GlopBuilder::setMeshIndexedQuads(void* vertexData, int quadCount) { TRIGGER_STAGE(kMeshStage); mOutGlop->mesh.vertexFlags = kNone_Attrib; mOutGlop->mesh.primitiveMode = GL_TRIANGLES; mOutGlop->mesh.vertexBufferObject = 0; mOutGlop->mesh.vertices = vertexData; mOutGlop->mesh.indexBufferObject = mRenderState.meshState().getQuadListIBO(); mOutGlop->mesh.indices = nullptr; mOutGlop->mesh.vertexCount = 6 * quadCount; mOutGlop->mesh.stride = kVertexStride; return *this; } GlopBuilder& GlopBuilder::setTransform(const Matrix4& ortho, const Matrix4& transform, bool fudgingOffset) { TRIGGER_STAGE(kTransformStage); Loading @@ -90,6 +105,7 @@ GlopBuilder& GlopBuilder::setTransform(const Matrix4& ortho, GlopBuilder& GlopBuilder::setModelViewMapUnitToRect(const Rect destination) { TRIGGER_STAGE(kModelViewStage); mOutGlop->transform.modelView.loadTranslate(destination.left, destination.top, 0.0f); mOutGlop->transform.modelView.scale(destination.getWidth(), destination.getHeight(), 1.0f); mOutGlop->bounds = destination; Loading @@ -98,22 +114,42 @@ GlopBuilder& GlopBuilder::setModelViewMapUnitToRect(const Rect destination) { GlopBuilder& GlopBuilder::setModelViewOffsetRect(float offsetX, float offsetY, const Rect source) { TRIGGER_STAGE(kModelViewStage); mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f); mOutGlop->bounds = source; mOutGlop->bounds.translate(offsetX, offsetY); return *this; } GlopBuilder& GlopBuilder::setPaint(const SkPaint* paint, float alphaScale) { GlopBuilder& GlopBuilder::setOptionalPaint(const SkPaint* paint, float alphaScale) { if (paint) { return setPaint(*paint, alphaScale); } TRIGGER_STAGE(kFillStage); // TODO: support null paint const SkShader* shader = paint->getShader(); const SkColorFilter* colorFilter = paint->getColorFilter(); mOutGlop->fill.color = { alphaScale, alphaScale, alphaScale, alphaScale }; SkXfermode::Mode mode = PaintUtils::getXfermode(paint->getXfermode()); const bool SWAP_SRC_DST = false; // TODO: account for texture blend if (alphaScale < 1.0f) { Blend::getFactors(SkXfermode::kSrcOver_Mode, SWAP_SRC_DST, &mOutGlop->blend.src, &mOutGlop->blend.dst); } else { mOutGlop->blend = { GL_ZERO, GL_ZERO }; } return *this; } GlopBuilder& GlopBuilder::setPaint(const SkPaint& paint, float alphaScale) { TRIGGER_STAGE(kFillStage); const SkShader* shader = paint.getShader(); const SkColorFilter* colorFilter = paint.getColorFilter(); SkXfermode::Mode mode = PaintUtils::getXfermode(paint.getXfermode()); if (mode != SkXfermode::kClear_Mode) { int color = paint->getColor(); int color = paint.getColor(); float alpha = (SkColorGetA(color) / 255.0f) * alphaScale; if (!shader) { float colorScale = alpha / 255.0f; Loading Loading @@ -195,6 +231,8 @@ GlopBuilder& GlopBuilder::setPaint(const SkPaint* paint, float alphaScale) { colorVector[1] = srcColorMatrix[9] / 255.0f; colorVector[2] = srcColorMatrix[14] / 255.0f; colorVector[3] = srcColorMatrix[19] / 255.0f; } else { LOG_ALWAYS_FATAL("unsupported ColorFilter"); } } else { mOutGlop->fill.filterMode = ProgramDescription::kColorNone; Loading
libs/hwui/GlopBuilder.h +4 −1 Original line number Diff line number Diff line Loading @@ -36,15 +36,18 @@ class GlopBuilder { PREVENT_COPY_AND_ASSIGN(GlopBuilder); public: GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop); GlopBuilder& setMeshUnitQuad(); GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp); GlopBuilder& setMeshIndexedQuads(void* vertexData, int quadCount); GlopBuilder& setTransform(const Matrix4& ortho, const Matrix4& transform, bool fudgingOffset); GlopBuilder& setModelViewMapUnitToRect(const Rect destination); GlopBuilder& setModelViewOffsetRect(float offsetX, float offsetY, const Rect source); GlopBuilder& setPaint(const SkPaint* paint, float alphaScale); GlopBuilder& setOptionalPaint(const SkPaint* paint, float alphaScale); GlopBuilder& setPaint(const SkPaint& paint, float alphaScale); void build(); private: enum StageFlags { Loading
libs/hwui/OpenGLRenderer.cpp +27 −10 Original line number Diff line number Diff line Loading @@ -1581,8 +1581,13 @@ void OpenGLRenderer::renderGlop(const Glop& glop) { setStencilFromClip(); } mRenderState.render(glop); if (!mRenderState.stencil().isWriteEnabled()) { // TODO: specify more clearly when a draw should dirty the layer. // is writing to the stencil the only time we should ignore this? dirtyLayer(glop.bounds.left, glop.bounds.top, glop.bounds.right, glop.bounds.bottom); } } /////////////////////////////////////////////////////////////////////////////// // Drawing commands Loading Loading @@ -2353,13 +2358,12 @@ void OpenGLRenderer::drawVertexBuffer(float translateX, float translateY, aBuilder.setMeshVertexBuffer(vertexBuffer, shadowInterp) .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), fudgeOffset) .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds()) .setPaint(paint, currentSnapshot()->alpha) .setPaint(*paint, currentSnapshot()->alpha) .build(); renderGlop(glop); return; } const VertexBuffer::MeshFeatureFlags meshFeatureFlags = vertexBuffer.getMeshFeatureFlags(); Rect bounds(vertexBuffer.getBounds()); bounds.translate(translateX, translateY); Loading Loading @@ -3218,12 +3222,6 @@ void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint return; } int color = paint->getColor(); // If a shader is set, preserve only the alpha if (getShader(paint)) { color |= 0x00ffffff; } float left = FLT_MAX; float top = FLT_MAX; float right = FLT_MIN; Loading Loading @@ -3253,6 +3251,25 @@ void OpenGLRenderer::drawColorRects(const float* rects, int count, const SkPaint return; } if (!paint->getShader() && !currentSnapshot()->roundRectClipState) { const Matrix4& transform = ignoreTransform ? Matrix4::identity() : *currentTransform(); Glop glop; GlopBuilder aBuilder(mRenderState, mCaches, &glop); aBuilder.setMeshIndexedQuads(&mesh[0], count / 4) .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false) .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom)) .setPaint(*paint, currentSnapshot()->alpha) .build(); renderGlop(glop); return; } int color = paint->getColor(); // If a shader is set, preserve only the alpha if (getShader(paint)) { color |= 0x00ffffff; } setupDraw(); setupDrawNoTexture(); setupDrawColor(color, ((color >> 24) & 0xFF) * currentSnapshot()->alpha); Loading Loading @@ -3286,7 +3303,7 @@ void OpenGLRenderer::drawColorRect(float left, float top, float right, float bot aBuilder.setMeshUnitQuad() .setTransform(currentSnapshot()->getOrthoMatrix(), transform, false) .setModelViewMapUnitToRect(Rect(left, top, right, bottom)) .setPaint(paint, currentSnapshot()->alpha) .setPaint(*paint, currentSnapshot()->alpha) .build(); renderGlop(glop); return; Loading
libs/hwui/renderstate/MeshState.cpp +17 −21 Original line number Diff line number Diff line Loading @@ -31,13 +31,29 @@ MeshState::MeshState() , mCurrentTexCoordsStride(0) , mTexCoordsArrayEnabled(false) , mQuadListIndices(0) { glGenBuffers(1, &mUnitQuadBuffer); glBindBuffer(GL_ARRAY_BUFFER, mUnitQuadBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(kUnitQuadVertices), kUnitQuadVertices, GL_STATIC_DRAW); mCurrentBuffer = mUnitQuadBuffer; std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[kMaxNumberOfQuads * 6]); for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) { uint16_t quad = i * 4; int index = i * 6; regionIndices[index ] = quad; // top-left regionIndices[index + 1] = quad + 1; // top-right regionIndices[index + 2] = quad + 2; // bottom-left regionIndices[index + 3] = quad + 2; // bottom-left regionIndices[index + 4] = quad + 1; // top-right regionIndices[index + 5] = quad + 3; // bottom-right } glGenBuffers(1, &mQuadListIndices); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mQuadListIndices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxNumberOfQuads * 6 * sizeof(uint16_t), regionIndices.get(), GL_STATIC_DRAW); mCurrentIndicesBuffer = mQuadListIndices; // position attribute always enabled glEnableVertexAttribArray(Program::kBindingPosition); } Loading Loading @@ -138,26 +154,6 @@ bool MeshState::bindIndicesBufferInternal(const GLuint buffer) { } bool MeshState::bindQuadIndicesBuffer() { if (!mQuadListIndices) { std::unique_ptr<uint16_t[]> regionIndices(new uint16_t[kMaxNumberOfQuads * 6]); for (uint32_t i = 0; i < kMaxNumberOfQuads; i++) { uint16_t quad = i * 4; int index = i * 6; regionIndices[index ] = quad; // top-left regionIndices[index + 1] = quad + 1; // top-right regionIndices[index + 2] = quad + 2; // bottom-left regionIndices[index + 3] = quad + 2; // bottom-left regionIndices[index + 4] = quad + 1; // top-right regionIndices[index + 5] = quad + 3; // bottom-right } glGenBuffers(1, &mQuadListIndices); bool force = bindIndicesBufferInternal(mQuadListIndices); glBufferData(GL_ELEMENT_ARRAY_BUFFER, kMaxNumberOfQuads * 6 * sizeof(uint16_t), regionIndices.get(), GL_STATIC_DRAW); return force; } return bindIndicesBufferInternal(mQuadListIndices); } Loading