1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2014 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker // This test only works with the GPU backend. 9*c8dee2aaSAndroid Build Coastguard Worker 10*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlendMode.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h" 16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h" 17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h" 18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h" 19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h" 20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 21*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h" 22*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkCanvasPriv.h" 23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCanvas.h" 24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrFragmentProcessor.h" 25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPaint.h" 26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SurfaceDrawContext.h" 27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/effects/GrConvexPolyEffect.h" 28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/effects/GrPorterDuffXferProcessor.h" 29*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/TestOps.h" 30*c8dee2aaSAndroid Build Coastguard Worker 31*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 32*c8dee2aaSAndroid Build Coastguard Worker #include <utility> 33*c8dee2aaSAndroid Build Coastguard Worker 34*c8dee2aaSAndroid Build Coastguard Worker class GrAppliedClip; 35*c8dee2aaSAndroid Build Coastguard Worker 36*c8dee2aaSAndroid Build Coastguard Worker namespace skiagm { 37*c8dee2aaSAndroid Build Coastguard Worker 38*c8dee2aaSAndroid Build Coastguard Worker /** 39*c8dee2aaSAndroid Build Coastguard Worker * This GM directly exercises a GrProcessor that draws convex polygons. 40*c8dee2aaSAndroid Build Coastguard Worker */ 41*c8dee2aaSAndroid Build Coastguard Worker class ConvexPolyEffect : public GpuGM { 42*c8dee2aaSAndroid Build Coastguard Worker public: ConvexPolyEffect()43*c8dee2aaSAndroid Build Coastguard Worker ConvexPolyEffect() { 44*c8dee2aaSAndroid Build Coastguard Worker this->setBGColor(0xFFFFFFFF); 45*c8dee2aaSAndroid Build Coastguard Worker } 46*c8dee2aaSAndroid Build Coastguard Worker 47*c8dee2aaSAndroid Build Coastguard Worker protected: getName() const48*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("convex_poly_effect"); } 49*c8dee2aaSAndroid Build Coastguard Worker getISize()50*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(720, 550); } 51*c8dee2aaSAndroid Build Coastguard Worker onOnceBeforeDraw()52*c8dee2aaSAndroid Build Coastguard Worker void onOnceBeforeDraw() override { 53*c8dee2aaSAndroid Build Coastguard Worker SkPath tri; 54*c8dee2aaSAndroid Build Coastguard Worker tri.moveTo(5.f, 5.f); 55*c8dee2aaSAndroid Build Coastguard Worker tri.lineTo(100.f, 20.f); 56*c8dee2aaSAndroid Build Coastguard Worker tri.lineTo(15.f, 100.f); 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker fPaths.push_back(tri); 59*c8dee2aaSAndroid Build Coastguard Worker fPaths.emplace_back(); 60*c8dee2aaSAndroid Build Coastguard Worker fPaths.back().reverseAddPath(tri); 61*c8dee2aaSAndroid Build Coastguard Worker 62*c8dee2aaSAndroid Build Coastguard Worker tri.close(); 63*c8dee2aaSAndroid Build Coastguard Worker fPaths.push_back(tri); 64*c8dee2aaSAndroid Build Coastguard Worker 65*c8dee2aaSAndroid Build Coastguard Worker SkPath ngon; 66*c8dee2aaSAndroid Build Coastguard Worker constexpr SkScalar kRadius = 50.f; 67*c8dee2aaSAndroid Build Coastguard Worker const SkPoint center = { kRadius, kRadius }; 68*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < GrConvexPolyEffect::kMaxEdges; ++i) { 69*c8dee2aaSAndroid Build Coastguard Worker SkScalar angle = 2 * SK_ScalarPI * i / GrConvexPolyEffect::kMaxEdges; 70*c8dee2aaSAndroid Build Coastguard Worker SkPoint point = { SkScalarCos(angle), SkScalarSin(angle) }; 71*c8dee2aaSAndroid Build Coastguard Worker point.scale(kRadius); 72*c8dee2aaSAndroid Build Coastguard Worker point = center + point; 73*c8dee2aaSAndroid Build Coastguard Worker if (0 == i) { 74*c8dee2aaSAndroid Build Coastguard Worker ngon.moveTo(point); 75*c8dee2aaSAndroid Build Coastguard Worker } else { 76*c8dee2aaSAndroid Build Coastguard Worker ngon.lineTo(point); 77*c8dee2aaSAndroid Build Coastguard Worker } 78*c8dee2aaSAndroid Build Coastguard Worker } 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker fPaths.push_back(ngon); 81*c8dee2aaSAndroid Build Coastguard Worker SkMatrix scaleM; 82*c8dee2aaSAndroid Build Coastguard Worker scaleM.setScale(1.1f, 0.4f); 83*c8dee2aaSAndroid Build Coastguard Worker ngon.transform(scaleM); 84*c8dee2aaSAndroid Build Coastguard Worker fPaths.push_back(ngon); 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker SkPath linePath; 87*c8dee2aaSAndroid Build Coastguard Worker linePath.moveTo(5.f, 5.f); 88*c8dee2aaSAndroid Build Coastguard Worker linePath.lineTo(6.f, 6.f); 89*c8dee2aaSAndroid Build Coastguard Worker fPaths.push_back(linePath); 90*c8dee2aaSAndroid Build Coastguard Worker } 91*c8dee2aaSAndroid Build Coastguard Worker onDraw(GrRecordingContext * rContext,SkCanvas * canvas,SkString * errorMsg)92*c8dee2aaSAndroid Build Coastguard Worker DrawResult onDraw(GrRecordingContext* rContext, SkCanvas* canvas, SkString* errorMsg) override { 93*c8dee2aaSAndroid Build Coastguard Worker auto sdc = skgpu::ganesh::TopDeviceSurfaceDrawContext(canvas); 94*c8dee2aaSAndroid Build Coastguard Worker if (!sdc) { 95*c8dee2aaSAndroid Build Coastguard Worker *errorMsg = kErrorMsg_DrawSkippedGpuOnly; 96*c8dee2aaSAndroid Build Coastguard Worker return DrawResult::kSkip; 97*c8dee2aaSAndroid Build Coastguard Worker } 98*c8dee2aaSAndroid Build Coastguard Worker 99*c8dee2aaSAndroid Build Coastguard Worker SkScalar y = 0; 100*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kDX = 12.f; 101*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kOutset = 5.f; 102*c8dee2aaSAndroid Build Coastguard Worker 103*c8dee2aaSAndroid Build Coastguard Worker for (const SkPath& path : fPaths) { 104*c8dee2aaSAndroid Build Coastguard Worker SkScalar x = 0; 105*c8dee2aaSAndroid Build Coastguard Worker 106*c8dee2aaSAndroid Build Coastguard Worker for (int et = 0; et < kGrClipEdgeTypeCnt; ++et) { 107*c8dee2aaSAndroid Build Coastguard Worker const SkMatrix m = SkMatrix::Translate(x, y); 108*c8dee2aaSAndroid Build Coastguard Worker SkPath p; 109*c8dee2aaSAndroid Build Coastguard Worker path.transform(m, &p); 110*c8dee2aaSAndroid Build Coastguard Worker 111*c8dee2aaSAndroid Build Coastguard Worker GrClipEdgeType edgeType = (GrClipEdgeType) et; 112*c8dee2aaSAndroid Build Coastguard Worker auto [success, fp] = GrConvexPolyEffect::Make(/*inputFP=*/nullptr, edgeType, p); 113*c8dee2aaSAndroid Build Coastguard Worker if (!success) { 114*c8dee2aaSAndroid Build Coastguard Worker continue; 115*c8dee2aaSAndroid Build Coastguard Worker } 116*c8dee2aaSAndroid Build Coastguard Worker 117*c8dee2aaSAndroid Build Coastguard Worker GrPaint grPaint; 118*c8dee2aaSAndroid Build Coastguard Worker grPaint.setColor4f({ 0, 0, 0, 1.f }); 119*c8dee2aaSAndroid Build Coastguard Worker grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc)); 120*c8dee2aaSAndroid Build Coastguard Worker grPaint.setCoverageFragmentProcessor(std::move(fp)); 121*c8dee2aaSAndroid Build Coastguard Worker auto rect = p.getBounds().makeOutset(kOutset, kOutset); 122*c8dee2aaSAndroid Build Coastguard Worker auto op = sk_gpu_test::test_ops::MakeRect(rContext, std::move(grPaint), rect); 123*c8dee2aaSAndroid Build Coastguard Worker sdc->addDrawOp(std::move(op)); 124*c8dee2aaSAndroid Build Coastguard Worker 125*c8dee2aaSAndroid Build Coastguard Worker x += SkScalarCeilToScalar(path.getBounds().width() + kDX); 126*c8dee2aaSAndroid Build Coastguard Worker } 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker // Draw AA and non AA paths using normal API for reference. 129*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 130*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(x, y); 131*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint; 132*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, paint); 133*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(path.getBounds().width() + 10.f, 0); 134*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true); 135*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, paint); 136*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 137*c8dee2aaSAndroid Build Coastguard Worker 138*c8dee2aaSAndroid Build Coastguard Worker y += SkScalarCeilToScalar(path.getBounds().height() + 20.f); 139*c8dee2aaSAndroid Build Coastguard Worker } 140*c8dee2aaSAndroid Build Coastguard Worker 141*c8dee2aaSAndroid Build Coastguard Worker return DrawResult::kOk; 142*c8dee2aaSAndroid Build Coastguard Worker } 143*c8dee2aaSAndroid Build Coastguard Worker 144*c8dee2aaSAndroid Build Coastguard Worker private: 145*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkPath> fPaths; 146*c8dee2aaSAndroid Build Coastguard Worker 147*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = GM; 148*c8dee2aaSAndroid Build Coastguard Worker }; 149*c8dee2aaSAndroid Build Coastguard Worker 150*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new ConvexPolyEffect;) 151*c8dee2aaSAndroid Build Coastguard Worker 152*c8dee2aaSAndroid Build Coastguard Worker } // namespace skiagm 153