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:
parent
fcf6359ce8
commit
6a5317a0e5
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user