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