ccpr: Don't do coverage count transformations on literal coverage atlases

Previously we would just run coverage count transformations on
everything, including cached literal coverage atlases. This was
wasteful since it isn't necessary if the atlas already has literal
coverage. MSAA mode will introduce even more atlases that don't need
coverage count transformations, so it's definitely time to clean this
up.

Bug: skia:
Change-Id: Ifc72eaa7cbd4ab5e4ef4acb5610117ae9f54e4c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/227144
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
Chris Dalton 2019-07-12 09:55:52 -06:00 committed by Skia Commit-Bot
parent fcf6359ce8
commit 6a5317a0e5
5 changed files with 64 additions and 31 deletions

View File

@ -357,7 +357,9 @@ void GrCCDrawPathsOp::SingleDraw::setupResources(
== fCacheEntry->cachedAtlas()->coverageType())
? SkPMColor4f{0,0,.25,.25} : SkPMColor4f{0,.25,0,.25};
#endif
op->recordInstance(fCacheEntry->cachedAtlas()->getOnFlushProxy(),
auto coverageMode = GrCCPathProcessor::GetCoverageMode(
fCacheEntry->cachedAtlas()->coverageType());
op->recordInstance(coverageMode, fCacheEntry->cachedAtlas()->getOnFlushProxy(),
resources->nextPathInstanceIdx());
resources->appendDrawPathInstance().set(
*fCacheEntry, fCachedMaskShift, SkPMColor4f_toFP16(fColor), doEvenOddFill);
@ -375,7 +377,8 @@ void GrCCDrawPathsOp::SingleDraw::setupResources(
if (auto atlas = resources->renderShapeInAtlas(
fMaskDevIBounds, fMatrix, fShape, fStrokeDevWidth, &octoBounds, &devIBounds,
&devToAtlasOffset)) {
op->recordInstance(atlas->textureProxy(), resources->nextPathInstanceIdx());
op->recordInstance(GrCCPathProcessor::CoverageMode::kCoverageCount, atlas->textureProxy(),
resources->nextPathInstanceIdx());
resources->appendDrawPathInstance().set(
octoBounds, devToAtlasOffset, SkPMColor4f_toFP16(fColor), doEvenOddFill);
@ -389,16 +392,16 @@ void GrCCDrawPathsOp::SingleDraw::setupResources(
}
}
inline void GrCCDrawPathsOp::recordInstance(GrTextureProxy* atlasProxy, int instanceIdx) {
inline void GrCCDrawPathsOp::recordInstance(
GrCCPathProcessor::CoverageMode coverageMode, GrTextureProxy* atlasProxy, int instanceIdx) {
if (fInstanceRanges.empty()) {
fInstanceRanges.push_back({atlasProxy, instanceIdx});
return;
}
if (fInstanceRanges.back().fAtlasProxy != atlasProxy) {
fInstanceRanges.push_back({coverageMode, atlasProxy, instanceIdx});
} else if (fInstanceRanges.back().fAtlasProxy != atlasProxy) {
fInstanceRanges.back().fEndInstanceIdx = instanceIdx;
fInstanceRanges.push_back({atlasProxy, instanceIdx});
return;
fInstanceRanges.push_back({coverageMode, atlasProxy, instanceIdx});
}
SkASSERT(fInstanceRanges.back().fCoverageMode == coverageMode);
SkASSERT(fInstanceRanges.back().fAtlasProxy == atlasProxy);
}
void GrCCDrawPathsOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
@ -427,7 +430,7 @@ void GrCCDrawPathsOp::onExecute(GrOpFlushState* flushState, const SkRect& chainB
SkASSERT(atlas->isInstantiated());
GrCCPathProcessor pathProc(
atlas->peekTexture(), atlas->textureSwizzle(), atlas->origin(),
range.fCoverageMode, atlas->peekTexture(), atlas->textureSwizzle(), atlas->origin(),
fViewMatrixIfUsingLocalCoords);
GrTextureProxy* atlasProxy = range.fAtlasProxy;
fixedDynamicState.fPrimitiveProcessorTextures = &atlasProxy;

View File

@ -84,7 +84,8 @@ private:
const SkIRect& shapeConservativeIBounds, const SkIRect& maskDevIBounds,
const SkRect& conservativeDevBounds, GrPaint&&);
void recordInstance(GrTextureProxy* atlasProxy, int instanceIdx);
void recordInstance(
GrCCPathProcessor::CoverageMode, GrTextureProxy* atlasProxy, int instanceIdx);
const SkMatrix fViewMatrixIfUsingLocalCoords;
@ -133,6 +134,7 @@ private:
GrProcessorSet fProcessors;
struct InstanceRange {
GrCCPathProcessor::CoverageMode fCoverageMode;
GrTextureProxy* fAtlasProxy;
int fEndInstanceIdx;
};

View File

@ -79,10 +79,11 @@ sk_sp<const GrGpuBuffer> GrCCPathProcessor::FindIndexBuffer(GrOnFlushResourcePro
}
}
GrCCPathProcessor::GrCCPathProcessor(const GrTexture* atlasTexture, const GrSwizzle& swizzle,
GrSurfaceOrigin atlasOrigin,
GrCCPathProcessor::GrCCPathProcessor(CoverageMode coverageMode, const GrTexture* atlasTexture,
const GrSwizzle& swizzle, GrSurfaceOrigin atlasOrigin,
const SkMatrix& viewMatrixIfUsingLocalCoords)
: INHERITED(kGrCCPathProcessor_ClassID)
, fCoverageMode(coverageMode)
, fAtlasAccess(atlasTexture->texturePriv().textureType(), atlasTexture->config(),
GrSamplerState::Filter::kNearest, GrSamplerState::WrapMode::kClamp, swizzle)
, fAtlasSize(SkISize::Make(atlasTexture->width(), atlasTexture->height()))
@ -150,6 +151,7 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
const GrCCPathProcessor& proc = args.fGP.cast<GrCCPathProcessor>();
GrGLSLUniformHandler* uniHandler = args.fUniformHandler;
GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
bool isCoverageCount = (CoverageMode::kCoverageCount == proc.fCoverageMode);
const char* atlasAdjust;
fAtlasAdjustUniform = uniHandler->addUniform(
@ -157,9 +159,10 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
varyingHandler->emitAttributes(proc);
GrGLSLVarying texcoord(kFloat3_GrSLType);
GrGLSLVarying color(kHalf4_GrSLType);
GrGLSLVarying texcoord((isCoverageCount) ? kFloat3_GrSLType : kFloat2_GrSLType);
varyingHandler->addVarying("texcoord", &texcoord);
GrGLSLVarying color(kHalf4_GrSLType);
varyingHandler->addPassThroughAttribute(
kInstanceAttribs[kColorAttribIdx], args.fOutputColor, Interpolation::kCanBeFlat);
@ -197,9 +200,9 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
"? float2(N[0].x, N[1].y)"
": float2(N[1].x, N[0].y);");
v->codeAppendf("octocoord = (ceil(octocoord * bloatdir - 1e-4) + 0.25) * bloatdir;");
v->codeAppendf("float2 atlascoord = octocoord + float2(dev_to_atlas_offset);");
// Convert to atlas coordinates in order to do our texture lookup.
v->codeAppendf("float2 atlascoord = octocoord + float2(dev_to_atlas_offset);");
if (kTopLeft_GrSurfaceOrigin == proc.fAtlasOrigin) {
v->codeAppendf("%s.xy = atlascoord * %s;", texcoord.vsOut(), atlasAdjust);
} else {
@ -207,7 +210,9 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
v->codeAppendf("%s.xy = float2(atlascoord.x * %s.x, 1 - atlascoord.y * %s.y);",
texcoord.vsOut(), atlasAdjust, atlasAdjust);
}
v->codeAppendf("%s.z = wind * .5;", texcoord.vsOut());
if (isCoverageCount) {
v->codeAppendf("%s.z = wind * .5;", texcoord.vsOut());
}
gpArgs->fPositionVar.set(kFloat2_GrSLType, "octocoord");
this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, proc.fLocalMatrix,
@ -216,19 +221,24 @@ void GrCCPathProcessor::Impl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
// Fragment shader.
GrGLSLFPFragmentBuilder* f = args.fFragBuilder;
// Look up coverage count in the atlas.
f->codeAppend ("half coverage = ");
// Look up coverage in the atlas.
f->codeAppendf("half coverage = ");
f->appendTextureLookup(args.fTexSamplers[0], SkStringPrintf("%s.xy", texcoord.fsIn()).c_str(),
kFloat2_GrSLType);
f->codeAppend (".a;");
f->codeAppendf(".a;");
// Scale coverage count by .5. Make it negative for even-odd paths and positive for winding
// ones. Clamp winding coverage counts at 1.0 (i.e. min(coverage/2, .5)).
f->codeAppendf("coverage = min(abs(coverage) * half(%s.z), .5);", texcoord.fsIn());
if (isCoverageCount) {
f->codeAppendf("coverage = abs(coverage);");
// For negative values, this finishes the even-odd sawtooth function. Since positive (winding)
// values were clamped at "coverage/2 = .5", this only undoes the previous multiply by .5.
f->codeAppend ("coverage = 1 - abs(fract(coverage) * 2 - 1);");
// Scale coverage count by .5. Make it negative for even-odd paths and positive for
// winding ones. Clamp winding coverage counts at 1.0 (i.e. min(coverage/2, .5)).
f->codeAppendf("coverage = min(abs(coverage) * half(%s.z), .5);", texcoord.fsIn());
// For negative values, this finishes the even-odd sawtooth function. Since positive
// (winding) values were clamped at "coverage/2 = .5", this only undoes the previous
// multiply by .5.
f->codeAppend ("coverage = 1 - abs(fract(coverage) * 2 - 1);");
}
f->codeAppendf("%s = half4(coverage);", args.fOutputCoverage);
}

View File

@ -13,6 +13,7 @@
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/ccpr/GrCCAtlas.h"
#include "src/gpu/ccpr/GrOctoBounds.h"
class GrCCPathCacheEntry;
@ -53,11 +54,26 @@ public:
static sk_sp<const GrGpuBuffer> FindVertexBuffer(GrOnFlushResourceProvider*);
static sk_sp<const GrGpuBuffer> FindIndexBuffer(GrOnFlushResourceProvider*);
GrCCPathProcessor(const GrTexture* atlasTexture, const GrSwizzle&, GrSurfaceOrigin atlasOrigin,
const SkMatrix& viewMatrixIfUsingLocalCoords = SkMatrix::I());
enum class CoverageMode : bool {
kCoverageCount,
kLiteral
};
static CoverageMode GetCoverageMode(GrCCAtlas::CoverageType coverageType) {
return (GrCCAtlas::CoverageType::kFP16_CoverageCount == coverageType)
? CoverageMode::kCoverageCount
: CoverageMode::kLiteral;
}
GrCCPathProcessor(
CoverageMode, const GrTexture* atlasTexture, const GrSwizzle&,
GrSurfaceOrigin atlasOrigin,
const SkMatrix& viewMatrixIfUsingLocalCoords = SkMatrix::I());
const char* name() const override { return "GrCCPathProcessor"; }
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
b->add32((uint32_t)fCoverageMode);
}
GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
void drawPaths(GrOpFlushState*, const GrPipeline&, const GrPipeline::FixedDynamicState*,
@ -67,6 +83,7 @@ public:
private:
const TextureSampler& onTextureSampler(int) const override { return fAtlasAccess; }
const CoverageMode fCoverageMode;
const TextureSampler fAtlasAccess;
SkISize fAtlasSize;
GrSurfaceOrigin fAtlasOrigin;

View File

@ -82,8 +82,9 @@ public:
auto srcProxy = fSrcProxy.get();
SkASSERT(srcProxy->isInstantiated());
GrCCPathProcessor pathProc(srcProxy->peekTexture(), srcProxy->textureSwizzle(),
srcProxy->origin());
GrCCPathProcessor pathProc(
GrCCPathProcessor::CoverageMode::kCoverageCount, srcProxy->peekTexture(),
srcProxy->textureSwizzle(), srcProxy->origin());
GrPipeline pipeline(GrScissorTest::kDisabled, SkBlendMode::kSrc,
flushState->drawOpArgs().fOutputSwizzle);