Revert "Revert "Revert "Use GrOvalOpFactory ops to draw non-AA rrects, ovals, and arcs."""

This reverts commit b4e965c103.

Reason for revert: Thin stroke problems, chrome pixel test, g3 clang-tidy

Original change's description:
> Revert "Revert "Use GrOvalOpFactory ops to draw non-AA rrects, ovals, and arcs.""
> 
> This reverts commit befff6580e.
> 
> Bug: skia:
> Change-Id: Ia108408cd986c03783af5058845790f6b17201f4
> Reviewed-on: https://skia-review.googlesource.com/98703
> Reviewed-by: Brian Salomon <bsalomon@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>

TBR=bsalomon@google.com

Change-Id: I785af7efdfc39680052f5721a55ecffbeaf1f0ad
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/98785
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2018-01-23 20:33:21 +00:00 committed by Skia Commit-Bot
parent 574b06f703
commit ea26d6b816
12 changed files with 122 additions and 272 deletions

View File

@ -9,12 +9,11 @@
#define GrTypesPriv_DEFINED #define GrTypesPriv_DEFINED
#include <chrono> #include <chrono>
#include "GrSharedEnums.h"
#include "GrTypes.h" #include "GrTypes.h"
#include "SkRefCnt.h" #include "SkRefCnt.h"
#include "GrSharedEnums.h"
class GrCaps; class GrCaps;
class GrPaint;
// The old libstdc++ uses the draft name "monotonic_clock" rather than "steady_clock". This might // The old libstdc++ uses the draft name "monotonic_clock" rather than "steady_clock". This might
// not actually be monotonic, depending on how libstdc++ was built. However, this is only currently // not actually be monotonic, depending on how libstdc++ was built. However, this is only currently
@ -88,18 +87,7 @@ enum class GrFSAAType {
*/ */
enum class GrAllowMixedSamples : bool { kNo = false, kYes = true }; enum class GrAllowMixedSamples : bool { kNo = false, kYes = true };
/** GrAAType GrChooseAAType(GrAA, GrFSAAType, GrAllowMixedSamples, const GrCaps&);
* We have code paths for some shapes that can draw non-AA using boolean fragment shader coverage.
* However, it may not be desirable to use this if it will trigger a dst copy. If the caller
* of GrChooseAAType passes GrAllowNonAABinaryCoverage::kYes and GrAA::kNo then GrChooseAAType will
* consider whether it is efficient to use coverage to implement a non-AA draw and if so return
* will GrAAType::kCoverage. If GrAA::kYes is passed then this value is ignored.
*/
enum class GrAllowNonAABinaryCoverage : bool { kNo = false, kYes = true };
/** GrPaint is only required if GrAllowNonAABinaryCoverage and GrAA are both kYes. */
GrAAType GrChooseAAType(GrAA, GrFSAAType, GrAllowMixedSamples, GrAllowNonAABinaryCoverage,
const GrPaint*, const GrCaps&);
/** /**
* Some pixel configs are inherently clamped to [0,1], while others can hold values outside of that * Some pixel configs are inherently clamped to [0,1], while others can hold values outside of that

View File

@ -124,8 +124,6 @@ bool GrClipStackClip::PathNeedsSWRenderer(GrContext* context,
canDrawArgs.fAAType = GrChooseAAType(GrAA(element->isAA()), canDrawArgs.fAAType = GrChooseAAType(GrAA(element->isAA()),
renderTargetContext->fsaaType(), renderTargetContext->fsaaType(),
GrAllowMixedSamples::kYes, GrAllowMixedSamples::kYes,
GrAllowNonAABinaryCoverage::kNo,
nullptr,
*context->caps()); *context->caps());
canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings; canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;

View File

@ -99,7 +99,6 @@ private:
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
GrAAType GrChooseAAType(GrAA aa, GrFSAAType fsaaType, GrAllowMixedSamples allowMixedSamples, GrAAType GrChooseAAType(GrAA aa, GrFSAAType fsaaType, GrAllowMixedSamples allowMixedSamples,
GrAllowNonAABinaryCoverage allowNonAABinaryCoverage, const GrPaint* paint,
const GrCaps& caps) { const GrCaps& caps) {
if (GrAA::kNo == aa) { if (GrAA::kNo == aa) {
// On some devices we cannot disable MSAA if it is enabled so we make the AA type reflect // On some devices we cannot disable MSAA if it is enabled so we make the AA type reflect
@ -107,34 +106,6 @@ GrAAType GrChooseAAType(GrAA aa, GrFSAAType fsaaType, GrAllowMixedSamples allowM
if (fsaaType == GrFSAAType::kUnifiedMSAA && !caps.multisampleDisableSupport()) { if (fsaaType == GrFSAAType::kUnifiedMSAA && !caps.multisampleDisableSupport()) {
return GrAAType::kMSAA; return GrAAType::kMSAA;
} }
if (GrAllowNonAABinaryCoverage::kYes == allowNonAABinaryCoverage) {
SkASSERT(paint);
// If we already have a coverage FP then we won't make anything worse.
if (paint->numCoverageFragmentProcessors()) {
return GrAAType::kCoverage;
}
// Shader based blending isn't so expensive with these extensions.
if (caps.shaderCaps()->fbFetchSupport() || caps.textureBarrierSupport()) {
return GrAAType::kCoverage;
}
SkBlendMode mode;
if (GrXPFactory::AsBlendMode(paint->getXPFactory(), &mode)) {
// If we have dual source blending then all Porter-Duff modes can use HW blending
// with coverage.
if (mode <= SkBlendMode::kLastCoeffMode &&
caps.shaderCaps()->dualSourceBlendingSupport()) {
return GrAAType::kCoverage;
}
if (SkBlendMode_SupportsCoverageAsAlpha(mode)) {
return GrAAType::kCoverage;
}
// If the mode is "advanced" then either we will already be doing dst copies or we
// have advanced blending support and it is ok to conflate coverage with alpha.
if (mode > SkBlendMode::kLastCoeffMode) {
return GrAAType::kCoverage;
}
}
}
return GrAAType::kNone; return GrAAType::kNone;
} }
switch (fsaaType) { switch (fsaaType) {
@ -944,12 +915,10 @@ void GrRenderTargetContext::drawRRect(const GrClip& origClip,
AutoCheckFlush acf(this->drawingManager()); AutoCheckFlush acf(this->drawingManager());
const SkStrokeRec stroke = style.strokeRec(); const SkStrokeRec stroke = style.strokeRec();
GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo, GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
GrAllowNonAABinaryCoverage::kYes, &paint);
if (GrAAType::kCoverage == aaType) { if (GrAAType::kCoverage == aaType) {
const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeCoverageRRectOp(std::move(paint), std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeRRectOp(std::move(paint),
aa,
viewMatrix, viewMatrix,
rrect, rrect,
stroke, stroke,
@ -1194,9 +1163,8 @@ bool GrRenderTargetContext::drawFilledDRRect(const GrClip& clip,
auto circleBounds = SkRect::MakeLTRB(cx - avgR, cy - avgR, cx + avgR, cy + avgR); auto circleBounds = SkRect::MakeLTRB(cx - avgR, cy - avgR, cx + avgR, cy + avgR);
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
stroke.setStrokeStyle(outerR - innerR); stroke.setStrokeStyle(outerR - innerR);
auto op = GrOvalOpFactory::MakeCoverageOvalOp(std::move(paint), aa, viewMatrix, auto op = GrOvalOpFactory::MakeOvalOp(std::move(paint), viewMatrix, circleBounds,
circleBounds, stroke, stroke, this->caps()->shaderCaps());
this->caps()->shaderCaps());
if (op) { if (op) {
this->addDrawOp(clip, std::move(op)); this->addDrawOp(clip, std::move(op));
return true; return true;
@ -1337,12 +1305,11 @@ void GrRenderTargetContext::drawOval(const GrClip& clip,
AutoCheckFlush acf(this->drawingManager()); AutoCheckFlush acf(this->drawingManager());
const SkStrokeRec& stroke = style.strokeRec(); const SkStrokeRec& stroke = style.strokeRec();
GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo, GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
GrAllowNonAABinaryCoverage::kYes, &paint);
if (GrAAType::kCoverage == aaType) { if (GrAAType::kCoverage == aaType) {
const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeCoverageOvalOp( std::unique_ptr<GrDrawOp> op =
std::move(paint), aa, viewMatrix, oval, stroke, shaderCaps); GrOvalOpFactory::MakeOvalOp(std::move(paint), viewMatrix, oval, stroke, shaderCaps);
if (op) { if (op) {
this->addDrawOp(clip, std::move(op)); this->addDrawOp(clip, std::move(op));
return; return;
@ -1369,12 +1336,10 @@ void GrRenderTargetContext::drawArc(const GrClip& clip,
AutoCheckFlush acf(this->drawingManager()); AutoCheckFlush acf(this->drawingManager());
GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo, GrAAType aaType = this->chooseAAType(aa, GrAllowMixedSamples::kNo);
GrAllowNonAABinaryCoverage::kYes, &paint);
if (GrAAType::kCoverage == aaType) { if (GrAAType::kCoverage == aaType) {
const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps(); const GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeCoverageArcOp(std::move(paint), std::unique_ptr<GrDrawOp> op = GrOvalOpFactory::MakeArcOp(std::move(paint),
aa,
viewMatrix, viewMatrix,
oval, oval,
startAngle, startAngle,

View File

@ -385,12 +385,8 @@ protected:
private: private:
class TextTarget; class TextTarget;
GrAAType chooseAAType( inline GrAAType chooseAAType(GrAA aa, GrAllowMixedSamples allowMixedSamples) {
GrAA aa, GrAllowMixedSamples allowMixedSamples, return GrChooseAAType(aa, this->fsaaType(), allowMixedSamples, *this->caps());
GrAllowNonAABinaryCoverage allowNonAABinaryCoverage = GrAllowNonAABinaryCoverage::kNo,
const GrPaint* paint = nullptr) {
return GrChooseAAType(aa, this->fsaaType(), allowMixedSamples, allowNonAABinaryCoverage,
paint, *this->caps());
} }
friend class GrAtlasTextBlob; // for access to add[Mesh]DrawOp friend class GrAtlasTextBlob; // for access to add[Mesh]DrawOp

View File

@ -193,11 +193,3 @@ sk_sp<const GrXferProcessor> GrXPFactory::MakeXferProcessor(const GrXPFactory* f
caps); caps);
} }
} }
bool GrXPFactory::AsBlendMode(const GrXPFactory* factory, SkBlendMode* mode) {
if (factory) {
return factory->asBlendMode(mode);
}
*mode = SkBlendMode::kSrcOver;
return true;
}

View File

@ -301,9 +301,6 @@ public:
const GrCaps&, const GrCaps&,
GrPixelConfigIsClamped); GrPixelConfigIsClamped);
/** If true mode will be the equivalent SkBlendMode for the XPFactory. */
static bool AsBlendMode(const GrXPFactory*, SkBlendMode* mode);
protected: protected:
constexpr GrXPFactory() {} constexpr GrXPFactory() {}
@ -322,8 +319,6 @@ private:
const GrProcessorAnalysisCoverage&, const GrProcessorAnalysisCoverage&,
const GrCaps&, const GrCaps&,
GrPixelConfigIsClamped) const = 0; GrPixelConfigIsClamped) const = 0;
virtual bool asBlendMode(SkBlendMode*) const { return false; }
}; };
#if defined(__GNUC__) #if defined(__GNUC__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop

View File

@ -225,8 +225,6 @@ private:
const GrCaps&, const GrCaps&,
GrPixelConfigIsClamped) const override; GrPixelConfigIsClamped) const override;
bool asBlendMode(SkBlendMode* mode) const override;
GR_DECLARE_XP_FACTORY_TEST GR_DECLARE_XP_FACTORY_TEST
SkBlendMode fMode; SkBlendMode fMode;
@ -364,11 +362,6 @@ GrXPFactory::AnalysisProperties CustomXPFactory::analysisProperties(
AnalysisProperties::kReadsDstInShader; AnalysisProperties::kReadsDstInShader;
} }
bool CustomXPFactory::asBlendMode(SkBlendMode* mode) const {
*mode = fMode;
return true;
}
GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory); GR_DEFINE_XP_FACTORY_TEST(CustomXPFactory);
#if GR_TEST_UTILS #if GR_TEST_UTILS
const GrXPFactory* CustomXPFactory::TestGet(GrProcessorTestData* d) { const GrXPFactory* CustomXPFactory::TestGet(GrProcessorTestData* d) {

View File

@ -861,11 +861,6 @@ GrXPFactory::AnalysisProperties GrPorterDuffXPFactory::analysisProperties(
return analysis_properties(color, coverage, caps, dstIsClamped, fBlendMode); return analysis_properties(color, coverage, caps, dstIsClamped, fBlendMode);
} }
bool GrPorterDuffXPFactory::asBlendMode(SkBlendMode* mode) const {
*mode = fBlendMode;
return true;
}
GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory);
#if GR_TEST_UTILS #if GR_TEST_UTILS

View File

@ -58,8 +58,6 @@ private:
const GrCaps&, const GrCaps&,
GrPixelConfigIsClamped) const override; GrPixelConfigIsClamped) const override;
bool asBlendMode(SkBlendMode* mode) const override;
GR_DECLARE_XP_FACTORY_TEST GR_DECLARE_XP_FACTORY_TEST
static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary); static void TestGetXPOutputTypes(const GrXferProcessor*, int* outPrimary, int* outSecondary);

View File

@ -66,12 +66,10 @@ static inline bool circle_stays_circle(const SkMatrix& m) { return m.isSimilarit
class CircleGeometryProcessor : public GrGeometryProcessor { class CircleGeometryProcessor : public GrGeometryProcessor {
public: public:
CircleGeometryProcessor(bool stroke, bool clipPlane, bool isectPlane, bool unionPlane, GrAA aa, CircleGeometryProcessor(bool stroke, bool clipPlane, bool isectPlane, bool unionPlane,
const SkMatrix& localMatrix) const SkMatrix& localMatrix)
: INHERITED(kCircleGeometryProcessor_ClassID) : INHERITED(kCircleGeometryProcessor_ClassID)
, fLocalMatrix(localMatrix) , fLocalMatrix(localMatrix) {
, fStroke(stroke)
, fAA(aa) {
fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType); fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType); fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
fInCircleEdge = &this->addVertexAttrib("inCircleEdge", kFloat4_GrVertexAttribType); fInCircleEdge = &this->addVertexAttrib("inCircleEdge", kFloat4_GrVertexAttribType);
@ -90,6 +88,7 @@ public:
} else { } else {
fInUnionPlane = nullptr; fInUnionPlane = nullptr;
} }
fStroke = stroke;
} }
~CircleGeometryProcessor() override {} ~CircleGeometryProcessor() override {}
@ -175,16 +174,7 @@ private:
} }
fragBuilder->codeAppend("edgeAlpha *= clip;"); fragBuilder->codeAppend("edgeAlpha *= clip;");
} }
if (GrAA::kYes == cgp.fAA) {
fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage); fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage);
} else {
// Using a value less than half is a bit of a hack. If 0.5 is used then filling
// a set of abutting arcs that should create a full circle can leave gaps at pixels
// that neither arc quite owns. Generally speaking, double hitting these pixels
// instead of missing them looks better.
fragBuilder->codeAppendf("%s = edgeAlpha > 0.4999 ? half4(1) : half4(0);",
args.fOutputCoverage);
}
} }
static void GenKey(const GrGeometryProcessor& gp, static void GenKey(const GrGeometryProcessor& gp,
@ -197,7 +187,6 @@ private:
key |= cgp.fInClipPlane ? 0x04 : 0x0; key |= cgp.fInClipPlane ? 0x04 : 0x0;
key |= cgp.fInIsectPlane ? 0x08 : 0x0; key |= cgp.fInIsectPlane ? 0x08 : 0x0;
key |= cgp.fInUnionPlane ? 0x10 : 0x0; key |= cgp.fInUnionPlane ? 0x10 : 0x0;
key |= GrAA::kYes == cgp.fAA ? 0x20 : 0x0;
b->add32(key); b->add32(key);
} }
@ -219,7 +208,6 @@ private:
const Attribute* fInIsectPlane; const Attribute* fInIsectPlane;
const Attribute* fInUnionPlane; const Attribute* fInUnionPlane;
bool fStroke; bool fStroke;
GrAA fAA;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST GR_DECLARE_GEOMETRY_PROCESSOR_TEST
@ -230,10 +218,9 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleGeometryProcessor);
#if GR_TEST_UTILS #if GR_TEST_UTILS
sk_sp<GrGeometryProcessor> CircleGeometryProcessor::TestCreate(GrProcessorTestData* d) { sk_sp<GrGeometryProcessor> CircleGeometryProcessor::TestCreate(GrProcessorTestData* d) {
GrAA aa = d->fRandom->nextBool() ? GrAA::kYes : GrAA::kNo;
return sk_sp<GrGeometryProcessor>(new CircleGeometryProcessor( return sk_sp<GrGeometryProcessor>(new CircleGeometryProcessor(
d->fRandom->nextBool(), d->fRandom->nextBool(), d->fRandom->nextBool(), d->fRandom->nextBool(), d->fRandom->nextBool(), d->fRandom->nextBool(),
d->fRandom->nextBool(), aa, GrTest::TestMatrix(d->fRandom))); d->fRandom->nextBool(), GrTest::TestMatrix(d->fRandom)));
} }
#endif #endif
@ -249,15 +236,14 @@ sk_sp<GrGeometryProcessor> CircleGeometryProcessor::TestCreate(GrProcessorTestDa
class EllipseGeometryProcessor : public GrGeometryProcessor { class EllipseGeometryProcessor : public GrGeometryProcessor {
public: public:
EllipseGeometryProcessor(bool stroke, GrAA aa, const SkMatrix& localMatrix) EllipseGeometryProcessor(bool stroke, const SkMatrix& localMatrix)
: INHERITED(kEllipseGeometryProcessor_ClassID) : INHERITED(kEllipseGeometryProcessor_ClassID)
, fLocalMatrix(localMatrix) , fLocalMatrix(localMatrix) {
, fStroke(stroke)
, fAA(aa) {
fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType); fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType); fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
fInEllipseOffset = &this->addVertexAttrib("inEllipseOffset", kHalf2_GrVertexAttribType); fInEllipseOffset = &this->addVertexAttrib("inEllipseOffset", kHalf2_GrVertexAttribType);
fInEllipseRadii = &this->addVertexAttrib("inEllipseRadii", kHalf4_GrVertexAttribType); fInEllipseRadii = &this->addVertexAttrib("inEllipseRadii", kHalf4_GrVertexAttribType);
fStroke = stroke;
} }
~EllipseGeometryProcessor() override {} ~EllipseGeometryProcessor() override {}
@ -332,12 +318,7 @@ private:
fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);"); fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
} }
if (GrAA::kYes == egp.fAA) {
fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage); fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage);
} else {
fragBuilder->codeAppendf("%s = edgeAlpha > 0.5 ? half4(1) : half4(0);",
args.fOutputCoverage);
}
} }
static void GenKey(const GrGeometryProcessor& gp, static void GenKey(const GrGeometryProcessor& gp,
@ -346,7 +327,6 @@ private:
const EllipseGeometryProcessor& egp = gp.cast<EllipseGeometryProcessor>(); const EllipseGeometryProcessor& egp = gp.cast<EllipseGeometryProcessor>();
uint16_t key = egp.fStroke ? 0x1 : 0x0; uint16_t key = egp.fStroke ? 0x1 : 0x0;
key |= egp.fLocalMatrix.hasPerspective() ? 0x2 : 0x0; key |= egp.fLocalMatrix.hasPerspective() ? 0x2 : 0x0;
key |= GrAA::kYes == egp.fAA ? 0x4 : 0x0;
b->add32(key); b->add32(key);
} }
@ -366,7 +346,6 @@ private:
const Attribute* fInEllipseRadii; const Attribute* fInEllipseRadii;
SkMatrix fLocalMatrix; SkMatrix fLocalMatrix;
bool fStroke; bool fStroke;
GrAA fAA;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST GR_DECLARE_GEOMETRY_PROCESSOR_TEST
@ -377,9 +356,8 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseGeometryProcessor);
#if GR_TEST_UTILS #if GR_TEST_UTILS
sk_sp<GrGeometryProcessor> EllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) { sk_sp<GrGeometryProcessor> EllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) {
GrAA aa = d->fRandom->nextBool() ? GrAA::kYes : GrAA::kNo; return sk_sp<GrGeometryProcessor>(
return sk_sp<GrGeometryProcessor>(new EllipseGeometryProcessor(d->fRandom->nextBool(), aa, new EllipseGeometryProcessor(d->fRandom->nextBool(), GrTest::TestMatrix(d->fRandom)));
GrTest::TestMatrix(d->fRandom)));
} }
#endif #endif
@ -398,15 +376,14 @@ enum class DIEllipseStyle { kStroke = 0, kHairline, kFill };
class DIEllipseGeometryProcessor : public GrGeometryProcessor { class DIEllipseGeometryProcessor : public GrGeometryProcessor {
public: public:
DIEllipseGeometryProcessor(const SkMatrix& viewMatrix, DIEllipseStyle style, GrAA aa) DIEllipseGeometryProcessor(const SkMatrix& viewMatrix, DIEllipseStyle style)
: INHERITED(kDIEllipseGeometryProcessor_ClassID) : INHERITED(kDIEllipseGeometryProcessor_ClassID)
, fViewMatrix(viewMatrix) , fViewMatrix(viewMatrix) {
, fStyle(style)
, fAA(aa) {
fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType); fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType); fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
fInEllipseOffsets0 = &this->addVertexAttrib("inEllipseOffsets0", kHalf2_GrVertexAttribType); fInEllipseOffsets0 = &this->addVertexAttrib("inEllipseOffsets0", kHalf2_GrVertexAttribType);
fInEllipseOffsets1 = &this->addVertexAttrib("inEllipseOffsets1", kHalf2_GrVertexAttribType); fInEllipseOffsets1 = &this->addVertexAttrib("inEllipseOffsets1", kHalf2_GrVertexAttribType);
fStyle = style;
} }
~DIEllipseGeometryProcessor() override {} ~DIEllipseGeometryProcessor() override {}
@ -496,12 +473,8 @@ private:
fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));"); fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);"); fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
} }
if (GrAA::kYes == diegp.fAA) {
fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage); fragBuilder->codeAppendf("%s = half4(edgeAlpha);", args.fOutputCoverage);
} else {
fragBuilder->codeAppendf("%s = edgeAlpha > 0.5 ? half4(1) : half4(0);",
args.fOutputCoverage);
}
} }
static void GenKey(const GrGeometryProcessor& gp, static void GenKey(const GrGeometryProcessor& gp,
@ -509,7 +482,6 @@ private:
GrProcessorKeyBuilder* b) { GrProcessorKeyBuilder* b) {
const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>(); const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>();
uint16_t key = static_cast<uint16_t>(diegp.fStyle); uint16_t key = static_cast<uint16_t>(diegp.fStyle);
key |= GrAA::kYes == diegp.fAA ? 0x80 : 0x0;
key |= ComputePosKey(diegp.fViewMatrix) << 10; key |= ComputePosKey(diegp.fViewMatrix) << 10;
b->add32(key); b->add32(key);
} }
@ -540,7 +512,6 @@ private:
const Attribute* fInEllipseOffsets1; const Attribute* fInEllipseOffsets1;
SkMatrix fViewMatrix; SkMatrix fViewMatrix;
DIEllipseStyle fStyle; DIEllipseStyle fStyle;
GrAA fAA;
GR_DECLARE_GEOMETRY_PROCESSOR_TEST GR_DECLARE_GEOMETRY_PROCESSOR_TEST
@ -551,9 +522,8 @@ GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseGeometryProcessor);
#if GR_TEST_UTILS #if GR_TEST_UTILS
sk_sp<GrGeometryProcessor> DIEllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) { sk_sp<GrGeometryProcessor> DIEllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) {
GrAA aa = d->fRandom->nextBool() ? GrAA::kYes : GrAA::kNo;
return sk_sp<GrGeometryProcessor>(new DIEllipseGeometryProcessor( return sk_sp<GrGeometryProcessor>(new DIEllipseGeometryProcessor(
GrTest::TestMatrix(d->fRandom), (DIEllipseStyle)(d->fRandom->nextRangeU(0, 2)), aa)); GrTest::TestMatrix(d->fRandom), (DIEllipseStyle)(d->fRandom->nextRangeU(0, 2))));
} }
#endif #endif
@ -621,7 +591,7 @@ public:
bool fUseCenter; bool fUseCenter;
}; };
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, GrAA aa, const SkMatrix& viewMatrix, static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
SkPoint center, SkScalar radius, const GrStyle& style, SkPoint center, SkScalar radius, const GrStyle& style,
const ArcParams* arcParams = nullptr) { const ArcParams* arcParams = nullptr) {
SkASSERT(circle_stays_circle(viewMatrix)); SkASSERT(circle_stays_circle(viewMatrix));
@ -648,13 +618,13 @@ public:
break; break;
} }
} }
return Helper::FactoryHelper<CircleOp>(std::move(paint), aa, viewMatrix, center, radius, return Helper::FactoryHelper<CircleOp>(std::move(paint), viewMatrix, center, radius, style,
style, arcParams); arcParams);
} }
CircleOp(const Helper::MakeArgs& helperArgs, GrColor color, GrAA aa, const SkMatrix& viewMatrix, CircleOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix,
SkPoint center, SkScalar radius, const GrStyle& style, const ArcParams* arcParams) SkPoint center, SkScalar radius, const GrStyle& style, const ArcParams* arcParams)
: GrMeshDrawOp(ClassID()), fHelper(helperArgs, GrAAType::kCoverage), fAA(aa) { : GrMeshDrawOp(ClassID()), fHelper(helperArgs, GrAAType::kCoverage) {
const SkStrokeRec& stroke = style.strokeRec(); const SkStrokeRec& stroke = style.strokeRec();
SkStrokeRec::Style recStyle = stroke.getStyle(); SkStrokeRec::Style recStyle = stroke.getStyle();
@ -846,7 +816,7 @@ private:
// Setup geometry processor // Setup geometry processor
sk_sp<GrGeometryProcessor> gp(new CircleGeometryProcessor( sk_sp<GrGeometryProcessor> gp(new CircleGeometryProcessor(
!fAllFill, fClipPlane, fClipPlaneIsect, fClipPlaneUnion, fAA, localMatrix)); !fAllFill, fClipPlane, fClipPlaneIsect, fClipPlaneUnion, localMatrix));
struct CircleVertex { struct CircleVertex {
SkPoint fPos; SkPoint fPos;
@ -1135,10 +1105,6 @@ private:
return false; return false;
} }
if (fAA != that->fAA) {
return false;
}
// Because we've set up the ops that don't use the planes with noop values // 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. // we can just accumulate used planes by later ops.
fClipPlane |= that->fClipPlane; fClipPlane |= that->fClipPlane;
@ -1173,7 +1139,6 @@ private:
bool fClipPlane; bool fClipPlane;
bool fClipPlaneIsect; bool fClipPlaneIsect;
bool fClipPlaneUnion; bool fClipPlaneUnion;
GrAA fAA;
typedef GrMeshDrawOp INHERITED; typedef GrMeshDrawOp INHERITED;
}; };
@ -1195,7 +1160,7 @@ private:
public: public:
DEFINE_OP_CLASS_ID DEFINE_OP_CLASS_ID
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, GrAA aa, const SkMatrix& viewMatrix, static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
const SkRect& ellipse, const SkStrokeRec& stroke) { const SkRect& ellipse, const SkStrokeRec& stroke) {
DeviceSpaceParams params; DeviceSpaceParams params;
// do any matrix crunching before we reset the draw state for device coords // do any matrix crunching before we reset the draw state for device coords
@ -1254,13 +1219,12 @@ public:
params.fXRadius += scaledStroke.fX; params.fXRadius += scaledStroke.fX;
params.fYRadius += scaledStroke.fY; params.fYRadius += scaledStroke.fY;
} }
return Helper::FactoryHelper<EllipseOp>(std::move(paint), aa, viewMatrix, params, stroke); return Helper::FactoryHelper<EllipseOp>(std::move(paint), viewMatrix, params, stroke);
} }
EllipseOp(const Helper::MakeArgs& helperArgs, GrColor color, GrAA aa, EllipseOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix,
const SkMatrix& viewMatrix, const DeviceSpaceParams& params, const DeviceSpaceParams& params, const SkStrokeRec& stroke)
const SkStrokeRec& stroke) : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage) {
: INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage), fAA(aa) {
SkStrokeRec::Style style = stroke.getStyle(); SkStrokeRec::Style style = stroke.getStyle();
bool isStrokeOnly = bool isStrokeOnly =
SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style; SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style;
@ -1320,7 +1284,7 @@ private:
} }
// Setup geometry processor // Setup geometry processor
sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, fAA, localMatrix)); sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix));
QuadHelper helper; QuadHelper helper;
size_t vertexStride = gp->getVertexStride(); size_t vertexStride = gp->getVertexStride();
@ -1392,10 +1356,6 @@ private:
return false; return false;
} }
if (fAA != that->fAA) {
return false;
}
fEllipses.push_back_n(that->fEllipses.count(), that->fEllipses.begin()); fEllipses.push_back_n(that->fEllipses.count(), that->fEllipses.begin());
this->joinBounds(*that); this->joinBounds(*that);
return true; return true;
@ -1413,7 +1373,6 @@ private:
SkMatrix fViewMatrixIfUsingLocalCoords; SkMatrix fViewMatrixIfUsingLocalCoords;
Helper fHelper; Helper fHelper;
bool fStroked; bool fStroked;
GrAA fAA;
SkSTArray<1, Ellipse, true> fEllipses; SkSTArray<1, Ellipse, true> fEllipses;
typedef GrMeshDrawOp INHERITED; typedef GrMeshDrawOp INHERITED;
@ -1437,7 +1396,7 @@ private:
public: public:
DEFINE_OP_CLASS_ID DEFINE_OP_CLASS_ID
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, GrAA aa, const SkMatrix& viewMatrix, static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
const SkRect& ellipse, const SkStrokeRec& stroke) { const SkRect& ellipse, const SkStrokeRec& stroke) {
DeviceSpaceParams params; DeviceSpaceParams params;
params.fCenter = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); params.fCenter = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
@ -1492,12 +1451,12 @@ public:
(params.fInnerXRadius <= 0 || params.fInnerYRadius <= 0)) { (params.fInnerXRadius <= 0 || params.fInnerYRadius <= 0)) {
params.fStyle = DIEllipseStyle::kFill; params.fStyle = DIEllipseStyle::kFill;
} }
return Helper::FactoryHelper<DIEllipseOp>(std::move(paint), aa, params, viewMatrix); return Helper::FactoryHelper<DIEllipseOp>(std::move(paint), params, viewMatrix);
} }
DIEllipseOp(Helper::MakeArgs& helperArgs, GrColor color, GrAA aa, DIEllipseOp(Helper::MakeArgs& helperArgs, GrColor color, const DeviceSpaceParams& params,
const DeviceSpaceParams& params, const SkMatrix& viewMatrix) const SkMatrix& viewMatrix)
: INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage), fAA(aa) { : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage) {
// This expands the outer rect so that after CTM we end up with a half-pixel border // This expands the outer rect so that after CTM we end up with a half-pixel border
SkScalar a = viewMatrix[SkMatrix::kMScaleX]; SkScalar a = viewMatrix[SkMatrix::kMScaleX];
SkScalar b = viewMatrix[SkMatrix::kMSkewX]; SkScalar b = viewMatrix[SkMatrix::kMSkewX];
@ -1552,7 +1511,7 @@ private:
void onPrepareDraws(Target* target) override { void onPrepareDraws(Target* target) override {
// Setup geometry processor // Setup geometry processor
sk_sp<GrGeometryProcessor> gp( sk_sp<GrGeometryProcessor> gp(
new DIEllipseGeometryProcessor(this->viewMatrix(), this->style(), fAA)); new DIEllipseGeometryProcessor(this->viewMatrix(), this->style()));
size_t vertexStride = gp->getVertexStride(); size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(DIEllipseVertex)); SkASSERT(vertexStride == sizeof(DIEllipseVertex));
@ -1617,10 +1576,6 @@ private:
return false; return false;
} }
if (fAA != that->fAA) {
return false;
}
fEllipses.push_back_n(that->fEllipses.count(), that->fEllipses.begin()); fEllipses.push_back_n(that->fEllipses.count(), that->fEllipses.begin());
this->joinBounds(*that); this->joinBounds(*that);
return true; return true;
@ -1644,7 +1599,6 @@ private:
Helper fHelper; Helper fHelper;
SkSTArray<1, Ellipse, true> fEllipses; SkSTArray<1, Ellipse, true> fEllipses;
GrAA fAA;
typedef GrMeshDrawOp INHERITED; typedef GrMeshDrawOp INHERITED;
}; };
@ -1784,19 +1738,17 @@ public:
// A devStrokeWidth <= 0 indicates a fill only. If devStrokeWidth > 0 then strokeOnly indicates // A devStrokeWidth <= 0 indicates a fill only. If devStrokeWidth > 0 then strokeOnly indicates
// whether the rrect is only stroked or stroked and filled. // whether the rrect is only stroked or stroked and filled.
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, GrAA aa, const SkMatrix& viewMatrix, static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
const SkRect& devRect, float devRadius, const SkRect& devRect, float devRadius,
float devStrokeWidth, bool strokeOnly) { float devStrokeWidth, bool strokeOnly) {
return Helper::FactoryHelper<CircularRRectOp>(std::move(paint), aa, viewMatrix, devRect, return Helper::FactoryHelper<CircularRRectOp>(std::move(paint), viewMatrix, devRect,
devRadius, devStrokeWidth, strokeOnly); devRadius, devStrokeWidth, strokeOnly);
} }
CircularRRectOp(Helper::MakeArgs& helperArgs, GrColor color, GrAA aa, CircularRRectOp(Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix,
const SkMatrix& viewMatrix, const SkRect& devRect, float devRadius, const SkRect& devRect, float devRadius, float devStrokeWidth, bool strokeOnly)
float devStrokeWidth, bool strokeOnly)
: INHERITED(ClassID()) : INHERITED(ClassID())
, fViewMatrixIfUsingLocalCoords(viewMatrix) , fViewMatrixIfUsingLocalCoords(viewMatrix)
, fHelper(helperArgs, GrAAType::kCoverage) , fHelper(helperArgs, GrAAType::kCoverage) {
, fAA(aa) {
SkRect bounds = devRect; SkRect bounds = devRect;
SkASSERT(!(devStrokeWidth <= 0 && strokeOnly)); SkASSERT(!(devStrokeWidth <= 0 && strokeOnly));
SkScalar innerRadius = 0.0f; SkScalar innerRadius = 0.0f;
@ -1958,7 +1910,7 @@ private:
// Setup geometry processor // Setup geometry processor
sk_sp<GrGeometryProcessor> gp( sk_sp<GrGeometryProcessor> gp(
new CircleGeometryProcessor(!fAllFill, false, false, false, fAA, localMatrix)); new CircleGeometryProcessor(!fAllFill, false, false, false, localMatrix));
size_t vertexStride = gp->getVertexStride(); size_t vertexStride = gp->getVertexStride();
SkASSERT(sizeof(CircleVertex) == vertexStride); SkASSERT(sizeof(CircleVertex) == vertexStride);
@ -2077,10 +2029,6 @@ private:
return false; return false;
} }
if (fAA != that->fAA) {
return false;
}
fRRects.push_back_n(that->fRRects.count(), that->fRRects.begin()); fRRects.push_back_n(that->fRRects.count(), that->fRRects.begin());
this->joinBounds(*that); this->joinBounds(*that);
fVertCount += that->fVertCount; fVertCount += that->fVertCount;
@ -2102,7 +2050,6 @@ private:
int fVertCount; int fVertCount;
int fIndexCount; int fIndexCount;
bool fAllFill; bool fAllFill;
GrAA fAA;
SkSTArray<1, RRect, true> fRRects; SkSTArray<1, RRect, true> fRRects;
typedef GrMeshDrawOp INHERITED; typedef GrMeshDrawOp INHERITED;
@ -2140,7 +2087,7 @@ public:
// If devStrokeWidths values are <= 0 indicates then fill only. Otherwise, strokeOnly indicates // If devStrokeWidths values are <= 0 indicates then fill only. Otherwise, strokeOnly indicates
// whether the rrect is only stroked or stroked and filled. // whether the rrect is only stroked or stroked and filled.
static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, GrAA aa, const SkMatrix& viewMatrix, static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
const SkRect& devRect, float devXRadius, float devYRadius, const SkRect& devRect, float devXRadius, float devYRadius,
SkVector devStrokeWidths, bool strokeOnly) { SkVector devStrokeWidths, bool strokeOnly) {
SkASSERT(devXRadius > 0.5); SkASSERT(devXRadius > 0.5);
@ -2171,15 +2118,15 @@ public:
return nullptr; return nullptr;
} }
} }
return Helper::FactoryHelper<EllipticalRRectOp>(std::move(paint), aa, viewMatrix, devRect, return Helper::FactoryHelper<EllipticalRRectOp>(std::move(paint), viewMatrix, devRect,
devXRadius, devYRadius, devStrokeWidths, devXRadius, devYRadius, devStrokeWidths,
strokeOnly); strokeOnly);
} }
EllipticalRRectOp(Helper::MakeArgs helperArgs, GrColor color, GrAA aa, EllipticalRRectOp(Helper::MakeArgs helperArgs, GrColor color, const SkMatrix& viewMatrix,
const SkMatrix& viewMatrix, const SkRect& devRect, float devXRadius, const SkRect& devRect, float devXRadius, float devYRadius,
float devYRadius, SkVector devStrokeHalfWidths, bool strokeOnly) SkVector devStrokeHalfWidths, bool strokeOnly)
: INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage), fAA(aa) { : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage) {
SkScalar innerXRadius = 0.0f; SkScalar innerXRadius = 0.0f;
SkScalar innerYRadius = 0.0f; SkScalar innerYRadius = 0.0f;
SkRect bounds = devRect; SkRect bounds = devRect;
@ -2245,7 +2192,7 @@ private:
} }
// Setup geometry processor // Setup geometry processor
sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, fAA, localMatrix)); sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix));
size_t vertexStride = gp->getVertexStride(); size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(EllipseVertex)); SkASSERT(vertexStride == sizeof(EllipseVertex));
@ -2333,9 +2280,7 @@ private:
!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) { !fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) {
return false; return false;
} }
if (fAA != that->fAA) {
return false;
}
fRRects.push_back_n(that->fRRects.count(), that->fRRects.begin()); fRRects.push_back_n(that->fRRects.count(), that->fRRects.begin());
this->joinBounds(*that); this->joinBounds(*that);
return true; return true;
@ -2353,14 +2298,12 @@ private:
SkMatrix fViewMatrixIfUsingLocalCoords; SkMatrix fViewMatrixIfUsingLocalCoords;
Helper fHelper; Helper fHelper;
bool fStroked; bool fStroked;
GrAA fAA;
SkSTArray<1, RRect, true> fRRects; SkSTArray<1, RRect, true> fRRects;
typedef GrMeshDrawOp INHERITED; typedef GrMeshDrawOp INHERITED;
}; };
static std::unique_ptr<GrDrawOp> make_rrect_op(GrPaint&& paint, static std::unique_ptr<GrDrawOp> make_rrect_op(GrPaint&& paint,
GrAA aa,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkRRect& rrect, const SkRRect& rrect,
const SkStrokeRec& stroke) { const SkStrokeRec& stroke) {
@ -2421,37 +2364,34 @@ static std::unique_ptr<GrDrawOp> make_rrect_op(GrPaint&& paint,
// if the corners are circles, use the circle renderer // if the corners are circles, use the circle renderer
if (isCircular) { if (isCircular) {
return CircularRRectOp::Make(std::move(paint), aa, viewMatrix, bounds, xRadius, return CircularRRectOp::Make(std::move(paint), viewMatrix, bounds, xRadius, scaledStroke.fX,
scaledStroke.fX, isStrokeOnly); isStrokeOnly);
// otherwise we use the ellipse renderer // otherwise we use the ellipse renderer
} else { } else {
return EllipticalRRectOp::Make(std::move(paint), aa, viewMatrix, bounds, xRadius, yRadius, return EllipticalRRectOp::Make(std::move(paint), viewMatrix, bounds, xRadius, yRadius,
scaledStroke, isStrokeOnly); scaledStroke, isStrokeOnly);
} }
} }
std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeCoverageRRectOp(GrPaint&& paint, std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeRRectOp(GrPaint&& paint,
GrAA aa,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkRRect& rrect, const SkRRect& rrect,
const SkStrokeRec& stroke, const SkStrokeRec& stroke,
const GrShaderCaps* shaderCaps) { const GrShaderCaps* shaderCaps) {
if (rrect.isOval()) { if (rrect.isOval()) {
return MakeCoverageOvalOp(std::move(paint), aa, viewMatrix, rrect.getBounds(), stroke, return MakeOvalOp(std::move(paint), viewMatrix, rrect.getBounds(), stroke, shaderCaps);
shaderCaps);
} }
if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) {
return nullptr; return nullptr;
} }
return make_rrect_op(std::move(paint), aa, viewMatrix, rrect, stroke); return make_rrect_op(std::move(paint), viewMatrix, rrect, stroke);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeCoverageOvalOp(GrPaint&& paint, std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeOvalOp(GrPaint&& paint,
GrAA aa,
const SkMatrix& viewMatrix, const SkMatrix& viewMatrix,
const SkRect& oval, const SkRect& oval,
const SkStrokeRec& stroke, const SkStrokeRec& stroke,
@ -2461,18 +2401,18 @@ std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeCoverageOvalOp(GrPaint&& paint,
if (width > SK_ScalarNearlyZero && SkScalarNearlyEqual(width, oval.height()) && if (width > SK_ScalarNearlyZero && SkScalarNearlyEqual(width, oval.height()) &&
circle_stays_circle(viewMatrix)) { circle_stays_circle(viewMatrix)) {
SkPoint center = {oval.centerX(), oval.centerY()}; SkPoint center = {oval.centerX(), oval.centerY()};
return CircleOp::Make(std::move(paint), aa, viewMatrix, center, width / 2.f, return CircleOp::Make(std::move(paint), viewMatrix, center, width / 2.f,
GrStyle(stroke, nullptr)); GrStyle(stroke, nullptr));
} }
// prefer the device space ellipse op for batchability // prefer the device space ellipse op for batchability
if (viewMatrix.rectStaysRect()) { if (viewMatrix.rectStaysRect()) {
return EllipseOp::Make(std::move(paint), aa, viewMatrix, oval, stroke); return EllipseOp::Make(std::move(paint), viewMatrix, oval, stroke);
} }
// Otherwise, if we have shader derivative support, render as device-independent // Otherwise, if we have shader derivative support, render as device-independent
if (shaderCaps->shaderDerivativeSupport()) { if (shaderCaps->shaderDerivativeSupport()) {
return DIEllipseOp::Make(std::move(paint), aa, viewMatrix, oval, stroke); return DIEllipseOp::Make(std::move(paint), viewMatrix, oval, stroke);
} }
return nullptr; return nullptr;
@ -2480,9 +2420,10 @@ std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeCoverageOvalOp(GrPaint&& paint,
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeCoverageArcOp( std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeArcOp(GrPaint&& paint, const SkMatrix& viewMatrix,
GrPaint&& paint, GrAA aa, const SkMatrix& viewMatrix, const SkRect& oval, const SkRect& oval, SkScalar startAngle,
SkScalar startAngle, SkScalar sweepAngle, bool useCenter, const GrStyle& style, SkScalar sweepAngle, bool useCenter,
const GrStyle& style,
const GrShaderCaps* shaderCaps) { const GrShaderCaps* shaderCaps) {
SkASSERT(!oval.isEmpty()); SkASSERT(!oval.isEmpty());
SkASSERT(sweepAngle); SkASSERT(sweepAngle);
@ -2496,7 +2437,7 @@ std::unique_ptr<GrDrawOp> GrOvalOpFactory::MakeCoverageArcOp(
SkPoint center = {oval.centerX(), oval.centerY()}; SkPoint center = {oval.centerX(), oval.centerY()};
CircleOp::ArcParams arcParams = {SkDegreesToRadians(startAngle), SkDegreesToRadians(sweepAngle), CircleOp::ArcParams arcParams = {SkDegreesToRadians(startAngle), SkDegreesToRadians(sweepAngle),
useCenter}; useCenter};
return CircleOp::Make(std::move(paint), aa, viewMatrix, center, width / 2.f, style, &arcParams); return CircleOp::Make(std::move(paint), viewMatrix, center, width / 2.f, style, &arcParams);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -2519,15 +2460,14 @@ GR_DRAW_OP_TEST_DEFINE(CircleOp) {
SkStrokeRec stroke = GrTest::TestStrokeRec(random); SkStrokeRec stroke = GrTest::TestStrokeRec(random);
CircleOp::ArcParams arcParamsTmp; CircleOp::ArcParams arcParamsTmp;
const CircleOp::ArcParams* arcParams = nullptr; const CircleOp::ArcParams* arcParams = nullptr;
GrAA aa = random->nextBool() ? GrAA::kYes : GrAA::kNo;
if (random->nextBool()) { if (random->nextBool()) {
arcParamsTmp.fStartAngleRadians = random->nextSScalar1() * SK_ScalarPI * 2; arcParamsTmp.fStartAngleRadians = random->nextSScalar1() * SK_ScalarPI * 2;
arcParamsTmp.fSweepAngleRadians = random->nextSScalar1() * SK_ScalarPI * 2 - .01f; arcParamsTmp.fSweepAngleRadians = random->nextSScalar1() * SK_ScalarPI * 2 - .01f;
arcParamsTmp.fUseCenter = random->nextBool(); arcParamsTmp.fUseCenter = random->nextBool();
arcParams = &arcParamsTmp; arcParams = &arcParamsTmp;
} }
std::unique_ptr<GrDrawOp> op = CircleOp::Make(std::move(paint), aa, viewMatrix, center, std::unique_ptr<GrDrawOp> op = CircleOp::Make(std::move(paint), viewMatrix, center, radius,
radius, GrStyle(stroke, nullptr), arcParams); GrStyle(stroke, nullptr), arcParams);
if (op) { if (op) {
return op; return op;
} }
@ -2537,24 +2477,19 @@ GR_DRAW_OP_TEST_DEFINE(CircleOp) {
GR_DRAW_OP_TEST_DEFINE(EllipseOp) { GR_DRAW_OP_TEST_DEFINE(EllipseOp) {
SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
SkRect ellipse = GrTest::TestSquare(random); SkRect ellipse = GrTest::TestSquare(random);
GrAA aa = random->nextBool() ? GrAA::kYes : GrAA::kNo; return EllipseOp::Make(std::move(paint), viewMatrix, ellipse, GrTest::TestStrokeRec(random));
return EllipseOp::Make(std::move(paint), aa, viewMatrix, ellipse,
GrTest::TestStrokeRec(random));
} }
GR_DRAW_OP_TEST_DEFINE(DIEllipseOp) { GR_DRAW_OP_TEST_DEFINE(DIEllipseOp) {
SkMatrix viewMatrix = GrTest::TestMatrix(random); SkMatrix viewMatrix = GrTest::TestMatrix(random);
SkRect ellipse = GrTest::TestSquare(random); SkRect ellipse = GrTest::TestSquare(random);
GrAA aa = random->nextBool() ? GrAA::kYes : GrAA::kNo; return DIEllipseOp::Make(std::move(paint), viewMatrix, ellipse, GrTest::TestStrokeRec(random));
return DIEllipseOp::Make(std::move(paint), aa, viewMatrix, ellipse,
GrTest::TestStrokeRec(random));
} }
GR_DRAW_OP_TEST_DEFINE(RRectOp) { GR_DRAW_OP_TEST_DEFINE(RRectOp) {
SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
const SkRRect& rrect = GrTest::TestRRectSimple(random); const SkRRect& rrect = GrTest::TestRRectSimple(random);
GrAA aa = random->nextBool() ? GrAA::kYes : GrAA::kNo; return make_rrect_op(std::move(paint), viewMatrix, rrect, GrTest::TestStrokeRec(random));
return make_rrect_op(std::move(paint), aa, viewMatrix, rrect, GrTest::TestStrokeRec(random));
} }
#endif #endif

View File

@ -22,26 +22,22 @@ class SkStrokeRec;
/* /*
* This namespace wraps helper functions that draw ovals, rrects, and arcs (filled & stroked) * This namespace wraps helper functions that draw ovals, rrects, and arcs (filled & stroked)
* The ops always use coverage even when their non-AA.
*/ */
class GrOvalOpFactory { class GrOvalOpFactory {
public: public:
static std::unique_ptr<GrDrawOp> MakeCoverageOvalOp(GrPaint&&, static std::unique_ptr<GrDrawOp> MakeOvalOp(GrPaint&&,
GrAA,
const SkMatrix&, const SkMatrix&,
const SkRect& oval, const SkRect& oval,
const SkStrokeRec&, const SkStrokeRec&,
const GrShaderCaps*); const GrShaderCaps*);
static std::unique_ptr<GrDrawOp> MakeCoverageRRectOp(GrPaint&&, static std::unique_ptr<GrDrawOp> MakeRRectOp(GrPaint&&,
GrAA,
const SkMatrix&, const SkMatrix&,
const SkRRect&, const SkRRect&,
const SkStrokeRec&, const SkStrokeRec&,
const GrShaderCaps*); const GrShaderCaps*);
static std::unique_ptr<GrDrawOp> MakeCoverageArcOp(GrPaint&&, static std::unique_ptr<GrDrawOp> MakeArcOp(GrPaint&&,
GrAA,
const SkMatrix&, const SkMatrix&,
const SkRect& oval, const SkRect& oval,
SkScalar startAngle, SkScalar startAngle,

View File

@ -580,8 +580,7 @@ void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
// The run's "font" overrides the anti-aliasing of the passed in SkPaint! // The run's "font" overrides the anti-aliasing of the passed in SkPaint!
GrAAType aaType = GrChooseAAType(this->aa(), renderTargetContext->fsaaType(), GrAAType aaType = GrChooseAAType(this->aa(), renderTargetContext->fsaaType(),
GrAllowMixedSamples::kYes, GrAllowNonAABinaryCoverage::kNo, GrAllowMixedSamples::kYes, *renderTargetContext->caps());
nullptr, *renderTargetContext->caps());
std::unique_ptr<GrDrawOp> op = GrDrawPathRangeOp::Make( std::unique_ptr<GrDrawOp> op = GrDrawPathRangeOp::Make(
viewMatrix, fTextRatio, fTextInverseRatio * x, fTextInverseRatio * y, viewMatrix, fTextRatio, fTextInverseRatio * x, fTextInverseRatio * y,