From 1c5489412de12ab9afdbc0085e65418ca8753b43 Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Tue, 22 May 2018 13:09:48 -0600 Subject: [PATCH] ccpr: Remove local matrix data from path instances Uses the built-in local matrix code instead trying to bake it into the path instance data. If we find a case that can benefit from this type of optimization in the future, we can use something like a texel buffer and send in all of the coord transform data -- not just the local matrix. Bug: skia: Change-Id: I194bc9e4f83e588f8aa93a1a4d40097475d84977 Reviewed-on: https://skia-review.googlesource.com/129332 Commit-Queue: Chris Dalton Reviewed-by: Robert Phillips Reviewed-by: Brian Salomon --- src/gpu/GrFragmentProcessor.cpp | 9 ++++++++ src/gpu/GrFragmentProcessor.h | 2 ++ src/gpu/ccpr/GrCCDrawPathsOp.cpp | 27 ++++++++++++++--------- src/gpu/ccpr/GrCCDrawPathsOp.h | 1 + src/gpu/ccpr/GrCCPathProcessor.cpp | 32 +++++++++++----------------- src/gpu/ccpr/GrCCPathProcessor.h | 11 +++++----- src/gpu/ccpr/GrCCPerFlushResources.h | 10 ++------- 7 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index 719ab7e451..93e1c7fa8b 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -479,6 +479,15 @@ GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) { } } +GrFragmentProcessor::Iter::Iter(const GrPaint& paint) { + for (int i = paint.numCoverageFragmentProcessors() - 1; i >= 0; --i) { + fFPStack.push_back(paint.getCoverageFragmentProcessor(i)); + } + for (int i = paint.numColorFragmentProcessors() - 1; i >= 0; --i) { + fFPStack.push_back(paint.getColorFragmentProcessor(i)); + } +} + const GrFragmentProcessor* GrFragmentProcessor::Iter::next() { if (fFPStack.empty()) { return nullptr; diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h index fa674d5d80..b875c7919f 100644 --- a/src/gpu/GrFragmentProcessor.h +++ b/src/gpu/GrFragmentProcessor.h @@ -13,6 +13,7 @@ class GrCoordTransform; class GrGLSLFragmentProcessor; class GrInvariantOutput; +class GrPaint; class GrPipeline; class GrProcessorKeyBuilder; class GrShaderCaps; @@ -191,6 +192,7 @@ public: public: explicit Iter(const GrFragmentProcessor* fp) { fFPStack.push_back(fp); } explicit Iter(const GrPipeline& pipeline); + explicit Iter(const GrPaint&); const GrFragmentProcessor* next(); private: diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.cpp b/src/gpu/ccpr/GrCCDrawPathsOp.cpp index d239812241..80304857d0 100644 --- a/src/gpu/ccpr/GrCCDrawPathsOp.cpp +++ b/src/gpu/ccpr/GrCCDrawPathsOp.cpp @@ -12,12 +12,23 @@ #include "ccpr/GrCCPerFlushResources.h" #include "ccpr/GrCoverageCountingPathRenderer.h" +static bool has_coord_transforms(const GrPaint& paint) { + GrFragmentProcessor::Iter iter(paint); + while (const GrFragmentProcessor* fp = iter.next()) { + if (!fp->coordTransforms().empty()) { + return true; + } + } + return false; +} + GrCCDrawPathsOp::GrCCDrawPathsOp(GrCoverageCountingPathRenderer* ccpr, GrPaint&& paint, const SkIRect& clipIBounds, const SkMatrix& viewMatrix, const SkPath& path, const SkRect& devBounds) : GrDrawOp(ClassID()) , fCCPR(ccpr) , fSRGBFlags(GrPipeline::SRGBFlagsFromPaint(paint)) + , fViewMatrixIfUsingLocalCoords(has_coord_transforms(paint) ? viewMatrix : SkMatrix::I()) , fDraws({clipIBounds, viewMatrix, path, paint.getColor(), nullptr}) , fProcessors(std::move(paint)) { SkDEBUGCODE(fCCPR->incrDrawOpCount_debugOnly()); @@ -57,7 +68,8 @@ bool GrCCDrawPathsOp::onCombineIfPossible(GrOp* op, const GrCaps& caps) { SkASSERT(that->fNumDraws); if (this->getFillType() != that->getFillType() || fSRGBFlags != that->fSRGBFlags || - fProcessors != that->fProcessors) { + fProcessors != that->fProcessors || + fViewMatrixIfUsingLocalCoords != that->fViewMatrixIfUsingLocalCoords) { return false; } @@ -111,14 +123,8 @@ void GrCCDrawPathsOp::setupResources(GrCCPerFlushResources* resources, currentAtlas = atlas; } - const SkMatrix& m = draw.fMatrix; - resources->appendDrawPathInstance( - devBounds, - devBounds45, - {{m.getScaleX(), m.getSkewY(), m.getSkewX(), m.getScaleY()}}, - {{m.getTranslateX(), m.getTranslateY()}}, - {{atlasOffsetX, atlasOffsetY}}, - draw.fColor); + resources->appendDrawPathInstance() = + {devBounds, devBounds45, {{atlasOffsetX, atlasOffsetY}}, draw.fColor}; } SkASSERT(resources->pathInstanceCount() == fBaseInstance + fNumDraws - fNumSkippedInstances); @@ -154,7 +160,8 @@ void GrCCDrawPathsOp::onExecute(GrOpFlushState* flushState) { } GrCCPathProcessor pathProc(flushState->resourceProvider(), - sk_ref_sp(batch.fAtlas->textureProxy()), this->getFillType()); + sk_ref_sp(batch.fAtlas->textureProxy()), this->getFillType(), + fViewMatrixIfUsingLocalCoords); pathProc.drawPaths(flushState, pipeline, resources->indexBuffer(), resources->vertexBuffer(), resources->instanceBuffer(), baseInstance, batch.fEndInstanceIdx, this->bounds()); diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.h b/src/gpu/ccpr/GrCCDrawPathsOp.h index 77223171de..35981723cb 100644 --- a/src/gpu/ccpr/GrCCDrawPathsOp.h +++ b/src/gpu/ccpr/GrCCDrawPathsOp.h @@ -68,6 +68,7 @@ private: GrCoverageCountingPathRenderer* const fCCPR; const uint32_t fSRGBFlags; + const SkMatrix fViewMatrixIfUsingLocalCoords; struct SingleDraw { SkIRect fClipIBounds; diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp index 5dacc6a3b5..588e2bcb7b 100644 --- a/src/gpu/ccpr/GrCCPathProcessor.cpp +++ b/src/gpu/ccpr/GrCCPathProcessor.cpp @@ -76,15 +76,14 @@ sk_sp GrCCPathProcessor::FindIndexBuffer(GrOnFlushResourceProvid } GrCCPathProcessor::GrCCPathProcessor(GrResourceProvider* resourceProvider, - sk_sp atlas, SkPath::FillType fillType) + sk_sp atlas, SkPath::FillType fillType, + const SkMatrix& viewMatrixIfUsingLocalCoords) : INHERITED(kGrCCPathProcessor_ClassID) , fFillType(fillType) , fAtlasAccess(std::move(atlas), GrSamplerState::Filter::kNearest, GrSamplerState::WrapMode::kClamp, kFragment_GrShaderFlag) { this->addInstanceAttrib("devbounds", kFloat4_GrVertexAttribType); this->addInstanceAttrib("devbounds45", kFloat4_GrVertexAttribType); - this->addInstanceAttrib("view_matrix", kFloat4_GrVertexAttribType); - this->addInstanceAttrib("view_translate", kFloat2_GrVertexAttribType); this->addInstanceAttrib("atlas_offset", kShort2_GrVertexAttribType); this->addInstanceAttrib("color", kUByte4_norm_GrVertexAttribType); @@ -92,25 +91,25 @@ GrCCPathProcessor::GrCCPathProcessor(GrResourceProvider* resourceProvider, this->getInstanceAttrib(InstanceAttribs::kDevBounds).fOffsetInRecord); SkASSERT(offsetof(Instance, fDevBounds45) == this->getInstanceAttrib(InstanceAttribs::kDevBounds45).fOffsetInRecord); - SkASSERT(offsetof(Instance, fViewMatrix) == - this->getInstanceAttrib(InstanceAttribs::kViewMatrix).fOffsetInRecord); - SkASSERT(offsetof(Instance, fViewTranslate) == - this->getInstanceAttrib(InstanceAttribs::kViewTranslate).fOffsetInRecord); SkASSERT(offsetof(Instance, fAtlasOffset) == this->getInstanceAttrib(InstanceAttribs::kAtlasOffset).fOffsetInRecord); SkASSERT(offsetof(Instance, fColor) == this->getInstanceAttrib(InstanceAttribs::kColor).fOffsetInRecord); SkASSERT(sizeof(Instance) == this->getInstanceStride()); - GR_STATIC_ASSERT(6 == kNumInstanceAttribs); + GR_STATIC_ASSERT(4 == kNumInstanceAttribs); this->addVertexAttrib("edge_norms", kFloat4_GrVertexAttribType); + if (resourceProvider->caps()->usePrimitiveRestart()) { + this->setWillUsePrimitiveRestart(); + } + fAtlasAccess.instantiate(resourceProvider); this->addTextureSampler(&fAtlasAccess); - if (resourceProvider->caps()->usePrimitiveRestart()) { - this->setWillUsePrimitiveRestart(); + if (!viewMatrixIfUsingLocalCoords.invert(&fLocalMatrix)) { + fLocalMatrix.setIdentity(); } } @@ -128,7 +127,7 @@ private: const GrCCPathProcessor& proc = primProc.cast(); pdman.set2f(fAtlasAdjustUniform, 1.0f / proc.atlas()->width(), 1.0f / proc.atlas()->height()); - this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); + this->setTransformDataHelper(proc.localMatrix(), pdman, &transformIter); } GrGLSLUniformHandler::UniformHandle fAtlasAdjustUniform; @@ -223,15 +222,8 @@ void GLSLPathProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { texcoord.vsOut(), atlasAdjust, atlasAdjust); } - // Convert to path/local cordinates. - v->codeAppendf("float2x2 viewmatrix = float2x2(%s.xy, %s.zw);", // float2x2(float4) busts Intel. - proc.getInstanceAttrib(InstanceAttribs::kViewMatrix).fName, - proc.getInstanceAttrib(InstanceAttribs::kViewMatrix).fName); - v->codeAppendf("float2 pathcoord = inverse(viewmatrix) * (octocoord - %s);", - proc.getInstanceAttrib(InstanceAttribs::kViewTranslate).fName); - - this->emitTransforms(v, varyingHandler, uniHandler, GrShaderVar("pathcoord", kFloat2_GrSLType), - args.fFPCoordTransformHandler); + this->emitTransforms(v, varyingHandler, uniHandler, GrShaderVar("octocoord", kFloat2_GrSLType), + proc.localMatrix(), args.fFPCoordTransformHandler); // Fragment shader. GrGLSLFPFragmentBuilder* f = args.fFragBuilder; diff --git a/src/gpu/ccpr/GrCCPathProcessor.h b/src/gpu/ccpr/GrCCPathProcessor.h index 40b16a4e9d..47893266da 100644 --- a/src/gpu/ccpr/GrCCPathProcessor.h +++ b/src/gpu/ccpr/GrCCPathProcessor.h @@ -32,8 +32,6 @@ public: enum class InstanceAttribs { kDevBounds, kDevBounds45, - kViewMatrix, // FIXME: This causes a lot of duplication. It could move to a texel buffer. - kViewTranslate, kAtlasOffset, kColor }; @@ -43,24 +41,24 @@ public: SkRect fDevBounds; SkRect fDevBounds45; // Bounding box in "| 1 -1 | * devCoords" space. // | 1 1 | - std::array fViewMatrix; // {kScaleX, kSkewy, kSkewX, kScaleY} - std::array fViewTranslate; std::array fAtlasOffset; uint32_t fColor; GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT); }; - GR_STATIC_ASSERT(4 * 16 == sizeof(Instance)); + GR_STATIC_ASSERT(4 * 10 == sizeof(Instance)); static sk_sp FindVertexBuffer(GrOnFlushResourceProvider*); static sk_sp FindIndexBuffer(GrOnFlushResourceProvider*); - GrCCPathProcessor(GrResourceProvider*, sk_sp atlas, SkPath::FillType); + GrCCPathProcessor(GrResourceProvider*, sk_sp atlas, SkPath::FillType, + const SkMatrix& viewMatrixIfUsingLocalCoords = SkMatrix::I()); const char* name() const override { return "GrCCPathProcessor"; } const GrSurfaceProxy* atlasProxy() const { return fAtlasAccess.proxy(); } const GrTexture* atlas() const { return fAtlasAccess.peekTexture(); } + const SkMatrix& localMatrix() const { return fLocalMatrix; } SkPath::FillType fillType() const { return fFillType; } const Attribute& getInstanceAttrib(InstanceAttribs attribID) const { const Attribute& attrib = this->getAttrib((int)attribID); @@ -84,6 +82,7 @@ public: private: const SkPath::FillType fFillType; const TextureSampler fAtlasAccess; + SkMatrix fLocalMatrix; typedef GrGeometryProcessor INHERITED; }; diff --git a/src/gpu/ccpr/GrCCPerFlushResources.h b/src/gpu/ccpr/GrCCPerFlushResources.h index 89ad6ae708..7585a7a286 100644 --- a/src/gpu/ccpr/GrCCPerFlushResources.h +++ b/src/gpu/ccpr/GrCCPerFlushResources.h @@ -30,16 +30,10 @@ public: const SkPath& devPath, const SkIRect& devPathIBounds, int16_t* atlasOffsetX, int16_t* atlasOffsetY); - // See GrCCPathProcessor::Instance. - int appendDrawPathInstance(const SkRect& devBounds, const SkRect& devBounds45, - const std::array& viewMatrix, - const std::array& viewTranslate, - const std::array& atlasOffset, uint32_t color) { + GrCCPathProcessor::Instance& appendDrawPathInstance() { SkASSERT(this->isMapped()); SkASSERT(fPathInstanceCount < fPathInstanceBufferCount); - fPathInstanceData[fPathInstanceCount] = {devBounds, devBounds45, viewMatrix, viewTranslate, - atlasOffset, color}; - return fPathInstanceCount++; + return fPathInstanceData[fPathInstanceCount++]; } int pathInstanceCount() const { return fPathInstanceCount; } -- 2.34.1