aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2016-12-14 15:52:56 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-14 21:29:49 +0000
commit289e3d8dd70b08b509aa29594fe831e0278304ef (patch)
treefc8e4e63eda88c1b504bafc1f60aabc4067899bf /src/gpu
parent222e9ad98be456c1aa5ef7be38a7ea11a3e3a7f1 (diff)
Bring sk_sp to oval GrDrawOps and rename batch->op
Change-Id: Ic0e95a29f1e2479d3d79b7d175290cb20422b585 Reviewed-on: https://skia-review.googlesource.com/6082 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrBatchTest.cpp16
-rw-r--r--src/gpu/GrOvalRenderer.h48
-rw-r--r--src/gpu/GrRenderTargetContext.cpp44
-rw-r--r--src/gpu/batches/GrOvalOpFactory.cpp (renamed from src/gpu/GrOvalRenderer.cpp)1033
-rw-r--r--src/gpu/batches/GrOvalOpFactory.h49
5 files changed, 574 insertions, 616 deletions
diff --git a/src/gpu/GrBatchTest.cpp b/src/gpu/GrBatchTest.cpp
index 09ed7b4c92..c09c12c531 100644
--- a/src/gpu/GrBatchTest.cpp
+++ b/src/gpu/GrBatchTest.cpp
@@ -20,12 +20,12 @@ DRAW_BATCH_TEST_EXTERN(AAStrokeRectOp);
DRAW_BATCH_TEST_EXTERN(AnalyticRectOp);
DRAW_BATCH_TEST_EXTERN(DashBatch);
DRAW_BATCH_TEST_EXTERN(DefaultPathBatch);
-DRAW_BATCH_TEST_EXTERN(CircleBatch);
-DRAW_BATCH_TEST_EXTERN(DIEllipseBatch);
-DRAW_BATCH_TEST_EXTERN(EllipseBatch);
+DRAW_BATCH_TEST_EXTERN(CircleOp);
+DRAW_BATCH_TEST_EXTERN(DIEllipseOp);
+DRAW_BATCH_TEST_EXTERN(EllipseOp);
DRAW_BATCH_TEST_EXTERN(GrDrawAtlasBatch);
DRAW_BATCH_TEST_EXTERN(NonAAStrokeRectOp);
-DRAW_BATCH_TEST_EXTERN(RRectBatch);
+DRAW_BATCH_TEST_EXTERN(RRectOp);
DRAW_BATCH_TEST_EXTERN(TesselatingPathBatch);
DRAW_BATCH_TEST_EXTERN(TextBlobBatch);
DRAW_BATCH_TEST_EXTERN(VerticesBatch);
@@ -40,12 +40,12 @@ static BatchTestFunc gTestBatches[] = {
DRAW_BATCH_TEST_ENTRY(AnalyticRectOp),
DRAW_BATCH_TEST_ENTRY(DashBatch),
DRAW_BATCH_TEST_ENTRY(DefaultPathBatch),
- DRAW_BATCH_TEST_ENTRY(CircleBatch),
- DRAW_BATCH_TEST_ENTRY(DIEllipseBatch),
- DRAW_BATCH_TEST_ENTRY(EllipseBatch),
+ DRAW_BATCH_TEST_ENTRY(CircleOp),
+ DRAW_BATCH_TEST_ENTRY(DIEllipseOp),
+ DRAW_BATCH_TEST_ENTRY(EllipseOp),
DRAW_BATCH_TEST_ENTRY(GrDrawAtlasBatch),
DRAW_BATCH_TEST_ENTRY(NonAAStrokeRectOp),
- DRAW_BATCH_TEST_ENTRY(RRectBatch),
+ DRAW_BATCH_TEST_ENTRY(RRectOp),
DRAW_BATCH_TEST_ENTRY(TesselatingPathBatch),
DRAW_BATCH_TEST_ENTRY(TextBlobBatch),
DRAW_BATCH_TEST_ENTRY(VerticesBatch)
diff --git a/src/gpu/GrOvalRenderer.h b/src/gpu/GrOvalRenderer.h
deleted file mode 100644
index 21144bd4f1..0000000000
--- a/src/gpu/GrOvalRenderer.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrOvalRenderer_DEFINED
-#define GrOvalRenderer_DEFINED
-
-#include "GrColor.h"
-
-class GrDrawOp;
-class GrShaderCaps;
-class GrStyle;
-class SkMatrix;
-struct SkRect;
-class SkRRect;
-class SkStrokeRec;
-
-/*
- * This class wraps helper functions that draw ovals and roundrects (filled & stroked)
- */
-class GrOvalRenderer {
-public:
- static GrDrawOp* CreateOvalBatch(GrColor,
- const SkMatrix& viewMatrix,
- const SkRect& oval,
- const SkStrokeRec& stroke,
- const GrShaderCaps* shaderCaps);
- static GrDrawOp* CreateRRectBatch(GrColor,
- bool needsDistance,
- const SkMatrix& viewMatrix,
- const SkRRect& rrect,
- const SkStrokeRec& stroke,
- const GrShaderCaps* shaderCaps);
-
- static GrDrawOp* CreateArcBatch(GrColor,
- const SkMatrix& viewMatrix,
- const SkRect& oval,
- SkScalar startAngle,
- SkScalar sweepAngle,
- bool useCenter,
- const GrStyle&,
- const GrShaderCaps* shaderCaps);
-};
-
-#endif // GrOvalRenderer_DEFINED
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 0ded922c64..1c0832b7ec 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -12,7 +12,6 @@
#include "GrDrawingManager.h"
#include "GrFixedClip.h"
#include "GrGpuResourcePriv.h"
-#include "GrOvalRenderer.h"
#include "GrPathRenderer.h"
#include "GrPipelineBuilder.h"
#include "GrRenderTarget.h"
@@ -25,6 +24,7 @@
#include "batches/GrDrawVerticesBatch.h"
#include "batches/GrNinePatch.h" // TODO Factory
#include "batches/GrOp.h"
+#include "batches/GrOvalOpFactory.h"
#include "batches/GrRectOpFactory.h"
#include "batches/GrRegionBatch.h"
#include "batches/GrShadowRRectBatch.h"
@@ -926,12 +926,12 @@ void GrRenderTargetContext::drawRRect(const GrClip& origClip,
aaType = this->decideAAType(aa);
if (GrAAType::kCoverage == aaType) {
const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
- sk_sp<GrDrawOp> op(GrOvalRenderer::CreateRRectBatch(paint.getColor(),
- paint.usesDistanceVectorField(),
- viewMatrix,
- rrect,
- stroke,
- shaderCaps));
+ sk_sp<GrDrawOp> op = GrOvalOpFactory::MakeRRectOp(paint.getColor(),
+ paint.usesDistanceVectorField(),
+ viewMatrix,
+ rrect,
+ stroke,
+ shaderCaps);
if (op) {
GrPipelineBuilder pipelineBuilder(paint, aaType);
this->getOpList()->addDrawOp(pipelineBuilder, this, *clip, std::move(op));
@@ -1159,11 +1159,8 @@ void GrRenderTargetContext::drawOval(const GrClip& clip,
aaType = this->decideAAType(aa);
if (GrAAType::kCoverage == aaType) {
const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
- sk_sp<GrDrawOp> op(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
- viewMatrix,
- oval,
- stroke,
- shaderCaps));
+ sk_sp<GrDrawOp> op =
+ GrOvalOpFactory::MakeOvalOp(paint.getColor(), viewMatrix, oval, stroke, shaderCaps);
if (op) {
GrPipelineBuilder pipelineBuilder(paint, aaType);
this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
@@ -1189,14 +1186,14 @@ void GrRenderTargetContext::drawArc(const GrClip& clip,
GrAAType aaType = this->decideAAType(aa);
if (GrAAType::kCoverage == aaType) {
const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
- sk_sp<GrDrawOp> op(GrOvalRenderer::CreateArcBatch(paint.getColor(),
- viewMatrix,
- oval,
- startAngle,
- sweepAngle,
- useCenter,
- style,
- shaderCaps));
+ sk_sp<GrDrawOp> op = GrOvalOpFactory::MakeArcOp(paint.getColor(),
+ viewMatrix,
+ oval,
+ startAngle,
+ sweepAngle,
+ useCenter,
+ style,
+ shaderCaps);
if (op) {
GrPipelineBuilder pipelineBuilder(paint, aaType);
this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
@@ -1401,11 +1398,8 @@ void GrRenderTargetContext::drawPath(const GrClip& clip,
if (isOval && !path.isInverseFillType()) {
const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
- sk_sp<GrDrawOp> op(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
- viewMatrix,
- ovalRect,
- style.strokeRec(),
- shaderCaps));
+ sk_sp<GrDrawOp> op = GrOvalOpFactory::MakeOvalOp(
+ paint.getColor(), viewMatrix, ovalRect, style.strokeRec(), shaderCaps);
if (op) {
GrPipelineBuilder pipelineBuilder(paint, aaType);
this->getOpList()->addDrawOp(pipelineBuilder, this, clip, std::move(op));
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/batches/GrOvalOpFactory.cpp
index 0b6ee5ee50..ca38bf2232 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/batches/GrOvalOpFactory.cpp
@@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
-#include "GrOvalRenderer.h"
+#include "GrOvalOpFactory.h"
#include "GrBatchTest.h"
#include "GrGeometryProcessor.h"
@@ -31,24 +31,21 @@
namespace {
struct EllipseVertex {
- SkPoint fPos;
- GrColor fColor;
- SkPoint fOffset;
- SkPoint fOuterRadii;
- SkPoint fInnerRadii;
+ SkPoint fPos;
+ GrColor fColor;
+ SkPoint fOffset;
+ SkPoint fOuterRadii;
+ SkPoint fInnerRadii;
};
struct DIEllipseVertex {
- SkPoint fPos;
- GrColor fColor;
- SkPoint fOuterOffset;
- SkPoint fInnerOffset;
+ SkPoint fPos;
+ GrColor fColor;
+ SkPoint fOuterOffset;
+ SkPoint fInnerOffset;
};
-inline bool circle_stays_circle(const SkMatrix& m) {
- return m.isSimilarity();
-}
-
+static inline bool circle_stays_circle(const SkMatrix& m) { return m.isSimilarity(); }
}
///////////////////////////////////////////////////////////////////////////////
@@ -123,7 +120,7 @@ private:
public:
GLSLProcessor() {}
- void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
+ void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const CircleGeometryProcessor& cgp = args.fGP.cast<CircleGeometryProcessor>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
@@ -168,29 +165,40 @@ private:
fragBuilder->codeAppend("float distanceToOuterEdge = circleEdge.z * (1.0 - d);");
fragBuilder->codeAppend("float edgeAlpha = clamp(distanceToOuterEdge, 0.0, 1.0);");
if (cgp.fStroke) {
- fragBuilder->codeAppend("float distanceToInnerEdge = circleEdge.z * (d - circleEdge.w);");
+ fragBuilder->codeAppend(
+ "float distanceToInnerEdge = circleEdge.z * (d - circleEdge.w);");
fragBuilder->codeAppend("float innerAlpha = clamp(distanceToInnerEdge, 0.0, 1.0);");
fragBuilder->codeAppend("edgeAlpha *= innerAlpha;");
}
if (args.fDistanceVectorName) {
const char* innerEdgeDistance = cgp.fStroke ? "distanceToInnerEdge" : "0.0";
- fragBuilder->codeAppend ("if (d == 0.0) {"); // if on the center of the circle
- fragBuilder->codeAppendf(" %s = vec4(1.0, 0.0, distanceToOuterEdge, "
- "%s);", // no normalize
- args.fDistanceVectorName, innerEdgeDistance);
- fragBuilder->codeAppend ("} else {");
- fragBuilder->codeAppendf(" %s = vec4(normalize(circleEdge.xy), distanceToOuterEdge, %s);",
- args.fDistanceVectorName, innerEdgeDistance);
- fragBuilder->codeAppend ("}");
+ fragBuilder->codeAppendf(
+ "if (d == 0.0) {" // if on the center of the circle
+ " %s = vec4(1.0, 0.0, distanceToOuterEdge, "
+ " %s);", // no normalize
+ args.fDistanceVectorName,
+ innerEdgeDistance);
+ fragBuilder->codeAppendf(
+ "} else {"
+ " %s = vec4(normalize(circleEdge.xy),"
+ " distanceToOuterEdge, %s);"
+ "}",
+ args.fDistanceVectorName, innerEdgeDistance);
}
if (cgp.fInClipPlane) {
- fragBuilder->codeAppend("float clip = clamp(circleEdge.z * dot(circleEdge.xy, clipPlane.xy) + clipPlane.z, 0.0, 1.0);");
+ fragBuilder->codeAppend(
+ "float clip = clamp(circleEdge.z * dot(circleEdge.xy, clipPlane.xy) + "
+ "clipPlane.z, 0.0, 1.0);");
if (cgp.fInIsectPlane) {
- fragBuilder->codeAppend("clip *= clamp(circleEdge.z * dot(circleEdge.xy, isectPlane.xy) + isectPlane.z, 0.0, 1.0);");
+ fragBuilder->codeAppend(
+ "clip *= clamp(circleEdge.z * dot(circleEdge.xy, isectPlane.xy) + "
+ "isectPlane.z, 0.0, 1.0);");
}
if (cgp.fInUnionPlane) {
- fragBuilder->codeAppend("clip += (1.0 - clip)*clamp(circleEdge.z * dot(circleEdge.xy, unionPlane.xy) + unionPlane.z, 0.0, 1.0);");
+ fragBuilder->codeAppend(
+ "clip += (1.0 - clip)*clamp(circleEdge.z * dot(circleEdge.xy, "
+ "unionPlane.xy) + unionPlane.z, 0.0, 1.0);");
}
fragBuilder->codeAppend("edgeAlpha *= clip;");
}
@@ -202,11 +210,11 @@ private:
GrProcessorKeyBuilder* b) {
const CircleGeometryProcessor& cgp = gp.cast<CircleGeometryProcessor>();
uint16_t key;
- key = cgp.fStroke ? 0x01 : 0x0;
+ key = cgp.fStroke ? 0x01 : 0x0;
key |= cgp.fLocalMatrix.hasPerspective() ? 0x02 : 0x0;
- key |= cgp.fInClipPlane ? 0x04 : 0x0;
- key |= cgp.fInIsectPlane ? 0x08 : 0x0;
- key |= cgp.fInUnionPlane ? 0x10 : 0x0;
+ key |= cgp.fInClipPlane ? 0x04 : 0x0;
+ key |= cgp.fInIsectPlane ? 0x08 : 0x0;
+ key |= cgp.fInUnionPlane ? 0x10 : 0x0;
b->add32(key);
}
@@ -220,14 +228,14 @@ private:
typedef GrGLSLGeometryProcessor INHERITED;
};
- SkMatrix fLocalMatrix;
+ SkMatrix fLocalMatrix;
const Attribute* fInPosition;
const Attribute* fInColor;
const Attribute* fInCircleEdge;
const Attribute* fInClipPlane;
const Attribute* fInIsectPlane;
const Attribute* fInUnionPlane;
- bool fStroke;
+ bool fStroke;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -237,10 +245,9 @@ private:
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleGeometryProcessor);
sk_sp<GrGeometryProcessor> CircleGeometryProcessor::TestCreate(GrProcessorTestData* d) {
- return sk_sp<GrGeometryProcessor>(
- new CircleGeometryProcessor(d->fRandom->nextBool(), d->fRandom->nextBool(),
- d->fRandom->nextBool(), d->fRandom->nextBool(),
- GrTest::TestMatrix(d->fRandom)));
+ return sk_sp<GrGeometryProcessor>(new CircleGeometryProcessor(
+ d->fRandom->nextBool(), d->fRandom->nextBool(), d->fRandom->nextBool(),
+ d->fRandom->nextBool(), GrTest::TestMatrix(d->fRandom)));
}
///////////////////////////////////////////////////////////////////////////////
@@ -255,8 +262,7 @@ sk_sp<GrGeometryProcessor> CircleGeometryProcessor::TestCreate(GrProcessorTestDa
class EllipseGeometryProcessor : public GrGeometryProcessor {
public:
- EllipseGeometryProcessor(bool stroke, const SkMatrix& localMatrix)
- : fLocalMatrix(localMatrix) {
+ EllipseGeometryProcessor(bool stroke, const SkMatrix& localMatrix) : fLocalMatrix(localMatrix) {
this->initClassID<EllipseGeometryProcessor>();
fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType);
fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
@@ -282,7 +288,7 @@ private:
public:
GLSLProcessor() {}
- void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{
+ void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const EllipseGeometryProcessor& egp = args.fGP.cast<EllipseGeometryProcessor>();
GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
@@ -298,8 +304,7 @@ private:
GrGLSLVertToFrag ellipseRadii(kVec4f_GrSLType);
varyingHandler->addVarying("EllipseRadii", &ellipseRadii);
- vertBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(),
- egp.fInEllipseRadii->fName);
+ vertBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), egp.fInEllipseRadii->fName);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
// setup pass through color
@@ -331,11 +336,10 @@ private:
// for inner curve
if (egp.fStroke) {
- fragBuilder->codeAppendf("scaledOffset = %s*%s.zw;",
- ellipseOffsets.fsIn(), ellipseRadii.fsIn());
- fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
- fragBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;",
+ fragBuilder->codeAppendf("scaledOffset = %s*%s.zw;", ellipseOffsets.fsIn(),
ellipseRadii.fsIn());
+ fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
+ fragBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;", ellipseRadii.fsIn());
fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
}
@@ -378,7 +382,7 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseGeometryProcessor);
sk_sp<GrGeometryProcessor> EllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) {
return sk_sp<GrGeometryProcessor>(
- new EllipseGeometryProcessor(d->fRandom->nextBool(), GrTest::TestMatrix(d->fRandom)));
+ new EllipseGeometryProcessor(d->fRandom->nextBool(), GrTest::TestMatrix(d->fRandom)));
}
///////////////////////////////////////////////////////////////////////////////
@@ -397,7 +401,7 @@ enum class DIEllipseStyle { kStroke = 0, kHairline, kFill };
class DIEllipseGeometryProcessor : public GrGeometryProcessor {
public:
DIEllipseGeometryProcessor(const SkMatrix& viewMatrix, DIEllipseStyle style)
- : fViewMatrix(viewMatrix) {
+ : fViewMatrix(viewMatrix) {
this->initClassID<DIEllipseGeometryProcessor>();
fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
kHigh_GrSLPrecision);
@@ -407,7 +411,6 @@ public:
fStyle = style;
}
-
virtual ~DIEllipseGeometryProcessor() {}
const char* name() const override { return "DIEllipseEdge"; }
@@ -423,8 +426,7 @@ public:
private:
class GLSLProcessor : public GrGLSLGeometryProcessor {
public:
- GLSLProcessor()
- : fViewMatrix(SkMatrix::InvalidMatrix()) {}
+ GLSLProcessor() : fViewMatrix(SkMatrix::InvalidMatrix()) {}
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
const DIEllipseGeometryProcessor& diegp = args.fGP.cast<DIEllipseGeometryProcessor>();
@@ -437,13 +439,11 @@ private:
GrGLSLVertToFrag offsets0(kVec2f_GrSLType);
varyingHandler->addVarying("EllipseOffsets0", &offsets0);
- vertBuilder->codeAppendf("%s = %s;", offsets0.vsOut(),
- diegp.fInEllipseOffsets0->fName);
+ vertBuilder->codeAppendf("%s = %s;", offsets0.vsOut(), diegp.fInEllipseOffsets0->fName);
GrGLSLVertToFrag offsets1(kVec2f_GrSLType);
varyingHandler->addVarying("EllipseOffsets1", &offsets1);
- vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(),
- diegp.fInEllipseOffsets1->fName);
+ vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), diegp.fInEllipseOffsets1->fName);
GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
varyingHandler->addPassThroughAttribute(diegp.fInColor, args.fOutputColor);
@@ -469,10 +469,10 @@ private:
fragBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;");
fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn());
fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn());
- fragBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
- " 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
- offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(),
- offsets0.fsIn());
+ fragBuilder->codeAppendf(
+ "vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
+ " 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
+ offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn());
fragBuilder->codeAppend("float grad_dot = dot(grad, grad);");
// avoid calling inversesqrt on zero.
@@ -492,10 +492,10 @@ private:
fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
fragBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn());
fragBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn());
- fragBuilder->codeAppendf("grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
- " 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
- offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(),
- offsets1.fsIn());
+ fragBuilder->codeAppendf(
+ "grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,"
+ " 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);",
+ offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn());
fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
}
@@ -536,8 +536,8 @@ private:
const Attribute* fInColor;
const Attribute* fInEllipseOffsets0;
const Attribute* fInEllipseOffsets1;
- SkMatrix fViewMatrix;
- DIEllipseStyle fStyle;
+ SkMatrix fViewMatrix;
+ DIEllipseStyle fStyle;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
@@ -547,9 +547,8 @@ private:
GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseGeometryProcessor);
sk_sp<GrGeometryProcessor> DIEllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) {
- return sk_sp<GrGeometryProcessor>(
- new DIEllipseGeometryProcessor(GrTest::TestMatrix(d->fRandom),
- (DIEllipseStyle)(d->fRandom->nextRangeU(0,2))));
+ return sk_sp<GrGeometryProcessor>(new DIEllipseGeometryProcessor(
+ GrTest::TestMatrix(d->fRandom), (DIEllipseStyle)(d->fRandom->nextRangeU(0, 2))));
}
///////////////////////////////////////////////////////////////////////////////
@@ -558,26 +557,31 @@ sk_sp<GrGeometryProcessor> DIEllipseGeometryProcessor::TestCreate(GrProcessorTes
// In the case of a normal fill, we draw geometry for the circle as an octagon.
static const uint16_t gFillCircleIndices[] = {
- // enter the octagon
- 0, 1, 8, 1, 2, 8,
- 2, 3, 8, 3, 4, 8,
- 4, 5, 8, 5, 6, 8,
- 6, 7, 8, 7, 0, 8,
+ // enter the octagon
+ // clang-format off
+ 0, 1, 8, 1, 2, 8,
+ 2, 3, 8, 3, 4, 8,
+ 4, 5, 8, 5, 6, 8,
+ 6, 7, 8, 7, 0, 8
+ // clang-format on
};
// For stroked circles, we use two nested octagons.
static const uint16_t gStrokeCircleIndices[] = {
- // enter the octagon
- 0, 1, 9, 0, 9, 8,
- 1, 2, 10, 1, 10, 9,
- 2, 3, 11, 2, 11, 10,
- 3, 4, 12, 3, 12, 11,
- 4, 5, 13, 4, 13, 12,
- 5, 6, 14, 5, 14, 13,
- 6, 7, 15, 6, 15, 14,
- 7, 0, 8, 7, 8, 15,
+ // enter the octagon
+ // clang-format off
+ 0, 1, 9, 0, 9, 8,
+ 1, 2, 10, 1, 10, 9,
+ 2, 3, 11, 2, 11, 10,
+ 3, 4, 12, 3, 12, 11,
+ 4, 5, 13, 4, 13, 12,
+ 5, 6, 14, 5, 14, 13,
+ 6, 7, 15, 6, 15, 14,
+ 7, 0, 8, 7, 8, 15,
+ // clang-format on
};
+
static const int kIndicesPerFillCircle = SK_ARRAY_COUNT(gFillCircleIndices);
static const int kIndicesPerStrokeCircle = SK_ARRAY_COUNT(gStrokeCircleIndices);
static const int kVertsPerStrokeCircle = 16;
@@ -597,7 +601,7 @@ static const uint16_t* circle_type_to_indices(bool stroked) {
///////////////////////////////////////////////////////////////////////////////
-class CircleBatch final : public GrMeshDrawOp {
+class CircleOp final : public GrMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
@@ -607,9 +611,9 @@ public:
SkScalar fSweepAngleRadians;
bool fUseCenter;
};
- static GrDrawOp* Create(GrColor color, const SkMatrix& viewMatrix, SkPoint center,
- SkScalar radius, const GrStyle& style,
- const ArcParams* arcParams = nullptr) {
+ static sk_sp<GrDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, SkPoint center,
+ SkScalar radius, const GrStyle& style,
+ const ArcParams* arcParams = nullptr) {
SkASSERT(circle_stays_circle(viewMatrix));
const SkStrokeRec& stroke = style.strokeRec();
if (style.hasPathEffect()) {
@@ -620,12 +624,12 @@ public:
// Arc support depends on the style.
switch (recStyle) {
case SkStrokeRec::kStrokeAndFill_Style:
- // This produces a strange result that this batch doesn't implement.
+ // This produces a strange result that this op doesn't implement.
return nullptr;
case SkStrokeRec::kFill_Style:
// This supports all fills.
break;
- case SkStrokeRec::kStroke_Style: // fall through
+ case SkStrokeRec::kStroke_Style: // fall through
case SkStrokeRec::kHairline_Style:
// Strokes that don't use the center point are supported with butt cap.
if (arcParams->fUseCenter || stroke.getCap() != SkPaint::kButt_Cap) {
@@ -639,8 +643,8 @@ public:
radius = viewMatrix.mapRadius(radius);
SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth());
- bool isStrokeOnly = SkStrokeRec::kStroke_Style == recStyle ||
- SkStrokeRec::kHairline_Style == recStyle;
+ bool isStrokeOnly =
+ SkStrokeRec::kStroke_Style == recStyle || SkStrokeRec::kHairline_Style == recStyle;
bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == recStyle;
SkScalar innerRadius = -SK_ScalarHalf;
@@ -666,8 +670,8 @@ public:
outerRadius += SK_ScalarHalf;
innerRadius -= SK_ScalarHalf;
bool stroked = isStrokeOnly && innerRadius > 0.0f;
- CircleBatch* batch = new CircleBatch();
- batch->fViewMatrixIfUsingLocalCoords = viewMatrix;
+ sk_sp<CircleOp> op(new CircleOp());
+ op->fViewMatrixIfUsingLocalCoords = viewMatrix;
// This makes every point fully inside the intersection plane.
static constexpr SkScalar kUnusedIsectPlane[] = {0.f, 0.f, 1.f};
@@ -687,9 +691,9 @@ public:
// case. In that case the two radial lines are equal and so that edge gets clipped
// twice. Since the shared edge goes through the center we fall back on the useCenter
// case.
- bool useCenter = (arcParams->fUseCenter || isStrokeOnly) &&
- !SkScalarNearlyEqual(SkScalarAbs(arcParams->fSweepAngleRadians),
- SK_ScalarPI);
+ bool useCenter =
+ (arcParams->fUseCenter || isStrokeOnly) &&
+ !SkScalarNearlyEqual(SkScalarAbs(arcParams->fSweepAngleRadians), SK_ScalarPI);
if (useCenter) {
SkVector norm0 = {startPoint.fY, -startPoint.fX};
SkVector norm1 = {stopPoint.fY, -stopPoint.fX};
@@ -698,9 +702,9 @@ public:
} else {
norm1.negate();
}
- batch->fClipPlane = true;
+ op->fClipPlane = true;
if (SkScalarAbs(arcParams->fSweepAngleRadians) > SK_ScalarPI) {
- batch->fGeoData.emplace_back(Geometry {
+ op->fGeoData.emplace_back(Geometry{
color,
innerRadius,
outerRadius,
@@ -708,12 +712,11 @@ public:
{kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
{norm1.fX, norm1.fY, 0.5f},
devBounds,
- stroked
- });
- batch->fClipPlaneIsect = false;
- batch->fClipPlaneUnion = true;
+ stroked});
+ op->fClipPlaneIsect = false;
+ op->fClipPlaneUnion = true;
} else {
- batch->fGeoData.emplace_back(Geometry {
+ op->fGeoData.emplace_back(Geometry{
color,
innerRadius,
outerRadius,
@@ -721,10 +724,9 @@ public:
{norm1.fX, norm1.fY, 0.5f},
{kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2]},
devBounds,
- stroked
- });
- batch->fClipPlaneIsect = true;
- batch->fClipPlaneUnion = false;
+ stroked});
+ op->fClipPlaneIsect = true;
+ op->fClipPlaneUnion = false;
}
} else {
// We clip to a secant of the original circle.
@@ -737,59 +739,56 @@ public:
}
SkScalar d = -norm.dot(startPoint) + 0.5f;
- batch->fGeoData.emplace_back(Geometry {
- color,
- innerRadius,
- outerRadius,
- {norm.fX, norm.fY, d},
- {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
- {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2]},
- devBounds,
- stroked
- });
- batch->fClipPlane = true;
- batch->fClipPlaneIsect = false;
- batch->fClipPlaneUnion = false;
+ op->fGeoData.emplace_back(
+ Geometry{color,
+ innerRadius,
+ outerRadius,
+ {norm.fX, norm.fY, d},
+ {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
+ {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2]},
+ devBounds,
+ stroked});
+ op->fClipPlane = true;
+ op->fClipPlaneIsect = false;
+ op->fClipPlaneUnion = false;
}
} else {
- batch->fGeoData.emplace_back(Geometry {
- color,
- innerRadius,
- outerRadius,
- {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
- {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
- {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2]},
- devBounds,
- stroked
- });
- batch->fClipPlane = false;
- batch->fClipPlaneIsect = false;
- batch->fClipPlaneUnion = false;
+ op->fGeoData.emplace_back(
+ Geometry{color,
+ innerRadius,
+ outerRadius,
+ {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
+ {kUnusedIsectPlane[0], kUnusedIsectPlane[1], kUnusedIsectPlane[2]},
+ {kUnusedUnionPlane[0], kUnusedUnionPlane[1], kUnusedUnionPlane[2]},
+ devBounds,
+ stroked});
+ op->fClipPlane = false;
+ op->fClipPlaneIsect = false;
+ op->fClipPlaneUnion = false;
}
// Use the original radius and stroke radius for the bounds so that it does not include the
// AA bloat.
radius += halfWidth;
- batch->setBounds({center.fX - radius, center.fY - radius,
- center.fX + radius, center.fY + radius},
- HasAABloat::kYes, IsZeroArea::kNo);
- batch->fVertCount = circle_type_to_vert_count(stroked);
- batch->fIndexCount = circle_type_to_index_count(stroked);
- batch->fAllFill = !stroked;
- return batch;
+ op->setBounds(
+ {center.fX - radius, center.fY - radius, center.fX + radius, center.fY + radius},
+ HasAABloat::kYes, IsZeroArea::kNo);
+ op->fVertCount = circle_type_to_vert_count(stroked);
+ op->fIndexCount = circle_type_to_index_count(stroked);
+ op->fAllFill = !stroked;
+ return std::move(op);
}
- const char* name() const override { return "CircleBatch"; }
+ const char* name() const override { return "CircleOp"; }
SkString dumpInfo() const override {
SkString string;
for (int i = 0; i < fGeoData.count(); ++i) {
- string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f],"
- "InnerRad: %.2f, OuterRad: %.2f\n",
- fGeoData[i].fColor,
- fGeoData[i].fDevBounds.fLeft, fGeoData[i].fDevBounds.fTop,
- fGeoData[i].fDevBounds.fRight, fGeoData[i].fDevBounds.fBottom,
- fGeoData[i].fInnerRadius,
- fGeoData[i].fOuterRadius);
+ string.appendf(
+ "Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f],"
+ "InnerRad: %.2f, OuterRad: %.2f\n",
+ fGeoData[i].fColor, fGeoData[i].fDevBounds.fLeft, fGeoData[i].fDevBounds.fTop,
+ fGeoData[i].fDevBounds.fRight, fGeoData[i].fDevBounds.fBottom,
+ fGeoData[i].fInnerRadius, fGeoData[i].fOuterRadius);
}
string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
@@ -799,13 +798,13 @@ public:
void computePipelineOptimizations(GrInitInvariantOutput* color,
GrInitInvariantOutput* coverage,
GrBatchToXPOverrides* overrides) const override {
- // When this is called on a batch, there is only one geometry bundle
+ // When this is called there is only one circle.
color->setKnownFourComponents(fGeoData[0].fColor);
coverage->setUnknownSingleComponent();
}
private:
- CircleBatch() : INHERITED(ClassID()) {}
+ CircleOp() : INHERITED(ClassID()) {}
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
// Handle any overrides that affect our GP.
overrides.getOverrideColorIfSet(&fGeoData[0].fColor);
@@ -821,15 +820,13 @@ private:
}
// Setup geometry processor
- sk_sp<GrGeometryProcessor> gp(new CircleGeometryProcessor(!fAllFill, fClipPlane,
- fClipPlaneIsect,
- fClipPlaneUnion,
- localMatrix));
+ sk_sp<GrGeometryProcessor> gp(new CircleGeometryProcessor(
+ !fAllFill, fClipPlane, fClipPlaneIsect, fClipPlaneUnion, localMatrix));
struct CircleVertex {
- SkPoint fPos;
- GrColor fColor;
- SkPoint fOffset;
+ SkPoint fPos;
+ GrColor fColor;
+ SkPoint fOffset;
SkScalar fOuterRadius;
SkScalar fInnerRadius;
// These planes may or may not be present in the vertex buffer.
@@ -838,14 +835,15 @@ private:
int instanceCount = fGeoData.count();
size_t vertexStride = gp->getVertexStride();
- SkASSERT(vertexStride == sizeof(CircleVertex) - (fClipPlane ? 0 : 3 * sizeof(SkScalar))
- - (fClipPlaneIsect? 0 : 3 * sizeof(SkScalar))
- - (fClipPlaneUnion? 0 : 3 * sizeof(SkScalar)));
+ SkASSERT(vertexStride ==
+ sizeof(CircleVertex) - (fClipPlane ? 0 : 3 * sizeof(SkScalar)) -
+ (fClipPlaneIsect ? 0 : 3 * sizeof(SkScalar)) -
+ (fClipPlaneUnion ? 0 : 3 * sizeof(SkScalar)));
const GrBuffer* vertexBuffer;
int firstVertex;
- char* vertices = (char*)target->makeVertexSpace(vertexStride, fVertCount,
- &vertexBuffer, &firstVertex);
+ char* vertices = (char*)target->makeVertexSpace(vertexStride, fVertCount, &vertexBuffer,
+ &firstVertex);
if (!vertices) {
SkDebugf("Could not allocate vertices\n");
return;
@@ -868,65 +866,65 @@ private:
SkScalar outerRadius = geom.fOuterRadius;
const SkRect& bounds = geom.fDevBounds;
- CircleVertex* v0 = reinterpret_cast<CircleVertex*>(vertices + 0*vertexStride);
- CircleVertex* v1 = reinterpret_cast<CircleVertex*>(vertices + 1*vertexStride);
- CircleVertex* v2 = reinterpret_cast<CircleVertex*>(vertices + 2*vertexStride);
- CircleVertex* v3 = reinterpret_cast<CircleVertex*>(vertices + 3*vertexStride);
- CircleVertex* v4 = reinterpret_cast<CircleVertex*>(vertices + 4*vertexStride);
- CircleVertex* v5 = reinterpret_cast<CircleVertex*>(vertices + 5*vertexStride);
- CircleVertex* v6 = reinterpret_cast<CircleVertex*>(vertices + 6*vertexStride);
- CircleVertex* v7 = reinterpret_cast<CircleVertex*>(vertices + 7*vertexStride);
+ CircleVertex* v0 = reinterpret_cast<CircleVertex*>(vertices + 0 * vertexStride);
+ CircleVertex* v1 = reinterpret_cast<CircleVertex*>(vertices + 1 * vertexStride);
+ CircleVertex* v2 = reinterpret_cast<CircleVertex*>(vertices + 2 * vertexStride);
+ CircleVertex* v3 = reinterpret_cast<CircleVertex*>(vertices + 3 * vertexStride);
+ CircleVertex* v4 = reinterpret_cast<CircleVertex*>(vertices + 4 * vertexStride);
+ CircleVertex* v5 = reinterpret_cast<CircleVertex*>(vertices + 5 * vertexStride);
+ CircleVertex* v6 = reinterpret_cast<CircleVertex*>(vertices + 6 * vertexStride);
+ CircleVertex* v7 = reinterpret_cast<CircleVertex*>(vertices + 7 * vertexStride);
// The inner radius in the vertex data must be specified in normalized space.
innerRadius = innerRadius / outerRadius;
SkPoint center = SkPoint::Make(bounds.centerX(), bounds.centerY());
- SkScalar halfWidth = 0.5f*bounds.width();
+ SkScalar halfWidth = 0.5f * bounds.width();
SkScalar octOffset = 0.41421356237f; // sqrt(2) - 1
- v0->fPos = center + SkPoint::Make(-octOffset*halfWidth, -halfWidth);
+ v0->fPos = center + SkPoint::Make(-octOffset * halfWidth, -halfWidth);
v0->fColor = color;
v0->fOffset = SkPoint::Make(-octOffset, -1);
v0->fOuterRadius = outerRadius;
v0->fInnerRadius = innerRadius;
- v1->fPos = center + SkPoint::Make(octOffset*halfWidth, -halfWidth);
+ v1->fPos = center + SkPoint::Make(octOffset * halfWidth, -halfWidth);
v1->fColor = color;
v1->fOffset = SkPoint::Make(octOffset, -1);
v1->fOuterRadius = outerRadius;
v1->fInnerRadius = innerRadius;
- v2->fPos = center + SkPoint::Make(halfWidth, -octOffset*halfWidth);
+ v2->fPos = center + SkPoint::Make(halfWidth, -octOffset * halfWidth);
v2->fColor = color;
v2->fOffset = SkPoint::Make(1, -octOffset);
v2->fOuterRadius = outerRadius;
v2->fInnerRadius = innerRadius;
- v3->fPos = center + SkPoint::Make(halfWidth, octOffset*halfWidth);
+ v3->fPos = center + SkPoint::Make(halfWidth, octOffset * halfWidth);
v3->fColor = color;
v3->fOffset = SkPoint::Make(1, octOffset);
v3->fOuterRadius = outerRadius;
v3->fInnerRadius = innerRadius;
- v4->fPos = center + SkPoint::Make(octOffset*halfWidth, halfWidth);
+ v4->fPos = center + SkPoint::Make(octOffset * halfWidth, halfWidth);
v4->fColor = color;
v4->fOffset = SkPoint::Make(octOffset, 1);
v4->fOuterRadius = outerRadius;
v4->fInnerRadius = innerRadius;
- v5->fPos = center + SkPoint::Make(-octOffset*halfWidth, halfWidth);
+ v5->fPos = center + SkPoint::Make(-octOffset * halfWidth, halfWidth);
v5->fColor = color;
v5->fOffset = SkPoint::Make(-octOffset, 1);
v5->fOuterRadius = outerRadius;
v5->fInnerRadius = innerRadius;
- v6->fPos = center + SkPoint::Make(-halfWidth, octOffset*halfWidth);
+ v6->fPos = center + SkPoint::Make(-halfWidth, octOffset * halfWidth);
v6->fColor = color;
v6->fOffset = SkPoint::Make(-1, octOffset);
v6->fOuterRadius = outerRadius;
v6->fInnerRadius = innerRadius;
- v7->fPos = center + SkPoint::Make(-halfWidth, -octOffset*halfWidth);
+ v7->fPos = center + SkPoint::Make(-halfWidth, -octOffset * halfWidth);
v7->fColor = color;
v7->fOffset = SkPoint::Make(-1, -octOffset);
v7->fOuterRadius = outerRadius;
@@ -981,51 +979,51 @@ private:
SkScalar s = 0.382683432f;
SkScalar r = geom.fInnerRadius;
- v0->fPos = center + SkPoint::Make(-s*r, -c*r);
+ v0->fPos = center + SkPoint::Make(-s * r, -c * r);
v0->fColor = color;
- v0->fOffset = SkPoint::Make(-s*innerRadius, -c*innerRadius);
+ v0->fOffset = SkPoint::Make(-s * innerRadius, -c * innerRadius);
v0->fOuterRadius = outerRadius;
v0->fInnerRadius = innerRadius;
- v1->fPos = center + SkPoint::Make(s*r, -c*r);
+ v1->fPos = center + SkPoint::Make(s * r, -c * r);
v1->fColor = color;
- v1->fOffset = SkPoint::Make(s*innerRadius, -c*innerRadius);
+ v1->fOffset = SkPoint::Make(s * innerRadius, -c * innerRadius);
v1->fOuterRadius = outerRadius;
v1->fInnerRadius = innerRadius;
- v2->fPos = center + SkPoint::Make(c*r, -s*r);
+ v2->fPos = center + SkPoint::Make(c * r, -s * r);
v2->fColor = color;
- v2->fOffset = SkPoint::Make(c*innerRadius, -s*innerRadius);
+ v2->fOffset = SkPoint::Make(c * innerRadius, -s * innerRadius);
v2->fOuterRadius = outerRadius;
v2->fInnerRadius = innerRadius;
- v3->fPos = center + SkPoint::Make(c*r, s*r);
+ v3->fPos = center + SkPoint::Make(c * r, s * r);
v3->fColor = color;
- v3->fOffset = SkPoint::Make(c*innerRadius, s*innerRadius);
+ v3->fOffset = SkPoint::Make(c * innerRadius, s * innerRadius);
v3->fOuterRadius = outerRadius;
v3->fInnerRadius = innerRadius;
- v4->fPos = center + SkPoint::Make(s*r, c*r);
+ v4->fPos = center + SkPoint::Make(s * r, c * r);
v4->fColor = color;
- v4->fOffset = SkPoint::Make(s*innerRadius, c*innerRadius);
+ v4->fOffset = SkPoint::Make(s * innerRadius, c * innerRadius);
v4->fOuterRadius = outerRadius;
v4->fInnerRadius = innerRadius;
- v5->fPos = center + SkPoint::Make(-s*r, c*r);
+ v5->fPos = center + SkPoint::Make(-s * r, c * r);
v5->fColor = color;
- v5->fOffset = SkPoint::Make(-s*innerRadius, c*innerRadius);
+ v5->fOffset = SkPoint::Make(-s * innerRadius, c * innerRadius);
v5->fOuterRadius = outerRadius;
v5->fInnerRadius = innerRadius;
- v6->fPos = center + SkPoint::Make(-c*r, s*r);
+ v6->fPos = center + SkPoint::Make(-c * r, s * r);
v6->fColor = color;
- v6->fOffset = SkPoint::Make(-c*innerRadius, s*innerRadius);
+ v6->fOffset = SkPoint::Make(-c * innerRadius, s * innerRadius);
v6->fOuterRadius = outerRadius;
v6->fInnerRadius = innerRadius;
- v7->fPos = center + SkPoint::Make(-c*r, -s*r);
+ v7->fPos = center + SkPoint::Make(-c * r, -s * r);
v7->fColor = color;
- v7->fOffset = SkPoint::Make(-c*innerRadius, -s*innerRadius);
+ v7->fOffset = SkPoint::Make(-c * innerRadius, -s * innerRadius);
v7->fOuterRadius = outerRadius;
v7->fInnerRadius = innerRadius;
@@ -1089,7 +1087,7 @@ private:
}
currStartVertex += circle_type_to_vert_count(geom.fStroked);
- vertices += circle_type_to_vert_count(geom.fStroked)*vertexStride;
+ vertices += circle_type_to_vert_count(geom.fStroked) * vertexStride;
}
GrMesh mesh;
@@ -1099,7 +1097,7 @@ private:
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
- CircleBatch* that = t->cast<CircleBatch>();
+ CircleOp* that = t->cast<CircleOp>();
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
that->bounds(), caps)) {
return false;
@@ -1109,8 +1107,8 @@ private:
return false;
}
- // Because we've set up the batches that don't use the planes with noop values
- // we can just accumulate used planes by later batches.
+ // Because we've set up the ops that don't use the planes with noop values
+ // we can just accumulate used planes by later ops.
fClipPlane |= that->fClipPlane;
fClipPlaneIsect |= that->fClipPlaneIsect;
fClipPlaneUnion |= that->fClipPlaneUnion;
@@ -1124,35 +1122,35 @@ private:
}
struct Geometry {
- GrColor fColor;
+ GrColor fColor;
SkScalar fInnerRadius;
SkScalar fOuterRadius;
SkScalar fClipPlane[3];
SkScalar fIsectPlane[3];
SkScalar fUnionPlane[3];
- SkRect fDevBounds;
- bool fStroked;
+ SkRect fDevBounds;
+ bool fStroked;
};
SkSTArray<1, Geometry, true> fGeoData;
- SkMatrix fViewMatrixIfUsingLocalCoords;
- int fVertCount;
- int fIndexCount;
- bool fAllFill;
- bool fClipPlane;
- bool fClipPlaneIsect;
- bool fClipPlaneUnion;
+ SkMatrix fViewMatrixIfUsingLocalCoords;
+ int fVertCount;
+ int fIndexCount;
+ bool fAllFill;
+ bool fClipPlane;
+ bool fClipPlaneIsect;
+ bool fClipPlaneUnion;
typedef GrMeshDrawOp INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
-class EllipseBatch : public GrMeshDrawOp {
+class EllipseOp : public GrMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
- static GrDrawOp* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& ellipse,
- const SkStrokeRec& stroke) {
+ static sk_sp<GrDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, const SkRect& ellipse,
+ const SkStrokeRec& stroke) {
SkASSERT(viewMatrix.rectStaysRect());
// do any matrix crunching before we reset the draw state for device coords
@@ -1160,22 +1158,22 @@ public:
viewMatrix.mapPoints(&center, 1);
SkScalar ellipseXRadius = SkScalarHalf(ellipse.width());
SkScalar ellipseYRadius = SkScalarHalf(ellipse.height());
- SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*ellipseXRadius +
- viewMatrix[SkMatrix::kMSkewY]*ellipseYRadius);
- SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*ellipseXRadius +
- viewMatrix[SkMatrix::kMScaleY]*ellipseYRadius);
+ SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX] * ellipseXRadius +
+ viewMatrix[SkMatrix::kMSkewY] * ellipseYRadius);
+ SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX] * ellipseXRadius +
+ viewMatrix[SkMatrix::kMScaleY] * ellipseYRadius);
// do (potentially) anisotropic mapping of stroke
SkVector scaledStroke;
SkScalar strokeWidth = stroke.getWidth();
- scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMScaleX] +
- viewMatrix[SkMatrix::kMSkewY]));
- scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSkewX] +
- viewMatrix[SkMatrix::kMScaleY]));
+ scaledStroke.fX = SkScalarAbs(
+ strokeWidth * (viewMatrix[SkMatrix::kMScaleX] + viewMatrix[SkMatrix::kMSkewY]));
+ scaledStroke.fY = SkScalarAbs(
+ strokeWidth * (viewMatrix[SkMatrix::kMSkewX] + viewMatrix[SkMatrix::kMScaleY]));
SkStrokeRec::Style style = stroke.getStyle();
- bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
- SkStrokeRec::kHairline_Style == style;
+ bool isStrokeOnly =
+ SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style;
bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
SkScalar innerXRadius = 0;
@@ -1189,13 +1187,15 @@ public:
// we only handle thick strokes for near-circular ellipses
if (scaledStroke.length() > SK_ScalarHalf &&
- (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) {
+ (SK_ScalarHalf * xRadius > yRadius || SK_ScalarHalf * yRadius > xRadius)) {
return nullptr;
}
// we don't handle it if curvature of the stroke is less than curvature of the ellipse
- if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY)*xRadius ||
- scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX)*yRadius) {
+ if (scaledStroke.fX * (yRadius * yRadius) <
+ (scaledStroke.fY * scaledStroke.fY) * xRadius ||
+ scaledStroke.fY * (xRadius * xRadius) <
+ (scaledStroke.fX * scaledStroke.fX) * yRadius) {
return nullptr;
}
@@ -1209,42 +1209,34 @@ public:
yRadius += scaledStroke.fY;
}
- EllipseBatch* batch = new EllipseBatch();
- batch->fGeoData.emplace_back(Geometry {
- color,
- xRadius,
- yRadius,
- innerXRadius,
- innerYRadius,
- SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRadius,
- center.fX + xRadius, center.fY + yRadius)
- });
+ sk_sp<EllipseOp> op(new EllipseOp());
+ op->fGeoData.emplace_back(
+ Geometry{color, xRadius, yRadius, innerXRadius, innerYRadius,
+ SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRadius,
+ center.fX + xRadius, center.fY + yRadius)});
- batch->setBounds(batch->fGeoData.back().fDevBounds, HasAABloat::kYes, IsZeroArea::kNo);
+ op->setBounds(op->fGeoData.back().fDevBounds, HasAABloat::kYes, IsZeroArea::kNo);
// Outset bounds to include half-pixel width antialiasing.
- batch->fGeoData[0].fDevBounds.outset(SK_ScalarHalf, SK_ScalarHalf);
+ op->fGeoData[0].fDevBounds.outset(SK_ScalarHalf, SK_ScalarHalf);
- batch->fStroked = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0;
- batch->fViewMatrixIfUsingLocalCoords = viewMatrix;
- return batch;
+ op->fStroked = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0;
+ op->fViewMatrixIfUsingLocalCoords = viewMatrix;
+ return std::move(op);
}
- const char* name() const override { return "EllipseBatch"; }
+ const char* name() const override { return "EllipseOp"; }
SkString dumpInfo() const override {
SkString string;
string.appendf("Stroked: %d\n", fStroked);
for (const auto& geo : fGeoData) {
- string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], "
- "XRad: %.2f, YRad: %.2f, InnerXRad: %.2f, InnerYRad: %.2f\n",
- geo.fColor,
- geo.fDevBounds.fLeft, geo.fDevBounds.fTop,
- geo.fDevBounds.fRight, geo.fDevBounds.fBottom,
- geo.fXRadius,
- geo.fYRadius,
- geo.fInnerXRadius,
- geo.fInnerYRadius);
+ string.appendf(
+ "Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], "
+ "XRad: %.2f, YRad: %.2f, InnerXRad: %.2f, InnerYRad: %.2f\n",
+ geo.fColor, geo.fDevBounds.fLeft, geo.fDevBounds.fTop, geo.fDevBounds.fRight,
+ geo.fDevBounds.fBottom, geo.fXRadius, geo.fYRadius, geo.fInnerXRadius,
+ geo.fInnerYRadius);
}
string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
@@ -1254,13 +1246,13 @@ public:
void computePipelineOptimizations(GrInitInvariantOutput* color,
GrInitInvariantOutput* coverage,
GrBatchToXPOverrides* overrides) const override {
- // When this is called on a batch, there is only one geometry bundle
+ // When this is called, there is only one ellipse.
color->setKnownFourComponents(fGeoData[0].fColor);
coverage->setUnknownSingleComponent();
}
private:
- EllipseBatch() : INHERITED(ClassID()) {}
+ EllipseOp() : INHERITED(ClassID()) {}
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
// Handle any overrides that affect our GP.
@@ -1285,8 +1277,8 @@ private:
QuadHelper helper;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(EllipseVertex));
- EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
- helper.init(target, vertexStride, instanceCount));
+ EllipseVertex* verts =
+ reinterpret_cast<EllipseVertex*>(helper.init(target, vertexStride, instanceCount));
if (!verts) {
return;
}
@@ -1311,13 +1303,13 @@ private:
SkScalar yMaxOffset = yRadius + SK_ScalarHalf;
// The inner radius in the vertex data must be specified in normalized space.
- verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop);
+ verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop);
verts[0].fColor = color;
verts[0].fOffset = SkPoint::Make(-xMaxOffset, -yMaxOffset);
verts[0].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
verts[0].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
- verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
+ verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
verts[1].fColor = color;
verts[1].fOffset = SkPoint::Make(-xMaxOffset, yMaxOffset);
verts[1].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
@@ -1341,7 +1333,7 @@ private:
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
- EllipseBatch* that = t->cast<EllipseBatch>();
+ EllipseOp* that = t->cast<EllipseOp>();
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
that->bounds(), caps)) {
@@ -1370,8 +1362,8 @@ private:
SkRect fDevBounds;
};
- bool fStroked;
- SkMatrix fViewMatrixIfUsingLocalCoords;
+ bool fStroked;
+ SkMatrix fViewMatrixIfUsingLocalCoords;
SkSTArray<1, Geometry, true> fGeoData;
typedef GrMeshDrawOp INHERITED;
@@ -1379,23 +1371,24 @@ private:
/////////////////////////////////////////////////////////////////////////////////////////////////
-class DIEllipseBatch : public GrMeshDrawOp {
+class DIEllipseOp : public GrMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
- static GrDrawOp* Create(GrColor color,
- const SkMatrix& viewMatrix,
- const SkRect& ellipse,
- const SkStrokeRec& stroke) {
+ static sk_sp<GrDrawOp> Make(GrColor color,
+ const SkMatrix& viewMatrix,
+ const SkRect& ellipse,
+ const SkStrokeRec& stroke) {
SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
SkScalar xRadius = SkScalarHalf(ellipse.width());
SkScalar yRadius = SkScalarHalf(ellipse.height());
SkStrokeRec::Style style = stroke.getStyle();
- DIEllipseStyle dieStyle = (SkStrokeRec::kStroke_Style == style) ?
- DIEllipseStyle::kStroke :
- (SkStrokeRec::kHairline_Style == style) ?
- DIEllipseStyle::kHairline : DIEllipseStyle::kFill;
+ DIEllipseStyle dieStyle = (SkStrokeRec::kStroke_Style == style)
+ ? DIEllipseStyle::kStroke
+ : (SkStrokeRec::kHairline_Style == style)
+ ? DIEllipseStyle::kHairline
+ : DIEllipseStyle::kFill;
SkScalar innerXRadius = 0;
SkScalar innerYRadius = 0;
@@ -1410,13 +1403,13 @@ public:
// we only handle thick strokes for near-circular ellipses
if (strokeWidth > SK_ScalarHalf &&
- (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) {
+ (SK_ScalarHalf * xRadius > yRadius || SK_ScalarHalf * yRadius > xRadius)) {
return nullptr;
}
// we don't handle it if curvature of the stroke is less than curvature of the ellipse
- if (strokeWidth*(yRadius*yRadius) < (strokeWidth*strokeWidth)*xRadius ||
- strokeWidth*(xRadius*xRadius) < (strokeWidth*strokeWidth)*yRadius) {
+ if (strokeWidth * (yRadius * yRadius) < (strokeWidth * strokeWidth) * xRadius ||
+ strokeWidth * (xRadius * xRadius) < (strokeWidth * strokeWidth) * yRadius) {
return nullptr;
}
@@ -1430,8 +1423,8 @@ public:
yRadius += strokeWidth;
}
if (DIEllipseStyle::kStroke == dieStyle) {
- dieStyle = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseStyle ::kStroke :
- DIEllipseStyle ::kFill;
+ dieStyle = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseStyle::kStroke
+ : DIEllipseStyle::kFill;
}
// This expands the outer rect so that after CTM we end up with a half-pixel border
@@ -1439,45 +1432,32 @@ public:
SkScalar b = viewMatrix[SkMatrix::kMSkewX];
SkScalar c = viewMatrix[SkMatrix::kMSkewY];
SkScalar d = viewMatrix[SkMatrix::kMScaleY];
- SkScalar geoDx = SK_ScalarHalf / SkScalarSqrt(a*a + c*c);
- SkScalar geoDy = SK_ScalarHalf / SkScalarSqrt(b*b + d*d);
-
- DIEllipseBatch* batch = new DIEllipseBatch();
- batch->fGeoData.emplace_back(Geometry {
- viewMatrix,
- color,
- xRadius,
- yRadius,
- innerXRadius,
- innerYRadius,
- geoDx,
- geoDy,
- dieStyle,
- SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY - yRadius - geoDy,
- center.fX + xRadius + geoDx, center.fY + yRadius + geoDy)
- });
- batch->setTransformedBounds(batch->fGeoData[0].fBounds, viewMatrix, HasAABloat::kYes,
- IsZeroArea::kNo);
- return batch;
+ SkScalar geoDx = SK_ScalarHalf / SkScalarSqrt(a * a + c * c);
+ SkScalar geoDy = SK_ScalarHalf / SkScalarSqrt(b * b + d * d);
+
+ sk_sp<DIEllipseOp> op(new DIEllipseOp());
+ op->fGeoData.emplace_back(Geometry{
+ viewMatrix, color, xRadius, yRadius, innerXRadius, innerYRadius, geoDx, geoDy,
+ dieStyle,
+ SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY - yRadius - geoDy,
+ center.fX + xRadius + geoDx, center.fY + yRadius + geoDy)});
+ op->setTransformedBounds(op->fGeoData[0].fBounds, viewMatrix, HasAABloat::kYes,
+ IsZeroArea::kNo);
+ return std::move(op);
}
- const char* name() const override { return "DIEllipseBatch"; }
+ const char* name() const override { return "DIEllipseOp"; }
SkString dumpInfo() const override {
SkString string;
for (const auto& geo : fGeoData) {
- string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], XRad: %.2f, "
- "YRad: %.2f, InnerXRad: %.2f, InnerYRad: %.2f, GeoDX: %.2f, "
- "GeoDY: %.2f\n",
- geo.fColor,
- geo.fBounds.fLeft, geo.fBounds.fTop,
- geo.fBounds.fRight, geo.fBounds.fBottom,
- geo.fXRadius,
- geo.fYRadius,
- geo.fInnerXRadius,
- geo.fInnerYRadius,
- geo.fGeoDx,
- geo.fGeoDy);
+ string.appendf(
+ "Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], XRad: %.2f, "
+ "YRad: %.2f, InnerXRad: %.2f, InnerYRad: %.2f, GeoDX: %.2f, "
+ "GeoDY: %.2f\n",
+ geo.fColor, geo.fBounds.fLeft, geo.fBounds.fTop, geo.fBounds.fRight,
+ geo.fBounds.fBottom, geo.fXRadius, geo.fYRadius, geo.fInnerXRadius,
+ geo.fInnerYRadius, geo.fGeoDx, geo.fGeoDy);
}
string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
@@ -1487,14 +1467,13 @@ public:
void computePipelineOptimizations(GrInitInvariantOutput* color,
GrInitInvariantOutput* coverage,
GrBatchToXPOverrides* overrides) const override {
- // When this is called on a batch, there is only one geometry bundle
+ // When this is called there is only one ellipse.
color->setKnownFourComponents(fGeoData[0].fColor);
coverage->setUnknownSingleComponent();
}
private:
-
- DIEllipseBatch() : INHERITED(ClassID()) {}
+ DIEllipseOp() : INHERITED(ClassID()) {}
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
// Handle any overrides that affect our GP.
@@ -1504,15 +1483,15 @@ private:
void onPrepareDraws(Target* target) const override {
// Setup geometry processor
- sk_sp<GrGeometryProcessor> gp(new DIEllipseGeometryProcessor(this->viewMatrix(),
- this->style()));
+ sk_sp<GrGeometryProcessor> gp(
+ new DIEllipseGeometryProcessor(this->viewMatrix(), this->style()));
int instanceCount = fGeoData.count();
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(DIEllipseVertex));
QuadHelper helper;
DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(
- helper.init(target, vertexStride, instanceCount));
+ helper.init(target, vertexStride, instanceCount));
if (!verts) {
return;
}
@@ -1538,7 +1517,7 @@ private:
verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy);
verts[0].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, -innerRatioY - offsetDy);
- verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
+ verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
verts[1].fColor = color;
verts[1].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, 1.0f + offsetDy);
verts[1].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, innerRatioY + offsetDy);
@@ -1559,7 +1538,7 @@ private:
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
- DIEllipseBatch* that = t->cast<DIEllipseBatch>();
+ DIEllipseOp* that = t->cast<DIEllipseOp>();
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
that->bounds(), caps)) {
return false;
@@ -1595,7 +1574,7 @@ private:
SkRect fBounds;
};
- bool fUsesLocalCoords;
+ bool fUsesLocalCoords;
SkSTArray<1, Geometry, true> fGeoData;
typedef GrMeshDrawOp INHERITED;
@@ -1635,36 +1614,39 @@ private:
// vertical line).
static const uint16_t gOverstrokeRRectIndices[] = {
- // overstroke quads
- // we place this at the beginning so that we can skip these indices when rendering normally
- 16, 17, 19, 16, 19, 18,
- 19, 17, 23, 19, 23, 21,
- 21, 23, 22, 21, 22, 20,
- 22, 16, 18, 22, 18, 20,
-
- // corners
- 0, 1, 5, 0, 5, 4,
- 2, 3, 7, 2, 7, 6,
- 8, 9, 13, 8, 13, 12,
- 10, 11, 15, 10, 15, 14,
-
- // edges
- 1, 2, 6, 1, 6, 5,
- 4, 5, 9, 4, 9, 8,
- 6, 7, 11, 6, 11, 10,
- 9, 10, 14, 9, 14, 13,
-
- // center
- // we place this at the end so that we can ignore these indices when not rendering as filled
- 5, 6, 10, 5, 10, 9,
+ // clang-format off
+ // overstroke quads
+ // we place this at the beginning so that we can skip these indices when rendering normally
+ 16, 17, 19, 16, 19, 18,
+ 19, 17, 23, 19, 23, 21,
+ 21, 23, 22, 21, 22, 20,
+ 22, 16, 18, 22, 18, 20,
+
+ // corners
+ 0, 1, 5, 0, 5, 4,
+ 2, 3, 7, 2, 7, 6,
+ 8, 9, 13, 8, 13, 12,
+ 10, 11, 15, 10, 15, 14,
+
+ // edges
+ 1, 2, 6, 1, 6, 5,
+ 4, 5, 9, 4, 9, 8,
+ 6, 7, 11, 6, 11, 10,
+ 9, 10, 14, 9, 14, 13,
+
+ // center
+ // we place this at the end so that we can ignore these indices when not rendering as filled
+ 5, 6, 10, 5, 10, 9,
+ // clang-format on
};
+
// fill and standard stroke indices skip the overstroke "ring"
-static const uint16_t* gStandardRRectIndices = gOverstrokeRRectIndices + 6*4;
+static const uint16_t* gStandardRRectIndices = gOverstrokeRRectIndices + 6 * 4;
// overstroke count is arraysize minus the center indices
static const int kIndicesPerOverstrokeRRect = SK_ARRAY_COUNT(gOverstrokeRRectIndices) - 6;
// fill count skips overstroke indices and includes center
-static const int kIndicesPerFillRRect = kIndicesPerOverstrokeRRect - 6*4 + 6;
+static const int kIndicesPerFillRRect = kIndicesPerOverstrokeRRect - 6 * 4 + 6;
// stroke count is fill count minus center indices
static const int kIndicesPerStrokeRRect = kIndicesPerFillRRect - 6;
static const int kVertsPerStandardRRect = 16;
@@ -1678,36 +1660,43 @@ enum RRectType {
};
static int rrect_type_to_vert_count(RRectType type) {
- static const int kTypeToVertCount[] = {
- kVertsPerStandardRRect,
- kVertsPerStandardRRect,
- kVertsPerOverstrokeRRect,
- kVertsPerOverstrokeRRect,
- };
-
- return kTypeToVertCount[type];
+ switch (type) {
+ case kFill_RRectType:
+ case kStroke_RRectType:
+ return kVertsPerStandardRRect;
+ case kOverstroke_RRectType:
+ case kFillWithDist_RRectType:
+ return kVertsPerOverstrokeRRect;
+ }
+ SkFAIL("Invalid type");
+ return 0;
}
static int rrect_type_to_index_count(RRectType type) {
- static const int kTypeToIndexCount[] = {
- kIndicesPerFillRRect,
- kIndicesPerStrokeRRect,
- kIndicesPerOverstrokeRRect,
- kIndicesPerOverstrokeRRect,
- };
-
- return kTypeToIndexCount[type];
+ switch (type) {
+ case kFill_RRectType:
+ return kIndicesPerFillRRect;
+ case kStroke_RRectType:
+ return kIndicesPerStrokeRRect;
+ case kOverstroke_RRectType:
+ case kFillWithDist_RRectType:
+ return kIndicesPerOverstrokeRRect;
+ }
+ SkFAIL("Invalid type");
+ return 0;
}
static const uint16_t* rrect_type_to_indices(RRectType type) {
- static const uint16_t* kTypeToIndices[] = {
- gStandardRRectIndices,
- gStandardRRectIndices,
- gOverstrokeRRectIndices,
- gOverstrokeRRectIndices,
- };
-
- return kTypeToIndices[type];
+ switch (type) {
+ case kFill_RRectType:
+ case kStroke_RRectType:
+ return gStandardRRectIndices;
+ case kOverstroke_RRectType:
+ case kFillWithDist_RRectType:
+ return gOverstrokeRRectIndices;
+ }
+ SkFAIL("Invalid type");
+ return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1721,17 +1710,15 @@ static const uint16_t* rrect_type_to_indices(RRectType type) {
// each vertex is also given the normalized x & y distance from the interior rect's edge
// the GP takes the min of those depths +1 to get the normalized distance to the outer edge
-class RRectCircleRendererBatch : public GrMeshDrawOp {
+class CircularRRectOp : public GrMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
// A devStrokeWidth <= 0 indicates a fill only. If devStrokeWidth > 0 then strokeOnly indicates
// whether the rrect is only stroked or stroked and filled.
- RRectCircleRendererBatch(GrColor color, bool needsDistance, const SkMatrix& viewMatrix,
- const SkRect& devRect, float devRadius,
- float devStrokeWidth, bool strokeOnly)
- : INHERITED(ClassID())
- , fViewMatrixIfUsingLocalCoords(viewMatrix) {
+ CircularRRectOp(GrColor color, bool needsDistance, const SkMatrix& viewMatrix,
+ const SkRect& devRect, float devRadius, float devStrokeWidth, bool strokeOnly)
+ : INHERITED(ClassID()), fViewMatrixIfUsingLocalCoords(viewMatrix) {
SkRect bounds = devRect;
SkASSERT(!(devStrokeWidth <= 0 && strokeOnly));
SkScalar innerRadius = 0.0f;
@@ -1750,8 +1737,7 @@ public:
devStrokeWidth += 0.25f;
// If stroke is greater than width or height, this is still a fill
// Otherwise we compute stroke params
- if (devStrokeWidth <= devRect.width() &&
- devStrokeWidth <= devRect.height()) {
+ if (devStrokeWidth <= devRect.width() && devStrokeWidth <= devRect.height()) {
innerRadius = devRadius - halfWidth;
type = (innerRadius >= 0) ? kStroke_RRectType : kOverstroke_RRectType;
}
@@ -1776,24 +1762,23 @@ public:
// Expand the rect for aa to generate correct vertices.
bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
- fGeoData.emplace_back(Geometry{ color, innerRadius, outerRadius, bounds, type });
+ fGeoData.emplace_back(Geometry{color, innerRadius, outerRadius, bounds, type});
fVertCount = rrect_type_to_vert_count(type);
fIndexCount = rrect_type_to_index_count(type);
fAllFill = (kFill_RRectType == type);
}
- const char* name() const override { return "RRectCircleBatch"; }
+ const char* name() const override { return "CircularRRectOp"; }
SkString dumpInfo() const override {
SkString string;
for (int i = 0; i < fGeoData.count(); ++i) {
- string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f],"
- "InnerRad: %.2f, OuterRad: %.2f\n",
- fGeoData[i].fColor,
- fGeoData[i].fDevBounds.fLeft, fGeoData[i].fDevBounds.fTop,
- fGeoData[i].fDevBounds.fRight, fGeoData[i].fDevBounds.fBottom,
- fGeoData[i].fInnerRadius,
- fGeoData[i].fOuterRadius);
+ string.appendf(
+ "Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f],"
+ "InnerRad: %.2f, OuterRad: %.2f\n",
+ fGeoData[i].fColor, fGeoData[i].fDevBounds.fLeft, fGeoData[i].fDevBounds.fTop,
+ fGeoData[i].fDevBounds.fRight, fGeoData[i].fDevBounds.fBottom,
+ fGeoData[i].fInnerRadius, fGeoData[i].fOuterRadius);
}
string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
@@ -1803,7 +1788,7 @@ public:
void computePipelineOptimizations(GrInitInvariantOutput* color,
GrInitInvariantOutput* coverage,
GrBatchToXPOverrides* overrides) const override {
- // When this is called on a batch, there is only one geometry bundle
+ // When this is called there is only one rrect.
color->setKnownFourComponents(fGeoData[0].fColor);
coverage->setUnknownSingleComponent();
}
@@ -1818,17 +1803,17 @@ private:
}
struct CircleVertex {
- SkPoint fPos;
- GrColor fColor;
- SkPoint fOffset;
+ SkPoint fPos;
+ GrColor fColor;
+ SkPoint fOffset;
SkScalar fOuterRadius;
SkScalar fInnerRadius;
// No half plane, we don't use it here.
};
- static void FillInOverstrokeVerts(CircleVertex** verts, const SkRect& bounds,
- SkScalar smInset, SkScalar bigInset, SkScalar xOffset,
- SkScalar outerRadius, SkScalar innerRadius, GrColor color) {
+ static void FillInOverstrokeVerts(CircleVertex** verts, const SkRect& bounds, SkScalar smInset,
+ SkScalar bigInset, SkScalar xOffset, SkScalar outerRadius,
+ SkScalar innerRadius, GrColor color) {
SkASSERT(smInset < bigInset);
// TL
@@ -1840,21 +1825,21 @@ private:
(*verts)++;
// TR
- (*verts)->fPos = SkPoint::Make(bounds.fRight - smInset, bounds.fTop + smInset);
+ (*verts)->fPos = SkPoint::Make(bounds.fRight - smInset, bounds.fTop + smInset);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(xOffset, 0);
(*verts)->fOuterRadius = outerRadius;
(*verts)->fInnerRadius = innerRadius;
(*verts)++;
- (*verts)->fPos = SkPoint::Make(bounds.fLeft + bigInset, bounds.fTop + bigInset);
+ (*verts)->fPos = SkPoint::Make(bounds.fLeft + bigInset, bounds.fTop + bigInset);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(0, 0);
(*verts)->fOuterRadius = outerRadius;
(*verts)->fInnerRadius = innerRadius;
(*verts)++;
- (*verts)->fPos = SkPoint::Make(bounds.fRight - bigInset, bounds.fTop + bigInset);
+ (*verts)->fPos = SkPoint::Make(bounds.fRight - bigInset, bounds.fTop + bigInset);
(*verts)->fColor = color;
(*verts)->fOffset = SkPoint::Make(0, 0);
(*verts)->fOuterRadius = outerRadius;
@@ -1900,9 +1885,8 @@ private:
}
// Setup geometry processor
- sk_sp<GrGeometryProcessor> gp(new CircleGeometryProcessor(!fAllFill,
- false, false,
- false, localMatrix));
+ sk_sp<GrGeometryProcessor> gp(
+ new CircleGeometryProcessor(!fAllFill, false, false, false, localMatrix));
int instanceCount = fGeoData.count();
size_t vertexStride = gp->getVertexStride();
@@ -1911,8 +1895,8 @@ private:
const GrBuffer* vertexBuffer;
int firstVertex;
- CircleVertex* verts = (CircleVertex*) target->makeVertexSpace(vertexStride, fVertCount,
- &vertexBuffer, &firstVertex);
+ CircleVertex* verts = (CircleVertex*)target->makeVertexSpace(vertexStride, fVertCount,
+ &vertexBuffer, &firstVertex);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
@@ -1935,20 +1919,16 @@ private:
const SkRect& bounds = args.fDevBounds;
- SkScalar yCoords[4] = {
- bounds.fTop,
- bounds.fTop + outerRadius,
- bounds.fBottom - outerRadius,
- bounds.fBottom
- };
+ SkScalar yCoords[4] = {bounds.fTop, bounds.fTop + outerRadius,
+ bounds.fBottom - outerRadius, bounds.fBottom};
- SkScalar yOuterRadii[4] = {-1, 0, 0, 1 };
+ SkScalar yOuterRadii[4] = {-1, 0, 0, 1};
// The inner radius in the vertex data must be specified in normalized space.
// For fills, specifying -1/outerRadius guarantees an alpha of 1.0 at the inner radius.
- SkScalar innerRadius = args.fType != kFill_RRectType &&
- args.fType != kFillWithDist_RRectType
- ? args.fInnerRadius / args.fOuterRadius
- : -1.0f / args.fOuterRadius;
+ SkScalar innerRadius =
+ args.fType != kFill_RRectType && args.fType != kFillWithDist_RRectType
+ ? args.fInnerRadius / args.fOuterRadius
+ : -1.0f / args.fOuterRadius;
for (int i = 0; i < 4; ++i) {
verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]);
verts->fColor = color;
@@ -1994,8 +1974,8 @@ private:
// geometry to the outer edge
SkScalar maxOffset = -args.fInnerRadius / overstrokeOuterRadius;
- FillInOverstrokeVerts(&verts, bounds, outerRadius, overstrokeOuterRadius,
- maxOffset, overstrokeOuterRadius, 0.0f, color);
+ FillInOverstrokeVerts(&verts, bounds, outerRadius, overstrokeOuterRadius, maxOffset,
+ overstrokeOuterRadius, 0.0f, color);
}
if (kFillWithDist_RRectType == args.fType) {
@@ -2003,8 +1983,8 @@ private:
SkScalar xOffset = 1.0f - outerRadius / halfMinDim;
- FillInOverstrokeVerts(&verts, bounds, outerRadius, halfMinDim,
- xOffset, halfMinDim, -1.0f, color);
+ FillInOverstrokeVerts(&verts, bounds, outerRadius, halfMinDim, xOffset, halfMinDim,
+ -1.0f, color);
}
const uint16_t* primIndices = rrect_type_to_indices(args.fType);
@@ -2023,7 +2003,7 @@ private:
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
- RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>();
+ CircularRRectOp* that = t->cast<CircularRRectOp>();
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
that->bounds(), caps)) {
return false;
@@ -2042,7 +2022,7 @@ private:
}
struct Geometry {
- GrColor fColor;
+ GrColor fColor;
SkScalar fInnerRadius;
SkScalar fOuterRadius;
SkRect fDevBounds;
@@ -2050,10 +2030,10 @@ private:
};
SkSTArray<1, Geometry, true> fGeoData;
- SkMatrix fViewMatrixIfUsingLocalCoords;
- int fVertCount;
- int fIndexCount;
- bool fAllFill;
+ SkMatrix fViewMatrixIfUsingLocalCoords;
+ int fVertCount;
+ int fIndexCount;
+ bool fAllFill;
typedef GrMeshDrawOp INHERITED;
};
@@ -2069,27 +2049,27 @@ static const GrBuffer* ref_rrect_index_buffer(RRectType type,
switch (type) {
case kFill_RRectType:
return resourceProvider->findOrCreateInstancedIndexBuffer(
- gStandardRRectIndices, kIndicesPerFillRRect, kNumRRectsInIndexBuffer,
- kVertsPerStandardRRect, gRRectOnlyIndexBufferKey);
+ gStandardRRectIndices, kIndicesPerFillRRect, kNumRRectsInIndexBuffer,
+ kVertsPerStandardRRect, gRRectOnlyIndexBufferKey);
case kStroke_RRectType:
return resourceProvider->findOrCreateInstancedIndexBuffer(
- gStandardRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndexBuffer,
- kVertsPerStandardRRect, gStrokeRRectOnlyIndexBufferKey);
+ gStandardRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndexBuffer,
+ kVertsPerStandardRRect, gStrokeRRectOnlyIndexBufferKey);
default:
SkASSERT(false);
return nullptr;
};
}
-class RRectEllipseRendererBatch : public GrMeshDrawOp {
+class EllipticalRRectOp : public GrMeshDrawOp {
public:
DEFINE_OP_CLASS_ID
// If devStrokeWidths values are <= 0 indicates then fill only. Otherwise, strokeOnly indicates
// whether the rrect is only stroked or stroked and filled.
- static GrDrawOp* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& devRect,
- float devXRadius, float devYRadius, SkVector devStrokeWidths,
- bool strokeOnly) {
+ static sk_sp<GrDrawOp> Make(GrColor color, const SkMatrix& viewMatrix, const SkRect& devRect,
+ float devXRadius, float devYRadius, SkVector devStrokeWidths,
+ bool strokeOnly) {
SkASSERT(devXRadius > 0.5);
SkASSERT(devYRadius > 0.5);
SkASSERT((devStrokeWidths.fX > 0) == (devStrokeWidths.fY > 0));
@@ -2107,17 +2087,18 @@ public:
// we only handle thick strokes for near-circular ellipses
if (devStrokeWidths.length() > SK_ScalarHalf &&
- (SK_ScalarHalf*devXRadius > devYRadius || SK_ScalarHalf*devYRadius > devXRadius)) {
+ (SK_ScalarHalf * devXRadius > devYRadius ||
+ SK_ScalarHalf * devYRadius > devXRadius)) {
return nullptr;
}
// we don't handle it if curvature of the stroke is less than curvature of the ellipse
- if (devStrokeWidths.fX*(devYRadius*devYRadius) <
- (devStrokeWidths.fY*devStrokeWidths.fY)*devXRadius) {
+ if (devStrokeWidths.fX * (devYRadius * devYRadius) <
+ (devStrokeWidths.fY * devStrokeWidths.fY) * devXRadius) {
return nullptr;
}
- if (devStrokeWidths.fY*(devXRadius*devXRadius) <
- (devStrokeWidths.fX*devStrokeWidths.fX)*devYRadius) {
+ if (devStrokeWidths.fY * (devXRadius * devXRadius) <
+ (devStrokeWidths.fX * devStrokeWidths.fX) * devYRadius) {
return nullptr;
}
@@ -2133,32 +2114,29 @@ public:
bounds.outset(devStrokeWidths.fX, devStrokeWidths.fY);
}
- RRectEllipseRendererBatch* batch = new RRectEllipseRendererBatch();
- batch->fStroked = stroked;
- batch->fViewMatrixIfUsingLocalCoords = viewMatrix;
- batch->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
+ sk_sp<EllipticalRRectOp> op(new EllipticalRRectOp());
+ op->fStroked = stroked;
+ op->fViewMatrixIfUsingLocalCoords = viewMatrix;
+ op->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
// Expand the rect for aa in order to generate the correct vertices.
bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
- batch->fGeoData.emplace_back(
- Geometry {color, devXRadius, devYRadius, innerXRadius, innerYRadius, bounds});
- return batch;
+ op->fGeoData.emplace_back(
+ Geometry{color, devXRadius, devYRadius, innerXRadius, innerYRadius, bounds});
+ return std::move(op);
}
- const char* name() const override { return "RRectEllipseRendererBatch"; }
+ const char* name() const override { return "EllipticalRRectOp"; }
SkString dumpInfo() const override {
SkString string;
string.appendf("Stroked: %d\n", fStroked);
for (const auto& geo : fGeoData) {
- string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], "
- "XRad: %.2f, YRad: %.2f, InnerXRad: %.2f, InnerYRad: %.2f\n",
- geo.fColor,
- geo.fDevBounds.fLeft, geo.fDevBounds.fTop,
- geo.fDevBounds.fRight, geo.fDevBounds.fBottom,
- geo.fXRadius,
- geo.fYRadius,
- geo.fInnerXRadius,
- geo.fInnerYRadius);
+ string.appendf(
+ "Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], "
+ "XRad: %.2f, YRad: %.2f, InnerXRad: %.2f, InnerYRad: %.2f\n",
+ geo.fColor, geo.fDevBounds.fLeft, geo.fDevBounds.fTop, geo.fDevBounds.fRight,
+ geo.fDevBounds.fBottom, geo.fXRadius, geo.fYRadius, geo.fInnerXRadius,
+ geo.fInnerYRadius);
}
string.append(DumpPipelineInfo(*this->pipeline()));
string.append(INHERITED::dumpInfo());
@@ -2168,13 +2146,13 @@ public:
void computePipelineOptimizations(GrInitInvariantOutput* color,
GrInitInvariantOutput* coverage,
GrBatchToXPOverrides* overrides) const override {
- // When this is called on a batch, there is only one geometry bundle
+ // When this is called there is only one rrect.
color->setKnownFourComponents(fGeoData[0].fColor);
coverage->setUnknownSingleComponent();
}
private:
- RRectEllipseRendererBatch() : INHERITED(ClassID()) {}
+ EllipticalRRectOp() : INHERITED(ClassID()) {}
void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
// Handle overrides that affect our GP.
@@ -2199,14 +2177,13 @@ private:
// drop out the middle quad if we're stroked
int indicesPerInstance = fStroked ? kIndicesPerStrokeRRect : kIndicesPerFillRRect;
- sk_sp<const GrBuffer> indexBuffer(
- ref_rrect_index_buffer(fStroked ? kStroke_RRectType : kFill_RRectType,
- target->resourceProvider()));
+ sk_sp<const GrBuffer> indexBuffer(ref_rrect_index_buffer(
+ fStroked ? kStroke_RRectType : kFill_RRectType, target->resourceProvider()));
InstancedHelper helper;
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
- helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
- kVertsPerStandardRRect, indicesPerInstance, instanceCount));
+ helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
+ kVertsPerStandardRRect, indicesPerInstance, instanceCount));
if (!verts || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
@@ -2229,18 +2206,12 @@ private:
const SkRect& bounds = args.fDevBounds;
- SkScalar yCoords[4] = {
- bounds.fTop,
- bounds.fTop + yOuterRadius,
- bounds.fBottom - yOuterRadius,
- bounds.fBottom
- };
- SkScalar yOuterOffsets[4] = {
- yOuterRadius,
- SK_ScalarNearlyZero, // we're using inversesqrt() in shader, so can't be exactly 0
- SK_ScalarNearlyZero,
- yOuterRadius
- };
+ SkScalar yCoords[4] = {bounds.fTop, bounds.fTop + yOuterRadius,
+ bounds.fBottom - yOuterRadius, bounds.fBottom};
+ SkScalar yOuterOffsets[4] = {yOuterRadius,
+ SK_ScalarNearlyZero, // we're using inversesqrt() in
+ // shader, so can't be exactly 0
+ SK_ScalarNearlyZero, yOuterRadius};
for (int i = 0; i < 4; ++i) {
verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]);
@@ -2276,7 +2247,7 @@ private:
}
bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
- RRectEllipseRendererBatch* that = t->cast<RRectEllipseRendererBatch>();
+ EllipticalRRectOp* that = t->cast<EllipticalRRectOp>();
if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
that->bounds(), caps)) {
@@ -2305,18 +2276,18 @@ private:
SkRect fDevBounds;
};
- bool fStroked;
- SkMatrix fViewMatrixIfUsingLocalCoords;
- SkSTArray<1, Geometry, true> fGeoData;
+ bool fStroked;
+ SkMatrix fViewMatrixIfUsingLocalCoords;
+ SkSTArray<1, Geometry, true> fGeoData;
typedef GrMeshDrawOp INHERITED;
};
-static GrDrawOp* create_rrect_batch(GrColor color,
- bool needsDistance,
- const SkMatrix& viewMatrix,
- const SkRRect& rrect,
- const SkStrokeRec& stroke) {
+static sk_sp<GrDrawOp> make_rrect_op(GrColor color,
+ bool needsDistance,
+ const SkMatrix& viewMatrix,
+ const SkRRect& rrect,
+ const SkStrokeRec& stroke) {
SkASSERT(viewMatrix.rectStaysRect());
SkASSERT(rrect.isSimple());
SkASSERT(!rrect.isOval());
@@ -2328,10 +2299,10 @@ static GrDrawOp* create_rrect_batch(GrColor color,
viewMatrix.mapRect(&bounds, rrectBounds);
SkVector radii = rrect.getSimpleRadii();
- SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX +
- viewMatrix[SkMatrix::kMSkewY]*radii.fY);
- SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*radii.fX +
- viewMatrix[SkMatrix::kMScaleY]*radii.fY);
+ SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX] * radii.fX +
+ viewMatrix[SkMatrix::kMSkewY] * radii.fY);
+ SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX] * radii.fX +
+ viewMatrix[SkMatrix::kMScaleY] * radii.fY);
SkStrokeRec::Style style = stroke.getStyle();
@@ -2339,8 +2310,8 @@ static GrDrawOp* create_rrect_batch(GrColor color,
SkVector scaledStroke = {-1, -1};
SkScalar strokeWidth = stroke.getWidth();
- bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
- SkStrokeRec::kHairline_Style == style;
+ bool isStrokeOnly =
+ SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style;
bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
bool isCircular = (xRadius == yRadius);
@@ -2348,17 +2319,17 @@ static GrDrawOp* create_rrect_batch(GrColor color,
if (SkStrokeRec::kHairline_Style == style) {
scaledStroke.set(1, 1);
} else {
- scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMScaleX] +
- viewMatrix[SkMatrix::kMSkewY]));
- scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSkewX] +
- viewMatrix[SkMatrix::kMScaleY]));
+ scaledStroke.fX = SkScalarAbs(
+ strokeWidth * (viewMatrix[SkMatrix::kMScaleX] + viewMatrix[SkMatrix::kMSkewY]));
+ scaledStroke.fY = SkScalarAbs(
+ strokeWidth * (viewMatrix[SkMatrix::kMSkewX] + viewMatrix[SkMatrix::kMScaleY]));
}
isCircular = isCircular && scaledStroke.fX == scaledStroke.fY;
// for non-circular rrects, if half of strokewidth is greater than radius,
// we don't handle that right now
- if (!isCircular &&
- (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStroke.fY > yRadius)) {
+ if (!isCircular && (SK_ScalarHalf * scaledStroke.fX > xRadius ||
+ SK_ScalarHalf * scaledStroke.fY > yRadius)) {
return nullptr;
}
}
@@ -2374,56 +2345,54 @@ static GrDrawOp* create_rrect_batch(GrColor color,
// if the corners are circles, use the circle renderer
if (isCircular) {
- return new RRectCircleRendererBatch(color, needsDistance, viewMatrix, bounds, xRadius,
- scaledStroke.fX, isStrokeOnly);
- // otherwise we use the ellipse renderer
+ return sk_sp<GrDrawOp>(new CircularRRectOp(color, needsDistance, viewMatrix, bounds,
+ xRadius, scaledStroke.fX, isStrokeOnly));
+ // otherwise we use the ellipse renderer
} else {
- return RRectEllipseRendererBatch::Create(color, viewMatrix, bounds, xRadius, yRadius,
- scaledStroke, isStrokeOnly);
-
+ return EllipticalRRectOp::Make(color, viewMatrix, bounds, xRadius, yRadius, scaledStroke,
+ isStrokeOnly);
}
}
-GrDrawOp* GrOvalRenderer::CreateRRectBatch(GrColor color,
- bool needsDistance,
- const SkMatrix& viewMatrix,
- const SkRRect& rrect,
- const SkStrokeRec& stroke,
- const GrShaderCaps* shaderCaps) {
+sk_sp<GrDrawOp> GrOvalOpFactory::MakeRRectOp(GrColor color,
+ bool needsDistance,
+ const SkMatrix& viewMatrix,
+ const SkRRect& rrect,
+ const SkStrokeRec& stroke,
+ const GrShaderCaps* shaderCaps) {
if (rrect.isOval()) {
- return CreateOvalBatch(color, viewMatrix, rrect.getBounds(), stroke, shaderCaps);
+ return MakeOvalOp(color, viewMatrix, rrect.getBounds(), stroke, shaderCaps);
}
if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) {
return nullptr;
}
- return create_rrect_batch(color, needsDistance, viewMatrix, rrect, stroke);
+ return make_rrect_op(color, needsDistance, viewMatrix, rrect, stroke);
}
///////////////////////////////////////////////////////////////////////////////
-GrDrawOp* GrOvalRenderer::CreateOvalBatch(GrColor color,
- const SkMatrix& viewMatrix,
- const SkRect& oval,
- const SkStrokeRec& stroke,
- const GrShaderCaps* shaderCaps) {
+sk_sp<GrDrawOp> GrOvalOpFactory::MakeOvalOp(GrColor color,
+ const SkMatrix& viewMatrix,
+ const SkRect& oval,
+ const SkStrokeRec& stroke,
+ const GrShaderCaps* shaderCaps) {
// we can draw circles
SkScalar width = oval.width();
if (SkScalarNearlyEqual(width, oval.height()) && circle_stays_circle(viewMatrix)) {
SkPoint center = {oval.centerX(), oval.centerY()};
- return CircleBatch::Create(color, viewMatrix, center, width / 2.f,
- GrStyle(stroke, nullptr));
+ return CircleOp::Make(color, viewMatrix, center, width / 2.f, GrStyle(stroke, nullptr));
}
// if we have shader derivative support, render as device-independent
if (shaderCaps->shaderDerivativeSupport()) {
- return DIEllipseBatch::Create(color, viewMatrix, oval, stroke);
+ return DIEllipseOp::Make(color, viewMatrix, oval, stroke);
}
// otherwise axis-aligned ellipses only
if (viewMatrix.rectStaysRect()) {
- return EllipseBatch::Create(color, viewMatrix, oval, stroke);
+ return EllipseOp::Make(color, viewMatrix, oval, stroke);
}
return nullptr;
@@ -2431,13 +2400,10 @@ GrDrawOp* GrOvalRenderer::CreateOvalBatch(GrColor color,
///////////////////////////////////////////////////////////////////////////////
-GrDrawOp* GrOvalRenderer::CreateArcBatch(GrColor color,
- const SkMatrix& viewMatrix,
- const SkRect& oval,
- SkScalar startAngle, SkScalar sweepAngle,
- bool useCenter,
- const GrStyle& style,
- const GrShaderCaps* shaderCaps) {
+sk_sp<GrDrawOp> GrOvalOpFactory::MakeArcOp(GrColor color, const SkMatrix& viewMatrix,
+ const SkRect& oval, SkScalar startAngle,
+ SkScalar sweepAngle, bool useCenter,
+ const GrStyle& style, const GrShaderCaps* shaderCaps) {
SkASSERT(!oval.isEmpty());
SkASSERT(sweepAngle);
SkScalar width = oval.width();
@@ -2448,19 +2414,16 @@ GrDrawOp* GrOvalRenderer::CreateArcBatch(GrColor color,
return nullptr;
}
SkPoint center = {oval.centerX(), oval.centerY()};
- CircleBatch::ArcParams arcParams = {
- SkDegreesToRadians(startAngle),
- SkDegreesToRadians(sweepAngle),
- useCenter
- };
- return CircleBatch::Create(color, viewMatrix, center, width/2.f, style, &arcParams);
+ CircleOp::ArcParams arcParams = {SkDegreesToRadians(startAngle), SkDegreesToRadians(sweepAngle),
+ useCenter};
+ return CircleOp::Make(color, viewMatrix, center, width / 2.f, style, &arcParams);
}
///////////////////////////////////////////////////////////////////////////////
#ifdef GR_TEST_UTILS
-DRAW_BATCH_TEST_DEFINE(CircleBatch) {
+DRAW_BATCH_TEST_DEFINE(CircleOp) {
do {
SkScalar rotate = random->nextSScalar1() * 360.f;
SkScalar translateX = random->nextSScalar1() * 1000.f;
@@ -2475,43 +2438,43 @@ DRAW_BATCH_TEST_DEFINE(CircleBatch) {
SkPoint center = {circle.centerX(), circle.centerY()};
SkScalar radius = circle.width() / 2.f;
SkStrokeRec stroke = GrTest::TestStrokeRec(random);
- CircleBatch::ArcParams arcParamsTmp;
- const CircleBatch::ArcParams* arcParams = nullptr;
+ CircleOp::ArcParams arcParamsTmp;
+ const CircleOp::ArcParams* arcParams = nullptr;
if (random->nextBool()) {
arcParamsTmp.fStartAngleRadians = random->nextSScalar1() * SK_ScalarPI * 2;
arcParamsTmp.fSweepAngleRadians = random->nextSScalar1() * SK_ScalarPI * 2 - .01f;
arcParamsTmp.fUseCenter = random->nextBool();
arcParams = &arcParamsTmp;
}
- GrDrawOp* batch = CircleBatch::Create(color, viewMatrix, center, radius,
- GrStyle(stroke, nullptr), arcParams);
- if (batch) {
- return batch;
+ sk_sp<GrDrawOp> op = CircleOp::Make(color, viewMatrix, center, radius,
+ GrStyle(stroke, nullptr), arcParams);
+ if (op) {
+ return op.release();
}
} while (true);
}
-DRAW_BATCH_TEST_DEFINE(EllipseBatch) {
+DRAW_BATCH_TEST_DEFINE(EllipseOp) {
SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
GrColor color = GrRandomColor(random);
SkRect ellipse = GrTest::TestSquare(random);
- return EllipseBatch::Create(color, viewMatrix, ellipse, GrTest::TestStrokeRec(random));
+ return EllipseOp::Make(color, viewMatrix, ellipse, GrTest::TestStrokeRec(random)).release();
}
-DRAW_BATCH_TEST_DEFINE(DIEllipseBatch) {
+DRAW_BATCH_TEST_DEFINE(DIEllipseOp) {
SkMatrix viewMatrix = GrTest::TestMatrix(random);
GrColor color = GrRandomColor(random);
SkRect ellipse = GrTest::TestSquare(random);
- return DIEllipseBatch::Create(color, viewMatrix, ellipse, GrTest::TestStrokeRec(random));
+ return DIEllipseOp::Make(color, viewMatrix, ellipse, GrTest::TestStrokeRec(random)).release();
}
-DRAW_BATCH_TEST_DEFINE(RRectBatch) {
+DRAW_BATCH_TEST_DEFINE(RRectOp) {
SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
GrColor color = GrRandomColor(random);
const SkRRect& rrect = GrTest::TestRRectSimple(random);
bool needsDistance = random->nextBool();
- return create_rrect_batch(color, needsDistance, viewMatrix, rrect,
- GrTest::TestStrokeRec(random));
+ return make_rrect_op(color, needsDistance, viewMatrix, rrect, GrTest::TestStrokeRec(random))
+ .release();
}
#endif
diff --git a/src/gpu/batches/GrOvalOpFactory.h b/src/gpu/batches/GrOvalOpFactory.h
new file mode 100644
index 0000000000..dfe7ebf37f
--- /dev/null
+++ b/src/gpu/batches/GrOvalOpFactory.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrOvalOpFactory_DEFINED
+#define GrOvalOpFactory_DEFINED
+
+#include "GrColor.h"
+#include "SkRefCnt.h"
+
+class GrDrawOp;
+class GrShaderCaps;
+class GrStyle;
+class SkMatrix;
+struct SkRect;
+class SkRRect;
+class SkStrokeRec;
+
+/*
+ * This namespace wraps helper functions that draw ovals, rrects, and arcs (filled & stroked)
+ */
+class GrOvalOpFactory {
+public:
+ static sk_sp<GrDrawOp> MakeOvalOp(GrColor,
+ const SkMatrix& viewMatrix,
+ const SkRect& oval,
+ const SkStrokeRec& stroke,
+ const GrShaderCaps* shaderCaps);
+ static sk_sp<GrDrawOp> MakeRRectOp(GrColor,
+ bool needsDistance,
+ const SkMatrix& viewMatrix,
+ const SkRRect& rrect,
+ const SkStrokeRec& stroke,
+ const GrShaderCaps* shaderCaps);
+
+ static sk_sp<GrDrawOp> MakeArcOp(GrColor,
+ const SkMatrix& viewMatrix,
+ const SkRect& oval,
+ SkScalar startAngle,
+ SkScalar sweepAngle,
+ bool useCenter,
+ const GrStyle&,
+ const GrShaderCaps* shaderCaps);
+};
+
+#endif // GrOvalOpFactory_DEFINED