Glop layer mesh rendering
Change-Id: I2d902819d5d77f496b67d4d25a298782903e410d
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index f133d42..4617588 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -73,8 +73,7 @@
return *this;
}
-GlopBuilder& GlopBuilder::setMeshTexturedUnitQuad(const UvMapper* uvMapper,
- bool isAlphaMaskTexture) {
+GlopBuilder& GlopBuilder::setMeshTexturedUnitQuad(const UvMapper* uvMapper) {
TRIGGER_STAGE(kMeshStage);
mOutGlop->mesh.vertexFlags = kTextureCoord_Attrib;
@@ -87,19 +86,18 @@
mOutGlop->mesh.vertexBufferObject = 0;
mOutGlop->mesh.vertices = &mOutGlop->mesh.mappedVertices[0];
+ mOutGlop->mesh.texCoordOffset = &mOutGlop->mesh.mappedVertices[0].u;
} else {
// standard UV coordinates, use regular unit quad VBO
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.elementCount = 4;
mOutGlop->mesh.stride = kTextureVertexStride;
- mOutGlop->mesh.texCoordOffset = (GLvoid*) kMeshTextureOffset;
-
mDescription.hasTexture = true;
- mDescription.hasAlpha8Texture = isAlphaMaskTexture;
return *this;
}
@@ -112,13 +110,29 @@
mOutGlop->mesh.vertices = vertexData;
mOutGlop->mesh.indexBufferObject = mRenderState.meshState().getQuadListIBO();
mOutGlop->mesh.indices = nullptr;
+ mOutGlop->mesh.texCoordOffset = nullptr;
mOutGlop->mesh.elementCount = 6 * quadCount;
mOutGlop->mesh.stride = kVertexStride;
- mOutGlop->mesh.texCoordOffset = nullptr;
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.elementCount = elementCount;
+ mOutGlop->mesh.stride = kTextureVertexStride;
+ mDescription.hasTexture = true;
+ return *this;
+}
+
GlopBuilder& GlopBuilder::setMeshVertexBuffer(const VertexBuffer& vertexBuffer, bool shadowInterp) {
TRIGGER_STAGE(kMeshStage);
@@ -132,6 +146,7 @@
mOutGlop->mesh.vertices = vertexBuffer.getBuffer();
mOutGlop->mesh.indexBufferObject = 0;
mOutGlop->mesh.indices = vertexBuffer.getIndices();
+ mOutGlop->mesh.texCoordOffset = nullptr;
mOutGlop->mesh.elementCount = indices
? vertexBuffer.getIndexCount() : vertexBuffer.getVertexCount();
mOutGlop->mesh.stride = alphaVertex ? kAlphaVertexStride : kVertexStride;
@@ -168,7 +183,7 @@
mOutGlop->blend = { GL_ZERO, GL_ZERO };
if (mOutGlop->fill.color.a < 1.0f
|| (mOutGlop->mesh.vertexFlags & kAlpha_Attrib)
- || (mOutGlop->fill.texture && mOutGlop->fill.texture->blend)
+ || (mOutGlop->fill.texture.texture && mOutGlop->fill.texture.texture->blend)
|| mOutGlop->roundRectClipState
|| PaintUtils::isBlendedShader(shader)
|| PaintUtils::isBlendedColorFilter(colorFilter)
@@ -240,9 +255,7 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = &texture;
- mOutGlop->fill.textureFilter = PaintUtils::getFilter(paint);
- mOutGlop->fill.textureClamp = GL_CLAMP_TO_EDGE;
+ mOutGlop->fill.texture = { &texture, PaintUtils::getFilter(paint), GL_CLAMP_TO_EDGE };
if (paint) {
int color = paint->getColor();
@@ -270,6 +283,7 @@
}
}
+ mDescription.hasAlpha8Texture = isAlphaMaskTexture;
if (isAlphaMaskTexture) {
mDescription.modulate = mOutGlop->fill.color.isNotBlack();
} else {
@@ -282,9 +296,7 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = nullptr;
- mOutGlop->fill.textureFilter = GL_INVALID_ENUM;
- mOutGlop->fill.textureClamp = GL_INVALID_ENUM;
+ mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM };
setFill(paint.getColor(), alphaScale, PaintUtils::getXfermode(paint.getXfermode()),
paint.getShader(), paint.getColorFilter());
@@ -297,15 +309,13 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = &texture;
-
- //specify invalid, since these are always static for PathTextures
- mOutGlop->fill.textureFilter = GL_INVALID_ENUM;
- mOutGlop->fill.textureClamp = GL_INVALID_ENUM;
+ //specify invalid filter/clamp, since these are always static for PathTextures
+ mOutGlop->fill.texture = { &texture, GL_INVALID_ENUM, GL_INVALID_ENUM };
setFill(paint.getColor(), alphaScale, PaintUtils::getXfermode(paint.getXfermode()),
paint.getShader(), paint.getColorFilter());
+ mDescription.hasAlpha8Texture = true;
mDescription.modulate = mOutGlop->fill.color.isNotBlack();
return *this;
}
@@ -315,11 +325,8 @@
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;
+ //specify invalid filter/clamp, since these are always static for ShadowTextures
+ mOutGlop->fill.texture = { &texture, GL_INVALID_ENUM, GL_INVALID_ENUM };
const int ALPHA_BITMASK = SK_ColorBLACK;
const int COLOR_BITMASK = ~ALPHA_BITMASK;
@@ -331,6 +338,7 @@
setFill(shadowColor, alphaScale, PaintUtils::getXfermode(paint.getXfermode()),
paint.getShader(), paint.getColorFilter());
+ mDescription.hasAlpha8Texture = true;
mDescription.modulate = mOutGlop->fill.color.isNotBlack();
return *this;
}
@@ -339,12 +347,8 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = nullptr;
- mOutGlop->fill.textureFilter = GL_INVALID_ENUM;
- mOutGlop->fill.textureClamp = GL_INVALID_ENUM;
-
+ mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM };
setFill(SK_ColorBLACK, 1.0f, SkXfermode::kSrcOver_Mode, nullptr, nullptr);
-
return *this;
}
@@ -352,19 +356,30 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = nullptr;
- mOutGlop->fill.textureFilter = GL_INVALID_ENUM;
- mOutGlop->fill.textureClamp = GL_INVALID_ENUM;
-
+ mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM };
setFill(SK_ColorBLACK, 1.0f, SkXfermode::kClear_Mode, nullptr, nullptr);
-
return *this;
}
+
+GlopBuilder& GlopBuilder::setFillLayer(Texture& texture, const SkColorFilter* colorFilter,
+ float alpha, SkXfermode::Mode mode) {
+ TRIGGER_STAGE(kFillStage);
+ REQUIRE_STAGES(kMeshStage);
+
+ mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE };
+ mOutGlop->fill.color = { alpha, alpha, alpha, alpha };
+
+ setFill(SK_ColorWHITE, alpha, mode, nullptr, colorFilter);
+
+ mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
+ return *this;
+}
+
////////////////////////////////////////////////////////////////////////////////
// Transform
////////////////////////////////////////////////////////////////////////////////
-GlopBuilder& GlopBuilder::setTransformClip(const Matrix4& ortho,
+GlopBuilder& GlopBuilder::setTransform(const Matrix4& ortho,
const Matrix4& transform, bool fudgingOffset) {
TRIGGER_STAGE(kTransformStage);
@@ -396,12 +411,13 @@
const Matrix4& canvasTransform = mOutGlop->transform.canvas;
if (CC_LIKELY(canvasTransform.isPureTranslate())) {
+ // snap by adjusting the model view matrix
const float translateX = canvasTransform.getTranslateX();
const float translateY = canvasTransform.getTranslateY();
left = (int) floorf(left + translateX + 0.5f) - translateX;
top = (int) floorf(top + translateY + 0.5f) - translateY;
- mOutGlop->fill.textureFilter = GL_NEAREST;
+ mOutGlop->fill.texture.filter = GL_NEAREST;
}
mOutGlop->transform.modelView.loadTranslate(left, top, 0.0f);
@@ -419,6 +435,30 @@
return *this;
}
+GlopBuilder& GlopBuilder::setModelViewOffsetRectSnap(float offsetX, float offsetY, const Rect source) {
+ TRIGGER_STAGE(kModelViewStage);
+ REQUIRE_STAGES(kTransformStage | kFillStage);
+
+ const Matrix4& canvasTransform = mOutGlop->transform.canvas;
+ if (CC_LIKELY(canvasTransform.isPureTranslate())) {
+ // snap by adjusting the model view matrix
+ const float translateX = canvasTransform.getTranslateX();
+ const float translateY = canvasTransform.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;
+ mOutGlop->fill.texture.filter = GL_NEAREST;
+ }
+
+ mOutGlop->transform.modelView.loadTranslate(offsetX, offsetY, 0.0f);
+ mOutGlop->bounds.translate(offsetX, offsetY);
+ return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RoundRectClip
+////////////////////////////////////////////////////////////////////////////////
+
GlopBuilder& GlopBuilder::setRoundRectClipState(const RoundRectClipState* roundRectClipState) {
TRIGGER_STAGE(kRoundRectClipStage);
@@ -431,11 +471,17 @@
// Build
////////////////////////////////////////////////////////////////////////////////
+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);
+}
+
void GlopBuilder::build() {
REQUIRE_STAGES(kAllStages);
// serialize shader info into ShaderData
- GLuint textureUnit = mOutGlop->fill.texture ? 1 : 0;
+ GLuint textureUnit = mOutGlop->fill.texture.texture ? 1 : 0;
SkiaShader::store(mCaches, mShader, mOutGlop->transform.modelView,
&textureUnit, &mDescription, &(mOutGlop->fill.skiaShaderData));
@@ -448,6 +494,8 @@
&& !mDescription.hasGradient
&& !mDescription.hasBitmap;
mOutGlop->fill.colorEnabled = mDescription.modulate || singleColor;
+
+ verify(mDescription, *mOutGlop);
}
} /* namespace uirenderer */