• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 Google LLC.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/gpu/piet/Scene.h"
9 
10 #include "include/core/SkTypes.h"
11 
12 namespace skgpu::piet {
13 namespace {
14 
get_piet_verb(SkPath::Verb verb,PgpuPathVerb * outVerb)15 bool get_piet_verb(SkPath::Verb verb, PgpuPathVerb* outVerb) {
16     switch (verb) {
17         case SkPath::kMove_Verb:
18             *outVerb = PgpuPathVerb::MoveTo;
19             break;
20         case SkPath::kLine_Verb:
21             *outVerb = PgpuPathVerb::LineTo;
22             break;
23         case SkPath::kQuad_Verb:
24             *outVerb = PgpuPathVerb::QuadTo;
25             break;
26         case SkPath::kConic_Verb:
27         case SkPath::kCubic_Verb:
28             *outVerb = PgpuPathVerb::CurveTo;
29             break;
30         case SkPath::kClose_Verb:
31             *outVerb = PgpuPathVerb::Close;
32             break;
33         case SkPath::kDone_Verb:
34         default:
35             return false;
36     }
37     return true;
38 }
39 
get_fill_type(SkPathFillType fillType)40 PgpuFill get_fill_type(SkPathFillType fillType) {
41     switch (fillType) {
42         case SkPathFillType::kWinding:
43             return PgpuFill::NonZero;
44         case SkPathFillType::kEvenOdd:
45             return PgpuFill::EvenOdd;
46         default:
47             // TODO(b/238756757): pgpu-render doesn't define fill types for kInverseWinding and
48             // kInverseEvenOdd. This should be updated to support those cases.
49             SkDebugf("piet: unsupported fill type\n");
50             break;
51     }
52     return PgpuFill::NonZero;
53 }
54 
55 }  // namespace
56 
Scene()57 Scene::Scene() : Object(pgpu_scene_new()) { SkASSERT(this->get() != nullptr); }
58 
addPath(const SkPath & path,const Transform & transform)59 void Scene::addPath(const SkPath& path, const Transform& transform) {
60     this->initBuilderIfNecessary();
61 
62     SkPath::Iter pathIter(path, /*forceClose=*/false);
63     PgpuPathIter iter;
64     iter.context = &pathIter;
65     iter.next_element = [](void* context, PgpuPathElement* outElem) {
66         SkASSERT(outElem);
67         SkASSERT(context);
68 
69         SkPoint points[4];
70         SkPath::Verb verb = static_cast<SkPath::Iter*>(context)->next(points);
71         if (!get_piet_verb(verb, &outElem->verb)) {
72             return false;
73         }
74 
75         for (int i = 0; i < 3; ++i) {
76             const SkPoint& p = points[i];
77             outElem->points[i] = {p.x(), p.y()};
78         }
79 
80         return true;
81     };
82 
83     pgpu_scene_builder_transform(fActiveBuilder->get(), &transform);
84     pgpu_scene_builder_fill_path(
85             fActiveBuilder->get(), get_fill_type(path.getFillType()), nullptr, nullptr, &iter);
86 }
87 
finalize()88 bool Scene::finalize() {
89     if (!fActiveBuilder) {
90         return false;
91     }
92     fActiveBuilder.reset();
93     return true;
94 }
95 
initBuilderIfNecessary()96 void Scene::initBuilderIfNecessary() {
97     if (!fActiveBuilder) {
98         fActiveBuilder = Builder(pgpu_scene_builder_for_scene(this->get()));
99         SkASSERT(fActiveBuilder);
100     }
101 }
102 
103 }  // namespace skgpu::piet
104