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