| Index: src/gpu/instanced/InstanceProcessor.cpp
|
| diff --git a/src/gpu/instanced/InstanceProcessor.cpp b/src/gpu/instanced/InstanceProcessor.cpp
|
| index acad4c1e1b0e446d71de88e1411cd534759bef24..82e3e219a3b6df9b988c67cae57e267f1740e972 100644
|
| --- a/src/gpu/instanced/InstanceProcessor.cpp
|
| +++ b/src/gpu/instanced/InstanceProcessor.cpp
|
| @@ -147,12 +147,12 @@ public:
|
| void init(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*);
|
| virtual void setupRect(GrGLSLVertexBuilder*) = 0;
|
| virtual void setupOval(GrGLSLVertexBuilder*) = 0;
|
| - void setupRRect(GrGLSLVertexBuilder*);
|
| + void setupRRect(GrGLSLVertexBuilder*, int* usedShapeDefinitions);
|
|
|
| void initInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*);
|
| virtual void setupInnerRect(GrGLSLVertexBuilder*) = 0;
|
| virtual void setupInnerOval(GrGLSLVertexBuilder*) = 0;
|
| - void setupInnerRRect(GrGLSLVertexBuilder*);
|
| + void setupInnerSimpleRRect(GrGLSLVertexBuilder*);
|
|
|
| const char* outShapeCoords() {
|
| return fModifiedShapeCoords ? fModifiedShapeCoords : fInputs.attr(Attrib::kShapeCoords);
|
| @@ -184,7 +184,7 @@ protected:
|
| virtual void onSetupRRect(GrGLSLVertexBuilder*) {}
|
|
|
| virtual void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) = 0;
|
| - virtual void onSetupInnerRRect(GrGLSLVertexBuilder*) = 0;
|
| + virtual void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) = 0;
|
|
|
| virtual void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*,
|
| const char* outCoverage, const char* outColor) = 0;
|
| @@ -237,11 +237,8 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
| v->codeAppend ("}");
|
| }
|
|
|
| - int usedShapeTypes = 0;
|
| -
|
| bool hasSingleShapeType = SkIsPow2(ip.batchInfo().fShapeTypes);
|
| if (!hasSingleShapeType) {
|
| - usedShapeTypes |= ip.batchInfo().fShapeTypes;
|
| v->define("SHAPE_TYPE_BIT", kShapeType_InfoBit);
|
| v->codeAppendf("uint shapeType = %s >> SHAPE_TYPE_BIT;",
|
| inputs.attr(Attrib::kInstanceInfo));
|
| @@ -250,38 +247,46 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
| SkAutoTDelete<Backend> backend(Backend::Create(pipeline, ip.batchInfo(), inputs));
|
| backend->init(varyingHandler, v);
|
|
|
| - if (hasSingleShapeType) {
|
| + int usedShapeDefinitions = 0;
|
| +
|
| + if (hasSingleShapeType || !(ip.batchInfo().fShapeTypes & ~kRRect_ShapesMask)) {
|
| if (kRect_ShapeFlag == ip.batchInfo().fShapeTypes) {
|
| backend->setupRect(v);
|
| } else if (kOval_ShapeFlag == ip.batchInfo().fShapeTypes) {
|
| backend->setupOval(v);
|
| } else {
|
| - backend->setupRRect(v);
|
| + backend->setupRRect(v, &usedShapeDefinitions);
|
| }
|
| } else {
|
| - v->codeAppend ("switch (shapeType) {");
|
| - if (ip.batchInfo().fShapeTypes & kRect_ShapeFlag) {
|
| - v->codeAppend ("case RECT_SHAPE_TYPE: {");
|
| - backend->setupRect(v);
|
| - v->codeAppend ("} break;");
|
| + if (ip.batchInfo().fShapeTypes & kRRect_ShapesMask) {
|
| + v->codeAppend ("if (shapeType >= SIMPLE_R_RECT_SHAPE_TYPE) {");
|
| + backend->setupRRect(v, &usedShapeDefinitions);
|
| + v->codeAppend ("}");
|
| + usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
|
| }
|
| if (ip.batchInfo().fShapeTypes & kOval_ShapeFlag) {
|
| - v->codeAppend ("case OVAL_SHAPE_TYPE: {");
|
| + if (ip.batchInfo().fShapeTypes & kRect_ShapeFlag) {
|
| + if (ip.batchInfo().fShapeTypes & kRRect_ShapesMask) {
|
| + v->codeAppend ("else ");
|
| + }
|
| + v->codeAppend ("if (OVAL_SHAPE_TYPE == shapeType) {");
|
| + usedShapeDefinitions |= kOval_ShapeFlag;
|
| + } else {
|
| + v->codeAppend ("else {");
|
| + }
|
| backend->setupOval(v);
|
| - v->codeAppend ("} break;");
|
| + v->codeAppend ("}");
|
| }
|
| - if (ip.batchInfo().fShapeTypes & kRRect_ShapesMask) {
|
| - v->codeAppend ("default: {");
|
| - backend->setupRRect(v);
|
| - v->codeAppend ("} break;");
|
| + if (ip.batchInfo().fShapeTypes & kRect_ShapeFlag) {
|
| + v->codeAppend ("else {");
|
| + backend->setupRect(v);
|
| + v->codeAppend ("}");
|
| }
|
| - v->codeAppend ("}");
|
| }
|
|
|
| if (ip.batchInfo().fInnerShapeTypes) {
|
| bool hasSingleInnerShapeType = SkIsPow2(ip.batchInfo().fInnerShapeTypes);
|
| if (!hasSingleInnerShapeType) {
|
| - usedShapeTypes |= ip.batchInfo().fInnerShapeTypes;
|
| v->definef("INNER_SHAPE_TYPE_MASK", "0x%xu", kInnerShapeType_InfoMask);
|
| v->define("INNER_SHAPE_TYPE_BIT", kInnerShapeType_InfoBit);
|
| v->codeAppendf("uint innerShapeType = ((%s & INNER_SHAPE_TYPE_MASK) >> "
|
| @@ -303,41 +308,55 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
|
|
|
| backend->initInnerShape(varyingHandler, v);
|
|
|
| + SkASSERT(0 == (ip.batchInfo().fInnerShapeTypes & kRRect_ShapesMask) ||
|
| + kSimpleRRect_ShapeFlag == (ip.batchInfo().fInnerShapeTypes & kRRect_ShapesMask));
|
| +
|
| if (hasSingleInnerShapeType) {
|
| if (kRect_ShapeFlag == ip.batchInfo().fInnerShapeTypes) {
|
| backend->setupInnerRect(v);
|
| } else if (kOval_ShapeFlag == ip.batchInfo().fInnerShapeTypes) {
|
| backend->setupInnerOval(v);
|
| } else {
|
| - backend->setupInnerRRect(v);
|
| + backend->setupInnerSimpleRRect(v);
|
| }
|
| } else {
|
| - v->codeAppend("switch (innerShapeType) {");
|
| - if (ip.batchInfo().fInnerShapeTypes & kRect_ShapeFlag) {
|
| - v->codeAppend("case RECT_SHAPE_TYPE: {");
|
| - backend->setupInnerRect(v);
|
| - v->codeAppend("} break;");
|
| + if (ip.batchInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
|
| + v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == innerShapeType) {");
|
| + backend->setupInnerSimpleRRect(v);
|
| + v->codeAppend("}");
|
| + usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
|
| }
|
| if (ip.batchInfo().fInnerShapeTypes & kOval_ShapeFlag) {
|
| - v->codeAppend("case OVAL_SHAPE_TYPE: {");
|
| + if (ip.batchInfo().fInnerShapeTypes & kRect_ShapeFlag) {
|
| + if (ip.batchInfo().fInnerShapeTypes & kSimpleRRect_ShapeFlag) {
|
| + v->codeAppend ("else ");
|
| + }
|
| + v->codeAppend ("if (OVAL_SHAPE_TYPE == innerShapeType) {");
|
| + usedShapeDefinitions |= kOval_ShapeFlag;
|
| + } else {
|
| + v->codeAppend ("else {");
|
| + }
|
| backend->setupInnerOval(v);
|
| - v->codeAppend("} break;");
|
| + v->codeAppend("}");
|
| }
|
| - if (ip.batchInfo().fInnerShapeTypes & kRRect_ShapesMask) {
|
| - v->codeAppend("default: {");
|
| - backend->setupInnerRRect(v);
|
| - v->codeAppend("} break;");
|
| + if (ip.batchInfo().fInnerShapeTypes & kRect_ShapeFlag) {
|
| + v->codeAppend("else {");
|
| + backend->setupInnerRect(v);
|
| + v->codeAppend("}");
|
| }
|
| - v->codeAppend("}");
|
| }
|
| }
|
|
|
| - if (usedShapeTypes & kRect_ShapeFlag) {
|
| - v->definef("RECT_SHAPE_TYPE", "%du", (int)ShapeType::kRect);
|
| - }
|
| - if (usedShapeTypes & kOval_ShapeFlag) {
|
| + if (usedShapeDefinitions & kOval_ShapeFlag) {
|
| v->definef("OVAL_SHAPE_TYPE", "%du", (int)ShapeType::kOval);
|
| }
|
| + if (usedShapeDefinitions & kSimpleRRect_ShapeFlag) {
|
| + v->definef("SIMPLE_R_RECT_SHAPE_TYPE", "%du", (int)ShapeType::kSimpleRRect);
|
| + }
|
| + if (usedShapeDefinitions & kNinePatch_ShapeFlag) {
|
| + v->definef("NINE_PATCH_SHAPE_TYPE", "%du", (int)ShapeType::kNinePatch);
|
| + }
|
| + SkASSERT(!(usedShapeDefinitions & (kRect_ShapeFlag | kComplexRRect_ShapeFlag)));
|
|
|
| backend->emitCode(v, f, pipeline.ignoresCoverage() ? nullptr : args.fOutputCoverage,
|
| args.fOutputColor);
|
| @@ -393,7 +412,7 @@ void GLSLInstanceProcessor::Backend::init(GrGLSLVaryingHandler* varyingHandler,
|
| }
|
| }
|
|
|
| -void GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v) {
|
| +void GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v, int* usedShapeDefinitions) {
|
| v->codeAppendf("uvec2 corner = uvec2(%s & 1, (%s >> 1) & 1);",
|
| fInputs.attr(Attrib::kVertexAttrs), fInputs.attr(Attrib::kVertexAttrs));
|
| v->codeAppend ("vec2 cornerSign = vec2(corner) * 2.0 - 1.0;");
|
| @@ -411,25 +430,30 @@ void GLSLInstanceProcessor::Backend::setupRRect(GrGLSLVertexBuilder* v) {
|
| this->setupComplexRadii(v);
|
| }
|
| } else {
|
| - v->codeAppend("switch (shapeType) {");
|
| if (types & kSimpleRRect_ShapeFlag) {
|
| - v->definef("SIMPLE_R_RECT_SHAPE_TYPE", "%du", (int)ShapeType::kSimpleRRect);
|
| - v->codeAppend ("case SIMPLE_R_RECT_SHAPE_TYPE: {");
|
| + v->codeAppend ("if (SIMPLE_R_RECT_SHAPE_TYPE == shapeType) {");
|
| this->setupSimpleRadii(v);
|
| - v->codeAppend ("} break;");
|
| + v->codeAppend ("}");
|
| + *usedShapeDefinitions |= kSimpleRRect_ShapeFlag;
|
| }
|
| if (types & kNinePatch_ShapeFlag) {
|
| - v->definef("NINE_PATCH_SHAPE_TYPE", "%du", (int)ShapeType::kNinePatch);
|
| - v->codeAppend ("case NINE_PATCH_SHAPE_TYPE: {");
|
| + if (types & kComplexRRect_ShapeFlag) {
|
| + if (types & kSimpleRRect_ShapeFlag) {
|
| + v->codeAppend ("else ");
|
| + }
|
| + v->codeAppend ("if (NINE_PATCH_SHAPE_TYPE == shapeType) {");
|
| + *usedShapeDefinitions |= kNinePatch_ShapeFlag;
|
| + } else {
|
| + v->codeAppend ("else {");
|
| + }
|
| this->setupNinePatchRadii(v);
|
| - v->codeAppend ("} break;");
|
| + v->codeAppend ("}");
|
| }
|
| if (types & kComplexRRect_ShapeFlag) {
|
| - v->codeAppend ("default: {");
|
| + v->codeAppend ("else {");
|
| this->setupComplexRadii(v);
|
| - v->codeAppend ("} break;");
|
| + v->codeAppend ("}");
|
| }
|
| - v->codeAppend("}");
|
| }
|
|
|
| this->adjustRRectVertices(v);
|
| @@ -507,12 +531,12 @@ void GLSLInstanceProcessor::Backend::initInnerShape(GrGLSLVaryingHandler* varyin
|
| }
|
| }
|
|
|
| -void GLSLInstanceProcessor::Backend::setupInnerRRect(GrGLSLVertexBuilder* v) {
|
| +void GLSLInstanceProcessor::Backend::setupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
|
| v->codeAppend("mat2 innerP = ");
|
| fInputs.fetchNextParam(kMat22f_GrSLType);
|
| v->codeAppend(";");
|
| v->codeAppend("vec2 innerRadii = innerP[0] * 2.0 / innerP[1];");
|
| - this->onSetupInnerRRect(v);
|
| + this->onSetupInnerSimpleRRect(v);
|
| }
|
|
|
| void GLSLInstanceProcessor::Backend::emitCode(GrGLSLVertexBuilder* v, GrGLSLPPFragmentBuilder* f,
|
| @@ -550,7 +574,7 @@ private:
|
| void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
|
| void setupInnerRect(GrGLSLVertexBuilder*) override;
|
| void setupInnerOval(GrGLSLVertexBuilder*) override;
|
| - void onSetupInnerRRect(GrGLSLVertexBuilder*) override;
|
| + void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;
|
|
|
| void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*,
|
| const char*) override;
|
| @@ -600,7 +624,7 @@ void GLSLInstanceProcessor::BackendNonAA::setupInnerOval(GrGLSLVertexBuilder* v)
|
| }
|
| }
|
|
|
| -void GLSLInstanceProcessor::BackendNonAA::onSetupInnerRRect(GrGLSLVertexBuilder* v) {
|
| +void GLSLInstanceProcessor::BackendNonAA::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
|
| v->codeAppendf("%s = vec4(1.0 - innerRadii, 1.0 / innerRadii);", fInnerRRect.vsOut());
|
| }
|
|
|
| @@ -690,7 +714,7 @@ private:
|
| void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
|
| void setupInnerRect(GrGLSLVertexBuilder*) override;
|
| void setupInnerOval(GrGLSLVertexBuilder*) override;
|
| - void onSetupInnerRRect(GrGLSLVertexBuilder*) override;
|
| + void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;
|
|
|
| void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char* outCoverage,
|
| const char* outColor) override;
|
| @@ -882,7 +906,7 @@ void GLSLInstanceProcessor::BackendCoverage::setupInnerOval(GrGLSLVertexBuilder*
|
| }
|
| }
|
|
|
| -void GLSLInstanceProcessor::BackendCoverage::onSetupInnerRRect(GrGLSLVertexBuilder* v) {
|
| +void GLSLInstanceProcessor::BackendCoverage::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
|
| // The distance to ellipse formula doesn't work well when the radii are less than half a pixel.
|
| v->codeAppend ("innerRadii = max(innerRadii, bloat);");
|
| v->codeAppendf("%s = 1.0 / (innerRadii * innerRadii * innerShapeHalfSize * "
|
| @@ -1064,7 +1088,7 @@ private:
|
| void onInitInnerShape(GrGLSLVaryingHandler*, GrGLSLVertexBuilder*) override;
|
| void setupInnerRect(GrGLSLVertexBuilder*) override;
|
| void setupInnerOval(GrGLSLVertexBuilder*) override;
|
| - void onSetupInnerRRect(GrGLSLVertexBuilder*) override;
|
| + void onSetupInnerSimpleRRect(GrGLSLVertexBuilder*) override;
|
|
|
| void onEmitCode(GrGLSLVertexBuilder*, GrGLSLPPFragmentBuilder*, const char*,
|
| const char*) override;
|
| @@ -1319,7 +1343,7 @@ void GLSLInstanceProcessor::BackendMultisample::setupInnerOval(GrGLSLVertexBuild
|
| }
|
| }
|
|
|
| -void GLSLInstanceProcessor::BackendMultisample::onSetupInnerRRect(GrGLSLVertexBuilder* v) {
|
| +void GLSLInstanceProcessor::BackendMultisample::onSetupInnerSimpleRRect(GrGLSLVertexBuilder* v) {
|
| // Avoid numeric instability by not allowing the inner radii to get smaller than 1/10th pixel.
|
| if (fFragInnerShapeHalfSpan.vsOut()) {
|
| v->codeAppendf("innerRadii = max(innerRadii, 2e-1 * %s);", fFragInnerShapeHalfSpan.vsOut());
|
|
|