diff options
author | Chris Craik <ccraik@google.com> | 2015-02-25 17:16:16 -0800 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2015-02-26 10:56:07 -0800 |
commit | ef2507439c08f4e9c4c9bba1c6243ca9df2ee827 (patch) | |
tree | 0312e1808ee6915a96e1770cb190ea4674e2376a /libs | |
parent | 03ae272459869b854e5db252fc81a64a516e111f (diff) | |
download | frameworks_base-ef2507439c08f4e9c4c9bba1c6243ca9df2ee827.zip frameworks_base-ef2507439c08f4e9c4c9bba1c6243ca9df2ee827.tar.gz frameworks_base-ef2507439c08f4e9c4c9bba1c6243ca9df2ee827.tar.bz2 |
Glop mesh reorg, support for drawBitmapMesh
Change-Id: Iaf5550bdd93da93e59a5b838234ab5612e067387
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/DisplayListOp.h | 7 | ||||
-rw-r--r-- | libs/hwui/Glop.h | 43 | ||||
-rw-r--r-- | libs/hwui/GlopBuilder.cpp | 127 | ||||
-rw-r--r-- | libs/hwui/GlopBuilder.h | 3 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 37 | ||||
-rw-r--r-- | libs/hwui/renderstate/MeshState.h | 1 | ||||
-rw-r--r-- | libs/hwui/renderstate/RenderState.cpp | 90 | ||||
-rw-r--r-- | libs/hwui/utils/Macros.h | 6 |
8 files changed, 179 insertions, 135 deletions
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index dba5121..1963475 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1399,8 +1399,11 @@ class DrawRenderNodeOp : public DrawBoundedOp { friend class DisplayListData; // grant DisplayListData access to info of child public: DrawRenderNodeOp(RenderNode* renderNode, int flags, const mat4& transformFromParent) - : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr), - mRenderNode(renderNode), mFlags(flags), mTransformFromParent(transformFromParent) {} + : DrawBoundedOp(0, 0, renderNode->getWidth(), renderNode->getHeight(), nullptr) + , mRenderNode(renderNode) + , mFlags(flags) + , mTransformFromParent(transformFromParent) + , mSkipInOrderDraw(false) {} virtual void defer(DeferStateStruct& deferStruct, int saveCount, int level, bool useQuickReject) override { diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h index e500546..c9a5679 100644 --- a/libs/hwui/Glop.h +++ b/libs/hwui/Glop.h @@ -41,12 +41,13 @@ class Texture; * Position is always enabled by MeshState, these other attributes * are enabled/disabled dynamically based on mesh content. */ -enum VertexAttribFlags { - kNone_Attrib = 0, - kTextureCoord_Attrib = 1 << 0, - kColor_Attrib = 1 << 1, - kAlpha_Attrib = 1 << 2, +enum class VertexAttribFlags { + kNone = 0, + kTextureCoord = 1 << 0, + kColor = 1 << 1, + kAlpha = 1 << 2, }; +MAKE_FLAGS_ENUM(VertexAttribFlags) /** * Structure containing all data required to issue an OpenGL draw @@ -63,22 +64,28 @@ enum VertexAttribFlags { */ // TODO: PREVENT_COPY_AND_ASSIGN(...) or similar struct Glop { - /* - * Stores mesh - vertex and index data. - * - * buffer objects and void*s are mutually exclusive - * indices are optional, currently only GL_UNSIGNED_SHORT supported - */ struct Mesh { - VertexAttribFlags vertexFlags; GLuint primitiveMode; // GL_TRIANGLES and GL_TRIANGLE_STRIP supported - GLuint vertexBufferObject; - GLuint indexBufferObject; - const void* vertices; - const void* indices; - GLvoid* texCoordOffset; + + // buffer object and void* are mutually exclusive. + // Only GL_UNSIGNED_SHORT supported. + struct Indices { + GLuint bufferObject; + const void* indices; + } indices; + + // buffer object and void*s are mutually exclusive. + // TODO: enforce mutual exclusion with restricted setters and/or unions + struct Vertices { + GLuint bufferObject; + VertexAttribFlags flags; + const void* position; + const void* texCoord; + const void* color; + GLsizei stride; + } vertices; + int elementCount; - GLsizei stride; TextureVertex mappedVertices[4]; } mesh; diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp index 1342c52..f50dfc8 100644 --- a/libs/hwui/GlopBuilder.cpp +++ b/libs/hwui/GlopBuilder.cpp @@ -61,15 +61,14 @@ GlopBuilder::GlopBuilder(RenderState& renderState, Caches& caches, Glop* outGlop GlopBuilder& GlopBuilder::setMeshUnitQuad() { TRIGGER_STAGE(kMeshStage); - mOutGlop->mesh.vertexFlags = kNone_Attrib; mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP; - mOutGlop->mesh.vertexBufferObject = mRenderState.meshState().getUnitQuadVBO(); - mOutGlop->mesh.vertices = nullptr; - mOutGlop->mesh.indexBufferObject = 0; - mOutGlop->mesh.indices = nullptr; + mOutGlop->mesh.indices = { 0, nullptr }; + mOutGlop->mesh.vertices = { + mRenderState.meshState().getUnitQuadVBO(), + VertexAttribFlags::kNone, + nullptr, nullptr, nullptr, + kTextureVertexStride }; mOutGlop->mesh.elementCount = 4; - mOutGlop->mesh.stride = kTextureVertexStride; - mOutGlop->mesh.texCoordOffset = nullptr; return *this; } @@ -81,70 +80,76 @@ GlopBuilder& GlopBuilder::setMeshTexturedUnitQuad(const UvMapper* uvMapper) { TRIGGER_STAGE(kMeshStage); - mOutGlop->mesh.vertexFlags = kTextureCoord_Attrib; mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP; - mOutGlop->mesh.vertexBufferObject = mRenderState.meshState().getUnitQuadVBO(); - mOutGlop->mesh.vertices = nullptr; - mOutGlop->mesh.texCoordOffset = (GLvoid*) kMeshTextureOffset; - mOutGlop->mesh.indexBufferObject = 0; - mOutGlop->mesh.indices = nullptr; + mOutGlop->mesh.indices = { 0, nullptr }; + mOutGlop->mesh.vertices = { + mRenderState.meshState().getUnitQuadVBO(), + VertexAttribFlags::kTextureCoord, + nullptr, (const void*) kMeshTextureOffset, nullptr, + kTextureVertexStride }; mOutGlop->mesh.elementCount = 4; - mOutGlop->mesh.stride = kTextureVertexStride; - mDescription.hasTexture = true; return *this; } GlopBuilder& GlopBuilder::setMeshTexturedUvQuad(const UvMapper* uvMapper, Rect uvs) { TRIGGER_STAGE(kMeshStage); - mOutGlop->mesh.vertexFlags = kTextureCoord_Attrib; - mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP; - if (CC_UNLIKELY(uvMapper)) { uvMapper->map(uvs); } setUnitQuadTextureCoords(uvs, &mOutGlop->mesh.mappedVertices[0]); - mOutGlop->mesh.vertexBufferObject = 0; - mOutGlop->mesh.vertices = &mOutGlop->mesh.mappedVertices[0].x; - mOutGlop->mesh.texCoordOffset = &mOutGlop->mesh.mappedVertices[0].u; - mOutGlop->mesh.indexBufferObject = 0; - mOutGlop->mesh.indices = nullptr; + const TextureVertex* textureVertex = mOutGlop->mesh.mappedVertices; + mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP; + mOutGlop->mesh.indices = { 0, nullptr }; + mOutGlop->mesh.vertices = { + 0, + VertexAttribFlags::kTextureCoord, + &textureVertex[0].x, &textureVertex[0].u, nullptr, + kTextureVertexStride }; mOutGlop->mesh.elementCount = 4; - mOutGlop->mesh.stride = kTextureVertexStride; - mDescription.hasTexture = true; return *this; } -GlopBuilder& GlopBuilder::setMeshIndexedQuads(void* vertexData, int quadCount) { +GlopBuilder& GlopBuilder::setMeshIndexedQuads(Vertex* 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.texCoordOffset = nullptr; + mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr }; + mOutGlop->mesh.vertices = { + 0, + VertexAttribFlags::kNone, + vertexData, nullptr, nullptr, + kVertexStride }; mOutGlop->mesh.elementCount = 6 * quadCount; - mOutGlop->mesh.stride = kVertexStride; - return *this; } GlopBuilder& GlopBuilder::setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount) { TRIGGER_STAGE(kMeshStage); - mOutGlop->mesh.vertexFlags = kTextureCoord_Attrib; mOutGlop->mesh.primitiveMode = GL_TRIANGLES; - mOutGlop->mesh.vertexBufferObject = 0; - mOutGlop->mesh.vertices = &vertexData[0].x; - mOutGlop->mesh.indexBufferObject = mRenderState.meshState().getQuadListIBO(); - mOutGlop->mesh.indices = nullptr; - mOutGlop->mesh.texCoordOffset = &vertexData[0].u; + mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr }; + mOutGlop->mesh.vertices = { + 0, + VertexAttribFlags::kTextureCoord, + &vertexData[0].x, &vertexData[0].u, nullptr, + kTextureVertexStride }; + mOutGlop->mesh.elementCount = elementCount; + return *this; +} + +GlopBuilder& GlopBuilder::setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount) { + TRIGGER_STAGE(kMeshStage); + + mOutGlop->mesh.primitiveMode = GL_TRIANGLES; + mOutGlop->mesh.indices = { 0, nullptr }; + mOutGlop->mesh.vertices = { + 0, + static_cast<VertexAttribFlags>(VertexAttribFlags::kTextureCoord | VertexAttribFlags::kColor), + &vertexData[0].x, &vertexData[0].u, &vertexData[0].r, + kColorTextureVertexStride }; mOutGlop->mesh.elementCount = elementCount; - mOutGlop->mesh.stride = kTextureVertexStride; - mDescription.hasTexture = true; return *this; } @@ -155,18 +160,17 @@ GlopBuilder& GlopBuilder::setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool alphaVertex = flags & VertexBuffer::kAlpha; bool indices = flags & VertexBuffer::kIndices; - mOutGlop->mesh.vertexFlags = alphaVertex ? kAlpha_Attrib : kNone_Attrib; + mOutGlop->mesh.primitiveMode = GL_TRIANGLE_STRIP; - mOutGlop->mesh.vertexBufferObject = 0; - mOutGlop->mesh.vertices = vertexBuffer.getBuffer(); - mOutGlop->mesh.indexBufferObject = 0; - mOutGlop->mesh.indices = vertexBuffer.getIndices(); - mOutGlop->mesh.texCoordOffset = nullptr; + mOutGlop->mesh.indices = { 0, vertexBuffer.getIndices() }; + mOutGlop->mesh.vertices = { + 0, + alphaVertex ? VertexAttribFlags::kAlpha : VertexAttribFlags::kNone, + vertexBuffer.getBuffer(), nullptr, nullptr, + alphaVertex ? kAlphaVertexStride : kVertexStride }; mOutGlop->mesh.elementCount = indices - ? vertexBuffer.getIndexCount() : vertexBuffer.getVertexCount(); - mOutGlop->mesh.stride = alphaVertex ? kAlphaVertexStride : kVertexStride; + ? vertexBuffer.getIndexCount() : vertexBuffer.getVertexCount(); - mDescription.hasVertexAlpha = alphaVertex; mDescription.useShadowAlphaInterp = shadowInterp; return *this; } @@ -197,7 +201,7 @@ void GlopBuilder::setFill(int color, float alphaScale, SkXfermode::Mode mode, mOutGlop->blend = { GL_ZERO, GL_ZERO }; if (mOutGlop->fill.color.a < 1.0f - || (mOutGlop->mesh.vertexFlags & kAlpha_Attrib) + || (mOutGlop->mesh.vertices.flags & VertexAttribFlags::kAlpha) || (mOutGlop->fill.texture.texture && mOutGlop->fill.texture.texture->blend) || mOutGlop->roundRectClipState || PaintUtils::isBlendedShader(shader) @@ -288,7 +292,7 @@ GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, bool isAlphaMask const bool SWAP_SRC_DST = false; if (alphaScale < 1.0f - || (mOutGlop->mesh.vertexFlags & kAlpha_Attrib) + || (mOutGlop->mesh.vertices.flags & VertexAttribFlags::kAlpha) || texture.blend || mOutGlop->roundRectClipState) { Blend::getFactors(SkXfermode::kSrcOver_Mode, SWAP_SRC_DST, @@ -489,20 +493,25 @@ GlopBuilder& GlopBuilder::setRoundRectClipState(const RoundRectClipState* roundR void verify(const ProgramDescription& description, const Glop& glop) { bool hasTexture = glop.fill.texture.texture != nullptr; LOG_ALWAYS_FATAL_IF(description.hasTexture != hasTexture); - LOG_ALWAYS_FATAL_IF((glop.mesh.vertexFlags & kTextureCoord_Attrib) != hasTexture); + LOG_ALWAYS_FATAL_IF((glop.mesh.vertices.flags & VertexAttribFlags::kTextureCoord) != hasTexture); + + if ((glop.mesh.vertices.flags & VertexAttribFlags::kAlpha) && glop.mesh.vertices.bufferObject) { + LOG_ALWAYS_FATAL("VBO and alpha attributes are not currently compatible"); + } } void GlopBuilder::build() { REQUIRE_STAGES(kAllStages); + mDescription.hasTexture = static_cast<int>(mOutGlop->mesh.vertices.flags & VertexAttribFlags::kTextureCoord); + mDescription.hasColors = static_cast<int>(mOutGlop->mesh.vertices.flags & VertexAttribFlags::kColor); + mDescription.hasVertexAlpha = static_cast<int>(mOutGlop->mesh.vertices.flags & VertexAttribFlags::kAlpha); + // 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)); - mOutGlop->fill.program = mCaches.programCache.get(mDescription); - mOutGlop->transform.canvas.mapRect(mOutGlop->bounds); - // duplicates ProgramCache's definition of color uniform presence const bool singleColor = !mDescription.hasTexture && !mDescription.hasExternalTexture @@ -511,6 +520,10 @@ void GlopBuilder::build() { mOutGlop->fill.colorEnabled = mDescription.modulate || singleColor; verify(mDescription, *mOutGlop); + + // Final step: populate program and map bounds into render target space + mOutGlop->fill.program = mCaches.programCache.get(mDescription); + mOutGlop->transform.canvas.mapRect(mOutGlop->bounds); } } /* namespace uirenderer */ diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h index 5a8354d..c24b122 100644 --- a/libs/hwui/GlopBuilder.h +++ b/libs/hwui/GlopBuilder.h @@ -42,7 +42,8 @@ public: GlopBuilder& setMeshTexturedUnitQuad(const UvMapper* uvMapper); GlopBuilder& setMeshTexturedUvQuad(const UvMapper* uvMapper, const Rect uvs); GlopBuilder& setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp); - GlopBuilder& setMeshIndexedQuads(void* vertexData, int quadCount); + GlopBuilder& setMeshIndexedQuads(Vertex* vertexData, int quadCount); + GlopBuilder& setMeshColoredTexturedMesh(ColorTextureVertex* vertexData, int elementCount); GlopBuilder& setMeshTexturedIndexedQuads(TextureVertex* vertexData, int elementCount); // TODO: take quadCount GlopBuilder& setFillPaint(const SkPaint& paint, float alphaScale); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 2bca9fa..3913ee5 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1234,7 +1234,7 @@ void OpenGLRenderer::clearLayerRegions() { aBuilder.setMeshIndexedQuads(&mesh[0], quadCount) .setFillClear() .setTransform(currentSnapshot()->getOrthoMatrix(), Matrix4::identity(), false) - .setModelViewOffsetRect(0, 0, currentSnapshot()->getClipRect()) + .setModelViewOffsetRect(0, 0, Rect(currentSnapshot()->getClipRect())) .setRoundRectClipState(currentSnapshot()->roundRectClipState) .build(); renderGlop(glop); @@ -2077,17 +2077,14 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m return; } - // TODO: use quickReject on bounds from vertices - mRenderState.scissor().setEnabled(true); - float left = FLT_MAX; float top = FLT_MAX; float right = FLT_MIN; float bottom = FLT_MIN; - const uint32_t count = meshWidth * meshHeight * 6; + const uint32_t elementCount = meshWidth * meshHeight * 6; - std::unique_ptr<ColorTextureVertex[]> mesh(new ColorTextureVertex[count]); + std::unique_ptr<ColorTextureVertex[]> mesh(new ColorTextureVertex[elementCount]); ColorTextureVertex* vertex = &mesh[0]; std::unique_ptr<int[]> tempColors; @@ -2098,7 +2095,6 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m colors = tempColors.get(); } - mCaches.textureState().activateTexture(0); Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap); const UvMapper& mapper(getMapper(texture)); @@ -2149,6 +2145,25 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m } const AutoTexture autoCleanup(texture); + if (USE_GLOPS) { + /* + * TODO: handle alpha_8 textures correctly by applying paint color, but *not* + * shader in that case to mimic the behavior in SkiaCanvas::drawBitmapMesh. + */ + bool isAlpha8Texture = false; + Glop glop; + GlopBuilder aBuilder(mRenderState, mCaches, &glop); + aBuilder.setMeshColoredTexturedMesh(mesh.get(), elementCount) + .setFillTexturePaint(*texture, isAlpha8Texture, paint, currentSnapshot()->alpha) + .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false) + .setModelViewOffsetRect(0, 0, Rect(left, top, right, bottom)) + .setRoundRectClipState(currentSnapshot()->roundRectClipState) + .build(); + renderGlop(glop); + return; + } + + mCaches.textureState().activateTexture(0); texture->setWrap(GL_CLAMP_TO_EDGE, true); texture->setFilter(PaintUtils::getFilter(paint), true); @@ -2156,12 +2171,10 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); - float a = alpha / 255.0f; - if (hasLayer()) { - dirtyLayer(left, top, right, bottom, *currentTransform()); - } + dirtyLayer(left, top, right, bottom, *currentTransform()); + float a = alpha / 255.0f; setupDraw(); setupDrawWithTextureAndColor(); setupDrawColor(a, a, a, a); @@ -2175,7 +2188,7 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m setupDrawColorFilterUniforms(getColorFilter(paint)); setupDrawMesh(&mesh[0].x, &mesh[0].u, &mesh[0].r); - glDrawArrays(GL_TRIANGLES, 0, count); + glDrawArrays(GL_TRIANGLES, 0, elementCount); int slot = mCaches.program().getAttrib("colors"); if (slot >= 0) { diff --git a/libs/hwui/renderstate/MeshState.h b/libs/hwui/renderstate/MeshState.h index 3c92ad8..e80f4d0 100644 --- a/libs/hwui/renderstate/MeshState.h +++ b/libs/hwui/renderstate/MeshState.h @@ -42,6 +42,7 @@ const TextureVertex kUnitQuadVertices[] = { const GLsizei kVertexStride = sizeof(Vertex); const GLsizei kAlphaVertexStride = sizeof(AlphaVertex); const GLsizei kTextureVertexStride = sizeof(TextureVertex); +const GLsizei kColorTextureVertexStride = sizeof(ColorTextureVertex); const GLsizei kMeshTextureOffset = 2 * sizeof(float); const GLsizei kVertexAlphaOffset = 2 * sizeof(float); diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp index 192bf81..7992077 100644 --- a/libs/hwui/renderstate/RenderState.cpp +++ b/libs/hwui/renderstate/RenderState.cpp @@ -199,16 +199,10 @@ void RenderState::postDecStrong(VirtualLightRefBase* object) { // Render /////////////////////////////////////////////////////////////////////////////// -/* - * Not yet supported: - * - * Textures + coordinates - * SkiaShader - * RoundRect clipping - */ - void RenderState::render(const Glop& glop) { const Glop::Mesh& mesh = glop.mesh; + const Glop::Mesh::Vertices& vertices = mesh.vertices; + const Glop::Mesh::Indices& indices = mesh.indices; const Glop::Fill& fill = glop.fill; // --------------------------------------------- @@ -226,15 +220,15 @@ void RenderState::render(const Glop& glop) { glop.transform.fudgingOffset); // Color filter uniforms - if (glop.fill.filterMode == ProgramDescription::kColorBlend) { - const FloatColor& color = glop.fill.filter.color; + if (fill.filterMode == ProgramDescription::kColorBlend) { + const FloatColor& color = fill.filter.color; glUniform4f(mCaches->program().getUniform("colorBlend"), color.r, color.g, color.b, color.a); - } else if (glop.fill.filterMode == ProgramDescription::kColorMatrix) { + } else if (fill.filterMode == ProgramDescription::kColorMatrix) { glUniformMatrix4fv(mCaches->program().getUniform("colorMatrix"), 1, GL_FALSE, - glop.fill.filter.matrix.matrix); + fill.filter.matrix.matrix); glUniform4fv(mCaches->program().getUniform("colorMatrixVector"), 1, - glop.fill.filter.matrix.vector); + fill.filter.matrix.vector); } // Round rect clipping uniforms @@ -253,48 +247,51 @@ void RenderState::render(const Glop& glop) { glUniform1f(fill.program->getUniform("roundRectRadius"), roundedOutRadius); } + // -------------------------------- // ---------- Mesh setup ---------- // -------------------------------- // vertices - const bool force = meshState().bindMeshBufferInternal(mesh.vertexBufferObject) - || (mesh.vertices != nullptr); - meshState().bindPositionVertexPointer(force, mesh.vertices, mesh.stride); + const bool force = meshState().bindMeshBufferInternal(vertices.bufferObject) + || (vertices.position != nullptr); + meshState().bindPositionVertexPointer(force, vertices.position, vertices.stride); // indices - meshState().bindIndicesBufferInternal(mesh.indexBufferObject); + meshState().bindIndicesBufferInternal(indices.bufferObject); - if (mesh.vertexFlags & kTextureCoord_Attrib) { - // glop.fill.texture always takes slot 0, shader samplers increment from there + if (vertices.flags & VertexAttribFlags::kTextureCoord) { + // fill.texture always takes slot 0, shader samplers increment from there mCaches->textureState().activateTexture(0); - if (glop.fill.texture.clamp != GL_INVALID_ENUM) { - glop.fill.texture.texture->setWrap(glop.fill.texture.clamp, true); + if (fill.texture.clamp != GL_INVALID_ENUM) { + fill.texture.texture->setWrap(fill.texture.clamp, true); } - if (glop.fill.texture.filter != GL_INVALID_ENUM) { - glop.fill.texture.texture->setFilter(glop.fill.texture.filter, true); + if (fill.texture.filter != GL_INVALID_ENUM) { + fill.texture.texture->setFilter(fill.texture.filter, true); } mCaches->textureState().bindTexture(fill.texture.texture->id); meshState().enableTexCoordsVertexArray(); - meshState().bindTexCoordsVertexPointer(force, mesh.texCoordOffset, mesh.stride); + meshState().bindTexCoordsVertexPointer(force, vertices.texCoord, vertices.stride); } else { meshState().disableTexCoordsVertexArray(); } - if (mesh.vertexFlags & kColor_Attrib) { - LOG_ALWAYS_FATAL("color vertex attribute not yet supported"); - // TODO: enable color attribute, disable when done + int colorLocation = -1; + if (vertices.flags & VertexAttribFlags::kColor) { + colorLocation = fill.program->getAttrib("colors"); + glEnableVertexAttribArray(colorLocation); + glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, vertices.stride, vertices.color); } - int alphaSlot = -1; - if (mesh.vertexFlags & kAlpha_Attrib) { - const void* alphaCoords = ((const GLbyte*) glop.mesh.vertices) + kVertexAlphaOffset; - alphaSlot = fill.program->getAttrib("vtxAlpha"); - glEnableVertexAttribArray(alphaSlot); - glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, kAlphaVertexStride, alphaCoords); + int alphaLocation = -1; + if (vertices.flags & VertexAttribFlags::kAlpha) { + // NOTE: alpha vertex position is computed assuming no VBO + const void* alphaCoords = ((const GLbyte*) vertices.position) + kVertexAlphaOffset; + alphaLocation = fill.program->getAttrib("vtxAlpha"); + glEnableVertexAttribArray(alphaLocation); + glVertexAttribPointer(alphaLocation, 1, GL_FLOAT, GL_FALSE, vertices.stride, alphaCoords); } - // Shader uniforms - SkiaShader::apply(*mCaches, glop.fill.skiaShaderData); + SkiaShader::apply(*mCaches, fill.skiaShaderData); // ------------------------------------ // ---------- GL state setup ---------- @@ -304,27 +301,27 @@ void RenderState::render(const Glop& glop) { // ------------------------------------ // ---------- Actual drawing ---------- // ------------------------------------ - if (mesh.indexBufferObject == meshState().getQuadListIBO()) { + if (indices.bufferObject == meshState().getQuadListIBO()) { // Since the indexed quad list is of limited length, we loop over // the glDrawXXX method while updating the vertex pointer GLsizei elementsCount = mesh.elementCount; - const GLbyte* vertices = static_cast<const GLbyte*>(mesh.vertices); + const GLbyte* vertexData = static_cast<const GLbyte*>(vertices.position); while (elementsCount > 0) { GLsizei drawCount = MathUtils::min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6); // rebind pointers without forcing, since initial bind handled above - meshState().bindPositionVertexPointer(false, vertices, mesh.stride); - if (mesh.vertexFlags & kTextureCoord_Attrib) { + meshState().bindPositionVertexPointer(false, vertexData, vertices.stride); + if (vertices.flags & VertexAttribFlags::kTextureCoord) { meshState().bindTexCoordsVertexPointer(false, - vertices + kMeshTextureOffset, mesh.stride); + vertexData + kMeshTextureOffset, vertices.stride); } glDrawElements(mesh.primitiveMode, drawCount, GL_UNSIGNED_SHORT, nullptr); elementsCount -= drawCount; - vertices += (drawCount / 6) * 4 * mesh.stride; + vertexData += (drawCount / 6) * 4 * vertices.stride; } - } else if (mesh.indexBufferObject || mesh.indices) { - glDrawElements(mesh.primitiveMode, mesh.elementCount, GL_UNSIGNED_SHORT, mesh.indices); + } else if (indices.bufferObject || indices.indices) { + glDrawElements(mesh.primitiveMode, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices); } else { glDrawArrays(mesh.primitiveMode, 0, mesh.elementCount); } @@ -332,8 +329,11 @@ void RenderState::render(const Glop& glop) { // ----------------------------------- // ---------- Mesh teardown ---------- // ----------------------------------- - if (glop.mesh.vertexFlags & kAlpha_Attrib) { - glDisableVertexAttribArray(alphaSlot); + if (vertices.flags & VertexAttribFlags::kAlpha) { + glDisableVertexAttribArray(alphaLocation); + } + if (vertices.flags & VertexAttribFlags::kColor) { + glDisableVertexAttribArray(colorLocation); } } diff --git a/libs/hwui/utils/Macros.h b/libs/hwui/utils/Macros.h index 49d364e7..2ed605e 100644 --- a/libs/hwui/utils/Macros.h +++ b/libs/hwui/utils/Macros.h @@ -41,6 +41,12 @@ } \ inline int operator&(int lhs, enumType rhs) { \ return lhs & static_cast<int>(rhs); \ + } \ + inline int operator&(enumType lhs, int rhs) { \ + return static_cast<int>(lhs) & rhs; \ + } \ + inline int operator&(enumType lhs, enumType rhs) { \ + return static_cast<int>(lhs) & static_cast<int>(rhs); \ } #endif /* MACROS_H */ |