CCPR: Rename GrCCPR* -> GrCC*

Also runs clang-format on the files that don't have special shader
builder styling.

Bug: skia:
Change-Id: I4a67569a7c8472acfb9200644c913844a92e3b2d
Reviewed-on: https://skia-review.googlesource.com/92083
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Chris Dalton 2018-01-08 17:21:41 -05:00 committed by Skia Commit-Bot
parent c35959f3cb
commit 383a2ef6ed
26 changed files with 562 additions and 593 deletions

View File

@ -296,26 +296,26 @@ skia_gpu_sources = [
"$_src/gpu/ops/GrTextureOp.h",
# coverage counting path renderer
"$_src/gpu/ccpr/GrCCPRAtlas.cpp",
"$_src/gpu/ccpr/GrCCPRAtlas.h",
"$_src/gpu/ccpr/GrCCPRClipProcessor.cpp",
"$_src/gpu/ccpr/GrCCPRClipProcessor.h",
"$_src/gpu/ccpr/GrCCPRCoverageOp.cpp",
"$_src/gpu/ccpr/GrCCPRCoverageOp.h",
"$_src/gpu/ccpr/GrCCPRCoverageProcessor.cpp",
"$_src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp",
"$_src/gpu/ccpr/GrCCPRCoverageProcessor_VSImpl.cpp",
"$_src/gpu/ccpr/GrCCPRCoverageProcessor.h",
"$_src/gpu/ccpr/GrCCPRCubicShader.cpp",
"$_src/gpu/ccpr/GrCCPRCubicShader.h",
"$_src/gpu/ccpr/GrCCPRGeometry.cpp",
"$_src/gpu/ccpr/GrCCPRGeometry.h",
"$_src/gpu/ccpr/GrCCPRPathProcessor.cpp",
"$_src/gpu/ccpr/GrCCPRPathProcessor.h",
"$_src/gpu/ccpr/GrCCPRQuadraticShader.cpp",
"$_src/gpu/ccpr/GrCCPRQuadraticShader.h",
"$_src/gpu/ccpr/GrCCPRTriangleShader.cpp",
"$_src/gpu/ccpr/GrCCPRTriangleShader.h",
"$_src/gpu/ccpr/GrCCAtlas.cpp",
"$_src/gpu/ccpr/GrCCAtlas.h",
"$_src/gpu/ccpr/GrCCClipProcessor.cpp",
"$_src/gpu/ccpr/GrCCClipProcessor.h",
"$_src/gpu/ccpr/GrCCCoverageOp.cpp",
"$_src/gpu/ccpr/GrCCCoverageOp.h",
"$_src/gpu/ccpr/GrCCCoverageProcessor.cpp",
"$_src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp",
"$_src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp",
"$_src/gpu/ccpr/GrCCCoverageProcessor.h",
"$_src/gpu/ccpr/GrCCCubicShader.cpp",
"$_src/gpu/ccpr/GrCCCubicShader.h",
"$_src/gpu/ccpr/GrCCGeometry.cpp",
"$_src/gpu/ccpr/GrCCGeometry.h",
"$_src/gpu/ccpr/GrCCPathProcessor.cpp",
"$_src/gpu/ccpr/GrCCPathProcessor.h",
"$_src/gpu/ccpr/GrCCQuadraticShader.cpp",
"$_src/gpu/ccpr/GrCCQuadraticShader.h",
"$_src/gpu/ccpr/GrCCTriangleShader.cpp",
"$_src/gpu/ccpr/GrCCTriangleShader.h",
"$_src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp",
"$_src/gpu/ccpr/GrCoverageCountingPathRenderer.h",

View File

@ -21,18 +21,18 @@
#include "SkPath.h"
#include "SkRectPriv.h"
#include "SkView.h"
#include "ccpr/GrCCPRCoverageProcessor.h"
#include "ccpr/GrCCPRGeometry.h"
#include "ccpr/GrCCCoverageProcessor.h"
#include "ccpr/GrCCGeometry.h"
#include "gl/GrGLGpu.cpp"
#include "ops/GrDrawOp.h"
using TriangleInstance = GrCCPRCoverageProcessor::TriangleInstance;
using CubicInstance = GrCCPRCoverageProcessor::CubicInstance;
using RenderPass = GrCCPRCoverageProcessor::RenderPass;
using TriangleInstance = GrCCCoverageProcessor::TriangleInstance;
using CubicInstance = GrCCCoverageProcessor::CubicInstance;
using RenderPass = GrCCCoverageProcessor::RenderPass;
static constexpr float kDebugBloat = 40;
static int is_quadratic(RenderPass pass) {
static int is_quadratic(RenderPass pass) {
return pass == RenderPass::kQuadraticHulls || pass == RenderPass::kQuadraticCorners;
}
@ -55,9 +55,7 @@ private:
class Click;
class Op;
void updateAndInval() {
this->updateGpuData();
}
void updateAndInval() { this->updateGpuData(); }
void updateGpuData();
@ -66,11 +64,7 @@ private:
SkMatrix fCubicKLM;
SkPoint fPoints[4] = {
{100.05f, 100.05f},
{400.75f, 100.05f},
{400.75f, 300.95f},
{100.05f, 300.95f}
};
{100.05f, 100.05f}, {400.75f, 100.05f}, {400.75f, 300.95f}, {100.05f, 300.95f}};
SkTArray<TriangleInstance> fTriangleInstances;
SkTArray<CubicInstance> fCubicInstances;
@ -82,9 +76,7 @@ class CCPRGeometryView::Op : public GrDrawOp {
DEFINE_OP_CLASS_ID
public:
Op(CCPRGeometryView* view)
: INHERITED(ClassID())
, fView(view) {
Op(CCPRGeometryView* view) : INHERITED(ClassID()), fView(view) {
this->setBounds(SkRectPriv::MakeLargest(), GrOp::HasAABloat::kNo, GrOp::IsZeroArea::kNo);
}
@ -110,11 +102,11 @@ static void draw_klm_line(int w, int h, SkCanvas* canvas, const SkScalar line[3]
if (SkScalarAbs(line[1]) > SkScalarAbs(line[0])) {
// Draw from vertical edge to vertical edge.
p1 = {0, -line[2] / line[1]};
p2 = {(SkScalar) w, (-line[2] - w * line[0]) / line[1]};
p2 = {(SkScalar)w, (-line[2] - w * line[0]) / line[1]};
} else {
// Draw from horizontal edge to horizontal edge.
p1 = {-line[2] / line[0], 0};
p2 = {(-line[2] - h * line[1]) / line[0], (SkScalar) h};
p2 = {(-line[2] - h * line[1]) / line[0], (SkScalar)h};
}
SkPaint linePaint;
@ -132,7 +124,7 @@ void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
SkPath outline;
outline.moveTo(fPoints[0]);
if (GrCCPRCoverageProcessor::RenderPassIsCubic(fRenderPass)) {
if (GrCCCoverageProcessor::RenderPassIsCubic(fRenderPass)) {
outline.cubicTo(fPoints[1], fPoints[2], fPoints[3]);
} else if (is_quadratic(fRenderPass)) {
outline.quadTo(fPoints[1], fPoints[3]);
@ -164,11 +156,10 @@ void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
#endif
SkString caption;
if (GrRenderTargetContext* rtc =
canvas->internal_private_accessTopLayerRenderTargetContext()) {
if (GrRenderTargetContext* rtc = canvas->internal_private_accessTopLayerRenderTargetContext()) {
rtc->priv().testingOnly_addDrawOp(skstd::make_unique<Op>(this));
caption.appendf("RenderPass_%s", GrCCPRCoverageProcessor::RenderPassName(fRenderPass));
if (GrCCPRCoverageProcessor::RenderPassIsCubic(fRenderPass)) {
caption.appendf("RenderPass_%s", GrCCCoverageProcessor::RenderPassName(fRenderPass));
if (GrCCCoverageProcessor::RenderPassIsCubic(fRenderPass)) {
caption.appendf(" (%s)", SkCubicTypeName(fCubicType));
}
} else {
@ -180,7 +171,7 @@ void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
pointsPaint.setStrokeWidth(8);
pointsPaint.setAntiAlias(true);
if (GrCCPRCoverageProcessor::RenderPassIsCubic(fRenderPass)) {
if (GrCCCoverageProcessor::RenderPassIsCubic(fRenderPass)) {
int w = this->width(), h = this->height();
canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, fPoints, pointsPaint);
draw_klm_line(w, h, canvas, &fCubicKLM[0], SK_ColorYELLOW);
@ -202,46 +193,47 @@ void CCPRGeometryView::updateGpuData() {
fTriangleInstances.reset();
fCubicInstances.reset();
if (GrCCPRCoverageProcessor::RenderPassIsCubic(fRenderPass)) {
if (GrCCCoverageProcessor::RenderPassIsCubic(fRenderPass)) {
double t[2], s[2];
fCubicType = GrPathUtils::getCubicKLM(fPoints, &fCubicKLM, t, s);
GrCCPRGeometry geometry;
GrCCGeometry geometry;
geometry.beginContour(fPoints[0]);
geometry.cubicTo(fPoints[1], fPoints[2], fPoints[3], kDebugBloat/2, kDebugBloat/2);
geometry.cubicTo(fPoints[1], fPoints[2], fPoints[3], kDebugBloat / 2, kDebugBloat / 2);
geometry.endContour();
int ptsIdx = 0;
for (GrCCPRGeometry::Verb verb : geometry.verbs()) {
for (GrCCGeometry::Verb verb : geometry.verbs()) {
switch (verb) {
case GrCCPRGeometry::Verb::kLineTo:
case GrCCGeometry::Verb::kLineTo:
++ptsIdx;
continue;
case GrCCPRGeometry::Verb::kMonotonicQuadraticTo:
case GrCCGeometry::Verb::kMonotonicQuadraticTo:
ptsIdx += 2;
continue;
case GrCCPRGeometry::Verb::kMonotonicCubicTo:
case GrCCGeometry::Verb::kMonotonicCubicTo:
fCubicInstances.push_back().set(&geometry.points()[ptsIdx], 0, 0);
ptsIdx += 3;
continue;
default: continue;
default:
continue;
}
}
} else if (is_quadratic(fRenderPass)) {
GrCCPRGeometry geometry;
GrCCGeometry geometry;
geometry.beginContour(fPoints[0]);
geometry.quadraticTo(fPoints[1], fPoints[3]);
geometry.endContour();
int ptsIdx = 0;
for (GrCCPRGeometry::Verb verb : geometry.verbs()) {
if (GrCCPRGeometry::Verb::kBeginContour == verb ||
GrCCPRGeometry::Verb::kEndOpenContour == verb ||
GrCCPRGeometry::Verb::kEndClosedContour == verb) {
for (GrCCGeometry::Verb verb : geometry.verbs()) {
if (GrCCGeometry::Verb::kBeginContour == verb ||
GrCCGeometry::Verb::kEndOpenContour == verb ||
GrCCGeometry::Verb::kEndClosedContour == verb) {
continue;
}
if (GrCCPRGeometry::Verb::kLineTo == verb) {
if (GrCCGeometry::Verb::kLineTo == verb) {
++ptsIdx;
continue;
}
SkASSERT(GrCCPRGeometry::Verb::kMonotonicQuadraticTo == verb);
SkASSERT(GrCCGeometry::Verb::kMonotonicQuadraticTo == verb);
fTriangleInstances.push_back().set(&geometry.points()[ptsIdx], Sk2f(0, 0));
ptsIdx += 2;
}
@ -253,34 +245,34 @@ void CCPRGeometryView::updateGpuData() {
void CCPRGeometryView::Op::onExecute(GrOpFlushState* state) {
GrResourceProvider* rp = state->resourceProvider();
GrContext* context = state->gpu()->getContext();
GrGLGpu* glGpu = kOpenGL_GrBackend == context->contextPriv().getBackend() ?
static_cast<GrGLGpu*>(state->gpu()) : nullptr;
GrGLGpu* glGpu = kOpenGL_GrBackend == context->contextPriv().getBackend()
? static_cast<GrGLGpu*>(state->gpu())
: nullptr;
if (!GrCCPRCoverageProcessor::DoesRenderPass(fView->fRenderPass, *state->caps().shaderCaps())) {
if (!GrCCCoverageProcessor::DoesRenderPass(fView->fRenderPass, *state->caps().shaderCaps())) {
return;
}
GrCCPRCoverageProcessor proc(rp, fView->fRenderPass, *state->caps().shaderCaps());
GrCCCoverageProcessor proc(rp, fView->fRenderPass, *state->caps().shaderCaps());
SkDEBUGCODE(proc.enableDebugVisualizations(kDebugBloat);)
SkSTArray<1, GrMesh> mesh;
if (GrCCPRCoverageProcessor::RenderPassIsCubic(fView->fRenderPass)) {
sk_sp<GrBuffer> instBuff(rp->createBuffer(fView->fCubicInstances.count() *
sizeof(CubicInstance), kVertex_GrBufferType,
kDynamic_GrAccessPattern,
GrResourceProvider::kNoPendingIO_Flag |
GrResourceProvider::kRequireGpuMemory_Flag,
fView->fCubicInstances.begin()));
SkSTArray<1, GrMesh>
mesh;
if (GrCCCoverageProcessor::RenderPassIsCubic(fView->fRenderPass)) {
sk_sp<GrBuffer> instBuff(rp->createBuffer(
fView->fCubicInstances.count() * sizeof(CubicInstance), kVertex_GrBufferType,
kDynamic_GrAccessPattern,
GrResourceProvider::kNoPendingIO_Flag | GrResourceProvider::kRequireGpuMemory_Flag,
fView->fCubicInstances.begin()));
if (!fView->fCubicInstances.empty() && instBuff) {
proc.appendMesh(instBuff.get(), fView->fCubicInstances.count(), 0, &mesh);
}
} else {
sk_sp<GrBuffer> instBuff(rp->createBuffer(fView->fTriangleInstances.count() *
sizeof(TriangleInstance), kVertex_GrBufferType,
kDynamic_GrAccessPattern,
GrResourceProvider::kNoPendingIO_Flag |
GrResourceProvider::kRequireGpuMemory_Flag,
fView->fTriangleInstances.begin()));
sk_sp<GrBuffer> instBuff(rp->createBuffer(
fView->fTriangleInstances.count() * sizeof(TriangleInstance), kVertex_GrBufferType,
kDynamic_GrAccessPattern,
GrResourceProvider::kNoPendingIO_Flag | GrResourceProvider::kRequireGpuMemory_Flag,
fView->fTriangleInstances.begin()));
if (!fView->fTriangleInstances.empty() && instBuff) {
proc.appendMesh(instBuff.get(), fView->fTriangleInstances.count(), 0, &mesh);
}
@ -320,7 +312,7 @@ public:
}
private:
void dragPoint(SkPoint points[], int idx) {
void dragPoint(SkPoint points[], int idx) {
SkIPoint delta = fICurr - fIPrev;
points[idx] += SkPoint::Make(delta.x(), delta.y());
}
@ -330,7 +322,7 @@ private:
SkView::Click* CCPRGeometryView::onFindClickHandler(SkScalar x, SkScalar y, unsigned) {
for (int i = 0; i < 4; ++i) {
if (!GrCCPRCoverageProcessor::RenderPassIsCubic(fRenderPass) && 2 == i) {
if (!GrCCCoverageProcessor::RenderPassIsCubic(fRenderPass) && 2 == i) {
continue;
}
if (fabs(x - fPoints[i].x()) < 20 && fabsf(y - fPoints[i].y()) < 20) {
@ -341,7 +333,7 @@ SkView::Click* CCPRGeometryView::onFindClickHandler(SkScalar x, SkScalar y, unsi
}
bool CCPRGeometryView::onClick(SampleView::Click* click) {
Click* myClick = (Click*) click;
Click* myClick = (Click*)click;
myClick->doClick(fPoints);
this->updateAndInval();
return true;
@ -372,6 +364,6 @@ bool CCPRGeometryView::onQuery(SkEvent* evt) {
return this->INHERITED::onQuery(evt);
}
DEF_SAMPLE( return new CCPRGeometryView; )
DEF_SAMPLE(return new CCPRGeometryView;)
#endif // SK_SUPPORT_GPU
#endif // SK_SUPPORT_GPU

View File

@ -67,7 +67,6 @@ public:
enum ClassID {
kBigKeyProcessor_ClassID,
kBlockInputFragmentProcessor_ClassID,
kCCPRClipProcessor_ClassID,
kCircleGeometryProcessor_ClassID,
kCircularRRectEffect_ClassID,
kColorMatrixEffect_ClassID,
@ -91,8 +90,9 @@ public:
kGrBicubicEffect_ClassID,
kGrBitmapTextGeoProc_ClassID,
kGrBlurredEdgeFragmentProcessor_ClassID,
kGrCCPRCoverageProcessor_ClassID,
kGrCCPRPathProcessor_ClassID,
kGrCCClipProcessor_ClassID,
kGrCCCoverageProcessor_ClassID,
kGrCCPathProcessor_ClassID,
kGrCircleBlurFragmentProcessor_ClassID,
kGrCircleEffect_ClassID,
kGrColorSpaceXformEffect_ClassID,

View File

@ -409,7 +409,7 @@ private:
friend class GrMSAAPathRenderer; // for access to add[Mesh]DrawOp
friend class GrStencilAndCoverPathRenderer; // for access to add[Mesh]DrawOp
friend class GrTessellatingPathRenderer; // for access to add[Mesh]DrawOp
friend class GrCCPRAtlas; // for access to addDrawOp
friend class GrCCAtlas; // for access to addDrawOp
friend class GrCoverageCountingPathRenderer; // for access to addDrawOp
// for a unit test
friend void test_draw_op(GrRenderTargetContext*, std::unique_ptr<GrFragmentProcessor>,

View File

@ -5,24 +5,22 @@
* found in the LICENSE file.
*/
#include "GrCCPRAtlas.h"
#include "GrCCAtlas.h"
#include "GrOnFlushResourceProvider.h"
#include "GrClip.h"
#include "GrOnFlushResourceProvider.h"
#include "GrRectanizer_skyline.h"
#include "GrTextureProxy.h"
#include "GrRenderTargetContext.h"
#include "GrTextureProxy.h"
#include "SkMakeUnique.h"
#include "SkMathPriv.h"
#include "ccpr/GrCCPRCoverageProcessor.h"
#include "ccpr/GrCCCoverageProcessor.h"
#include "ops/GrDrawOp.h"
class GrCCPRAtlas::Node {
class GrCCAtlas::Node {
public:
Node(std::unique_ptr<Node> previous, int l, int t, int r, int b)
: fPrevious(std::move(previous))
, fX(l), fY(t)
, fRectanizer(r - l, b - t) {}
: fPrevious(std::move(previous)), fX(l), fY(t), fRectanizer(r - l, b - t) {}
Node* previous() const { return fPrevious.get(); }
@ -38,14 +36,13 @@ public:
}
private:
const std::unique_ptr<Node> fPrevious;
const int fX, fY;
GrRectanizerSkyline fRectanizer;
const std::unique_ptr<Node> fPrevious;
const int fX, fY;
GrRectanizerSkyline fRectanizer;
};
GrCCPRAtlas::GrCCPRAtlas(const GrCaps& caps, int minWidth, int minHeight)
: fMaxAtlasSize(caps.maxRenderTargetSize())
, fDrawBounds{0, 0} {
GrCCAtlas::GrCCAtlas(const GrCaps& caps, int minWidth, int minHeight)
: fMaxAtlasSize(caps.maxRenderTargetSize()), fDrawBounds{0, 0} {
SkASSERT(fMaxAtlasSize <= caps.maxTextureSize());
SkASSERT(SkTMax(minWidth, minHeight) <= fMaxAtlasSize);
int initialSize = GrNextPow2(SkTMax(minWidth, minHeight));
@ -55,10 +52,9 @@ GrCCPRAtlas::GrCCPRAtlas(const GrCaps& caps, int minWidth, int minHeight)
fTopNode = skstd::make_unique<Node>(nullptr, 0, 0, initialSize, initialSize);
}
GrCCPRAtlas::~GrCCPRAtlas() {
}
GrCCAtlas::~GrCCAtlas() {}
bool GrCCPRAtlas::addRect(int w, int h, SkIPoint16* loc) {
bool GrCCAtlas::addRect(int w, int h, SkIPoint16* loc) {
// This can't be called anymore once finalize() has been called.
SkASSERT(!fTextureProxy);
@ -71,7 +67,7 @@ bool GrCCPRAtlas::addRect(int w, int h, SkIPoint16* loc) {
return true;
}
bool GrCCPRAtlas::internalPlaceRect(int w, int h, SkIPoint16* loc) {
bool GrCCAtlas::internalPlaceRect(int w, int h, SkIPoint16* loc) {
SkASSERT(SkTMax(w, h) < fMaxAtlasSize);
for (Node* node = fTopNode.get(); node; node = node->previous()) {
@ -100,8 +96,8 @@ bool GrCCPRAtlas::internalPlaceRect(int w, int h, SkIPoint16* loc) {
return true;
}
sk_sp<GrRenderTargetContext> GrCCPRAtlas::finalize(GrOnFlushResourceProvider* onFlushRP,
std::unique_ptr<GrDrawOp> atlasOp) {
sk_sp<GrRenderTargetContext> GrCCAtlas::finalize(
GrOnFlushResourceProvider* onFlushRP, std::unique_ptr<GrDrawOp> atlasOp) {
SkASSERT(!fTextureProxy);
GrSurfaceDesc desc;

View File

@ -5,8 +5,8 @@
* found in the LICENSE file.
*/
#ifndef GrCCPRAtlas_DEFINED
#define GrCCPRAtlas_DEFINED
#ifndef GrCCAtlas_DEFINED
#define GrCCAtlas_DEFINED
#include "SkRefCnt.h"
#include "SkSize.h"
@ -23,18 +23,18 @@ struct SkIPoint16;
* dependent max texture size. When finalized, it also creates and stores a GrTextureProxy for the
* underlying atlas.
*/
class GrCCPRAtlas {
class GrCCAtlas {
public:
static constexpr int kMinSize = 1024;
GrCCPRAtlas(const GrCaps&, int minWidth, int minHeight);
~GrCCPRAtlas();
GrCCAtlas(const GrCaps&, int minWidth, int minHeight);
~GrCCAtlas();
bool addRect(int devWidth, int devHeight, SkIPoint16* loc);
const SkISize& drawBounds() { return fDrawBounds; }
sk_sp<GrRenderTargetContext> SK_WARN_UNUSED_RESULT finalize(GrOnFlushResourceProvider*,
std::unique_ptr<GrDrawOp> atlasOp);
sk_sp<GrRenderTargetContext> SK_WARN_UNUSED_RESULT
finalize(GrOnFlushResourceProvider*, std::unique_ptr<GrDrawOp> atlasOp);
GrTextureProxy* textureProxy() const { return fTextureProxy.get(); }
@ -43,14 +43,14 @@ private:
bool internalPlaceRect(int w, int h, SkIPoint16* loc);
const int fMaxAtlasSize;
const int fMaxAtlasSize;
int fWidth;
int fHeight;
SkISize fDrawBounds;
std::unique_ptr<Node> fTopNode;
int fWidth;
int fHeight;
SkISize fDrawBounds;
std::unique_ptr<Node> fTopNode;
sk_sp<GrTextureProxy> fTextureProxy;
sk_sp<GrTextureProxy> fTextureProxy;
};
#endif

View File

@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
#include "GrCCPRClipProcessor.h"
#include "GrCCClipProcessor.h"
#include "GrTexture.h"
#include "GrTextureProxy.h"
@ -13,9 +13,9 @@
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
GrCCPRClipProcessor::GrCCPRClipProcessor(const ClipPath* clipPath, MustCheckBounds mustCheckBounds,
GrCCClipProcessor::GrCCClipProcessor(const ClipPath* clipPath, MustCheckBounds mustCheckBounds,
SkPath::FillType overrideFillType)
: INHERITED(kCCPRClipProcessor_ClassID, kCompatibleWithCoverageAsAlpha_OptimizationFlag)
: INHERITED(kGrCCClipProcessor_ClassID, kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, fClipPath(clipPath)
, fMustCheckBounds((bool)mustCheckBounds)
, fOverrideFillType(overrideFillType)
@ -24,18 +24,17 @@ GrCCPRClipProcessor::GrCCPRClipProcessor(const ClipPath* clipPath, MustCheckBoun
this->addTextureSampler(&fAtlasAccess);
}
std::unique_ptr<GrFragmentProcessor> GrCCPRClipProcessor::clone() const {
return skstd::make_unique<GrCCPRClipProcessor>(fClipPath, MustCheckBounds(fMustCheckBounds),
std::unique_ptr<GrFragmentProcessor> GrCCClipProcessor::clone() const {
return skstd::make_unique<GrCCClipProcessor>(fClipPath, MustCheckBounds(fMustCheckBounds),
fOverrideFillType);
}
void GrCCPRClipProcessor::onGetGLSLProcessorKey(const GrShaderCaps&,
GrProcessorKeyBuilder* b) const {
void GrCCClipProcessor::onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const {
b->add32((fOverrideFillType << 1) | (int)fMustCheckBounds);
}
bool GrCCPRClipProcessor::onIsEqual(const GrFragmentProcessor& fp) const {
const GrCCPRClipProcessor& that = fp.cast<GrCCPRClipProcessor>();
bool GrCCClipProcessor::onIsEqual(const GrFragmentProcessor& fp) const {
const GrCCClipProcessor& that = fp.cast<GrCCClipProcessor>();
// Each ClipPath path has a unique atlas proxy, so hasSameSamplersAndAccesses should have
// already weeded out FPs with different ClipPaths.
SkASSERT(that.fClipPath->deviceSpacePath().getGenerationID() ==
@ -43,10 +42,10 @@ bool GrCCPRClipProcessor::onIsEqual(const GrFragmentProcessor& fp) const {
return that.fOverrideFillType == fOverrideFillType;
}
class GrCCPRClipProcessor::Impl : public GrGLSLFragmentProcessor {
class GrCCClipProcessor::Impl : public GrGLSLFragmentProcessor {
public:
void emitCode(EmitArgs& args) override {
const GrCCPRClipProcessor& proc = args.fFp.cast<GrCCPRClipProcessor>();
const GrCCClipProcessor& proc = args.fFp.cast<GrCCClipProcessor>();
GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
@ -93,7 +92,7 @@ public:
void onSetData(const GrGLSLProgramDataManager& pdman,
const GrFragmentProcessor& fp) override {
const GrCCPRClipProcessor& proc = fp.cast<GrCCPRClipProcessor>();
const GrCCClipProcessor& proc = fp.cast<GrCCClipProcessor>();
if (proc.fMustCheckBounds) {
const SkRect pathIBounds = SkRect::Make(proc.fClipPath->pathDevIBounds());
pdman.set4f(fPathIBoundsUniform, pathIBounds.left(), pathIBounds.top(),
@ -109,6 +108,6 @@ private:
UniformHandle fAtlasTransformUniform;
};
GrGLSLFragmentProcessor* GrCCPRClipProcessor::onCreateGLSLInstance() const {
GrGLSLFragmentProcessor* GrCCClipProcessor::onCreateGLSLInstance() const {
return new Impl();
}

View File

@ -5,13 +5,13 @@
* found in the LICENSE file.
*/
#ifndef GrCCPRClipProcessor_DEFINED
#define GrCCPRClipProcessor_DEFINED
#ifndef GrCCClipProcessor_DEFINED
#define GrCCClipProcessor_DEFINED
#include "GrFragmentProcessor.h"
#include "ccpr/GrCoverageCountingPathRenderer.h"
class GrCCPRClipProcessor : public GrFragmentProcessor {
class GrCCClipProcessor : public GrFragmentProcessor {
public:
using ClipPath = GrCoverageCountingPathRenderer::ClipPath;
@ -20,9 +20,9 @@ public:
kYes = true
};
GrCCPRClipProcessor(const ClipPath*, MustCheckBounds, SkPath::FillType overrideFillType);
GrCCClipProcessor(const ClipPath*, MustCheckBounds, SkPath::FillType overrideFillType);
const char* name() const override { return "GrCCPRClipProcessor"; }
const char* name() const override { return "GrCCClipProcessor"; }
std::unique_ptr<GrFragmentProcessor> clone() const override;
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
bool onIsEqual(const GrFragmentProcessor&) const override;

View File

@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
#include "GrCCPRCoverageOp.h"
#include "GrCCCoverageOp.h"
#include "GrCaps.h"
#include "GrGpuCommandBuffer.h"
@ -15,13 +15,13 @@
#include "SkPath.h"
#include "SkPathPriv.h"
#include "SkPoint.h"
#include "ccpr/GrCCPRGeometry.h"
#include "ccpr/GrCCGeometry.h"
using TriangleInstance = GrCCPRCoverageProcessor::TriangleInstance;
using CubicInstance = GrCCPRCoverageProcessor::CubicInstance;
using TriangleInstance = GrCCCoverageProcessor::TriangleInstance;
using CubicInstance = GrCCCoverageProcessor::CubicInstance;
void GrCCPRCoverageOpsBuilder::parsePath(const SkMatrix& m, const SkPath& path, SkRect* devBounds,
SkRect* devBounds45) {
void GrCCCoverageOpsBuilder::parsePath(const SkMatrix& m, const SkPath& path, SkRect* devBounds,
SkRect* devBounds45) {
const SkPoint* pts = SkPathPriv::PointData(path);
int numPts = path.countPoints();
SkASSERT(numPts + 1 <= fLocalDevPtsBuffer.count());
@ -69,19 +69,19 @@ void GrCCPRCoverageOpsBuilder::parsePath(const SkMatrix& m, const SkPath& path,
SkPoint topLeftPts[2], bottomRightPts[2];
topLeft.store(topLeftPts);
bottomRight.store(bottomRightPts);
devBounds->setLTRB(topLeftPts[0].x(), topLeftPts[0].y(),
bottomRightPts[0].x(), bottomRightPts[0].y());
devBounds45->setLTRB(topLeftPts[1].x(), topLeftPts[1].y(),
bottomRightPts[1].x(), bottomRightPts[1].y());
devBounds->setLTRB(topLeftPts[0].x(), topLeftPts[0].y(), bottomRightPts[0].x(),
bottomRightPts[0].y());
devBounds45->setLTRB(topLeftPts[1].x(), topLeftPts[1].y(), bottomRightPts[1].x(),
bottomRightPts[1].y());
this->parsePath(path, fLocalDevPtsBuffer.get());
}
void GrCCPRCoverageOpsBuilder::parseDeviceSpacePath(const SkPath& deviceSpacePath) {
void GrCCCoverageOpsBuilder::parseDeviceSpacePath(const SkPath& deviceSpacePath) {
this->parsePath(deviceSpacePath, SkPathPriv::PointData(deviceSpacePath));
}
void GrCCPRCoverageOpsBuilder::parsePath(const SkPath& path, const SkPoint* deviceSpacePts) {
void GrCCCoverageOpsBuilder::parsePath(const SkPath& path, const SkPoint* deviceSpacePts) {
SkASSERT(!fParsingPath);
SkDEBUGCODE(fParsingPath = true);
SkASSERT(path.isEmpty() || deviceSpacePts);
@ -134,36 +134,30 @@ void GrCCPRCoverageOpsBuilder::parsePath(const SkPath& path, const SkPoint* devi
this->endContourIfNeeded(insideContour);
}
void GrCCPRCoverageOpsBuilder::endContourIfNeeded(bool insideContour) {
void GrCCCoverageOpsBuilder::endContourIfNeeded(bool insideContour) {
if (insideContour) {
fCurrPathTallies += fGeometry.endContour();
}
}
void GrCCPRCoverageOpsBuilder::saveParsedPath(ScissorMode scissorMode,
const SkIRect& clippedDevIBounds,
int16_t atlasOffsetX, int16_t atlasOffsetY) {
void GrCCCoverageOpsBuilder::saveParsedPath(ScissorMode scissorMode,
const SkIRect& clippedDevIBounds, int16_t atlasOffsetX,
int16_t atlasOffsetY) {
SkASSERT(fParsingPath);
fPathsInfo.push_back() = {
scissorMode,
atlasOffsetX, atlasOffsetY,
std::move(fTerminatingOp)
};
fPathsInfo.push_back() = {scissorMode, atlasOffsetX, atlasOffsetY, std::move(fTerminatingOp)};
fTallies[(int)scissorMode] += fCurrPathTallies;
if (ScissorMode::kScissored == scissorMode) {
fScissorBatches.push_back() = {
fCurrPathTallies,
clippedDevIBounds.makeOffset(atlasOffsetX, atlasOffsetY)
};
fScissorBatches.push_back() = {fCurrPathTallies,
clippedDevIBounds.makeOffset(atlasOffsetX, atlasOffsetY)};
}
SkDEBUGCODE(fParsingPath = false);
}
void GrCCPRCoverageOpsBuilder::discardParsedPath() {
void GrCCCoverageOpsBuilder::discardParsedPath() {
SkASSERT(fParsingPath);
// The code will still work whether or not the below assertion is true. It is just unlikely that
@ -175,9 +169,9 @@ void GrCCPRCoverageOpsBuilder::discardParsedPath() {
SkDEBUGCODE(fParsingPath = false);
}
void GrCCPRCoverageOpsBuilder::emitOp(SkISize drawBounds) {
void GrCCCoverageOpsBuilder::emitOp(SkISize drawBounds) {
SkASSERT(!fTerminatingOp);
fTerminatingOp.reset(new GrCCPRCoverageOp(std::move(fScissorBatches), drawBounds));
fTerminatingOp.reset(new GrCCCoverageOp(std::move(fScissorBatches), drawBounds));
SkASSERT(fScissorBatches.empty());
}
@ -204,8 +198,7 @@ static TriangleInstance* emit_recursive_fan(const SkTArray<SkPoint, true>& pts,
const int32_t oneThirdCount = indexCount / 3;
const int32_t twoThirdsCount = (2 * indexCount) / 3;
out++->set(pts[indices[firstIndex]],
pts[indices[firstIndex + oneThirdCount]],
out++->set(pts[indices[firstIndex]], pts[indices[firstIndex + oneThirdCount]],
pts[indices[firstIndex + twoThirdsCount]], atlasOffset);
out = emit_recursive_fan(pts, indices, firstIndex, oneThirdCount + 1, atlasOffset, out);
@ -222,8 +215,8 @@ static TriangleInstance* emit_recursive_fan(const SkTArray<SkPoint, true>& pts,
return out;
}
bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP,
SkTArray<std::unique_ptr<GrCCPRCoverageOp>>* ops) {
bool GrCCCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP,
SkTArray<std::unique_ptr<GrCCCoverageOp>>* ops) {
SkASSERT(!fParsingPath);
// Here we build a single instance buffer to share with every draw call from every CoverageOP we
@ -252,14 +245,14 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP,
// Cubics (loops and serpentines) view the same instance buffer as an array of CubicInstance[].
// So, reinterpreting the instance data as CubicInstance[], we start them on the first index
// that will not overwrite previous TriangleInstance data.
int cubicBaseIdx = GR_CT_DIV_ROUND_UP(triEndIdx * sizeof(TriangleInstance),
sizeof(CubicInstance));
int cubicBaseIdx =
GR_CT_DIV_ROUND_UP(triEndIdx * sizeof(TriangleInstance), sizeof(CubicInstance));
baseInstances[0].fCubics = cubicBaseIdx;
baseInstances[1].fCubics = baseInstances[0].fCubics + fTallies[0].fCubics;
int cubicEndIdx = baseInstances[1].fCubics + fTallies[1].fCubics;
sk_sp<GrBuffer> instanceBuffer = onFlushRP->makeBuffer(kVertex_GrBufferType,
cubicEndIdx * sizeof(CubicInstance));
sk_sp<GrBuffer> instanceBuffer =
onFlushRP->makeBuffer(kVertex_GrBufferType, cubicEndIdx * sizeof(CubicInstance));
if (!instanceBuffer) {
return false;
}
@ -285,9 +278,9 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP,
const SkTArray<SkPoint, true>& pts = fGeometry.points();
// Expand the ccpr verbs into GPU instance buffers.
for (GrCCPRGeometry::Verb verb : fGeometry.verbs()) {
for (GrCCGeometry::Verb verb : fGeometry.verbs()) {
switch (verb) {
case GrCCPRGeometry::Verb::kBeginPath:
case GrCCGeometry::Verb::kBeginPath:
SkASSERT(currFan.empty());
currIndices = &instanceIndices[(int)currPathInfo->fScissorMode];
atlasOffsetX = static_cast<float>(currPathInfo->fAtlasOffsetX);
@ -308,42 +301,42 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP,
++currPathInfo;
continue;
case GrCCPRGeometry::Verb::kBeginContour:
case GrCCGeometry::Verb::kBeginContour:
SkASSERT(currFan.empty());
currFan.push_back(++ptsIdx);
continue;
case GrCCPRGeometry::Verb::kLineTo:
case GrCCGeometry::Verb::kLineTo:
SkASSERT(!currFan.empty());
currFan.push_back(++ptsIdx);
continue;
case GrCCPRGeometry::Verb::kMonotonicQuadraticTo:
case GrCCGeometry::Verb::kMonotonicQuadraticTo:
SkASSERT(!currFan.empty());
triangleInstanceData[currIndices->fQuadratics++].set(&pts[ptsIdx], atlasOffset);
currFan.push_back(ptsIdx += 2);
continue;
case GrCCPRGeometry::Verb::kMonotonicCubicTo:
case GrCCGeometry::Verb::kMonotonicCubicTo:
SkASSERT(!currFan.empty());
cubicInstanceData[currIndices->fCubics++].set(&pts[ptsIdx],
atlasOffsetX, atlasOffsetY);
cubicInstanceData[currIndices->fCubics++].set(&pts[ptsIdx], atlasOffsetX,
atlasOffsetY);
currFan.push_back(ptsIdx += 3);
continue;
case GrCCPRGeometry::Verb::kEndClosedContour: // endPt == startPt.
case GrCCGeometry::Verb::kEndClosedContour: // endPt == startPt.
SkASSERT(!currFan.empty());
currFan.pop_back();
// fallthru.
case GrCCPRGeometry::Verb::kEndOpenContour: // endPt != startPt.
// fallthru.
case GrCCGeometry::Verb::kEndOpenContour: // endPt != startPt.
if (currFan.count() >= 3) {
int fanSize = currFan.count();
// Reserve space for emit_recursive_fan. Technically this can grow to
// fanSize + log3(fanSize), but we approximate with log2.
currFan.push_back_n(SkNextLog2(fanSize));
SkDEBUGCODE(TriangleInstance* end =)
emit_recursive_fan(pts, currFan, 0, fanSize, atlasOffset,
triangleInstanceData + currIndices->fTriangles);
emit_recursive_fan(pts, currFan, 0, fanSize, atlasOffset,
triangleInstanceData + currIndices->fTriangles);
currIndices->fTriangles += fanSize - 2;
SkASSERT(triangleInstanceData + currIndices->fTriangles == end);
}
@ -372,9 +365,9 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP,
return true;
}
void GrCCPRCoverageOp::setInstanceBuffer(sk_sp<GrBuffer> instanceBuffer,
const PrimitiveTallies baseInstances[kNumScissorModes],
const PrimitiveTallies endInstances[kNumScissorModes]) {
void GrCCCoverageOp::setInstanceBuffer(sk_sp<GrBuffer> instanceBuffer,
const PrimitiveTallies baseInstances[kNumScissorModes],
const PrimitiveTallies endInstances[kNumScissorModes]) {
fInstanceBuffer = std::move(instanceBuffer);
fBaseInstances[0] = baseInstances[0];
fBaseInstances[1] = baseInstances[1];
@ -382,8 +375,8 @@ void GrCCPRCoverageOp::setInstanceBuffer(sk_sp<GrBuffer> instanceBuffer,
fInstanceCounts[1] = endInstances[1] - baseInstances[1];
}
void GrCCPRCoverageOp::onExecute(GrOpFlushState* flushState) {
using RenderPass = GrCCPRCoverageProcessor::RenderPass;
void GrCCCoverageOp::onExecute(GrOpFlushState* flushState) {
using RenderPass = GrCCCoverageProcessor::RenderPass;
SkASSERT(fInstanceBuffer);
@ -397,7 +390,7 @@ void GrCCPRCoverageOp::onExecute(GrOpFlushState* flushState) {
this->drawMaskPrimitives(flushState, pipeline, RenderPass::kTriangleHulls,
&PrimitiveTallies::fTriangles);
this->drawMaskPrimitives(flushState, pipeline, RenderPass::kTriangleEdges,
&PrimitiveTallies::fTriangles); // Might get skipped.
&PrimitiveTallies::fTriangles); // Might get skipped.
this->drawMaskPrimitives(flushState, pipeline, RenderPass::kTriangleCorners,
&PrimitiveTallies::fTriangles);
@ -414,21 +407,21 @@ void GrCCPRCoverageOp::onExecute(GrOpFlushState* flushState) {
&PrimitiveTallies::fCubics);
}
void GrCCPRCoverageOp::drawMaskPrimitives(GrOpFlushState* flushState, const GrPipeline& pipeline,
GrCCPRCoverageProcessor::RenderPass renderPass,
int PrimitiveTallies::* instanceType) const {
using ScissorMode = GrCCPRCoverageOpsBuilder::ScissorMode;
void GrCCCoverageOp::drawMaskPrimitives(GrOpFlushState* flushState, const GrPipeline& pipeline,
GrCCCoverageProcessor::RenderPass renderPass,
int PrimitiveTallies::*instanceType) const {
using ScissorMode = GrCCCoverageOpsBuilder::ScissorMode;
SkASSERT(pipeline.getScissorState().enabled());
if (!GrCCPRCoverageProcessor::DoesRenderPass(renderPass, *flushState->caps().shaderCaps())) {
if (!GrCCCoverageProcessor::DoesRenderPass(renderPass, *flushState->caps().shaderCaps())) {
return;
}
fMeshesScratchBuffer.reset();
fDynamicStatesScratchBuffer.reset();
GrCCPRCoverageProcessor proc(flushState->resourceProvider(), renderPass,
*flushState->caps().shaderCaps());
GrCCCoverageProcessor proc(flushState->resourceProvider(), renderPass,
*flushState->caps().shaderCaps());
if (int instanceCount = fInstanceCounts[(int)ScissorMode::kNonScissored].*instanceType) {
SkASSERT(instanceCount > 0);

View File

@ -5,23 +5,23 @@
* found in the LICENSE file.
*/
#ifndef GrCCPRCoverageOp_DEFINED
#define GrCCPRCoverageOp_DEFINED
#ifndef GrCCCoverageOp_DEFINED
#define GrCCCoverageOp_DEFINED
#include "GrMesh.h"
#include "SkRect.h"
#include "SkRefCnt.h"
#include "ccpr/GrCCPRCoverageProcessor.h"
#include "ccpr/GrCCPRGeometry.h"
#include "ccpr/GrCCCoverageProcessor.h"
#include "ccpr/GrCCGeometry.h"
#include "ops/GrDrawOp.h"
class GrCCPRCoverageOp;
class GrCCCoverageOp;
class GrOnFlushResourceProvider;
class SkMatrix;
class SkPath;
/**
* This class produces GrCCPRCoverageOps that render coverage count masks and atlases. A path is
* This class produces GrCCCoverageOps that render coverage count masks and atlases. A path is
* added to the current op in two steps:
*
* 1) parsePath(ScissorMode, viewMatrix, path, &devBounds, &devBounds45);
@ -30,28 +30,25 @@ class SkPath;
*
* 2) saveParsedPath(offsetX, offsetY, clipBounds);
*
* The client can flush the currently saved paths to a GrCCPRCoverageOp by calling emitOp, and
* The client can flush the currently saved paths to a GrCCCoverageOp by calling emitOp, and
* retrieve all emitted ops after calling finalize().
*/
class GrCCPRCoverageOpsBuilder {
class GrCCCoverageOpsBuilder {
public:
// Indicates whether a path should enforce a scissor clip when rendering its mask. (Specified
// as an int because these values get used directly as indices into arrays.)
enum class ScissorMode : int {
kNonScissored = 0,
kScissored = 1
};
enum class ScissorMode : int { kNonScissored = 0, kScissored = 1 };
static constexpr int kNumScissorModes = 2;
GrCCPRCoverageOpsBuilder(int maxTotalPaths, int maxPathPoints, int numSkPoints, int numSkVerbs)
GrCCCoverageOpsBuilder(int maxTotalPaths, int maxPathPoints, int numSkPoints, int numSkVerbs)
: fPathsInfo(maxTotalPaths)
, fLocalDevPtsBuffer(maxPathPoints + 1) // Overallocate by one point to accomodate for
// overflow with Sk4f. (See parsePath.)
, fLocalDevPtsBuffer(maxPathPoints + 1) // Overallocate by one point to accomodate for
// overflow with Sk4f. (See parsePath.)
, fGeometry(numSkPoints, numSkVerbs)
, fTallies{PrimitiveTallies(), PrimitiveTallies()}
, fScissorBatches(maxTotalPaths) {}
~GrCCPRCoverageOpsBuilder() {
~GrCCCoverageOpsBuilder() {
// Enforce the contract that the client always calls saveParsedPath or discardParsedPath.
SkASSERT(!fParsingPath);
}
@ -72,27 +69,27 @@ public:
// Commits the currently-parsed path from staging to the next Op, and specifies whether the mask
// should be rendered with a scissor clip in effect. Accepts an optional post-device-space
// translate for placement in an atlas.
void saveParsedPath(ScissorMode, const SkIRect& clippedDevIBounds,
int16_t atlasOffsetX, int16_t atlasOffsetY);
void saveParsedPath(ScissorMode, const SkIRect& clippedDevIBounds, int16_t atlasOffsetX,
int16_t atlasOffsetY);
void discardParsedPath();
// Flushes all currently-saved paths internally to a GrCCPRCoverageOp.
// Flushes all currently-saved paths internally to a GrCCCoverageOp.
//
// NOTE: if there is a parsed path in the staging area, it will not be included. But the client
// may still call saveParsedPath to include it in a future Op.
void emitOp(SkISize drawBounds);
// Builds GPU buffers and returns the list of GrCCPRCoverageOps as specified by calls to emitOp.
bool finalize(GrOnFlushResourceProvider*, SkTArray<std::unique_ptr<GrCCPRCoverageOp>>*);
// Builds GPU buffers and returns the list of GrCCCoverageOps as specified by calls to emitOp.
bool finalize(GrOnFlushResourceProvider*, SkTArray<std::unique_ptr<GrCCCoverageOp>>*);
private:
using PrimitiveTallies = GrCCPRGeometry::PrimitiveTallies;
using PrimitiveTallies = GrCCGeometry::PrimitiveTallies;
// Every kBeginPath verb has a corresponding PathInfo entry.
struct PathInfo {
ScissorMode fScissorMode;
int16_t fAtlasOffsetX, fAtlasOffsetY;
std::unique_ptr<GrCCPRCoverageOp> fTerminatingOp;
std::unique_ptr<GrCCCoverageOp> fTerminatingOp;
};
// Every PathInfo with a mode of kScissored has a corresponding ScissorBatch.
@ -113,25 +110,25 @@ private:
SkSTArray<32, PathInfo, true> fPathsInfo;
const SkAutoSTArray<32, SkPoint> fLocalDevPtsBuffer;
GrCCPRGeometry fGeometry;
GrCCGeometry fGeometry;
PrimitiveTallies fTallies[kNumScissorModes];
SkTArray<ScissorBatch, true> fScissorBatches;
std::unique_ptr<GrCCPRCoverageOp> fTerminatingOp;
std::unique_ptr<GrCCCoverageOp> fTerminatingOp;
friend class GrCCPRCoverageOp; // For ScissorBatch.
friend class GrCCCoverageOp; // For ScissorBatch.
};
/**
* This Op renders coverage count masks and atlases. Create it using GrCCPRCoverageOpsBuilder.
* This Op renders coverage count masks and atlases. Create it using GrCCCoverageOpsBuilder.
*/
class GrCCPRCoverageOp : public GrDrawOp {
class GrCCCoverageOp : public GrDrawOp {
public:
DEFINE_OP_CLASS_ID
// GrDrawOp interface.
const char* name() const override { return "GrCCPRCoverageOp"; }
const char* name() const override { return "GrCCCoverageOp"; }
FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
RequiresDstTexture finalize(const GrCaps&, const GrAppliedClip*,
GrPixelConfigIsClamped) override {
@ -142,14 +139,14 @@ public:
void onExecute(GrOpFlushState*) override;
private:
static constexpr int kNumScissorModes = GrCCPRCoverageOpsBuilder::kNumScissorModes;
using PrimitiveTallies = GrCCPRGeometry::PrimitiveTallies;
using ScissorBatch = GrCCPRCoverageOpsBuilder::ScissorBatch;
static constexpr int kNumScissorModes = GrCCCoverageOpsBuilder::kNumScissorModes;
using PrimitiveTallies = GrCCGeometry::PrimitiveTallies;
using ScissorBatch = GrCCCoverageOpsBuilder::ScissorBatch;
GrCCPRCoverageOp(SkTArray<ScissorBatch, true>&& scissorBatches, const SkISize& drawBounds)
: INHERITED(ClassID())
, fScissorBatches(std::move(scissorBatches))
, fDrawBounds(drawBounds) {
GrCCCoverageOp(SkTArray<ScissorBatch, true>&& scissorBatches, const SkISize& drawBounds)
: INHERITED(ClassID())
, fScissorBatches(std::move(scissorBatches))
, fDrawBounds(drawBounds) {
this->setBounds(SkRect::MakeIWH(fDrawBounds.width(), fDrawBounds.height()),
GrOp::HasAABloat::kNo, GrOp::IsZeroArea::kNo);
}
@ -158,8 +155,8 @@ private:
const PrimitiveTallies baseInstances[kNumScissorModes],
const PrimitiveTallies endInstances[kNumScissorModes]);
void drawMaskPrimitives(GrOpFlushState*, const GrPipeline&, GrCCPRCoverageProcessor::RenderPass,
int PrimitiveTallies::* instanceType) const;
void drawMaskPrimitives(GrOpFlushState*, const GrPipeline&, GrCCCoverageProcessor::RenderPass,
int PrimitiveTallies::*instanceType) const;
sk_sp<GrBuffer> fInstanceBuffer;
PrimitiveTallies fBaseInstances[kNumScissorModes];
@ -170,7 +167,7 @@ private:
mutable SkTArray<GrMesh> fMeshesScratchBuffer;
mutable SkTArray<GrPipeline::DynamicState, true> fDynamicStatesScratchBuffer;
friend class GrCCPRCoverageOpsBuilder;
friend class GrCCCoverageOpsBuilder;
typedef GrDrawOp INHERITED;
};

View File

@ -5,20 +5,20 @@
* found in the LICENSE file.
*/
#include "GrCCPRCoverageProcessor.h"
#include "GrCCCoverageProcessor.h"
#include "SkMakeUnique.h"
#include "ccpr/GrCCPRCubicShader.h"
#include "ccpr/GrCCPRQuadraticShader.h"
#include "ccpr/GrCCPRTriangleShader.h"
#include "ccpr/GrCCCubicShader.h"
#include "ccpr/GrCCQuadraticShader.h"
#include "ccpr/GrCCTriangleShader.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
void GrCCPRCoverageProcessor::Shader::emitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code,
const char* position, const char* coverage,
const char* wind) {
void GrCCCoverageProcessor::Shader::emitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code,
const char* position, const char* coverage,
const char* wind) {
SkASSERT(GrGLSLVarying::Scope::kVertToGeo != scope);
WindHandling windHandling = this->onEmitVaryings(varyingHandler, scope, code, position,
coverage, wind);
@ -29,10 +29,10 @@ void GrCCPRCoverageProcessor::Shader::emitVaryings(GrGLSLVaryingHandler* varying
}
}
void GrCCPRCoverageProcessor::Shader::emitFragmentCode(const GrCCPRCoverageProcessor& proc,
GrGLSLPPFragmentBuilder* f,
const char* skOutputColor,
const char* skOutputCoverage) const {
void GrCCCoverageProcessor::Shader::emitFragmentCode(const GrCCCoverageProcessor& proc,
GrGLSLPPFragmentBuilder* f,
const char* skOutputColor,
const char* skOutputCoverage) const {
f->codeAppendf("half coverage = 0;");
this->onEmitFragmentCode(f, "coverage");
if (fWind.fsIn()) {
@ -49,10 +49,10 @@ void GrCCPRCoverageProcessor::Shader::emitFragmentCode(const GrCCPRCoverageProce
#endif
}
void GrCCPRCoverageProcessor::Shader::EmitEdgeDistanceEquation(GrGLSLVertexGeoBuilder* s,
const char* leftPt,
const char* rightPt,
const char* outputDistanceEquation) {
void GrCCCoverageProcessor::Shader::EmitEdgeDistanceEquation(GrGLSLVertexGeoBuilder* s,
const char* leftPt,
const char* rightPt,
const char* outputDistanceEquation) {
s->codeAppendf("float2 n = float2(%s.y - %s.y, %s.x - %s.x);",
rightPt, leftPt, leftPt, rightPt);
s->codeAppend ("float nwidth = (abs(n.x) + abs(n.y)) * (bloat * 2);");
@ -62,8 +62,8 @@ void GrCCPRCoverageProcessor::Shader::EmitEdgeDistanceEquation(GrGLSLVertexGeoBu
s->codeAppendf("%s = float3(-n, dot(n, %s) - .5);", outputDistanceEquation, leftPt);
}
int GrCCPRCoverageProcessor::Shader::DefineSoftSampleLocations(GrGLSLPPFragmentBuilder* f,
const char* samplesName) {
int GrCCCoverageProcessor::Shader::DefineSoftSampleLocations(GrGLSLPPFragmentBuilder* f,
const char* samplesName) {
// Standard DX11 sample locations.
#if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
f->defineConstant("float2[8]", samplesName, "float2[8]("
@ -82,8 +82,8 @@ int GrCCPRCoverageProcessor::Shader::DefineSoftSampleLocations(GrGLSLPPFragmentB
#endif
}
void GrCCPRCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&,
GrProcessorKeyBuilder* b) const {
void GrCCCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&,
GrProcessorKeyBuilder* b) const {
int key = (int)fRenderPass << 1;
if (Impl::kGeometryShader == fImpl) {
key |= 1;
@ -96,27 +96,27 @@ void GrCCPRCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&,
b->add32(key);
}
GrGLSLPrimitiveProcessor* GrCCPRCoverageProcessor::createGLSLInstance(const GrShaderCaps&) const {
GrGLSLPrimitiveProcessor* GrCCCoverageProcessor::createGLSLInstance(const GrShaderCaps&) const {
std::unique_ptr<Shader> shader;
switch (fRenderPass) {
case RenderPass::kTriangleHulls:
case RenderPass::kTriangleEdges:
shader = skstd::make_unique<GrCCPRTriangleShader>();
shader = skstd::make_unique<GrCCTriangleShader>();
break;
case RenderPass::kTriangleCorners:
shader = skstd::make_unique<GrCCPRTriangleCornerShader>();
shader = skstd::make_unique<GrCCTriangleCornerShader>();
break;
case RenderPass::kQuadraticHulls:
shader = skstd::make_unique<GrCCPRQuadraticHullShader>();
shader = skstd::make_unique<GrCCQuadraticHullShader>();
break;
case RenderPass::kQuadraticCorners:
shader = skstd::make_unique<GrCCPRQuadraticCornerShader>();
shader = skstd::make_unique<GrCCQuadraticCornerShader>();
break;
case RenderPass::kCubicHulls:
shader = skstd::make_unique<GrCCPRCubicHullShader>();
shader = skstd::make_unique<GrCCCubicHullShader>();
break;
case RenderPass::kCubicCorners:
shader = skstd::make_unique<GrCCPRCubicCornerShader>();
shader = skstd::make_unique<GrCCCubicCornerShader>();
break;
}
return Impl::kGeometryShader == fImpl ? this->createGSImpl(std::move(shader))

View File

@ -5,8 +5,8 @@
* found in the LICENSE file.
*/
#ifndef GrCCPRCoverageProcessor_DEFINED
#define GrCCPRCoverageProcessor_DEFINED
#ifndef GrCCCoverageProcessor_DEFINED
#define GrCCCoverageProcessor_DEFINED
#include "GrGeometryProcessor.h"
#include "GrShaderCaps.h"
@ -26,11 +26,11 @@ class GrMesh;
* The caller is responsible to execute all render passes for all applicable primitives into a
* cleared, floating point, alpha-only render target using SkBlendMode::kPlus (see RenderPass
* below). Once all of a path's primitives have been drawn, the render target contains a composite
* coverage count that can then be used to draw the path (see GrCCPRPathProcessor).
* coverage count that can then be used to draw the path (see GrCCPathProcessor).
*
* To draw a renderer pass, see appendMesh below.
*/
class GrCCPRCoverageProcessor : public GrGeometryProcessor {
class GrCCCoverageProcessor : public GrGeometryProcessor {
public:
// Defines a single triangle or closed quadratic bezier, with transposed x,y point values.
struct TriangleInstance {
@ -91,8 +91,8 @@ public:
return RenderPass::kTriangleEdges != renderPass || caps.geometryShaderSupport();
}
GrCCPRCoverageProcessor(GrResourceProvider* rp, RenderPass pass, const GrShaderCaps& caps)
: INHERITED(kGrCCPRCoverageProcessor_ClassID)
GrCCCoverageProcessor(GrResourceProvider* rp, RenderPass pass, const GrShaderCaps& caps)
: INHERITED(kGrCCCoverageProcessor_ClassID)
, fRenderPass(pass)
, fImpl(caps.geometryShaderSupport() ? Impl::kGeometryShader : Impl::kVertexShader) {
SkASSERT(DoesRenderPass(pass, caps));
@ -162,7 +162,7 @@ public:
void emitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
const char* position, const char* coverage, const char* wind);
void emitFragmentCode(const GrCCPRCoverageProcessor& proc, GrGLSLPPFragmentBuilder*,
void emitFragmentCode(const GrCCCoverageProcessor& proc, GrGLSLPPFragmentBuilder*,
const char* skOutputColor, const char* skOutputCoverage) const;
// Defines an equation ("dot(float3(pt, 1), distance_equation)") that is -1 on the outside
@ -246,31 +246,31 @@ private:
const Impl fImpl;
sk_sp<const GrBuffer> fVertexBuffer; // Used by VSImpl.
sk_sp<const GrBuffer> fIndexBuffer; // Used by VSImpl.
SkDEBUGCODE(float fDebugBloat = 0;)
SkDEBUGCODE(float fDebugBloat = 0);
typedef GrGeometryProcessor INHERITED;
};
inline void GrCCPRCoverageProcessor::TriangleInstance::set(const SkPoint p[3], const Sk2f& trans) {
inline void GrCCCoverageProcessor::TriangleInstance::set(const SkPoint p[3], const Sk2f& trans) {
this->set(p[0], p[1], p[2], trans);
}
inline void GrCCPRCoverageProcessor::TriangleInstance::set(const SkPoint& p0, const SkPoint& p1,
const SkPoint& p2, const Sk2f& trans) {
inline void GrCCCoverageProcessor::TriangleInstance::set(const SkPoint& p0, const SkPoint& p1,
const SkPoint& p2, const Sk2f& trans) {
Sk2f P0 = Sk2f::Load(&p0) + trans;
Sk2f P1 = Sk2f::Load(&p1) + trans;
Sk2f P2 = Sk2f::Load(&p2) + trans;
Sk2f::Store3(this, P0, P1, P2);
}
inline void GrCCPRCoverageProcessor::CubicInstance::set(const SkPoint p[4], float dx, float dy) {
inline void GrCCCoverageProcessor::CubicInstance::set(const SkPoint p[4], float dx, float dy) {
Sk4f X,Y;
Sk4f::Load2(p, &X, &Y);
(X + dx).store(&fX);
(Y + dy).store(&fY);
}
inline bool GrCCPRCoverageProcessor::RenderPassIsCubic(RenderPass pass) {
inline bool GrCCCoverageProcessor::RenderPassIsCubic(RenderPass pass) {
switch (pass) {
case RenderPass::kTriangleHulls:
case RenderPass::kTriangleEdges:
@ -286,7 +286,7 @@ inline bool GrCCPRCoverageProcessor::RenderPassIsCubic(RenderPass pass) {
return false;
}
inline const char* GrCCPRCoverageProcessor::RenderPassName(RenderPass pass) {
inline const char* GrCCCoverageProcessor::RenderPassName(RenderPass pass) {
switch (pass) {
case RenderPass::kTriangleHulls: return "kTriangleHulls";
case RenderPass::kTriangleEdges: return "kTriangleEdges";

View File

@ -5,19 +5,19 @@
* found in the LICENSE file.
*/
#include "GrCCPRCoverageProcessor.h"
#include "GrCCCoverageProcessor.h"
#include "GrMesh.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
using InputType = GrGLSLGeometryBuilder::InputType;
using OutputType = GrGLSLGeometryBuilder::OutputType;
using Shader = GrCCPRCoverageProcessor::Shader;
using Shader = GrCCCoverageProcessor::Shader;
/**
* This class and its subclasses implement the coverage processor with geometry shaders.
*/
class GrCCPRCoverageProcessor::GSImpl : public GrGLSLGeometryProcessor {
class GrCCCoverageProcessor::GSImpl : public GrGLSLGeometryProcessor {
protected:
GSImpl(std::unique_ptr<Shader> shader) : fShader(std::move(shader)) {}
@ -27,7 +27,7 @@ protected:
}
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
const GrCCPRCoverageProcessor& proc = args.fGP.cast<GrCCPRCoverageProcessor>();
const GrCCCoverageProcessor& proc = args.fGP.cast<GrCCCoverageProcessor>();
// The vertex shader simply forwards transposed x or y values to the geometry shader.
SkASSERT(1 == proc.numAttribs());
@ -45,7 +45,7 @@ protected:
fShader->emitFragmentCode(proc, args.fFragBuilder, args.fOutputColor, args.fOutputCoverage);
}
void emitGeometryShader(const GrCCPRCoverageProcessor& proc,
void emitGeometryShader(const GrCCCoverageProcessor& proc,
GrGLSLVaryingHandler* varyingHandler, GrGLSLGeometryBuilder* g,
const char* rtAdjust) const {
int numInputPoints = proc.numInputPoints();
@ -102,7 +102,7 @@ protected:
/**
* Generates a conservative raster hull around a triangle. (See comments for RenderPass)
*/
class GSHull3Impl : public GrCCPRCoverageProcessor::GSImpl {
class GSHull3Impl : public GrCCCoverageProcessor::GSImpl {
public:
GSHull3Impl(std::unique_ptr<Shader> shader) : GSImpl(std::move(shader)) {}
@ -175,7 +175,7 @@ public:
/**
* Generates a conservative raster hull around a convex quadrilateral. (See comments for RenderPass)
*/
class GSHull4Impl : public GrCCPRCoverageProcessor::GSImpl {
class GSHull4Impl : public GrCCCoverageProcessor::GSImpl {
public:
GSHull4Impl(std::unique_ptr<Shader> shader) : GSImpl(std::move(shader)) {}
@ -246,7 +246,7 @@ public:
/**
* Generates conservatives around each edge of a triangle. (See comments for RenderPass)
*/
class GSEdgeImpl : public GrCCPRCoverageProcessor::GSImpl {
class GSEdgeImpl : public GrCCCoverageProcessor::GSImpl {
public:
GSEdgeImpl(std::unique_ptr<Shader> shader) : GSImpl(std::move(shader)) {}
@ -295,7 +295,7 @@ public:
/**
* Generates conservative rasters around corners. (See comments for RenderPass)
*/
class GSCornerImpl : public GrCCPRCoverageProcessor::GSImpl {
class GSCornerImpl : public GrCCCoverageProcessor::GSImpl {
public:
GSCornerImpl(std::unique_ptr<Shader> shader, int numCorners)
: GSImpl(std::move(shader)), fNumCorners(numCorners) {}
@ -320,7 +320,7 @@ private:
const int fNumCorners;
};
void GrCCPRCoverageProcessor::initGS() {
void GrCCCoverageProcessor::initGS() {
SkASSERT(Impl::kGeometryShader == fImpl);
if (RenderPassIsCubic(fRenderPass)) {
this->addVertexAttrib("x_or_y_values", kFloat4_GrVertexAttribType); // (See appendMesh.)
@ -332,8 +332,8 @@ void GrCCPRCoverageProcessor::initGS() {
this->setWillUseGeoShader();
}
void GrCCPRCoverageProcessor::appendGSMesh(GrBuffer* instanceBuffer, int instanceCount,
int baseInstance, SkTArray<GrMesh>* out) const {
void GrCCCoverageProcessor::appendGSMesh(GrBuffer* instanceBuffer, int instanceCount,
int baseInstance, SkTArray<GrMesh>* out) const {
// GSImpl doesn't actually make instanced draw calls. Instead, we feed transposed x,y point
// values to the GPU in a regular vertex array and draw kLines (see initGS). Then, each vertex
// invocation receives either the shape's x or y values as inputs, which it forwards to the
@ -344,21 +344,20 @@ void GrCCPRCoverageProcessor::appendGSMesh(GrBuffer* instanceBuffer, int instanc
mesh.setVertexData(instanceBuffer, baseInstance * 2);
}
GrGLSLPrimitiveProcessor*
GrCCPRCoverageProcessor::createGSImpl(std::unique_ptr<Shader> shader) const {
GrGLSLPrimitiveProcessor* GrCCCoverageProcessor::createGSImpl(std::unique_ptr<Shader> shadr) const {
switch (fRenderPass) {
case RenderPass::kTriangleHulls:
return new GSHull3Impl(std::move(shader));
return new GSHull3Impl(std::move(shadr));
case RenderPass::kQuadraticHulls:
case RenderPass::kCubicHulls:
return new GSHull4Impl(std::move(shader));
return new GSHull4Impl(std::move(shadr));
case RenderPass::kTriangleEdges:
return new GSEdgeImpl(std::move(shader));
return new GSEdgeImpl(std::move(shadr));
case RenderPass::kTriangleCorners:
return new GSCornerImpl(std::move(shader), 3);
return new GSCornerImpl(std::move(shadr), 3);
case RenderPass::kQuadraticCorners:
case RenderPass::kCubicCorners:
return new GSCornerImpl(std::move(shader), 2);
return new GSCornerImpl(std::move(shadr), 2);
}
SK_ABORT("Invalid RenderPass");
return nullptr;

View File

@ -5,12 +5,12 @@
* found in the LICENSE file.
*/
#include "GrCCPRCoverageProcessor.h"
#include "GrCCCoverageProcessor.h"
#include "GrMesh.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
using Shader = GrCCPRCoverageProcessor::Shader;
using Shader = GrCCCoverageProcessor::Shader;
static constexpr int kAttribIdx_X = 0;
static constexpr int kAttribIdx_Y = 1;
@ -19,7 +19,7 @@ static constexpr int kAttribIdx_VertexData = 2;
/**
* This class and its subclasses implement the coverage processor with vertex shaders.
*/
class GrCCPRCoverageProcessor::VSImpl : public GrGLSLGeometryProcessor {
class GrCCCoverageProcessor::VSImpl : public GrGLSLGeometryProcessor {
protected:
VSImpl(std::unique_ptr<Shader> shader) : fShader(std::move(shader)) {}
@ -29,7 +29,7 @@ protected:
}
void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
const GrCCPRCoverageProcessor& proc = args.fGP.cast<GrCCPRCoverageProcessor>();
const GrCCCoverageProcessor& proc = args.fGP.cast<GrCCCoverageProcessor>();
// Vertex shader.
GrGLSLVertexBuilder* v = args.fVertBuilder;
@ -69,7 +69,7 @@ protected:
fShader->emitFragmentCode(proc, args.fFragBuilder, args.fOutputColor, args.fOutputCoverage);
}
virtual const char* emitVertexPosition(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder*,
virtual const char* emitVertexPosition(const GrCCCoverageProcessor&, GrGLSLVertexBuilder*,
GrGPArgs*) const = 0;
virtual ~VSImpl() {}
@ -208,12 +208,12 @@ GR_DECLARE_STATIC_UNIQUE_KEY(gHull4IndexBufferKey);
* Generates a conservative raster hull around a convex polygon. For triangles, we also generate
* independent conservative rasters around each edge. (See comments for RenderPass)
*/
class VSHullAndEdgeImpl : public GrCCPRCoverageProcessor::VSImpl {
class VSHullAndEdgeImpl : public GrCCCoverageProcessor::VSImpl {
public:
VSHullAndEdgeImpl(std::unique_ptr<Shader> shader, int numSides)
: VSImpl(std::move(shader)), fNumSides(numSides) {}
const char* emitVertexPosition(const GrCCPRCoverageProcessor& proc, GrGLSLVertexBuilder* v,
const char* emitVertexPosition(const GrCCCoverageProcessor& proc, GrGLSLVertexBuilder* v,
GrGPArgs* gpArgs) const override {
Shader::GeometryVars vars;
fShader->emitSetupCode(v, "pts", nullptr, "wind", &vars);
@ -300,11 +300,11 @@ GR_DECLARE_STATIC_UNIQUE_KEY(gCornerIndexBufferKey);
/**
* Generates conservative rasters around corners. (See comments for RenderPass)
*/
class VSCornerImpl : public GrCCPRCoverageProcessor::VSImpl {
class VSCornerImpl : public GrCCCoverageProcessor::VSImpl {
public:
VSCornerImpl(std::unique_ptr<Shader> shader) : VSImpl(std::move(shader)) {}
const char* emitVertexPosition(const GrCCPRCoverageProcessor&, GrGLSLVertexBuilder* v,
const char* emitVertexPosition(const GrCCCoverageProcessor&, GrGLSLVertexBuilder* v,
GrGPArgs* gpArgs) const override {
Shader::GeometryVars vars;
v->codeAppend ("int corner_id = sk_VertexID / 4;");
@ -319,7 +319,7 @@ public:
}
};
void GrCCPRCoverageProcessor::initVS(GrResourceProvider* rp) {
void GrCCCoverageProcessor::initVS(GrResourceProvider* rp) {
SkASSERT(Impl::kVertexShader == fImpl);
GrVertexAttribType inputPtsType = RenderPassIsCubic(fRenderPass) ?
@ -388,9 +388,9 @@ void GrCCPRCoverageProcessor::initVS(GrResourceProvider* rp) {
#endif
}
static int num_indices_per_instance(GrCCPRCoverageProcessor::RenderPass pass) {
static int num_indices_per_instance(GrCCCoverageProcessor::RenderPass pass) {
switch (pass) {
using RenderPass = GrCCPRCoverageProcessor::RenderPass;
using RenderPass = GrCCCoverageProcessor::RenderPass;
case RenderPass::kTriangleHulls:
return SK_ARRAY_COUNT(kHull3AndEdgeIndices);
case RenderPass::kQuadraticHulls:
@ -409,8 +409,8 @@ static int num_indices_per_instance(GrCCPRCoverageProcessor::RenderPass pass) {
return 0;
}
void GrCCPRCoverageProcessor::appendVSMesh(GrBuffer* instanceBuffer, int instanceCount,
int baseInstance, SkTArray<GrMesh>* out) const {
void GrCCCoverageProcessor::appendVSMesh(GrBuffer* instanceBuffer, int instanceCount,
int baseInstance, SkTArray<GrMesh>* out) const {
SkASSERT(Impl::kVertexShader == fImpl);
GrMesh& mesh = out->emplace_back(GrPrimitiveType::kTriangles);
mesh.setIndexedInstanced(fIndexBuffer.get(), num_indices_per_instance(fRenderPass),
@ -420,21 +420,20 @@ void GrCCPRCoverageProcessor::appendVSMesh(GrBuffer* instanceBuffer, int instanc
}
}
GrGLSLPrimitiveProcessor*
GrCCPRCoverageProcessor::createVSImpl(std::unique_ptr<Shader> shader) const {
GrGLSLPrimitiveProcessor* GrCCCoverageProcessor::createVSImpl(std::unique_ptr<Shader> shadr) const {
switch (fRenderPass) {
case RenderPass::kTriangleHulls:
return new VSHullAndEdgeImpl(std::move(shader), 3);
return new VSHullAndEdgeImpl(std::move(shadr), 3);
case RenderPass::kQuadraticHulls:
case RenderPass::kCubicHulls:
return new VSHullAndEdgeImpl(std::move(shader), 4);
return new VSHullAndEdgeImpl(std::move(shadr), 4);
case RenderPass::kTriangleEdges:
SK_ABORT("kTriangleEdges RenderPass is not used by VSImpl.");
return nullptr;
case RenderPass::kTriangleCorners:
case RenderPass::kQuadraticCorners:
case RenderPass::kCubicCorners:
return new VSCornerImpl(std::move(shader));
return new VSCornerImpl(std::move(shadr));
}
SK_ABORT("Invalid RenderPass");
return nullptr;

View File

@ -5,16 +5,16 @@
* found in the LICENSE file.
*/
#include "GrCCPRCubicShader.h"
#include "GrCCCubicShader.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
using Shader = GrCCPRCoverageProcessor::Shader;
using Shader = GrCCCoverageProcessor::Shader;
void GrCCPRCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID, const char* wind,
GeometryVars* vars) const {
void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID, const char* wind,
GeometryVars* vars) const {
// Find the cubic's power basis coefficients.
s->codeAppendf("float2x4 C = float4x4(-1, 3, -3, 1, "
" 3, -6, 3, 0, "
@ -75,10 +75,10 @@ void GrCCPRCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts
this->onEmitSetupCode(s, pts, repetitionID, vars);
}
Shader::WindHandling GrCCPRCubicShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope,
SkString* code, const char* position,
const char* coverage, const char* /*wind*/) {
Shader::WindHandling GrCCCubicShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope,
SkString* code, const char* position,
const char* coverage, const char* /*wind*/) {
SkASSERT(!coverage);
fKLMD.reset(kFloat4_GrSLType, scope);
@ -91,8 +91,8 @@ Shader::WindHandling GrCCPRCubicShader::onEmitVaryings(GrGLSLVaryingHandler* var
return WindHandling::kNotHandled;
}
void GrCCPRCubicHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code) {
void GrCCCubicHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code) {
fGradMatrix.reset(kFloat2x2_GrSLType, scope);
varyingHandler->addVarying("grad_matrix", &fGradMatrix);
// "klm" was just defined by the base class.
@ -101,8 +101,8 @@ void GrCCPRCubicHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
OutName(fGradMatrix), fKLMMatrix.c_str(), fKLMMatrix.c_str());
}
void GrCCPRCubicHullShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
void GrCCCubicHullShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
f->codeAppendf("float k = %s.x, l = %s.y, m = %s.z, d = %s.w;",
fKLMD.fsIn(), fKLMD.fsIn(), fKLMD.fsIn(), fKLMD.fsIn());
f->codeAppend ("float f = k*k*k - l*m;");
@ -111,14 +111,14 @@ void GrCCPRCubicHullShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
f->codeAppendf("%s += min(d, 0);", outputCoverage); // Flat closing edge.
}
void GrCCPRCubicCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID, GeometryVars* vars) const {
void GrCCCubicCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID, GeometryVars* vars) const {
s->codeAppendf("float2 corner = %s[%s * 3];", pts, repetitionID);
vars->fCornerVars.fPoint = "corner";
}
void GrCCPRCubicCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code) {
void GrCCCubicCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code) {
fdKLMDdx.reset(kFloat4_GrSLType, scope);
varyingHandler->addFlatVarying("dklmddx", &fdKLMDdx);
code->appendf("%s = float4(%s[0].x, %s[1].x, %s[2].x, %s.x);",
@ -132,8 +132,8 @@ void GrCCPRCubicCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandle
fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str());
}
void GrCCPRCubicCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
void GrCCCubicCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
f->codeAppendf("float2x4 grad_klmd = float2x4(%s, %s);", fdKLMDdx.fsIn(), fdKLMDdy.fsIn());
// Erase what the previous hull shader wrote. We don't worry about the two corners falling on

View File

@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
#ifndef GrCCPRCubicShader_DEFINED
#define GrCCPRCubicShader_DEFINED
#ifndef GrCCCubicShader_DEFINED
#define GrCCCubicShader_DEFINED
#include "ccpr/GrCCPRCoverageProcessor.h"
#include "ccpr/GrCCCoverageProcessor.h"
/**
* This class renders the coverage of convex closed cubic segments using the techniques outlined in
@ -19,9 +19,9 @@
*
* The provided curve segments must be convex, monotonic with respect to the vector of their closing
* edge [P3 - P0], and must not contain or be near any inflection points or loop intersections.
* (Use GrCCPRGeometry.)
* (Use GrCCGeometry.)
*/
class GrCCPRCubicShader : public GrCCPRCoverageProcessor::Shader {
class GrCCCubicShader : public GrCCCoverageProcessor::Shader {
protected:
void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
const char* wind, GeometryVars*) const final;
@ -39,14 +39,14 @@ protected:
GrGLSLVarying fKLMD;
};
class GrCCPRCubicHullShader : public GrCCPRCubicShader {
class GrCCCubicHullShader : public GrCCCubicShader {
void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
GrGLSLVarying fGradMatrix;
};
class GrCCPRCubicCornerShader : public GrCCPRCubicShader {
class GrCCCubicCornerShader : public GrCCCubicShader {
void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
GeometryVars*) const override;
void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;

View File

@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
#include "GrCCPRGeometry.h"
#include "GrCCGeometry.h"
#include "GrTypes.h"
#include "GrPathUtils.h"
@ -18,12 +18,12 @@ GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT);
GR_STATIC_ASSERT(2 * sizeof(float) == sizeof(SkPoint));
GR_STATIC_ASSERT(0 == offsetof(SkPoint, fX));
void GrCCPRGeometry::beginPath() {
void GrCCGeometry::beginPath() {
SkASSERT(!fBuildingContour);
fVerbs.push_back(Verb::kBeginPath);
}
void GrCCPRGeometry::beginContour(const SkPoint& devPt) {
void GrCCGeometry::beginContour(const SkPoint& devPt) {
SkASSERT(!fBuildingContour);
fCurrFanPoint = fCurrAnchorPoint = devPt;
@ -35,10 +35,10 @@ void GrCCPRGeometry::beginContour(const SkPoint& devPt) {
fPoints.push_back(devPt);
fVerbs.push_back(Verb::kBeginContour);
SkDEBUGCODE(fBuildingContour = true;)
SkDEBUGCODE(fBuildingContour = true);
}
void GrCCPRGeometry::lineTo(const SkPoint& devPt) {
void GrCCGeometry::lineTo(const SkPoint& devPt) {
SkASSERT(fBuildingContour);
SkASSERT(fCurrFanPoint == fPoints.back());
fCurrFanPoint = devPt;
@ -90,7 +90,7 @@ static inline Sk2f lerp(const Sk2f& a, const Sk2f& b, const Sk2f& t) {
return SkNx_fma(t, b - a, a);
}
void GrCCPRGeometry::quadraticTo(const SkPoint& devP0, const SkPoint& devP1) {
void GrCCGeometry::quadraticTo(const SkPoint& devP0, const SkPoint& devP1) {
SkASSERT(fBuildingContour);
SkASSERT(fCurrFanPoint == fPoints.back());
@ -102,8 +102,8 @@ void GrCCPRGeometry::quadraticTo(const SkPoint& devP0, const SkPoint& devP1) {
this->appendMonotonicQuadratics(p0, p1, p2);
}
inline void GrCCPRGeometry::appendMonotonicQuadratics(const Sk2f& p0, const Sk2f& p1,
const Sk2f& p2) {
inline void GrCCGeometry::appendMonotonicQuadratics(const Sk2f& p0, const Sk2f& p1,
const Sk2f& p2) {
Sk2f tan0 = p1 - p0;
Sk2f tan1 = p2 - p1;
@ -141,8 +141,8 @@ inline void GrCCPRGeometry::appendMonotonicQuadratics(const Sk2f& p0, const Sk2f
this->appendSingleMonotonicQuadratic(p012, p12, p2);
}
inline void GrCCPRGeometry::appendSingleMonotonicQuadratic(const Sk2f& p0, const Sk2f& p1,
const Sk2f& p2) {
inline void GrCCGeometry::appendSingleMonotonicQuadratic(const Sk2f& p0, const Sk2f& p1,
const Sk2f& p2) {
SkASSERT(fPoints.back() == SkPoint::Make(p0[0], p0[1]));
// Don't send curves to the GPU if we know they are nearly flat (or just very small).
@ -285,8 +285,8 @@ static inline bool is_cubic_nearly_quadratic(const Sk2f& p0, const Sk2f& p1, con
return ((c1 - c2).abs() <= 1).allTrue();
}
void GrCCPRGeometry::cubicTo(const SkPoint& devP1, const SkPoint& devP2, const SkPoint& devP3,
float inflectPad, float loopIntersectPad) {
void GrCCGeometry::cubicTo(const SkPoint& devP1, const SkPoint& devP2, const SkPoint& devP3,
float inflectPad, float loopIntersectPad) {
SkASSERT(fBuildingContour);
SkASSERT(fCurrFanPoint == fPoints.back());
@ -390,15 +390,15 @@ void GrCCPRGeometry::cubicTo(const SkPoint& devP1, const SkPoint& devP2, const S
// Next we chop the cubic up at all T0..T3 inside 0..1 and store the resulting segments.
if (T1 >= 1) {
// Only sections 1 & 2 can be in 0..1.
this->chopCubic<&GrCCPRGeometry::appendMonotonicCubics,
&GrCCPRGeometry::appendCubicApproximation>(p0, p1, p2, p3, T0);
this->chopCubic<&GrCCGeometry::appendMonotonicCubics,
&GrCCGeometry::appendCubicApproximation>(p0, p1, p2, p3, T0);
return;
}
if (T2 <= 0) {
// Only sections 4 & 5 can be in 0..1.
this->chopCubic<&GrCCPRGeometry::appendCubicApproximation,
&GrCCPRGeometry::appendMonotonicCubics>(p0, p1, p2, p3, T3);
this->chopCubic<&GrCCGeometry::appendCubicApproximation,
&GrCCGeometry::appendMonotonicCubics>(p0, p1, p2, p3, T3);
return;
}
@ -414,8 +414,8 @@ void GrCCPRGeometry::cubicTo(const SkPoint& devP1, const SkPoint& devP2, const S
Sk2f abcd1 = lerp(abc1, bcd1, T1T1);
// Sections 1 & 2.
this->chopCubic<&GrCCPRGeometry::appendMonotonicCubics,
&GrCCPRGeometry::appendCubicApproximation>(p0, ab1, abc1, abcd1, T0/T1);
this->chopCubic<&GrCCGeometry::appendMonotonicCubics,
&GrCCGeometry::appendCubicApproximation>(p0, ab1, abc1, abcd1, T0/T1);
if (T2 >= 1) {
// The rest of the curve is Section 3 (middle section).
@ -453,14 +453,14 @@ void GrCCPRGeometry::cubicTo(const SkPoint& devP1, const SkPoint& devP2, const S
}
// Sections 4 & 5.
this->chopCubic<&GrCCPRGeometry::appendCubicApproximation,
&GrCCPRGeometry::appendMonotonicCubics>(abcd2, bcd2, cd2, p3, (T3-T2) / (1-T2));
this->chopCubic<&GrCCGeometry::appendCubicApproximation,
&GrCCGeometry::appendMonotonicCubics>(abcd2, bcd2, cd2, p3, (T3-T2) / (1-T2));
}
template<GrCCPRGeometry::AppendCubicFn AppendLeftRight>
inline void GrCCPRGeometry::chopCubicAtMidTangent(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
const Sk2f& p3, const Sk2f& tan0,
const Sk2f& tan3, int maxFutureSubdivisions) {
template<GrCCGeometry::AppendCubicFn AppendLeftRight>
inline void GrCCGeometry::chopCubicAtMidTangent(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
const Sk2f& p3, const Sk2f& tan0,
const Sk2f& tan3, int maxFutureSubdivisions) {
// Find the T value whose tangent is perpendicular to the vector that bisects tan0 and -tan3.
Sk2f n = normalize(tan0) - normalize(tan3);
@ -482,9 +482,9 @@ inline void GrCCPRGeometry::chopCubicAtMidTangent(const Sk2f& p0, const Sk2f& p1
this->chopCubic<AppendLeftRight, AppendLeftRight>(p0, p1, p2, p3, T, maxFutureSubdivisions);
}
template<GrCCPRGeometry::AppendCubicFn AppendLeft, GrCCPRGeometry::AppendCubicFn AppendRight>
inline void GrCCPRGeometry::chopCubic(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
const Sk2f& p3, float T, int maxFutureSubdivisions) {
template<GrCCGeometry::AppendCubicFn AppendLeft, GrCCGeometry::AppendCubicFn AppendRight>
inline void GrCCGeometry::chopCubic(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
const Sk2f& p3, float T, int maxFutureSubdivisions) {
if (T >= 1) {
(this->*AppendLeft)(p0, p1, p2, p3, maxFutureSubdivisions);
return;
@ -506,8 +506,8 @@ inline void GrCCPRGeometry::chopCubic(const Sk2f& p0, const Sk2f& p1, const Sk2f
(this->*AppendRight)(abcd, bcd, cd, p3, maxFutureSubdivisions);
}
void GrCCPRGeometry::appendMonotonicCubics(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
const Sk2f& p3, int maxSubdivisions) {
void GrCCGeometry::appendMonotonicCubics(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
const Sk2f& p3, int maxSubdivisions) {
SkASSERT(maxSubdivisions >= 0);
if ((p0 == p3).allTrue()) {
return;
@ -518,9 +518,9 @@ void GrCCPRGeometry::appendMonotonicCubics(const Sk2f& p0, const Sk2f& p1, const
Sk2f tan3 = first_unless_nearly_zero(p3 - p2, p3 - p1);
if (!is_convex_curve_monotonic(p0, tan0, p3, tan3)) {
this->chopCubicAtMidTangent<&GrCCPRGeometry::appendMonotonicCubics>(p0, p1, p2, p3,
tan0, tan3,
maxSubdivisions-1);
this->chopCubicAtMidTangent<&GrCCGeometry::appendMonotonicCubics>(p0, p1, p2, p3,
tan0, tan3,
maxSubdivisions - 1);
return;
}
}
@ -542,8 +542,8 @@ void GrCCPRGeometry::appendMonotonicCubics(const Sk2f& p0, const Sk2f& p1, const
++fCurrContourTallies.fCubics;
}
void GrCCPRGeometry::appendCubicApproximation(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
const Sk2f& p3, int maxSubdivisions) {
void GrCCGeometry::appendCubicApproximation(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2,
const Sk2f& p3, int maxSubdivisions) {
SkASSERT(maxSubdivisions >= 0);
if ((p0 == p3).allTrue()) {
return;
@ -561,9 +561,9 @@ void GrCCPRGeometry::appendCubicApproximation(const Sk2f& p0, const Sk2f& p1, co
Sk2f tan0, tan3, c;
if (!is_cubic_nearly_quadratic(p0, p1, p2, p3, tan0, tan3, c) && maxSubdivisions) {
this->chopCubicAtMidTangent<&GrCCPRGeometry::appendCubicApproximation>(p0, p1, p2, p3,
tan0, tan3,
maxSubdivisions - 1);
this->chopCubicAtMidTangent<&GrCCGeometry::appendCubicApproximation>(p0, p1, p2, p3,
tan0, tan3,
maxSubdivisions - 1);
return;
}
@ -574,7 +574,7 @@ void GrCCPRGeometry::appendCubicApproximation(const Sk2f& p0, const Sk2f& p1, co
}
}
GrCCPRGeometry::PrimitiveTallies GrCCPRGeometry::endContour() {
GrCCGeometry::PrimitiveTallies GrCCGeometry::endContour() {
SkASSERT(fBuildingContour);
SkASSERT(fVerbs.count() >= fCurrContourTallies.fTriangles);
@ -590,6 +590,6 @@ GrCCPRGeometry::PrimitiveTallies GrCCPRGeometry::endContour() {
fCurrContourTallies.fTriangles = SkTMax(fanSize - 2, 0);
SkDEBUGCODE(fBuildingContour = false;)
SkDEBUGCODE(fBuildingContour = false);
return fCurrContourTallies;
}

View File

@ -5,8 +5,8 @@
* found in the LICENSE file.
*/
#ifndef GrGrCCPRGeometry_DEFINED
#define GrGrCCPRGeometry_DEFINED
#ifndef GrGrCCGeometry_DEFINED
#define GrGrCCGeometry_DEFINED
#include "SkGeometry.h"
#include "SkNx.h"
@ -15,12 +15,12 @@
/**
* This class chops device-space contours up into a series of segments that CCPR knows how to
* render. (See GrCCPRGeometry::Verb.)
* render. (See GrCCGeometry::Verb.)
*
* NOTE: This must be done in device space, since an affine transformation can change whether a
* curve is monotonic.
*/
class GrCCPRGeometry {
class GrCCGeometry {
public:
// These are the verbs that CCPR knows how to draw. If a path has any segments that don't map to
// this list, then they are chopped into smaller ones that do. A list of these comprise a
@ -45,7 +45,7 @@ public:
PrimitiveTallies operator-(const PrimitiveTallies&) const;
};
GrCCPRGeometry(int numSkPoints = 0, int numSkVerbs = 0)
GrCCGeometry(int numSkPoints = 0, int numSkVerbs = 0)
: fPoints(numSkPoints * 3) // Reserve for a 3x expansion in points and verbs.
, fVerbs(numSkVerbs * 3) {}
@ -94,9 +94,9 @@ private:
inline void appendMonotonicQuadratics(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2);
inline void appendSingleMonotonicQuadratic(const Sk2f& p0, const Sk2f& p1, const Sk2f& p2);
using AppendCubicFn = void(GrCCPRGeometry::*)(const Sk2f& p0, const Sk2f& p1,
const Sk2f& p2, const Sk2f& p3,
int maxSubdivisions);
using AppendCubicFn = void(GrCCGeometry::*)(const Sk2f& p0, const Sk2f& p1,
const Sk2f& p2, const Sk2f& p3,
int maxSubdivisions);
static constexpr int kMaxSubdivionsPerCubicSection = 2;
template<AppendCubicFn AppendLeftRight>
@ -125,14 +125,14 @@ private:
SkSTArray<128, Verb, true> fVerbs;
};
inline void GrCCPRGeometry::PrimitiveTallies::operator+=(const PrimitiveTallies& b) {
inline void GrCCGeometry::PrimitiveTallies::operator+=(const PrimitiveTallies& b) {
fTriangles += b.fTriangles;
fQuadratics += b.fQuadratics;
fCubics += b.fCubics;
}
GrCCPRGeometry::PrimitiveTallies
inline GrCCPRGeometry::PrimitiveTallies::operator-(const PrimitiveTallies& b) const {
GrCCGeometry::PrimitiveTallies
inline GrCCGeometry::PrimitiveTallies::operator-(const PrimitiveTallies& b) const {
return {fTriangles - b.fTriangles,
fQuadratics - b.fQuadratics,
fCubics - b.fCubics};

View File

@ -5,7 +5,7 @@
* found in the LICENSE file.
*/
#include "GrCCPRPathProcessor.h"
#include "GrCCPathProcessor.h"
#include "GrOnFlushResourceProvider.h"
#include "GrTexture.h"
@ -36,14 +36,14 @@ static constexpr float kOctoEdgeNorms[8 * 4] = {
GR_DECLARE_STATIC_UNIQUE_KEY(gVertexBufferKey);
sk_sp<const GrBuffer> GrCCPRPathProcessor::FindVertexBuffer(GrOnFlushResourceProvider* onFlushRP) {
sk_sp<const GrBuffer> GrCCPathProcessor::FindVertexBuffer(GrOnFlushResourceProvider* onFlushRP) {
GR_DEFINE_STATIC_UNIQUE_KEY(gVertexBufferKey);
return onFlushRP->findOrMakeStaticBuffer(kVertex_GrBufferType, sizeof(kOctoEdgeNorms),
kOctoEdgeNorms, gVertexBufferKey);
}
// Index buffer for the octagon defined above.
static uint16_t kOctoIndices[GrCCPRPathProcessor::kPerInstanceIndexCount] = {
static uint16_t kOctoIndices[GrCCPathProcessor::kPerInstanceIndexCount] = {
0, 4, 2,
0, 6, 4,
0, 2, 1,
@ -54,15 +54,15 @@ static uint16_t kOctoIndices[GrCCPRPathProcessor::kPerInstanceIndexCount] = {
GR_DECLARE_STATIC_UNIQUE_KEY(gIndexBufferKey);
sk_sp<const GrBuffer> GrCCPRPathProcessor::FindIndexBuffer(GrOnFlushResourceProvider* onFlushRP) {
sk_sp<const GrBuffer> GrCCPathProcessor::FindIndexBuffer(GrOnFlushResourceProvider* onFlushRP) {
GR_DEFINE_STATIC_UNIQUE_KEY(gIndexBufferKey);
return onFlushRP->findOrMakeStaticBuffer(kIndex_GrBufferType, sizeof(kOctoIndices),
kOctoIndices, gIndexBufferKey);
}
GrCCPRPathProcessor::GrCCPRPathProcessor(GrResourceProvider* rp, sk_sp<GrTextureProxy> atlas,
SkPath::FillType fillType, const GrShaderCaps& shaderCaps)
: INHERITED(kGrCCPRPathProcessor_ClassID)
GrCCPathProcessor::GrCCPathProcessor(GrResourceProvider* rp, sk_sp<GrTextureProxy> atlas,
SkPath::FillType fillType, const GrShaderCaps& shaderCaps)
: INHERITED(kGrCCPathProcessor_ClassID)
, fFillType(fillType)
, fAtlasAccess(std::move(atlas), GrSamplerState::Filter::kNearest,
GrSamplerState::WrapMode::kClamp, kFragment_GrShaderFlag) {
@ -95,7 +95,7 @@ GrCCPRPathProcessor::GrCCPRPathProcessor(GrResourceProvider* rp, sk_sp<GrTexture
this->addTextureSampler(&fAtlasAccess);
}
void GrCCPRPathProcessor::getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const {
void GrCCPathProcessor::getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const {
b->add32((fFillType << 16) | this->atlasProxy()->origin());
}
@ -106,7 +106,7 @@ public:
private:
void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc,
FPCoordTransformIter&& transformIter) override {
const GrCCPRPathProcessor& proc = primProc.cast<GrCCPRPathProcessor>();
const GrCCPathProcessor& proc = primProc.cast<GrCCPathProcessor>();
pdman.set2f(fAtlasAdjustUniform, 1.0f / proc.atlas()->width(),
1.0f / proc.atlas()->height());
this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
@ -117,13 +117,13 @@ private:
typedef GrGLSLGeometryProcessor INHERITED;
};
GrGLSLPrimitiveProcessor* GrCCPRPathProcessor::createGLSLInstance(const GrShaderCaps&) const {
GrGLSLPrimitiveProcessor* GrCCPathProcessor::createGLSLInstance(const GrShaderCaps&) const {
return new GLSLPathProcessor();
}
void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
using InstanceAttribs = GrCCPRPathProcessor::InstanceAttribs;
const GrCCPRPathProcessor& proc = args.fGP.cast<GrCCPRPathProcessor>();
using InstanceAttribs = GrCCPathProcessor::InstanceAttribs;
const GrCCPathProcessor& proc = args.fGP.cast<GrCCPathProcessor>();
GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;

View File

@ -5,8 +5,8 @@
* found in the LICENSE file.
*/
#ifndef GrCCPRPathProcessor_DEFINED
#define GrCCPRPathProcessor_DEFINED
#ifndef GrCCPathProcessor_DEFINED
#define GrCCPathProcessor_DEFINED
#include "GrGeometryProcessor.h"
#include "SkPath.h"
@ -16,7 +16,7 @@ class GrOnFlushResourceProvider;
class GrShaderCaps;
/**
* This class draws AA paths using the coverage count masks produced by GrCCPRCoverageProcessor.
* This class draws AA paths using the coverage count masks produced by GrCCCoverageProcessor.
*
* Paths are drawn as bloated octagons, and coverage is derived from the coverage count mask and
* fill rule.
@ -24,7 +24,7 @@ class GrShaderCaps;
* The caller must set up an instance buffer as detailed below, then draw indexed-instanced
* triangles using the index and vertex buffers provided by this class.
*/
class GrCCPRPathProcessor : public GrGeometryProcessor {
class GrCCPathProcessor : public GrGeometryProcessor {
public:
static constexpr int kPerInstanceIndexCount = 6 * 3;
@ -55,10 +55,10 @@ public:
static sk_sp<const GrBuffer> FindIndexBuffer(GrOnFlushResourceProvider*);
static sk_sp<const GrBuffer> FindVertexBuffer(GrOnFlushResourceProvider*);
GrCCPRPathProcessor(GrResourceProvider*, sk_sp<GrTextureProxy> atlas, SkPath::FillType,
const GrShaderCaps&);
GrCCPathProcessor(GrResourceProvider*, sk_sp<GrTextureProxy> atlas, SkPath::FillType,
const GrShaderCaps&);
const char* name() const override { return "GrCCPRPathProcessor"; }
const char* name() const override { return "GrCCPathProcessor"; }
const GrSurfaceProxy* atlasProxy() const { return fAtlasAccess.proxy(); }
const GrTexture* atlas() const { return fAtlasAccess.peekTexture(); }
SkPath::FillType fillType() const { return fFillType; }

View File

@ -5,17 +5,17 @@
* found in the LICENSE file.
*/
#include "GrCCPRQuadraticShader.h"
#include "GrCCQuadraticShader.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
using Shader = GrCCPRCoverageProcessor::Shader;
using Shader = GrCCCoverageProcessor::Shader;
void GrCCPRQuadraticShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID, const char* wind,
GeometryVars* vars) const {
void GrCCQuadraticShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID, const char* wind,
GeometryVars* vars) const {
s->declareGlobal(fCanonicalMatrix);
s->codeAppendf("%s = float3x3(0.0, 0, 1, "
"0.5, 0, 1, "
@ -33,11 +33,11 @@ void GrCCPRQuadraticShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char*
this->onEmitSetupCode(s, pts, repetitionID, vars);
}
Shader::WindHandling GrCCPRQuadraticShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope,
SkString* code, const char* position,
const char* coverage,
const char* /*wind*/) {
Shader::WindHandling GrCCQuadraticShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope,
SkString* code, const char* position,
const char* coverage,
const char* /*wind*/) {
SkASSERT(!coverage);
fXYD.reset(kFloat3_GrSLType, scope);
@ -52,9 +52,9 @@ Shader::WindHandling GrCCPRQuadraticShader::onEmitVaryings(GrGLSLVaryingHandler*
return WindHandling::kNotHandled;
}
void GrCCPRQuadraticHullShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* /*repetitionID*/,
GeometryVars* vars) const {
void GrCCQuadraticHullShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* /*repetitionID*/,
GeometryVars* vars) const {
// Find the T value whose tangent is halfway between the tangents at the endpionts.
s->codeAppendf("float2 tan0 = %s[1] - %s[0];", pts, pts);
s->codeAppendf("float2 tan1 = %s[2] - %s[1];", pts, pts);
@ -71,30 +71,30 @@ void GrCCPRQuadraticHullShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const
vars->fHullVars.fAlternatePoints = "quadratic_hull";
}
void GrCCPRQuadraticHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code) {
void GrCCQuadraticHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code) {
fGrad.reset(kFloat2_GrSLType, scope);
varyingHandler->addVarying("grad", &fGrad);
code->appendf("%s = float2(2 * %s.x, -1) * float2x2(%s);",
OutName(fGrad), OutName(fXYD), fCanonicalMatrix.c_str());
}
void GrCCPRQuadraticHullShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
void GrCCQuadraticHullShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
f->codeAppendf("float d = (%s.x * %s.x - %s.y) * inversesqrt(dot(%s, %s));",
fXYD.fsIn(), fXYD.fsIn(), fXYD.fsIn(), fGrad.fsIn(), fGrad.fsIn());
f->codeAppendf("%s = clamp(0.5 - d, 0, 1);", outputCoverage);
f->codeAppendf("%s += min(%s.z, 0);", outputCoverage, fXYD.fsIn()); // Flat closing edge.
}
void GrCCPRQuadraticCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID,
GeometryVars* vars) const {
void GrCCQuadraticCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID,
GeometryVars* vars) const {
s->codeAppendf("float2 corner = %s[%s * 2];", pts, repetitionID);
vars->fCornerVars.fPoint = "corner";
}
void GrCCPRQuadraticCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
void GrCCQuadraticCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code) {
fdXYDdx.reset(kFloat3_GrSLType, scope);
varyingHandler->addFlatVarying("dXYDdx", &fdXYDdx);
@ -109,8 +109,8 @@ void GrCCPRQuadraticCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHa
fEdgeDistanceEquation.c_str());
}
void GrCCPRQuadraticCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
void GrCCQuadraticCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
f->codeAppendf("float x = %s.x, y = %s.y, d = %s.z;",
fXYD.fsIn(), fXYD.fsIn(), fXYD.fsIn());
f->codeAppendf("float2x3 grad_xyd = float2x3(%s, %s);", fdXYDdx.fsIn(), fdXYDdy.fsIn());

View File

@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
#ifndef GrCCPRQuadraticShader_DEFINED
#define GrCCPRQuadraticShader_DEFINED
#ifndef GrCCQuadraticShader_DEFINED
#define GrCCQuadraticShader_DEFINED
#include "ccpr/GrCCPRCoverageProcessor.h"
#include "ccpr/GrCCCoverageProcessor.h"
/**
* This class renders the coverage of closed quadratic curves using the techniques outlined in
@ -18,9 +18,9 @@
* https://www.microsoft.com/en-us/research/wp-content/uploads/2005/01/p1000-loop.pdf
*
* The provided curves must be monotonic with respect to the vector of their closing edge [P2 - P0].
* (Use GrCCPRGeometry.)
* (Use GrCCGeometry.)
*/
class GrCCPRQuadraticShader : public GrCCPRCoverageProcessor::Shader {
class GrCCQuadraticShader : public GrCCCoverageProcessor::Shader {
protected:
void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
const char* wind, GeometryVars*) const final;
@ -44,7 +44,7 @@ protected:
* uses simple distance-to-edge to subtract out coverage for the flat closing edge [P2 -> P0]. Since
* the provided curves are monotonic, this will get every pixel right except the two corners.
*/
class GrCCPRQuadraticHullShader : public GrCCPRQuadraticShader {
class GrCCQuadraticHullShader : public GrCCQuadraticShader {
void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
GeometryVars*) const override;
void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
@ -56,7 +56,7 @@ class GrCCPRQuadraticHullShader : public GrCCPRQuadraticShader {
/**
* This pass fixes the corners of a closed quadratic segment with soft MSAA.
*/
class GrCCPRQuadraticCornerShader : public GrCCPRQuadraticShader {
class GrCCQuadraticCornerShader : public GrCCQuadraticShader {
void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
GeometryVars*) const override;
void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;

View File

@ -5,17 +5,17 @@
* found in the LICENSE file.
*/
#include "GrCCPRTriangleShader.h"
#include "GrCCTriangleShader.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
using Shader = GrCCPRCoverageProcessor::Shader;
using Shader = GrCCCoverageProcessor::Shader;
Shader::WindHandling GrCCPRTriangleShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope,
SkString* code, const char* /*position*/,
const char* coverage, const char* wind) {
Shader::WindHandling GrCCTriangleShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope,
SkString* code, const char* /*position*/,
const char* coverage, const char* wind) {
fCoverageTimesWind.reset(kHalf_GrSLType, scope);
if (!coverage) {
varyingHandler->addFlatVarying("wind", &fCoverageTimesWind);
@ -27,14 +27,14 @@ Shader::WindHandling GrCCPRTriangleShader::onEmitVaryings(GrGLSLVaryingHandler*
return WindHandling::kHandled;
}
void GrCCPRTriangleShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
void GrCCTriangleShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
f->codeAppendf("%s = %s;", outputCoverage, fCoverageTimesWind.fsIn());
}
void GrCCPRTriangleCornerShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID, const char* wind,
GeometryVars* vars) const {
void GrCCTriangleCornerShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
const char* repetitionID, const char* wind,
GeometryVars* vars) const {
s->codeAppendf("float2 corner = %s[%s];", pts, repetitionID);
vars->fCornerVars.fPoint = "corner";
@ -87,10 +87,10 @@ void GrCCPRTriangleCornerShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const
}
Shader::WindHandling
GrCCPRTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code,
const char* position, const char* coverage,
const char* /*wind*/) {
GrCCTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
GrGLSLVarying::Scope scope, SkString* code,
const char* position, const char* coverage,
const char* /*wind*/) {
SkASSERT(!coverage);
fCornerLocationInAABoxes.reset(kFloat2x2_GrSLType, scope);
@ -109,8 +109,8 @@ GrCCPRTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
return WindHandling::kNotHandled;
}
void GrCCPRTriangleCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
void GrCCTriangleCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
const char* outputCoverage) const {
// By the time we reach this shader, the pixel is in the following state:
//
// 1. The hull shader has emitted a coverage of 1.

View File

@ -5,10 +5,10 @@
* found in the LICENSE file.
*/
#ifndef GrCCPRTriangleShader_DEFINED
#define GrCCPRTriangleShader_DEFINED
#ifndef GrCCTriangleShader_DEFINED
#define GrCCTriangleShader_DEFINED
#include "ccpr/GrCCPRCoverageProcessor.h"
#include "ccpr/GrCCCoverageProcessor.h"
/**
* Steps 1 & 2: Draw the triangle's conservative raster hull with a coverage of +1, then smooth the
@ -16,7 +16,7 @@
* coverage=-1 on the outside to coverage=0 on the inside. The Impl may choose to
* implement these steps in either one or two actual render passes.
*/
class GrCCPRTriangleShader : public GrCCPRCoverageProcessor::Shader {
class GrCCTriangleShader : public GrCCCoverageProcessor::Shader {
WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
const char* position, const char* coverage,
const char* wind) override;
@ -30,7 +30,7 @@ class GrCCPRTriangleShader : public GrCCPRCoverageProcessor::Shader {
* done previously so that it takes into account the region that is outside both edges at
* the same time.
*/
class GrCCPRTriangleCornerShader : public GrCCPRCoverageProcessor::Shader {
class GrCCTriangleCornerShader : public GrCCCoverageProcessor::Shader {
void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
const char* wind, GeometryVars*) const override;
WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,

View File

@ -11,14 +11,14 @@
#include "GrClip.h"
#include "GrGpu.h"
#include "GrGpuCommandBuffer.h"
#include "GrOpFlushState.h"
#include "GrRenderTargetOpList.h"
#include "GrStyle.h"
#include "GrTexture.h"
#include "SkMakeUnique.h"
#include "SkMatrix.h"
#include "SkPathOps.h"
#include "GrOpFlushState.h"
#include "GrRenderTargetOpList.h"
#include "GrTexture.h"
#include "GrStyle.h"
#include "ccpr/GrCCPRClipProcessor.h"
#include "ccpr/GrCCClipProcessor.h"
// Shorthand for keeping line lengths under control with nested classes...
using CCPR = GrCoverageCountingPathRenderer;
@ -38,31 +38,27 @@ static void crop_path(const SkPath& path, const SkIRect& cropbox, SkPath* out) {
bool GrCoverageCountingPathRenderer::IsSupported(const GrCaps& caps) {
const GrShaderCaps& shaderCaps = *caps.shaderCaps();
return shaderCaps.integerSupport() &&
shaderCaps.flatInterpolationSupport() &&
caps.instanceAttribSupport() &&
GrCaps::kNone_MapFlags != caps.mapBufferFlags() &&
return shaderCaps.integerSupport() && shaderCaps.flatInterpolationSupport() &&
caps.instanceAttribSupport() && GrCaps::kNone_MapFlags != caps.mapBufferFlags() &&
caps.isConfigTexturable(kAlpha_half_GrPixelConfig) &&
caps.isConfigRenderable(kAlpha_half_GrPixelConfig, /*withMSAA=*/false) &&
!caps.blacklistCoverageCounting();
}
sk_sp<GrCoverageCountingPathRenderer>
GrCoverageCountingPathRenderer::CreateIfSupported(const GrCaps& caps, bool drawCachablePaths) {
sk_sp<GrCoverageCountingPathRenderer> GrCoverageCountingPathRenderer::CreateIfSupported(
const GrCaps& caps, bool drawCachablePaths) {
auto ccpr = IsSupported(caps) ? new GrCoverageCountingPathRenderer(drawCachablePaths) : nullptr;
return sk_sp<GrCoverageCountingPathRenderer>(ccpr);
}
GrPathRenderer::CanDrawPath
GrCoverageCountingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
GrPathRenderer::CanDrawPath GrCoverageCountingPathRenderer::onCanDrawPath(
const CanDrawPathArgs& args) const {
if (args.fShape->hasUnstyledKey() && !fDrawCachablePaths) {
return CanDrawPath::kNo;
}
if (!args.fShape->style().isSimpleFill() ||
args.fShape->inverseFilled() ||
args.fViewMatrix->hasPerspective() ||
GrAAType::kCoverage != args.fAAType) {
if (!args.fShape->style().isSimpleFill() || args.fShape->inverseFilled() ||
args.fViewMatrix->hasPerspective() || GrAAType::kCoverage != args.fAAType) {
return CanDrawPath::kNo;
}
@ -113,8 +109,8 @@ CCPR::DrawPathsOp::DrawPathsOp(GrCoverageCountingPathRenderer* ccpr, const DrawP
, fOwningRTPendingPaths(nullptr) {
SkDEBUGCODE(++fCCPR->fPendingDrawOpsCount);
SkDEBUGCODE(fBaseInstance = -1);
SkDEBUGCODE(fInstanceCount = 1;)
SkDEBUGCODE(fNumSkippedInstances = 0;)
SkDEBUGCODE(fInstanceCount = 1);
SkDEBUGCODE(fNumSkippedInstances = 0);
GrRenderTargetContext* const rtc = args.fRenderTargetContext;
SkRect devBounds;
@ -133,7 +129,7 @@ CCPR::DrawPathsOp::DrawPathsOp(GrCoverageCountingPathRenderer* ccpr, const DrawP
fHeadDraw.fMatrix = *args.fViewMatrix;
args.fShape->asPath(&fHeadDraw.fPath);
}
fHeadDraw.fColor = color; // Can't call args.fPaint.getColor() because it has been std::move'd.
fHeadDraw.fColor = color; // Can't call args.fPaint.getColor() because it has been std::move'd.
// FIXME: intersect with clip bounds to (hopefully) improve batching.
// (This is nontrivial due to assumptions in generating the octagon cover geometry.)
@ -155,9 +151,9 @@ GrDrawOp::RequiresDstTexture CCPR::DrawPathsOp::finalize(const GrCaps& caps,
// There should only be one single path draw in this Op right now.
SkASSERT(1 == fInstanceCount);
SkASSERT(&fHeadDraw == fTailDraw);
GrProcessorSet::Analysis analysis = fProcessors.finalize(
fHeadDraw.fColor, GrProcessorAnalysisCoverage::kSingleChannel, clip, false, caps,
dstIsClamped, &fHeadDraw.fColor);
GrProcessorSet::Analysis analysis =
fProcessors.finalize(fHeadDraw.fColor, GrProcessorAnalysisCoverage::kSingleChannel,
clip, false, caps, dstIsClamped, &fHeadDraw.fColor);
return analysis.requiresDstTexture() ? RequiresDstTexture::kYes : RequiresDstTexture::kNo;
}
@ -170,8 +166,7 @@ bool CCPR::DrawPathsOp::onCombineIfPossible(GrOp* op, const GrCaps& caps) {
SkASSERT(!that->fOwningRTPendingPaths || that->fOwningRTPendingPaths == fOwningRTPendingPaths);
SkASSERT(that->fInstanceCount);
if (this->getFillType() != that->getFillType() ||
fSRGBFlags != that->fSRGBFlags ||
if (this->getFillType() != that->getFillType() || fSRGBFlags != that->fSRGBFlags ||
fProcessors != that->fProcessors) {
return false;
}
@ -181,7 +176,7 @@ bool CCPR::DrawPathsOp::onCombineIfPossible(GrOp* op, const GrCaps& caps) {
this->joinBounds(*that);
SkDEBUGCODE(fInstanceCount += that->fInstanceCount;)
SkDEBUGCODE(fInstanceCount += that->fInstanceCount);
SkDEBUGCODE(that->fInstanceCount = 0);
return true;
}
@ -205,11 +200,10 @@ bool GrCoverageCountingPathRenderer::canMakeClipProcessor(const SkPath& deviceSp
return true;
}
std::unique_ptr<GrFragmentProcessor>
GrCoverageCountingPathRenderer::makeClipProcessor(uint32_t opListID, const SkPath& deviceSpacePath,
const SkIRect& accessRect, int rtWidth,
int rtHeight) {
using MustCheckBounds = GrCCPRClipProcessor::MustCheckBounds;
std::unique_ptr<GrFragmentProcessor> GrCoverageCountingPathRenderer::makeClipProcessor(
uint32_t opListID, const SkPath& deviceSpacePath, const SkIRect& accessRect, int rtWidth,
int rtHeight) {
using MustCheckBounds = GrCCClipProcessor::MustCheckBounds;
SkASSERT(!fFlushing);
SkASSERT(this->canMakeClipProcessor(deviceSpacePath));
@ -223,37 +217,39 @@ GrCoverageCountingPathRenderer::makeClipProcessor(uint32_t opListID, const SkPat
}
bool mustCheckBounds = !clipPath.pathDevIBounds().contains(accessRect);
return skstd::make_unique<GrCCPRClipProcessor>(&clipPath, MustCheckBounds(mustCheckBounds),
deviceSpacePath.getFillType());
return skstd::make_unique<GrCCClipProcessor>(&clipPath, MustCheckBounds(mustCheckBounds),
deviceSpacePath.getFillType());
}
void CCPR::ClipPath::init(const SkPath& deviceSpacePath, const SkIRect& accessRect, int rtWidth,
int rtHeight) {
SkASSERT(this->isUninitialized());
fAtlasLazyProxy = GrSurfaceProxy::MakeLazy([this](GrResourceProvider* resourceProvider,
GrSurfaceOrigin* outOrigin) {
SkASSERT(fHasAtlas);
SkASSERT(!fHasAtlasTransform);
fAtlasLazyProxy = GrSurfaceProxy::MakeLazy(
[this](GrResourceProvider* resourceProvider, GrSurfaceOrigin* outOrigin) {
SkASSERT(fHasAtlas);
SkASSERT(!fHasAtlasTransform);
GrTextureProxy* textureProxy = fAtlas ? fAtlas->textureProxy() : nullptr;
if (!textureProxy || !textureProxy->instantiate(resourceProvider)) {
fAtlasScale = fAtlasTranslate = {0, 0};
SkDEBUGCODE(fHasAtlasTransform = true);
return sk_sp<GrTexture>();
}
GrTextureProxy* textureProxy = fAtlas ? fAtlas->textureProxy() : nullptr;
if (!textureProxy || !textureProxy->instantiate(resourceProvider)) {
fAtlasScale = fAtlasTranslate = {0, 0};
SkDEBUGCODE(fHasAtlasTransform = true);
return sk_sp<GrTexture>();
}
fAtlasScale = {1.f / textureProxy->width(), 1.f / textureProxy->height()};
fAtlasTranslate = {fAtlasOffsetX * fAtlasScale.x(), fAtlasOffsetY * fAtlasScale.y()};
if (kBottomLeft_GrSurfaceOrigin == textureProxy->origin()) {
fAtlasScale.fY = -fAtlasScale.y();
fAtlasTranslate.fY = 1 - fAtlasTranslate.y();
}
SkDEBUGCODE(fHasAtlasTransform = true);
fAtlasScale = {1.f / textureProxy->width(), 1.f / textureProxy->height()};
fAtlasTranslate = {fAtlasOffsetX * fAtlasScale.x(),
fAtlasOffsetY * fAtlasScale.y()};
if (kBottomLeft_GrSurfaceOrigin == textureProxy->origin()) {
fAtlasScale.fY = -fAtlasScale.y();
fAtlasTranslate.fY = 1 - fAtlasTranslate.y();
}
SkDEBUGCODE(fHasAtlasTransform = true);
*outOrigin = textureProxy->origin();
return sk_ref_sp(textureProxy->priv().peekTexture());
}, GrSurfaceProxy::Renderable::kYes, kAlpha_half_GrPixelConfig);
*outOrigin = textureProxy->origin();
return sk_ref_sp(textureProxy->priv().peekTexture());
},
GrSurfaceProxy::Renderable::kYes, kAlpha_half_GrPixelConfig);
const SkRect& pathDevBounds = deviceSpacePath.getBounds();
if (SkTMax(pathDevBounds.height(), pathDevBounds.width()) > kPathCropThreshold) {
@ -269,24 +265,24 @@ void CCPR::ClipPath::init(const SkPath& deviceSpacePath, const SkIRect& accessRe
void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlushRP,
const uint32_t* opListIDs, int numOpListIDs,
SkTArray<sk_sp<GrRenderTargetContext>>* results) {
using PathInstance = GrCCPRPathProcessor::Instance;
using PathInstance = GrCCPathProcessor::Instance;
SkASSERT(!fFlushing);
SkASSERT(!fPerFlushIndexBuffer);
SkASSERT(!fPerFlushVertexBuffer);
SkASSERT(!fPerFlushInstanceBuffer);
SkASSERT(fPerFlushAtlases.empty());
SkDEBUGCODE(fFlushing = true;)
SkDEBUGCODE(fFlushing = true);
if (fRTPendingPathsMap.empty()) {
return; // Nothing to draw.
return; // Nothing to draw.
}
fPerFlushResourcesAreValid = false;
// Count the paths that are being flushed.
int maxTotalPaths = 0, maxPathPoints = 0, numSkPoints = 0, numSkVerbs = 0;
SkDEBUGCODE(int numClipPaths = 0;)
SkDEBUGCODE(int numClipPaths = 0);
for (int i = 0; i < numOpListIDs; ++i) {
auto it = fRTPendingPathsMap.find(opListIDs[i]);
if (fRTPendingPathsMap.end() == it) {
@ -318,24 +314,24 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
}
if (!maxTotalPaths) {
return; // Nothing to draw.
return; // Nothing to draw.
}
// Allocate GPU buffers.
fPerFlushIndexBuffer = GrCCPRPathProcessor::FindIndexBuffer(onFlushRP);
fPerFlushIndexBuffer = GrCCPathProcessor::FindIndexBuffer(onFlushRP);
if (!fPerFlushIndexBuffer) {
SkDebugf("WARNING: failed to allocate ccpr path index buffer.\n");
return;
}
fPerFlushVertexBuffer = GrCCPRPathProcessor::FindVertexBuffer(onFlushRP);
fPerFlushVertexBuffer = GrCCPathProcessor::FindVertexBuffer(onFlushRP);
if (!fPerFlushVertexBuffer) {
SkDebugf("WARNING: failed to allocate ccpr path vertex buffer.\n");
return;
}
fPerFlushInstanceBuffer = onFlushRP->makeBuffer(kVertex_GrBufferType,
maxTotalPaths * sizeof(PathInstance));
fPerFlushInstanceBuffer =
onFlushRP->makeBuffer(kVertex_GrBufferType, maxTotalPaths * sizeof(PathInstance));
if (!fPerFlushInstanceBuffer) {
SkDebugf("WARNING: failed to allocate path instance buffer. No paths will be drawn.\n");
return;
@ -345,8 +341,8 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
SkASSERT(pathInstanceData);
int pathInstanceIdx = 0;
GrCCPRCoverageOpsBuilder atlasOpsBuilder(maxTotalPaths, maxPathPoints, numSkPoints, numSkVerbs);
SkDEBUGCODE(int skippedTotalPaths = 0;)
GrCCCoverageOpsBuilder atlasOpsBuilder(maxTotalPaths, maxPathPoints, numSkPoints, numSkVerbs);
SkDEBUGCODE(int skippedTotalPaths = 0);
// Allocate atlas(es) and fill out GPU instance buffers.
for (int i = 0; i < numOpListIDs; ++i) {
@ -363,7 +359,7 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
pathInstanceIdx = op->setupResources(onFlushRP, &atlasOpsBuilder, pathInstanceData,
pathInstanceIdx);
drawOpsIter.next();
SkDEBUGCODE(skippedTotalPaths += op->numSkippedInstances_debugOnly();)
SkDEBUGCODE(skippedTotalPaths += op->numSkippedInstances_debugOnly());
}
for (auto& clipsIter : rtPendingPaths.fClipPaths) {
@ -379,7 +375,7 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
atlasOpsBuilder.emitOp(fPerFlushAtlases.back().drawBounds());
}
SkSTArray<4, std::unique_ptr<GrCCPRCoverageOp>> atlasOps(fPerFlushAtlases.count());
SkSTArray<4, std::unique_ptr<GrCCCoverageOp>> atlasOps(fPerFlushAtlases.count());
if (!atlasOpsBuilder.finalize(onFlushRP, &atlasOps)) {
SkDebugf("WARNING: failed to allocate ccpr atlas buffers. No paths will be drawn.\n");
return;
@ -387,12 +383,12 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
SkASSERT(atlasOps.count() == fPerFlushAtlases.count());
// Draw the coverage ops into their respective atlases.
GrTAllocator<GrCCPRAtlas>::Iter atlasIter(&fPerFlushAtlases);
for (std::unique_ptr<GrCCPRCoverageOp>& atlasOp : atlasOps) {
GrTAllocator<GrCCAtlas>::Iter atlasIter(&fPerFlushAtlases);
for (std::unique_ptr<GrCCCoverageOp>& atlasOp : atlasOps) {
SkAssertResult(atlasIter.next());
GrCCPRAtlas* atlas = atlasIter.get();
SkASSERT(atlasOp->bounds() == SkRect::MakeIWH(atlas->drawBounds().width(),
atlas->drawBounds().height()));
GrCCAtlas* atlas = atlasIter.get();
SkASSERT(atlasOp->bounds() ==
SkRect::MakeIWH(atlas->drawBounds().width(), atlas->drawBounds().height()));
if (auto rtc = atlas->finalize(onFlushRP, std::move(atlasOp))) {
results->push_back(std::move(rtc));
}
@ -403,10 +399,10 @@ void GrCoverageCountingPathRenderer::preFlush(GrOnFlushResourceProvider* onFlush
}
int CCPR::DrawPathsOp::setupResources(GrOnFlushResourceProvider* onFlushRP,
GrCCPRCoverageOpsBuilder* atlasOpsBuilder,
GrCCPRPathProcessor::Instance* pathInstanceData,
GrCCCoverageOpsBuilder* atlasOpsBuilder,
GrCCPathProcessor::Instance* pathInstanceData,
int pathInstanceIdx) {
const GrCCPRAtlas* currentAtlas = nullptr;
const GrCCAtlas* currentAtlas = nullptr;
SkASSERT(fInstanceCount > 0);
SkASSERT(-1 == fBaseInstance);
fBaseInstance = pathInstanceIdx;
@ -422,9 +418,8 @@ int CCPR::DrawPathsOp::setupResources(GrOnFlushResourceProvider* onFlushRP,
devBounds.roundOut(&devIBounds);
int16_t offsetX, offsetY;
GrCCPRAtlas* atlas = fCCPR->placeParsedPathInAtlas(onFlushRP, draw->fClipIBounds,
devIBounds, &offsetX, &offsetY,
atlasOpsBuilder);
GrCCAtlas* atlas = fCCPR->placeParsedPathInAtlas(onFlushRP, draw->fClipIBounds, devIBounds,
&offsetX, &offsetY, atlasOpsBuilder);
if (!atlas) {
SkDEBUGCODE(++fNumSkippedInstances);
continue;
@ -438,13 +433,12 @@ int CCPR::DrawPathsOp::setupResources(GrOnFlushResourceProvider* onFlushRP,
const SkMatrix& m = draw->fMatrix;
pathInstanceData[pathInstanceIdx++] = {
devBounds,
devBounds45,
{{m.getScaleX(), m.getSkewY(), m.getSkewX(), m.getScaleY()}},
{{m.getTranslateX(), m.getTranslateY()}},
{{offsetX, offsetY}},
draw->fColor
};
devBounds,
devBounds45,
{{m.getScaleX(), m.getSkewY(), m.getSkewX(), m.getScaleY()}},
{{m.getTranslateX(), m.getTranslateY()}},
{{offsetX, offsetY}},
draw->fColor};
}
SkASSERT(pathInstanceIdx == fBaseInstance + fInstanceCount - fNumSkippedInstances);
@ -457,7 +451,7 @@ int CCPR::DrawPathsOp::setupResources(GrOnFlushResourceProvider* onFlushRP,
void CCPR::ClipPath::placePathInAtlas(GrCoverageCountingPathRenderer* ccpr,
GrOnFlushResourceProvider* onFlushRP,
GrCCPRCoverageOpsBuilder* atlasOpsBuilder) {
GrCCCoverageOpsBuilder* atlasOpsBuilder) {
SkASSERT(!this->isUninitialized());
SkASSERT(!fHasAtlas);
atlasOpsBuilder->parseDeviceSpacePath(fDeviceSpacePath);
@ -466,14 +460,14 @@ void CCPR::ClipPath::placePathInAtlas(GrCoverageCountingPathRenderer* ccpr,
SkDEBUGCODE(fHasAtlas = true);
}
GrCCPRAtlas*
GrCoverageCountingPathRenderer::placeParsedPathInAtlas(GrOnFlushResourceProvider* onFlushRP,
const SkIRect& clipIBounds,
const SkIRect& pathIBounds,
int16_t* atlasOffsetX,
int16_t* atlasOffsetY,
GrCCPRCoverageOpsBuilder* atlasOpsBuilder) {
using ScissorMode = GrCCPRCoverageOpsBuilder::ScissorMode;
GrCCAtlas* GrCoverageCountingPathRenderer::placeParsedPathInAtlas(
GrOnFlushResourceProvider* onFlushRP,
const SkIRect& clipIBounds,
const SkIRect& pathIBounds,
int16_t* atlasOffsetX,
int16_t* atlasOffsetY,
GrCCCoverageOpsBuilder* atlasOpsBuilder) {
using ScissorMode = GrCCCoverageOpsBuilder::ScissorMode;
ScissorMode scissorMode;
SkIRect clippedPathIBounds;
@ -509,10 +503,10 @@ void CCPR::DrawPathsOp::onExecute(GrOpFlushState* flushState) {
SkASSERT(flushState->rtCommandBuffer());
if (!fCCPR->fPerFlushResourcesAreValid) {
return; // Setup failed.
return; // Setup failed.
}
SkASSERT(fBaseInstance >= 0); // Make sure setupResources has been called.
SkASSERT(fBaseInstance >= 0); // Make sure setupResources has been called.
GrPipeline::InitArgs initArgs;
initArgs.fFlags = fSRGBFlags;
@ -529,16 +523,16 @@ void CCPR::DrawPathsOp::onExecute(GrOpFlushState* flushState) {
SkASSERT(batch.fEndInstanceIdx > baseInstance);
if (!batch.fAtlas->textureProxy()) {
continue; // Atlas failed to allocate.
continue; // Atlas failed to allocate.
}
GrCCPRPathProcessor coverProc(flushState->resourceProvider(),
sk_ref_sp(batch.fAtlas->textureProxy()), this->getFillType(),
*flushState->gpu()->caps()->shaderCaps());
GrCCPathProcessor coverProc(flushState->resourceProvider(),
sk_ref_sp(batch.fAtlas->textureProxy()), this->getFillType(),
*flushState->gpu()->caps()->shaderCaps());
GrMesh mesh(GrPrimitiveType::kTriangles);
mesh.setIndexedInstanced(fCCPR->fPerFlushIndexBuffer.get(),
GrCCPRPathProcessor::kPerInstanceIndexCount,
GrCCPathProcessor::kPerInstanceIndexCount,
fCCPR->fPerFlushInstanceBuffer.get(),
batch.fEndInstanceIdx - baseInstance, baseInstance);
mesh.setVertexData(fCCPR->fPerFlushVertexBuffer.get());
@ -560,5 +554,5 @@ void GrCoverageCountingPathRenderer::postFlush(GrDeferredUploadToken, const uint
for (int i = 0; i < numOpListIDs; ++i) {
fRTPendingPathsMap.erase(opListIDs[i]);
}
SkDEBUGCODE(fFlushing = false;)
SkDEBUGCODE(fFlushing = false);
}

View File

@ -8,27 +8,24 @@
#ifndef GrCoverageCountingPathRenderer_DEFINED
#define GrCoverageCountingPathRenderer_DEFINED
#include <map>
#include "GrAllocator.h"
#include "GrOnFlushResourceProvider.h"
#include "GrPathRenderer.h"
#include "SkTInternalLList.h"
#include "ccpr/GrCCPRAtlas.h"
#include "ccpr/GrCCPRCoverageOp.h"
#include "ccpr/GrCCPRPathProcessor.h"
#include "ccpr/GrCCAtlas.h"
#include "ccpr/GrCCCoverageOp.h"
#include "ccpr/GrCCPathProcessor.h"
#include "ops/GrDrawOp.h"
#include <map>
/**
* This is a path renderer that draws antialiased paths by counting coverage in an offscreen
* buffer. (See GrCCPRCoverageProcessor, GrCCPRPathProcessor)
* buffer. (See GrCCCoverageProcessor, GrCCPathProcessor)
*
* It also serves as the per-render-target tracker for pending path draws, and at the start of
* flush, it compiles GPU buffers and renders a "coverage count atlas" for the upcoming paths.
*/
class GrCoverageCountingPathRenderer
: public GrPathRenderer
, public GrOnFlushCallbackObject {
class GrCoverageCountingPathRenderer : public GrPathRenderer, public GrOnFlushCallbackObject {
struct RTPendingPaths;
public:
@ -52,7 +49,7 @@ public:
DrawPathsOp(GrCoverageCountingPathRenderer*, const DrawPathArgs&, GrColor);
~DrawPathsOp() override;
struct SingleDraw {
struct SingleDraw {
SkIRect fClipIBounds;
SkMatrix fMatrix;
SkPath fPath;
@ -80,8 +77,8 @@ public:
void onPrepare(GrOpFlushState*) override {}
void onExecute(GrOpFlushState*) override;
int setupResources(GrOnFlushResourceProvider*, GrCCPRCoverageOpsBuilder*,
GrCCPRPathProcessor::Instance* pathInstanceData, int pathInstanceIdx);
int setupResources(GrOnFlushResourceProvider*, GrCCCoverageOpsBuilder*,
GrCCPathProcessor::Instance* pathInstanceData, int pathInstanceIdx);
private:
SkPath::FillType getFillType() const {
@ -90,11 +87,11 @@ public:
}
struct AtlasBatch {
const GrCCPRAtlas* fAtlas;
const GrCCAtlas* fAtlas;
int fEndInstanceIdx;
};
void addAtlasBatch(const GrCCPRAtlas* atlas, int endInstanceIdx) {
void addAtlasBatch(const GrCCAtlas* atlas, int endInstanceIdx) {
SkASSERT(endInstanceIdx > fBaseInstance);
SkASSERT(fAtlasBatches.empty() ||
endInstanceIdx > fAtlasBatches.back().fEndInstanceIdx);
@ -108,8 +105,8 @@ public:
SingleDraw* fTailDraw;
RTPendingPaths* fOwningRTPendingPaths;
int fBaseInstance;
SkDEBUGCODE(int fInstanceCount;)
SkDEBUGCODE(int fNumSkippedInstances;)
SkDEBUGCODE(int fInstanceCount);
SkDEBUGCODE(int fNumSkippedInstances);
SkSTArray<1, AtlasBatch, true> fAtlasBatches;
typedef GrDrawOp INHERITED;
@ -158,9 +155,12 @@ public:
return fPathDevIBounds;
}
void placePathInAtlas(GrCoverageCountingPathRenderer*, GrOnFlushResourceProvider*,
GrCCPRCoverageOpsBuilder*);
GrCCCoverageOpsBuilder*);
const SkVector& atlasScale() const { SkASSERT(fHasAtlasTransform); return fAtlasScale; }
const SkVector& atlasScale() const {
SkASSERT(fHasAtlasTransform);
return fAtlasScale;
}
const SkVector& atlasTranslate() const {
SkASSERT(fHasAtlasTransform);
return fAtlasTranslate;
@ -172,7 +172,7 @@ public:
SkIRect fPathDevIBounds;
SkIRect fAccessRect;
const GrCCPRAtlas* fAtlas = nullptr;
const GrCCAtlas* fAtlas = nullptr;
int16_t fAtlasOffsetX;
int16_t fAtlasOffsetY;
SkDEBUGCODE(bool fHasAtlas = false);
@ -186,8 +186,8 @@ public:
std::unique_ptr<GrFragmentProcessor> makeClipProcessor(uint32_t oplistID,
const SkPath& deviceSpacePath,
const SkIRect& accessRect,
int rtWidth, int rtHeight);
const SkIRect& accessRect, int rtWidth,
int rtHeight);
// GrOnFlushCallbackObject overrides.
void preFlush(GrOnFlushResourceProvider*, const uint32_t* opListIDs, int numOpListIDs,
@ -198,9 +198,9 @@ private:
GrCoverageCountingPathRenderer(bool drawCachablePaths)
: fDrawCachablePaths(drawCachablePaths) {}
GrCCPRAtlas* placeParsedPathInAtlas(GrOnFlushResourceProvider*, const SkIRect& accessRect,
const SkIRect& pathIBounds, int16_t* atlasOffsetX,
int16_t* atlasOffsetY, GrCCPRCoverageOpsBuilder*);
GrCCAtlas* placeParsedPathInAtlas(GrOnFlushResourceProvider*, const SkIRect& accessRect,
const SkIRect& pathIBounds, int16_t* atlasOffsetX,
int16_t* atlasOffsetY, GrCCCoverageOpsBuilder*);
struct RTPendingPaths {
~RTPendingPaths() {
@ -215,14 +215,14 @@ private:
// A map from render target ID to the individual render target's pending paths.
std::map<uint32_t, RTPendingPaths> fRTPendingPathsMap;
SkDEBUGCODE(int fPendingDrawOpsCount = 0;)
SkDEBUGCODE(int fPendingDrawOpsCount = 0);
sk_sp<const GrBuffer> fPerFlushIndexBuffer;
sk_sp<const GrBuffer> fPerFlushVertexBuffer;
sk_sp<GrBuffer> fPerFlushInstanceBuffer;
GrSTAllocator<4, GrCCPRAtlas> fPerFlushAtlases;
GrSTAllocator<4, GrCCAtlas> fPerFlushAtlases;
bool fPerFlushResourcesAreValid;
SkDEBUGCODE(bool fFlushing = false;)
SkDEBUGCODE(bool fFlushing = false);
const bool fDrawCachablePaths;
};