diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp index 9f23b1b7ab..9ef2860346 100644 --- a/gm/beziereffects.cpp +++ b/gm/beziereffects.cpp @@ -67,191 +67,9 @@ private: typedef GrMeshDrawOp INHERITED; }; -class BezierCubicTestOp : public BezierTestOp { -public: - DEFINE_OP_CLASS_ID - - const char* name() const override { return "BezierCubicTestOp"; } - - static std::unique_ptr Make(GrContext* context, - sk_sp gp, - const SkRect& rect, - const SkPMColor4f& color) { - GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); - - return pool->allocate(std::move(gp), rect, color); - } - -private: - friend class ::GrOpMemoryPool; // for ctor - - BezierCubicTestOp(sk_sp gp, const SkRect& rect, - const SkPMColor4f& color) - : INHERITED(std::move(gp), rect, color, ClassID()) {} - - void onPrepareDraws(Target* target) override { - SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(SkPoint)); - QuadHelper helper(target, sizeof(SkPoint), 1); - SkPoint* pts = reinterpret_cast(helper.vertices()); - if (!pts) { - return; - } - SkRect rect = this->rect(); - SkPointPriv::SetRectTriStrip(pts, rect, sizeof(SkPoint)); - auto pipe = this->makePipeline(target); - helper.recordDraw(target, this->gp(), pipe.fPipeline, pipe.fFixedDynamicState); - } - - static constexpr int kVertsPerCubic = 4; - static constexpr int kIndicesPerCubic = 6; - - typedef BezierTestOp INHERITED; -}; - /** * This GM directly exercises effects that draw Bezier curves in the GPU backend. */ -class BezierCubicEffects : public GM { -public: - BezierCubicEffects() { - this->setBGColor(0xFFFFFFFF); - } - -protected: - SkString onShortName() override { - return SkString("bezier_cubic_effects"); - } - - SkISize onISize() override { - return SkISize::Make(800, 800); - } - - void onDraw(SkCanvas* canvas) override { - GrRenderTargetContext* renderTargetContext = - canvas->internal_private_accessTopLayerRenderTargetContext(); - if (!renderTargetContext) { - skiagm::GM::DrawGpuOnlyMessage(canvas); - return; - } - - GrContext* context = canvas->getGrContext(); - if (!context) { - return; - } - - if (!context->contextPriv().caps()->shaderCaps()->floatIs32Bits()) { - SkPaint paint; - sk_tool_utils::set_portable_typeface(&paint); - paint.setAntiAlias(true); - paint.setTextSize(20); - - canvas->clear(SK_ColorWHITE); - canvas->drawString("float != fp32", 20, 40, paint); - return; - } - - struct Vertex { - SkPoint fPosition; - float fKLM[4]; // The last value is ignored. The effect expects a vec4f. - }; - - constexpr int kNumCubics = 15; - SkRandom rand; - - // Mult by 3 for each edge effect type - int numCols = SkScalarCeilToInt(SkScalarSqrt(SkIntToScalar(kNumCubics*3))); - int numRows = SkScalarCeilToInt(SkIntToScalar(kNumCubics*3) / numCols); - SkScalar w = SkIntToScalar(renderTargetContext->width()) / numCols; - SkScalar h = SkIntToScalar(renderTargetContext->height()) / numRows; - int row = 0; - int col = 0; - SkPMColor4f color = SkPMColor4f::FromBytes_RGBA(0xff000000); - - for (int i = 0; i < kNumCubics; ++i) { - SkPoint baseControlPts[] = { - {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}, - {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}, - {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)}, - {rand.nextRangeF(0.f, w), rand.nextRangeF(0.f, h)} - }; - for(GrClipEdgeType edgeType : {GrClipEdgeType::kFillBW, - GrClipEdgeType::kFillAA, - GrClipEdgeType::kHairlineAA}) { - SkScalar x = col * w; - SkScalar y = row * h; - SkPoint controlPts[] = { - {x + baseControlPts[0].fX, y + baseControlPts[0].fY}, - {x + baseControlPts[1].fX, y + baseControlPts[1].fY}, - {x + baseControlPts[2].fX, y + baseControlPts[2].fY}, - {x + baseControlPts[3].fX, y + baseControlPts[3].fY} - }; - SkPoint chopped[10]; - SkMatrix klm; - int loopIndex; - int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts, - chopped, - &klm, - &loopIndex); - - SkPaint ctrlPtPaint; - ctrlPtPaint.setColor(rand.nextU() | 0xFF000000); - canvas->drawCircle(controlPts[0], 8.f, ctrlPtPaint); - for (int i = 1; i < 4; ++i) { - canvas->drawCircle(controlPts[i], 6.f, ctrlPtPaint); - } - - SkPaint polyPaint; - polyPaint.setColor(0xffA0A0A0); - polyPaint.setStrokeWidth(0); - polyPaint.setStyle(SkPaint::kStroke_Style); - canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, controlPts, polyPaint); - - SkPaint choppedPtPaint; - choppedPtPaint.setColor(~ctrlPtPaint.getColor() | 0xFF000000); - - for (int c = 0; c < cnt; ++c) { - SkPoint* pts = chopped + 3 * c; - - for (int i = 0; i < 4; ++i) { - canvas->drawCircle(pts[i], 3.f, choppedPtPaint); - } - - SkRect bounds; - bounds.set(pts, 4); - - SkPaint boundsPaint; - boundsPaint.setColor(0xff808080); - boundsPaint.setStrokeWidth(0); - boundsPaint.setStyle(SkPaint::kStroke_Style); - canvas->drawRect(bounds, boundsPaint); - - - bool flipKL = (c == loopIndex && cnt != 3); - sk_sp gp = - GrCubicEffect::Make(color, SkMatrix::I(), klm, flipKL, edgeType, - *context->contextPriv().caps()); - if (!gp) { - break; - } - - std::unique_ptr op = - BezierCubicTestOp::Make(context, std::move(gp), bounds, color); - renderTargetContext->priv().testingOnly_addDrawOp(std::move(op)); - } - ++col; - if (numCols == col) { - col = 0; - ++row; - } - } - } - } - -private: - typedef GM INHERITED; -}; - -////////////////////////////////////////////////////////////////////////////// class BezierConicTestOp : public BezierTestOp { public: @@ -651,7 +469,6 @@ private: typedef GM INHERITED; }; -DEF_GM(return new BezierCubicEffects;) DEF_GM(return new BezierConicEffects;) DEF_GM(return new BezierQuadEffects;) } diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h index 48eba1ebf6..d230c24662 100644 --- a/src/gpu/GrProcessor.h +++ b/src/gpu/GrProcessor.h @@ -102,7 +102,6 @@ public: kGrConicEffect_ClassID, kGrConstColorProcessor_ClassID, kGrConvexPolyEffect_ClassID, - kGrCubicEffect_ClassID, kGrDeviceSpaceTextureDecalFragmentProcessor_ClassID, kGrDiffuseLightingEffect_ClassID, kGrDisplacementMapEffect_ClassID, diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index 0f59eda13e..da7fca60e2 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -460,226 +460,3 @@ sk_sp GrQuadEffect::TestCreate(GrProcessorTestData* d) { return gp; } #endif - -////////////////////////////////////////////////////////////////////////////// -// Cubic -////////////////////////////////////////////////////////////////////////////// - -class GrGLCubicEffect : public GrGLSLGeometryProcessor { -public: - GrGLCubicEffect(const GrGeometryProcessor&); - - void onEmitCode(EmitArgs&, GrGPArgs*) override; - - static inline void GenKey(const GrGeometryProcessor&, - const GrShaderCaps&, - GrProcessorKeyBuilder*); - - void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc, - FPCoordTransformIter&& transformIter) override { - const GrCubicEffect& ce = primProc.cast(); - - if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) { - fViewMatrix = ce.viewMatrix(); - float viewMatrix[3 * 3]; - GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); - pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); - } - - if (!fDevKLMMatrix.cheapEqualTo(ce.devKLMMatrix())) { - fDevKLMMatrix = ce.devKLMMatrix(); - float devKLMMatrix[3 * 3]; - GrGLSLGetMatrix<3>(devKLMMatrix, fDevKLMMatrix); - pdman.setMatrix3f(fDevKLMUniform, devKLMMatrix); - } - - if (ce.color() != fColor) { - pdman.set4fv(fColorUniform, 1, ce.color().vec()); - fColor = ce.color(); - } - - this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); - } - -private: - SkMatrix fViewMatrix; - SkMatrix fDevKLMMatrix; - SkPMColor4f fColor; - GrClipEdgeType fEdgeType; - UniformHandle fColorUniform; - UniformHandle fViewMatrixUniform; - UniformHandle fDevKLMUniform; - - typedef GrGLSLGeometryProcessor INHERITED; -}; - -GrGLCubicEffect::GrGLCubicEffect(const GrGeometryProcessor& processor) - : fViewMatrix(SkMatrix::InvalidMatrix()) - , fDevKLMMatrix(SkMatrix::InvalidMatrix()) - , fColor(SK_PMColor4fILLEGAL) { - const GrCubicEffect& ce = processor.cast(); - fEdgeType = ce.getEdgeType(); -} - -void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { - GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; - const GrCubicEffect& gp = args.fGP.cast(); - GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - - // emit attributes - varyingHandler->emitAttributes(gp); - - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - // Setup pass through color - if (!gp.colorIgnored()) { - this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, &fColorUniform); - } - - // Setup position - this->writeOutputPosition(vertBuilder, - uniformHandler, - gpArgs, - gp.inPosition().name(), - gp.viewMatrix(), - &fViewMatrixUniform); - - // Setup KLM - const char* devkLMMatrixName; - fDevKLMUniform = uniformHandler->addUniform(kVertex_GrShaderFlag, kFloat3x3_GrSLType, "KLM", - &devkLMMatrixName); - GrGLSLVarying v(kFloat3_GrSLType); - varyingHandler->addVarying("CubicCoeffs", &v); - vertBuilder->codeAppendf("%s = %s * float3(%s, 1);", - v.vsOut(), devkLMMatrixName, gpArgs->fPositionVar.c_str()); - - - GrGLSLVarying gradCoeffs(kFloat4_GrSLType); - if (GrClipEdgeType::kFillAA == fEdgeType || GrClipEdgeType::kHairlineAA == fEdgeType) { - varyingHandler->addVarying("GradCoeffs", &gradCoeffs); - vertBuilder->codeAppendf("float k = %s[0], l = %s[1], m = %s[2];", - v.vsOut(), v.vsOut(), v.vsOut()); - vertBuilder->codeAppendf("float2 gk = float2(%s[0][0], %s[1][0]), " - "gl = float2(%s[0][1], %s[1][1]), " - "gm = float2(%s[0][2], %s[1][2]);", - devkLMMatrixName, devkLMMatrixName, devkLMMatrixName, - devkLMMatrixName, devkLMMatrixName, devkLMMatrixName); - vertBuilder->codeAppendf("%s = float4(3 * k * gk, -m * gl - l * gm);", - gradCoeffs.vsOut()); - } - - // emit transforms with position - this->emitTransforms(vertBuilder, - varyingHandler, - uniformHandler, - gp.inPosition().asShaderVar(), - args.fFPCoordTransformHandler); - - GrShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0); - GrShaderVar gF("gF", kFloat2_GrSLType, 0); - GrShaderVar func("func", kFloat_GrSLType, 0); - - fragBuilder->declAppend(edgeAlpha); - fragBuilder->declAppend(gF); - fragBuilder->declAppend(func); - - switch (fEdgeType) { - case GrClipEdgeType::kHairlineAA: { - fragBuilder->codeAppendf("%s = %s.x * %s.xy + %s.zw;", - gF.c_str(), v.fsIn(), gradCoeffs.fsIn(), gradCoeffs.fsIn()); - fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;", - func.c_str(), v.fsIn(), v.fsIn(), - v.fsIn(), v.fsIn(), v.fsIn()); - fragBuilder->codeAppendf("%s = abs(%s);", func.c_str(), func.c_str()); - fragBuilder->codeAppendf("%s = %s * inversesqrt(dot(%s, %s));", - edgeAlpha.c_str(), func.c_str(), gF.c_str(), gF.c_str()); - fragBuilder->codeAppendf("%s = max(1.0 - %s, 0.0);", - edgeAlpha.c_str(), edgeAlpha.c_str()); - // Add line below for smooth cubic ramp - // fragBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);", - // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(), - // edgeAlpha.c_str()); - break; - } - case GrClipEdgeType::kFillAA: { - fragBuilder->codeAppendf("%s = %s.x * %s.xy + %s.zw;", - gF.c_str(), v.fsIn(), gradCoeffs.fsIn(), gradCoeffs.fsIn()); - fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;", - func.c_str(), - v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn()); - fragBuilder->codeAppendf("%s = %s * inversesqrt(dot(%s, %s));", - edgeAlpha.c_str(), func.c_str(), gF.c_str(), gF.c_str()); - fragBuilder->codeAppendf("%s = saturate(0.5 - %s);", - edgeAlpha.c_str(), edgeAlpha.c_str()); - // Add line below for smooth cubic ramp - // fragBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);", - // edgeAlpha.c_str(), edgeAlpha.c_str(), edgeAlpha.c_str(), - // edgeAlpha.c_str()); - break; - } - case GrClipEdgeType::kFillBW: { - fragBuilder->codeAppendf("%s = %s.x * %s.x * %s.x - %s.y * %s.z;", - edgeAlpha.c_str(), v.fsIn(), v.fsIn(), - v.fsIn(), v.fsIn(), v.fsIn()); - fragBuilder->codeAppendf("%s = half(%s < 0.0);", edgeAlpha.c_str(), edgeAlpha.c_str()); - break; - } - default: - SK_ABORT("Shouldn't get here"); - } - - - fragBuilder->codeAppendf("%s = float4(%s);", args.fOutputCoverage, edgeAlpha.c_str()); -} - -void GrGLCubicEffect::GenKey(const GrGeometryProcessor& gp, - const GrShaderCaps&, - GrProcessorKeyBuilder* b) { - const GrCubicEffect& ce = gp.cast(); - uint32_t key = ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2; - key |= ComputePosKey(ce.viewMatrix()) << 5; - b->add32(key); -} - -////////////////////////////////////////////////////////////////////////////// - -constexpr GrPrimitiveProcessor::Attribute GrCubicEffect::kInPosition; - -GrCubicEffect::~GrCubicEffect() {} - -void GrCubicEffect::getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const { - GrGLCubicEffect::GenKey(*this, caps, b); -} - -GrGLSLPrimitiveProcessor* GrCubicEffect::createGLSLInstance(const GrShaderCaps&) const { - return new GrGLCubicEffect(*this); -} - -GrCubicEffect::GrCubicEffect(const SkPMColor4f& color, const SkMatrix& viewMatrix, const SkMatrix& - devKLMMatrix, GrClipEdgeType edgeType) - : INHERITED(kGrCubicEffect_ClassID) - , fColor(color) - , fViewMatrix(viewMatrix) - , fDevKLMMatrix(devKLMMatrix) - , fEdgeType(edgeType) { - this->setVertexAttributeCnt(1); -} - -////////////////////////////////////////////////////////////////////////////// - -GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrCubicEffect); - -#if GR_TEST_UTILS -sk_sp GrCubicEffect::TestCreate(GrProcessorTestData* d) { - sk_sp gp; - do { - GrClipEdgeType edgeType = - static_cast( - d->fRandom->nextULessThan(kGrClipEdgeTypeCnt)); - gp = GrCubicEffect::Make(SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)), - GrTest::TestMatrix(d->fRandom), GrTest::TestMatrix(d->fRandom), - d->fRandom->nextBool(), edgeType, *d->caps()); - } while (nullptr == gp); - return gp; -} -#endif diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h index b168fdd9cd..835901fe1d 100644 --- a/src/gpu/effects/GrBezierEffect.h +++ b/src/gpu/effects/GrBezierEffect.h @@ -217,91 +217,4 @@ private: typedef GrGeometryProcessor INHERITED; }; -////////////////////////////////////////////////////////////////////////////// -/** - * Shader is based off of "Resolution Independent Curve Rendering using - * Programmable Graphics Hardware" by Loop and Blinn. - * The output of this effect is a hairline edge for non rational cubics. - * Cubics are specified by implicit equation K^3 - LM. - * K, L, and M, are the first three values of the vertex attribute, - * the fourth value is not used. Distance is calculated using a - * first order approximation from the taylor series. - * Coverage for AA is max(0, 1-distance). - */ -class GrGLCubicEffect; - -class GrCubicEffect : public GrGeometryProcessor { -public: - static sk_sp Make(const SkPMColor4f& color, - const SkMatrix& viewMatrix, - const SkMatrix& klm, - bool flipKL, - const GrClipEdgeType edgeType, - const GrCaps& caps) { - if (!caps.shaderCaps()->floatIs32Bits()) { - // Cubic math will be too unstable if the hardware doesn't support full fp32. - return nullptr; - } - - // Map KLM to something that operates in device space. - SkMatrix devKLM; - if (!viewMatrix.invert(&devKLM)) { - return nullptr; - } - devKLM.postConcat(klm); - if (flipKL) { - devKLM.postScale(-1, -1); - } - - switch (edgeType) { - case GrClipEdgeType::kFillAA: - return sk_sp( - new GrCubicEffect(color, viewMatrix, devKLM, GrClipEdgeType::kFillAA)); - case GrClipEdgeType::kHairlineAA: - return sk_sp( - new GrCubicEffect(color, viewMatrix, devKLM, GrClipEdgeType::kHairlineAA)); - case GrClipEdgeType::kFillBW: - return sk_sp( - new GrCubicEffect(color, viewMatrix, devKLM, GrClipEdgeType::kFillBW)); - default: - return nullptr; - } - } - - ~GrCubicEffect() override; - - const char* name() const override { return "Cubic"; } - - inline const Attribute& inPosition() const { return kInPosition; } - inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); } - inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); } - inline GrClipEdgeType getEdgeType() const { return fEdgeType; } - const SkPMColor4f& color() const { return fColor; } - bool colorIgnored() const { return SK_PMColor4fILLEGAL == fColor; } - const SkMatrix& viewMatrix() const { return fViewMatrix; } - const SkMatrix& devKLMMatrix() const { return fDevKLMMatrix; } - - void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; - - GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; - -private: - GrCubicEffect(const SkPMColor4f&, const SkMatrix& viewMatrix, const SkMatrix& devKLMMatrix, - GrClipEdgeType); - - const Attribute& onVertexAttribute(int) const override { return kInPosition; } - - SkPMColor4f fColor; - SkMatrix fViewMatrix; - SkMatrix fDevKLMMatrix; - GrClipEdgeType fEdgeType; - - static constexpr Attribute kInPosition = - {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType}; - - GR_DECLARE_GEOMETRY_PROCESSOR_TEST - - typedef GrGeometryProcessor INHERITED; -}; - #endif