Handle shader matrix correctly when ignoring canvas transform

bug:20063841

Restores old SkShader matrix behavior from before the Glop refactor.

Many drawing operations draw without sending the canvas transform to
the GL shader. In such cases, we need to adapt the matrix sent to the
SkShader logic to invert the canvas transform that's built into
the mesh.

Change-Id: I42b6f59df36ce46436322b95bf9ad2140795ee58
This commit is contained in:
Chris Craik
2015-06-01 10:35:35 -07:00
parent 1e47a8e096
commit 53e51e4aa9
10 changed files with 204 additions and 133 deletions

View File

@@ -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);
if (linearFiltering) {
textureFillFlags |= TextureFillFlags::kForceFilter;
int textureFillFlags = TextureFillFlags::None;
if (texture.getFormat() == GL_ALPHA) {
textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture;
}
const Matrix4& transform = pureTranslate ? Matrix4::identity() : *(renderer->currentTransform());
if (linearFiltering) {
textureFillFlags |= TextureFillFlags::ForceFilter;
}
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();

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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,

View File

@@ -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();

View File

@@ -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 composeLayerRect(Layer* layer, const Rect& rect, bool swap = false);
void composeLayerRectSwapped(Layer* layer, const Rect& rect);
/**
* Draws the content in layer to the screen.
*/
void composeLayerRect(Layer* layer, const Rect& rect);
/**
* Clears all the regions corresponding to the current list of layers.

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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;