diff options
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageOp.cpp | 117 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageOp.h | 9 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageProcessor.cpp | 44 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageProcessor.h | 81 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp | 14 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCubicShader.cpp | 8 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRCubicShader.h | 4 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRPathProcessor.cpp | 6 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRPathProcessor.h | 18 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRQuadraticShader.cpp | 8 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRQuadraticShader.h | 4 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRTriangleShader.cpp | 8 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCCPRTriangleShader.h | 5 | ||||
-rw-r--r-- | src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp | 2 |
14 files changed, 153 insertions, 175 deletions
diff --git a/src/gpu/ccpr/GrCCPRCoverageOp.cpp b/src/gpu/ccpr/GrCCPRCoverageOp.cpp index 4d985a563f..8786ed4338 100644 --- a/src/gpu/ccpr/GrCCPRCoverageOp.cpp +++ b/src/gpu/ccpr/GrCCPRCoverageOp.cpp @@ -14,11 +14,10 @@ #include "SkPath.h" #include "SkPathPriv.h" #include "SkPoint.h" -#include "SkNx.h" #include "ccpr/GrCCPRGeometry.h" using TriangleInstance = GrCCPRCoverageProcessor::TriangleInstance; -using CurveInstance = GrCCPRCoverageProcessor::CurveInstance; +using CubicInstance = GrCCPRCoverageProcessor::CubicInstance; void GrCCPRCoverageOpsBuilder::parsePath(const SkMatrix& m, const SkPath& path, SkRect* devBounds, SkRect* devBounds45) { @@ -147,7 +146,7 @@ void GrCCPRCoverageOpsBuilder::saveParsedPath(ScissorMode scissorMode, fPathsInfo.push_back() = { scissorMode, - (int32_t) (((uint32_t) (int32_t) atlasOffsetY << 16) | (atlasOffsetX & 0xffff)), + atlasOffsetX, atlasOffsetY, std::move(fTerminatingOp) }; @@ -194,8 +193,9 @@ void GrCCPRCoverageOpsBuilder::emitOp(SkISize drawBounds) { // elements past the end for this method to use as scratch space. // // Returns the next triangle instance after the final one emitted. -static TriangleInstance* emit_recursive_fan(SkTArray<int32_t, true>& indices, int firstIndex, - int indexCount, int32_t packedAtlasOffset, +static TriangleInstance* emit_recursive_fan(const SkTArray<SkPoint, true>& pts, + SkTArray<int32_t, true>& indices, int firstIndex, + int indexCount, const Sk2f& atlasOffset, TriangleInstance out[]) { if (indexCount < 3) { return out; @@ -203,22 +203,19 @@ static TriangleInstance* emit_recursive_fan(SkTArray<int32_t, true>& indices, in const int32_t oneThirdCount = indexCount / 3; const int32_t twoThirdsCount = (2 * indexCount) / 3; - *out++ = { - indices[firstIndex], - indices[firstIndex + oneThirdCount], - indices[firstIndex + twoThirdsCount], - packedAtlasOffset - }; + out++->set(pts[indices[firstIndex]], + pts[indices[firstIndex + oneThirdCount]], + pts[indices[firstIndex + twoThirdsCount]], atlasOffset); - out = emit_recursive_fan(indices, firstIndex, oneThirdCount + 1, packedAtlasOffset, out); - out = emit_recursive_fan(indices, firstIndex + oneThirdCount, - twoThirdsCount - oneThirdCount + 1, packedAtlasOffset, out); + out = emit_recursive_fan(pts, indices, firstIndex, oneThirdCount + 1, atlasOffset, out); + out = emit_recursive_fan(pts, indices, firstIndex + oneThirdCount, + twoThirdsCount - oneThirdCount + 1, atlasOffset, out); int endIndex = firstIndex + indexCount; int32_t oldValue = indices[endIndex]; indices[endIndex] = indices[firstIndex]; - out = emit_recursive_fan(indices, firstIndex + twoThirdsCount, indexCount - twoThirdsCount + 1, - packedAtlasOffset, out); + out = emit_recursive_fan(pts, indices, firstIndex + twoThirdsCount, + indexCount - twoThirdsCount + 1, atlasOffset, out); indices[endIndex] = oldValue; return out; @@ -228,40 +225,53 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP, SkTArray<std::unique_ptr<GrCCPRCoverageOp>>* ops) { SkASSERT(!fParsingPath); - const SkTArray<SkPoint, true>& points = fGeometry.points(); - sk_sp<GrBuffer> pointsBuffer = onFlushRP->makeBuffer(kTexel_GrBufferType, - points.count() * 2 * sizeof(float), - points.begin()); - if (!pointsBuffer) { - return false; - } - - // Configure the instance buffer layout. + // Here we build a single instance buffer to share with every draw call from every CoverageOP we + // plan to produce. + // + // CoverageOps process 4 different types of primitives (triangles, quadratics, serpentines, + // loops), and each primitive type is further divided into instances that require a scissor and + // those that don't. This leaves us with 8 independent instance arrays to build for the GPU. + // + // Rather than placing each instance array in its own GPU buffer, we allocate a single + // megabuffer and lay them all out side-by-side. We can offset the "baseInstance" parameter in + // our draw calls to direct the GPU to the applicable elements within a given array. + // + // We already know how big to make each of the 8 arrays from fTallies[kNumScissorModes], so + // layout is straightforward. PrimitiveTallies baseInstances[kNumScissorModes]; - // int4 indices. + + // Start with triangles and quadratics. They both view the instance buffer as an array of + // TriangleInstance[], so we can just start at zero and lay them out one after the other. baseInstances[0].fTriangles = 0; baseInstances[1].fTriangles = baseInstances[0].fTriangles + fTallies[0].fTriangles; - // int2 indices (curves index the buffer as int2 rather than int4). - baseInstances[0].fQuadratics = (baseInstances[1].fTriangles + fTallies[1].fTriangles) * 2; + baseInstances[0].fQuadratics = baseInstances[1].fTriangles + fTallies[1].fTriangles; baseInstances[1].fQuadratics = baseInstances[0].fQuadratics + fTallies[0].fQuadratics; - baseInstances[0].fSerpentines = baseInstances[1].fQuadratics + fTallies[1].fQuadratics; + int triEndIdx = baseInstances[1].fQuadratics + fTallies[1].fQuadratics; + + // 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)); + baseInstances[0].fSerpentines = cubicBaseIdx; baseInstances[1].fSerpentines = baseInstances[0].fSerpentines + fTallies[0].fSerpentines; baseInstances[0].fLoops = baseInstances[1].fSerpentines + fTallies[1].fSerpentines; baseInstances[1].fLoops = baseInstances[0].fLoops + fTallies[0].fLoops; - int instanceBufferSize = (baseInstances[1].fLoops + fTallies[1].fLoops) * sizeof(CurveInstance); + int cubicEndIdx = baseInstances[1].fLoops + fTallies[1].fLoops; sk_sp<GrBuffer> instanceBuffer = onFlushRP->makeBuffer(kVertex_GrBufferType, - instanceBufferSize); + cubicEndIdx * sizeof(CubicInstance)); if (!instanceBuffer) { return false; } TriangleInstance* triangleInstanceData = static_cast<TriangleInstance*>(instanceBuffer->map()); - CurveInstance* curveInstanceData = reinterpret_cast<CurveInstance*>(triangleInstanceData); - SkASSERT(curveInstanceData); + CubicInstance* cubicInstanceData = reinterpret_cast<CubicInstance*>(triangleInstanceData); + SkASSERT(cubicInstanceData); PathInfo* currPathInfo = fPathsInfo.begin(); - int32_t packedAtlasOffset; + float atlasOffsetX, atlasOffsetY; + Sk2f atlasOffset; int ptsIdx = -1; PrimitiveTallies instanceIndices[2] = {baseInstances[0], baseInstances[1]}; PrimitiveTallies* currIndices; @@ -273,20 +283,24 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP, PrimitiveTallies initialBaseInstances[] = {baseInstances[0], baseInstances[1]}; #endif + const SkTArray<SkPoint, true>& pts = fGeometry.points(); + // Expand the ccpr verbs into GPU instance buffers. for (GrCCPRGeometry::Verb verb : fGeometry.verbs()) { switch (verb) { case GrCCPRGeometry::Verb::kBeginPath: SkASSERT(currFan.empty()); currIndices = &instanceIndices[(int)currPathInfo->fScissorMode]; - packedAtlasOffset = currPathInfo->fPackedAtlasOffset; + atlasOffsetX = static_cast<float>(currPathInfo->fAtlasOffsetX); + atlasOffsetY = static_cast<float>(currPathInfo->fAtlasOffsetY); + atlasOffset = {atlasOffsetX, atlasOffsetY}; #ifdef SK_DEBUG if (ScissorMode::kScissored == currPathInfo->fScissorMode) { ++numScissoredPaths; } #endif if (auto op = std::move(currPathInfo->fTerminatingOp)) { - op->setBuffers(pointsBuffer, instanceBuffer, baseInstances, instanceIndices); + op->setInstanceBuffer(instanceBuffer, baseInstances, instanceIndices); baseInstances[0] = instanceIndices[0]; baseInstances[1] = instanceIndices[1]; SkDEBUGCODE(numScissorBatches += op->fScissorBatches.count()); @@ -307,19 +321,21 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP, case GrCCPRGeometry::Verb::kMonotonicQuadraticTo: SkASSERT(!currFan.empty()); - curveInstanceData[currIndices->fQuadratics++] = {ptsIdx, packedAtlasOffset}; + triangleInstanceData[currIndices->fQuadratics++].set(&pts[ptsIdx], atlasOffset); currFan.push_back(ptsIdx += 2); continue; case GrCCPRGeometry::Verb::kMonotonicSerpentineTo: SkASSERT(!currFan.empty()); - curveInstanceData[currIndices->fSerpentines++] = {ptsIdx, packedAtlasOffset}; + cubicInstanceData[currIndices->fSerpentines++].set(&pts[ptsIdx], + atlasOffsetX, atlasOffsetY); currFan.push_back(ptsIdx += 3); continue; case GrCCPRGeometry::Verb::kMonotonicLoopTo: SkASSERT(!currFan.empty()); - curveInstanceData[currIndices->fLoops++] = {ptsIdx, packedAtlasOffset}; + cubicInstanceData[currIndices->fLoops++].set(&pts[ptsIdx], + atlasOffsetX, atlasOffsetY); currFan.push_back(ptsIdx += 3); continue; @@ -334,7 +350,7 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP, // fanSize + log3(fanSize), but we approximate with log2. currFan.push_back_n(SkNextLog2(fanSize)); SkDEBUGCODE(TriangleInstance* end =) - emit_recursive_fan(currFan, 0, fanSize, packedAtlasOffset, + emit_recursive_fan(pts, currFan, 0, fanSize, atlasOffset, triangleInstanceData + currIndices->fTriangles); currIndices->fTriangles += fanSize - 2; SkASSERT(triangleInstanceData + currIndices->fTriangles == end); @@ -347,30 +363,28 @@ bool GrCCPRCoverageOpsBuilder::finalize(GrOnFlushResourceProvider* onFlushRP, instanceBuffer->unmap(); if (auto op = std::move(fTerminatingOp)) { - op->setBuffers(std::move(pointsBuffer), std::move(instanceBuffer), baseInstances, - instanceIndices); + op->setInstanceBuffer(std::move(instanceBuffer), baseInstances, instanceIndices); SkDEBUGCODE(numScissorBatches += op->fScissorBatches.count()); ops->push_back(std::move(op)); } SkASSERT(currPathInfo == fPathsInfo.end()); - SkASSERT(ptsIdx == points.count() - 1); + SkASSERT(ptsIdx == pts.count() - 1); SkASSERT(numScissoredPaths == numScissorBatches); SkASSERT(instanceIndices[0].fTriangles == initialBaseInstances[1].fTriangles); - SkASSERT(instanceIndices[1].fTriangles * 2 == initialBaseInstances[0].fQuadratics); + SkASSERT(instanceIndices[1].fTriangles == initialBaseInstances[0].fQuadratics); SkASSERT(instanceIndices[0].fQuadratics == initialBaseInstances[1].fQuadratics); - SkASSERT(instanceIndices[1].fQuadratics == initialBaseInstances[0].fSerpentines); + SkASSERT(instanceIndices[1].fQuadratics == triEndIdx); SkASSERT(instanceIndices[0].fSerpentines == initialBaseInstances[1].fSerpentines); SkASSERT(instanceIndices[1].fSerpentines == initialBaseInstances[0].fLoops); SkASSERT(instanceIndices[0].fLoops == initialBaseInstances[1].fLoops); - SkASSERT(instanceIndices[1].fLoops * (int) sizeof(CurveInstance) == instanceBufferSize); + SkASSERT(instanceIndices[1].fLoops == cubicEndIdx); return true; } -void GrCCPRCoverageOp::setBuffers(sk_sp<GrBuffer> pointsBuffer, sk_sp<GrBuffer> instanceBuffer, - const PrimitiveTallies baseInstances[kNumScissorModes], - const PrimitiveTallies endInstances[kNumScissorModes]) { - fPointsBuffer = std::move(pointsBuffer); +void GrCCPRCoverageOp::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]; @@ -381,7 +395,6 @@ void GrCCPRCoverageOp::setBuffers(sk_sp<GrBuffer> pointsBuffer, sk_sp<GrBuffer> void GrCCPRCoverageOp::onExecute(GrOpFlushState* flushState) { using RenderPass = GrCCPRCoverageProcessor::RenderPass; - SkASSERT(fPointsBuffer); SkASSERT(fInstanceBuffer); GrPipeline pipeline(flushState->drawOpArgs().fProxy, GrPipeline::ScissorState::kEnabled, @@ -456,7 +469,7 @@ void GrCCPRCoverageOp::drawMaskPrimitives(GrOpFlushState* flushState, const GrPi SkASSERT(fMeshesScratchBuffer.count() == fDynamicStatesScratchBuffer.count()); if (!fMeshesScratchBuffer.empty()) { - GrCCPRCoverageProcessor proc(renderPass, fPointsBuffer.get()); + GrCCPRCoverageProcessor proc(renderPass); SkASSERT(flushState->rtCommandBuffer()); flushState->rtCommandBuffer()->draw(pipeline, proc, fMeshesScratchBuffer.begin(), fDynamicStatesScratchBuffer.begin(), diff --git a/src/gpu/ccpr/GrCCPRCoverageOp.h b/src/gpu/ccpr/GrCCPRCoverageOp.h index ba818a1b12..571e29a8cf 100644 --- a/src/gpu/ccpr/GrCCPRCoverageOp.h +++ b/src/gpu/ccpr/GrCCPRCoverageOp.h @@ -91,7 +91,7 @@ private: // Every kBeginPath verb has a corresponding PathInfo entry. struct PathInfo { ScissorMode fScissorMode; - int32_t fPackedAtlasOffset; // (offsetY << 16) | (offsetX & 0xffff) + int16_t fAtlasOffsetX, fAtlasOffsetY; std::unique_ptr<GrCCPRCoverageOp> fTerminatingOp; }; @@ -154,15 +154,14 @@ private: GrOp::HasAABloat::kNo, GrOp::IsZeroArea::kNo); } - void setBuffers(sk_sp<GrBuffer> pointsBuffer, sk_sp<GrBuffer> instanceBuffer, - const PrimitiveTallies baseInstances[kNumScissorModes], - const PrimitiveTallies endInstances[kNumScissorModes]); + void setInstanceBuffer(sk_sp<GrBuffer> instanceBuffer, + const PrimitiveTallies baseInstances[kNumScissorModes], + const PrimitiveTallies endInstances[kNumScissorModes]); void drawMaskPrimitives(GrOpFlushState*, const GrPipeline&, const GrCCPRCoverageProcessor::RenderPass, GrPrimitiveType, int vertexCount, int PrimitiveTallies::* instanceType) const; - sk_sp<GrBuffer> fPointsBuffer; sk_sp<GrBuffer> fInstanceBuffer; PrimitiveTallies fBaseInstances[kNumScissorModes]; PrimitiveTallies fInstanceCounts[kNumScissorModes]; diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp index 1dc129f2ba..d77324dd6f 100644 --- a/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp +++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.cpp @@ -13,30 +13,28 @@ #include "ccpr/GrCCPRTriangleShader.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" -static GrVertexAttribType instance_array_format(GrCCPRCoverageProcessor::RenderPass renderPass) { - switch (renderPass) { - case GrCCPRCoverageProcessor::RenderPass::kTriangleHulls: - case GrCCPRCoverageProcessor::RenderPass::kTriangleEdges: - case GrCCPRCoverageProcessor::RenderPass::kTriangleCorners: - return kInt4_GrVertexAttribType; - case GrCCPRCoverageProcessor::RenderPass::kQuadraticHulls: - case GrCCPRCoverageProcessor::RenderPass::kQuadraticCorners: - case GrCCPRCoverageProcessor::RenderPass::kSerpentineHulls: - case GrCCPRCoverageProcessor::RenderPass::kLoopHulls: - case GrCCPRCoverageProcessor::RenderPass::kSerpentineCorners: - case GrCCPRCoverageProcessor::RenderPass::kLoopCorners: - return kInt2_GrVertexAttribType; - } - SK_ABORT("Unexpected GrCCPRCoverageProcessor::RenderPass."); - return kInt4_GrVertexAttribType; -} - -GrCCPRCoverageProcessor::GrCCPRCoverageProcessor(RenderPass renderPass, GrBuffer* pointsBuffer) +GrCCPRCoverageProcessor::GrCCPRCoverageProcessor(RenderPass renderPass) : INHERITED(kGrCCPRCoverageProcessor_ClassID) - , fRenderPass(renderPass) - , fInstanceAttrib(this->addInstanceAttrib("instance", instance_array_format(fRenderPass))) { - fPointsBufferAccess.reset(kRG_float_GrPixelConfig, pointsBuffer, kVertex_GrShaderFlag); - this->addBufferAccess(&fPointsBufferAccess); + , fRenderPass(renderPass) { + if (RenderPassIsCubic(fRenderPass)) { + this->addInstanceAttrib("X", kFloat4_GrVertexAttribType); + this->addInstanceAttrib("Y", kFloat4_GrVertexAttribType); + + SkASSERT(offsetof(CubicInstance, fX) == + this->getInstanceAttrib(InstanceAttribs::kX).fOffsetInRecord); + SkASSERT(offsetof(CubicInstance, fY) == + this->getInstanceAttrib(InstanceAttribs::kY).fOffsetInRecord); + SkASSERT(sizeof(CubicInstance) == this->getInstanceStride()); + } else { + this->addInstanceAttrib("X", kFloat3_GrVertexAttribType); + this->addInstanceAttrib("Y", kFloat3_GrVertexAttribType); + + SkASSERT(offsetof(TriangleInstance, fX) == + this->getInstanceAttrib(InstanceAttribs::kX).fOffsetInRecord); + SkASSERT(offsetof(TriangleInstance, fY) == + this->getInstanceAttrib(InstanceAttribs::kY).fOffsetInRecord); + SkASSERT(sizeof(TriangleInstance) == this->getInstanceStride()); + } this->setWillUseGeoShader(); } diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.h b/src/gpu/ccpr/GrCCPRCoverageProcessor.h index 9c5d6901f9..3c4050a73b 100644 --- a/src/gpu/ccpr/GrCCPRCoverageProcessor.h +++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.h @@ -9,6 +9,7 @@ #define GrCCPRCoverageProcessor_DEFINED #include "GrGeometryProcessor.h" +#include "SkNx.h" #include "glsl/GrGLSLGeometryProcessor.h" #include "glsl/GrGLSLVarying.h" @@ -25,12 +26,9 @@ class GrGLSLShaderBuilder; * 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). * - * Caller provides the primitives' (x,y) input points in an fp32x2 (RG) texel buffer, and an - * instance buffer with a single int32x4 attrib (for triangles) or int32x2 (for curves) defined - * below. There are no vertex attribs. - * - * Draw calls are instanced, with one vertex per bezier point (3 for triangles). They use the - * corresponding GrPrimitiveType as defined below. + * Draw calls are instanced. They use use the corresponding GrPrimitiveTypes as defined below. + * Caller fills out the primitives' atlas-space vertices and control points in instance arrays + * using the provided structs below. There are no vertex attribs. */ class GrCCPRCoverageProcessor : public GrGeometryProcessor { public: @@ -38,21 +36,25 @@ public: static constexpr GrPrimitiveType kQuadraticsGrPrimitiveType = GrPrimitiveType::kTriangles; static constexpr GrPrimitiveType kCubicsGrPrimitiveType = GrPrimitiveType::kLinesAdjacency; - struct TriangleInstance { - int32_t fPt0Idx; - int32_t fPt1Idx; - int32_t fPt2Idx; - int32_t fPackedAtlasOffset; // (offsetY << 16) | (offsetX & 0xffff) + enum class InstanceAttribs : int { + kX, + kY }; - GR_STATIC_ASSERT(4 * 4 == sizeof(TriangleInstance)); + struct TriangleInstance { // Also used by quadratics. + float fX[3]; + float fY[3]; - struct CurveInstance { - int32_t fPtsIdx; - int32_t fPackedAtlasOffset; // (offsetY << 16) | (offsetX & 0xffff) + void set(const SkPoint[3], const Sk2f& trans); + void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans); }; - GR_STATIC_ASSERT(2 * 4 == sizeof(CurveInstance)); + struct CubicInstance { + float fX[4]; + float fY[4]; + + void set(const SkPoint[4], float dx, float dy); + }; /** * All primitive shapes (triangles and convex closed curve segments) require more than one @@ -76,6 +78,10 @@ public: kLoopCorners }; + static constexpr bool RenderPassIsCubic(RenderPass pass) { + return pass >= RenderPass::kSerpentineHulls && pass <= RenderPass::kLoopCorners; + } + static const char* GetRenderPassName(RenderPass); /** @@ -117,11 +123,6 @@ public: // (number of wedges for a hull, number of edges, or number of corners.) virtual int getNumSegments() const = 0; - // Appends an expression that fetches input point # "pointId" from the texel buffer. - virtual void appendInputPointFetch(const GrCCPRCoverageProcessor&, GrGLSLShaderBuilder*, - const TexelBufferHandle& pointsBuffer, - const char* pointId) const = 0; - // Determines the winding direction of the primitive. The subclass must write a value of // either -1, 0, or +1 to "outputWind" (e.g. "sign(area)"). Fractional values are not valid. virtual void emitWind(GrGLSLShaderBuilder*, const char* pts, @@ -194,13 +195,16 @@ public: GrGLSLGeoToFrag fWind{kHalf_GrSLType}; }; - GrCCPRCoverageProcessor(RenderPass, GrBuffer* pointsBuffer); + GrCCPRCoverageProcessor(RenderPass); - const char* instanceAttrib() const { return fInstanceAttrib.fName; } const char* name() const override { return GetRenderPassName(fRenderPass); } SkString dumpInfo() const override { return SkStringPrintf("%s\n%s", this->name(), this->INHERITED::dumpInfo().c_str()); } + const Attribute& getInstanceAttrib(InstanceAttribs attribID) const { + return this->getAttrib((int)attribID); + } + void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; @@ -221,18 +225,29 @@ private: static GrGLSLPrimitiveProcessor* CreateGSImpl(std::unique_ptr<Shader>); - int atlasOffsetIdx() const { - SkASSERT(kInt2_GrVertexAttribType == fInstanceAttrib.fType || - kInt4_GrVertexAttribType == fInstanceAttrib.fType); - return kInt4_GrVertexAttribType == fInstanceAttrib.fType ? 3 : 1; - } - - const RenderPass fRenderPass; - const Attribute& fInstanceAttrib; - BufferAccess fPointsBufferAccess; - SkDEBUGCODE(float fDebugBloat = 0;) + const RenderPass fRenderPass; + SkDEBUGCODE(float fDebugBloat = 0;) typedef GrGeometryProcessor INHERITED; }; +inline void GrCCPRCoverageProcessor::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) { + 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) { + Sk4f X,Y; + Sk4f::Load2(p, &X, &Y); + (X + dx).store(&fX); + (Y + dy).store(&fY); +} + #endif diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp b/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp index 5286a29508..51791a1628 100644 --- a/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp +++ b/src/gpu/ccpr/GrCCPRCoverageProcessor_GSImpl.cpp @@ -28,17 +28,9 @@ protected: // Vertex shader. GrGLSLVertexBuilder* v = args.fVertBuilder; - // The Intel GLSL compiler hits an internal assertion if we index the input attrib itself - // with sk_VertexID. - v->codeAppendf("int pointID = sk_VertexID;"); - v->codeAppend ("float2 self = "); - fShader->appendInputPointFetch(proc, v, args.fTexelBuffers[0], "pointID"); - v->codeAppend (".xy;"); - v->codeAppendf("int packedoffset = %s[%i];", - proc.fInstanceAttrib.fName, proc.atlasOffsetIdx()); - v->codeAppend ("float2 atlasoffset = float2((packedoffset << 16) >> 16, " - "packedoffset >> 16);"); - v->codeAppend ("self += atlasoffset;"); + v->codeAppendf("float2 self = float2(%s[sk_VertexID], %s[sk_VertexID]);", + proc.getInstanceAttrib(InstanceAttribs::kX).fName, + proc.getInstanceAttrib(InstanceAttribs::kY).fName); gpArgs->fPositionVar.set(kFloat2_GrSLType, "self"); // Geometry shader. diff --git a/src/gpu/ccpr/GrCCPRCubicShader.cpp b/src/gpu/ccpr/GrCCPRCubicShader.cpp index 62d9a838b0..59cd2a8537 100644 --- a/src/gpu/ccpr/GrCCPRCubicShader.cpp +++ b/src/gpu/ccpr/GrCCPRCubicShader.cpp @@ -9,14 +9,6 @@ #include "glsl/GrGLSLFragmentShaderBuilder.h" -void GrCCPRCubicShader::appendInputPointFetch(const GrCCPRCoverageProcessor& proc, - GrGLSLShaderBuilder* s, - const TexelBufferHandle& pointsBuffer, - const char* pointId) const { - s->appendTexelFetch(pointsBuffer, - SkStringPrintf("%s.x + %s", proc.instanceAttrib(), pointId).c_str()); -} - void GrCCPRCubicShader::emitWind(GrGLSLShaderBuilder* s, const char* pts, const char* outputWind) const { diff --git a/src/gpu/ccpr/GrCCPRCubicShader.h b/src/gpu/ccpr/GrCCPRCubicShader.h index a6d597d3c8..8cfacd61bb 100644 --- a/src/gpu/ccpr/GrCCPRCubicShader.h +++ b/src/gpu/ccpr/GrCCPRCubicShader.h @@ -33,10 +33,6 @@ protected: int getNumInputPoints() const final { return 4; } - void appendInputPointFetch(const GrCCPRCoverageProcessor&, GrGLSLShaderBuilder*, - const TexelBufferHandle& pointsBuffer, - const char* pointId) const final; - void emitWind(GrGLSLShaderBuilder*, const char* pts, const char* outputWind) const final; void emitSetupCode(GrGLSLShaderBuilder*, const char* pts, const char* segmentId, diff --git a/src/gpu/ccpr/GrCCPRPathProcessor.cpp b/src/gpu/ccpr/GrCCPRPathProcessor.cpp index ff3c60c134..612035af4a 100644 --- a/src/gpu/ccpr/GrCCPRPathProcessor.cpp +++ b/src/gpu/ccpr/GrCCPRPathProcessor.cpp @@ -51,7 +51,9 @@ GR_DECLARE_STATIC_UNIQUE_KEY(gIndexBufferKey); GrCCPRPathProcessor::GrCCPRPathProcessor(GrResourceProvider* rp, sk_sp<GrTextureProxy> atlas, SkPath::FillType fillType, const GrShaderCaps& shaderCaps) : INHERITED(kGrCCPRPathProcessor_ClassID) - , fFillType(fillType) { + , 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); @@ -77,8 +79,6 @@ GrCCPRPathProcessor::GrCCPRPathProcessor(GrResourceProvider* rp, sk_sp<GrTexture this->addVertexAttrib("edge_norms", kFloat4_GrVertexAttribType); - fAtlasAccess.reset(std::move(atlas), GrSamplerState::Filter::kNearest, - GrSamplerState::WrapMode::kClamp, kFragment_GrShaderFlag); fAtlasAccess.instantiate(rp); this->addTextureSampler(&fAtlasAccess); } diff --git a/src/gpu/ccpr/GrCCPRPathProcessor.h b/src/gpu/ccpr/GrCCPRPathProcessor.h index 82711756ee..7ad314e1d6 100644 --- a/src/gpu/ccpr/GrCCPRPathProcessor.h +++ b/src/gpu/ccpr/GrCCPRPathProcessor.h @@ -41,13 +41,13 @@ public: static constexpr int kNumInstanceAttribs = 1 + (int)InstanceAttribs::kColor; struct Instance { - SkRect fDevBounds; - SkRect fDevBounds45; // Bounding box in "| 1 -1 | * devCoords" space. - // | 1 1 | - std::array<float, 4> fViewMatrix; // {kScaleX, kSkewy, kSkewX, kScaleY} - std::array<float, 2> fViewTranslate; - std::array<int16_t, 2> fAtlasOffset; - uint32_t fColor; + SkRect fDevBounds; + SkRect fDevBounds45; // Bounding box in "| 1 -1 | * devCoords" space. + // | 1 1 | + std::array<float, 4> fViewMatrix; // {kScaleX, kSkewy, kSkewX, kScaleY} + std::array<float, 2> fViewTranslate; + std::array<int16_t, 2> fAtlasOffset; + uint32_t fColor; GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT); }; @@ -77,8 +77,8 @@ public: GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; private: - const SkPath::FillType fFillType; - TextureSampler fAtlasAccess; + const SkPath::FillType fFillType; + const TextureSampler fAtlasAccess; typedef GrGeometryProcessor INHERITED; }; diff --git a/src/gpu/ccpr/GrCCPRQuadraticShader.cpp b/src/gpu/ccpr/GrCCPRQuadraticShader.cpp index bdef285f1a..6dd062b923 100644 --- a/src/gpu/ccpr/GrCCPRQuadraticShader.cpp +++ b/src/gpu/ccpr/GrCCPRQuadraticShader.cpp @@ -9,14 +9,6 @@ #include "glsl/GrGLSLFragmentShaderBuilder.h" -void GrCCPRQuadraticShader::appendInputPointFetch(const GrCCPRCoverageProcessor& proc, - GrGLSLShaderBuilder* s, - const TexelBufferHandle& pointsBuffer, - const char* pointId) const { - s->appendTexelFetch(pointsBuffer, - SkStringPrintf("%s.x + %s", proc.instanceAttrib(), pointId).c_str()); -} - void GrCCPRQuadraticShader::emitWind(GrGLSLShaderBuilder* s, const char* pts, const char* outputWind) const { s->codeAppendf("float area_times_2 = determinant(float2x2(%s[1] - %s[0], %s[2] - %s[0]));", diff --git a/src/gpu/ccpr/GrCCPRQuadraticShader.h b/src/gpu/ccpr/GrCCPRQuadraticShader.h index 38dd14e737..4877edec44 100644 --- a/src/gpu/ccpr/GrCCPRQuadraticShader.h +++ b/src/gpu/ccpr/GrCCPRQuadraticShader.h @@ -24,10 +24,6 @@ class GrCCPRQuadraticShader : public GrCCPRCoverageProcessor::Shader { protected: int getNumInputPoints() const final { return 3; } - void appendInputPointFetch(const GrCCPRCoverageProcessor&, GrGLSLShaderBuilder*, - const TexelBufferHandle& pointsBuffer, - const char* pointId) const override; - void emitWind(GrGLSLShaderBuilder*, const char* pts, const char* outputWind) const final; void emitSetupCode(GrGLSLShaderBuilder*, const char* pts, const char* segmentId, diff --git a/src/gpu/ccpr/GrCCPRTriangleShader.cpp b/src/gpu/ccpr/GrCCPRTriangleShader.cpp index a1f4198f86..c2c624b1ae 100644 --- a/src/gpu/ccpr/GrCCPRTriangleShader.cpp +++ b/src/gpu/ccpr/GrCCPRTriangleShader.cpp @@ -10,14 +10,6 @@ #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLVertexGeoBuilder.h" -void GrCCPRTriangleShader::appendInputPointFetch(const GrCCPRCoverageProcessor& proc, - GrGLSLShaderBuilder* s, - const TexelBufferHandle& pointsBuffer, - const char* pointId) const { - s->appendTexelFetch(pointsBuffer, - SkStringPrintf("%s[%s]", proc.instanceAttrib(), pointId).c_str()); -} - void GrCCPRTriangleShader::emitWind(GrGLSLShaderBuilder* s, const char* pts, const char* outputWind) const { s->codeAppendf("%s = sign(determinant(float2x2(%s[1] - %s[0], %s[2] - %s[0])));", diff --git a/src/gpu/ccpr/GrCCPRTriangleShader.h b/src/gpu/ccpr/GrCCPRTriangleShader.h index 64e54954a2..a0bbb66819 100644 --- a/src/gpu/ccpr/GrCCPRTriangleShader.h +++ b/src/gpu/ccpr/GrCCPRTriangleShader.h @@ -18,11 +18,6 @@ class GrCCPRTriangleShader : public GrCCPRCoverageProcessor::Shader { public: int getNumInputPoints() const final { return 3; } int getNumSegments() const final { return 3; } // 3 wedges, 3 edges, 3 corners. - - void appendInputPointFetch(const GrCCPRCoverageProcessor&, GrGLSLShaderBuilder*, - const TexelBufferHandle& pointsBuffer, - const char* pointId) const final; - void emitWind(GrGLSLShaderBuilder* s, const char* pts, const char* outputWind) const final; }; diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp index 95fd619dcd..937fd4824b 100644 --- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp +++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp @@ -39,10 +39,8 @@ 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.geometryShaderSupport() && - shaderCaps.texelBufferSupport() && shaderCaps.integerSupport() && shaderCaps.flatInterpolationSupport() && - shaderCaps.maxVertexSamplers() >= 1 && caps.instanceAttribSupport() && GrCaps::kNone_MapFlags != caps.mapBufferFlags() && caps.isConfigTexturable(kAlpha_half_GrPixelConfig) && |