From 6a5317a0e58a4b50e49b003387e1b1f2bbbe7be3 Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Fri, 12 Jul 2019 09:55:52 -0600 Subject: [PATCH] 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 Commit-Queue: Chris Dalton --- src/gpu/ccpr/GrCCDrawPathsOp.cpp | 23 ++++++++------- src/gpu/ccpr/GrCCDrawPathsOp.h | 4 ++- src/gpu/ccpr/GrCCPathProcessor.cpp | 40 ++++++++++++++++---------- src/gpu/ccpr/GrCCPathProcessor.h | 23 +++++++++++++-- src/gpu/ccpr/GrCCPerFlushResources.cpp | 5 ++-- 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.cpp b/src/gpu/ccpr/GrCCDrawPathsOp.cpp index b1e5ab8f5c..ed9a004df9 100644 --- a/src/gpu/ccpr/GrCCDrawPathsOp.cpp +++ b/src/gpu/ccpr/GrCCDrawPathsOp.cpp @@ -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; diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.h b/src/gpu/ccpr/GrCCDrawPathsOp.h index 1f951385a8..2b607e1e4a 100644 --- a/src/gpu/ccpr/GrCCDrawPathsOp.h +++ b/src/gpu/ccpr/GrCCDrawPathsOp.h @@ -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; }; diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp index 72a093246d..8b8af8af54 100644 --- a/src/gpu/ccpr/GrCCPathProcessor.cpp +++ b/src/gpu/ccpr/GrCCPathProcessor.cpp @@ -79,10 +79,11 @@ sk_sp 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(); 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); } diff --git a/src/gpu/ccpr/GrCCPathProcessor.h b/src/gpu/ccpr/GrCCPathProcessor.h index 7a5d8f656b..ac97fd848a 100644 --- a/src/gpu/ccpr/GrCCPathProcessor.h +++ b/src/gpu/ccpr/GrCCPathProcessor.h @@ -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 FindVertexBuffer(GrOnFlushResourceProvider*); static sk_sp 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; diff --git a/src/gpu/ccpr/GrCCPerFlushResources.cpp b/src/gpu/ccpr/GrCCPerFlushResources.cpp index 33ac61bd3c..2f7ac99dd4 100644 --- a/src/gpu/ccpr/GrCCPerFlushResources.cpp +++ b/src/gpu/ccpr/GrCCPerFlushResources.cpp @@ -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);