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/graphite/RendererProvider.h"
9
10 #include "include/core/SkPathTypes.h"
11 #include "include/core/SkVertices.h"
12 #include "src/gpu/AtlasTypes.h"
13 #include "src/gpu/graphite/Caps.h"
14 #include "src/gpu/graphite/InternalDrawTypeFlags.h"
15 #include "src/gpu/graphite/render/AnalyticBlurRenderStep.h"
16 #include "src/gpu/graphite/render/AnalyticRRectRenderStep.h"
17 #include "src/gpu/graphite/render/BitmapTextRenderStep.h"
18 #include "src/gpu/graphite/render/CircularArcRenderStep.h"
19 #include "src/gpu/graphite/render/CommonDepthStencilSettings.h"
20 #include "src/gpu/graphite/render/CoverBoundsRenderStep.h"
21 #include "src/gpu/graphite/render/CoverageMaskRenderStep.h"
22 #include "src/gpu/graphite/render/MiddleOutFanRenderStep.h"
23 #include "src/gpu/graphite/render/PerEdgeAAQuadRenderStep.h"
24 #include "src/gpu/graphite/render/SDFTextLCDRenderStep.h"
25 #include "src/gpu/graphite/render/SDFTextRenderStep.h"
26 #include "src/gpu/graphite/render/TessellateCurvesRenderStep.h"
27 #include "src/gpu/graphite/render/TessellateStrokesRenderStep.h"
28 #include "src/gpu/graphite/render/TessellateWedgesRenderStep.h"
29 #include "src/gpu/graphite/render/VerticesRenderStep.h"
30 #include "src/sksl/SkSLUtil.h"
31
32 #ifdef SK_ENABLE_VELLO_SHADERS
33 #include "src/gpu/graphite/compute/VelloRenderer.h"
34 #endif
35
36 namespace skgpu::graphite {
37
IsVelloRendererSupported(const Caps * caps)38 bool RendererProvider::IsVelloRendererSupported(const Caps* caps) {
39 #ifdef SK_ENABLE_VELLO_SHADERS
40 return caps->computeSupport();
41 #else
42 return false;
43 #endif
44 }
45
46 // The destructor is intentionally defined here and not in the header file to allow forward
47 // declared types (such as `VelloRenderer`) to be defined as a `std::unique_ptr` parameter type
48 // in members.
49 RendererProvider::~RendererProvider() = default;
50
RendererProvider(const Caps * caps,StaticBufferManager * bufferManager)51 RendererProvider::RendererProvider(const Caps* caps, StaticBufferManager* bufferManager) {
52 // This constructor requires all Renderers be densely packed so that it can simply iterate over
53 // the fields directly and fill 'fRenderers' with every one that was initialized with a
54 // non-empty renderer. While this is a little magical, it simplifies the rest of the logic
55 // and can be enforced statically.
56 static constexpr size_t kRendererSize = offsetof(RendererProvider, fRenderers) -
57 offsetof(RendererProvider, fStencilTessellatedCurves);
58 static_assert(kRendererSize % sizeof(Renderer) == 0, "Renderer declarations are not dense");
59
60 const bool infinitySupport = caps->shaderCaps()->fInfinitySupport;
61
62 // Single-step renderers don't share RenderSteps
63 auto makeFromStep = [&](std::unique_ptr<RenderStep> singleStep, DrawTypeFlags drawTypes) {
64 std::string name = "SingleStep[";
65 name += singleStep->name();
66 name += "]";
67 fRenderSteps.push_back(std::move(singleStep));
68 return Renderer(name, drawTypes, fRenderSteps.back().get());
69 };
70
71 fConvexTessellatedWedges =
72 makeFromStep(std::make_unique<TessellateWedgesRenderStep>(
73 "convex", infinitySupport, kDirectDepthGreaterPass, bufferManager),
74 DrawTypeFlags::kNonSimpleShape);
75 fTessellatedStrokes = makeFromStep(
76 std::make_unique<TessellateStrokesRenderStep>(infinitySupport),
77 DrawTypeFlags::kNonSimpleShape);
78 fCoverageMask = makeFromStep(
79 std::make_unique<CoverageMaskRenderStep>(),
80 static_cast<DrawTypeFlags>(static_cast<int>(DrawTypeFlags::kNonSimpleShape) |
81 static_cast<int>(InternalDrawTypeFlags::kCoverageMask)));
82
83 static constexpr struct {
84 skgpu::MaskFormat fFormat;
85 DrawTypeFlags fDrawType;
86 } kBitmapTextVariants [] = {
87 // We are using 565 here to represent LCD text, regardless of texture format
88 { skgpu::MaskFormat::kA8, DrawTypeFlags::kBitmapText_Mask },
89 { skgpu::MaskFormat::kA565, DrawTypeFlags::kBitmapText_LCD },
90 { skgpu::MaskFormat::kARGB, DrawTypeFlags::kBitmapText_Color }
91 };
92
93 for (auto textVariant : kBitmapTextVariants) {
94 fBitmapText[int(textVariant.fFormat)] =
95 makeFromStep(std::make_unique<BitmapTextRenderStep>(textVariant.fFormat),
96 textVariant.fDrawType);
97 }
98 for (bool lcd : {false, true}) {
99 fSDFText[lcd] = lcd ? makeFromStep(std::make_unique<SDFTextLCDRenderStep>(),
100 DrawTypeFlags::kSDFText_LCD)
101 : makeFromStep(std::make_unique<SDFTextRenderStep>(),
102 DrawTypeFlags::kSDFText);
103 }
104 fAnalyticRRect = makeFromStep(
105 std::make_unique<AnalyticRRectRenderStep>(bufferManager),
106 static_cast<DrawTypeFlags>(static_cast<int>(DrawTypeFlags::kSimpleShape) |
107 static_cast<int>(InternalDrawTypeFlags::kAnalyticRRect)));
108 fPerEdgeAAQuad = makeFromStep(std::make_unique<PerEdgeAAQuadRenderStep>(bufferManager),
109 DrawTypeFlags::kSimpleShape);
110 fNonAABoundsFill = makeFromStep(std::make_unique<CoverBoundsRenderStep>(
111 "non-aa-fill", kDirectDepthGreaterPass),
112 DrawTypeFlags::kSimpleShape);
113 fCircularArc = makeFromStep(std::make_unique<CircularArcRenderStep>(bufferManager),
114 DrawTypeFlags::kSimpleShape);
115 fAnalyticBlur = makeFromStep(std::make_unique<AnalyticBlurRenderStep>(),
116 DrawTypeFlags::kSimpleShape);
117
118 // vertices
119 for (PrimitiveType primType : {PrimitiveType::kTriangles, PrimitiveType::kTriangleStrip}) {
120 for (bool color : {false, true}) {
121 for (bool texCoords : {false, true}) {
122 int index = 4*(primType == PrimitiveType::kTriangleStrip) + 2*color + texCoords;
123 fVertices[index] = makeFromStep(
124 std::make_unique<VerticesRenderStep>(primType, color, texCoords),
125 DrawTypeFlags::kDrawVertices);
126 }
127 }
128 }
129
130 // The tessellating path renderers that use stencil can share the cover steps.
131 auto coverFill = std::make_unique<CoverBoundsRenderStep>("regular-cover", kRegularCoverPass);
132 auto coverInverse = std::make_unique<CoverBoundsRenderStep>("inverse-cover", kInverseCoverPass);
133
134 for (bool evenOdd : {false, true}) {
135 // These steps can be shared by regular and inverse fills
136 auto stencilFan = std::make_unique<MiddleOutFanRenderStep>(evenOdd);
137 auto stencilCurve = std::make_unique<TessellateCurvesRenderStep>(
138 evenOdd, infinitySupport, bufferManager);
139 auto stencilWedge =
140 evenOdd ? std::make_unique<TessellateWedgesRenderStep>(
141 "evenodd", infinitySupport, kEvenOddStencilPass, bufferManager)
142 : std::make_unique<TessellateWedgesRenderStep>(
143 "winding", infinitySupport, kWindingStencilPass, bufferManager);
144
145 for (bool inverse : {false, true}) {
146 static const char* kTessVariants[4] =
147 {"[winding]", "[evenodd]", "[inverse-winding]", "[inverse-evenodd]"};
148
149 int index = 2*inverse + evenOdd; // matches SkPathFillType
150 std::string variant = kTessVariants[index];
151
152 const RenderStep* coverStep = inverse ? coverInverse.get() : coverFill.get();
153 fStencilTessellatedCurves[index] = Renderer("StencilTessellatedCurvesAndTris" + variant,
154 DrawTypeFlags::kNonSimpleShape,
155 stencilFan.get(),
156 stencilCurve.get(),
157 coverStep);
158
159 fStencilTessellatedWedges[index] = Renderer("StencilTessellatedWedges" + variant,
160 DrawTypeFlags::kNonSimpleShape,
161 stencilWedge.get(),
162 coverStep);
163 }
164
165 fRenderSteps.push_back(std::move(stencilFan));
166 fRenderSteps.push_back(std::move(stencilCurve));
167 fRenderSteps.push_back(std::move(stencilWedge));
168 }
169
170 fRenderSteps.push_back(std::move(coverInverse));
171 fRenderSteps.push_back(std::move(coverFill));
172
173 // Fill out 'fRenderers' by iterating the "span" from fStencilTessellatedCurves to fRenderers
174 // and checking if they've been skipped or not.
175 SkSpan<Renderer> allRenderers = {fStencilTessellatedCurves, kRendererSize / sizeof(Renderer)};
176 for (const Renderer& r : allRenderers) {
177 if (r.numRenderSteps() > 0) {
178 fRenderers.push_back(&r);
179 }
180 }
181
182 #ifdef SK_ENABLE_VELLO_SHADERS
183 fVelloRenderer = std::make_unique<VelloRenderer>(caps);
184 #endif
185 }
186
lookup(uint32_t uniqueID) const187 const RenderStep* RendererProvider::lookup(uint32_t uniqueID) const {
188 for (auto&& rs : fRenderSteps) {
189 if (rs->uniqueID() == uniqueID) {
190 return rs.get();
191 }
192 }
193 return nullptr;
194 }
195
196 } // namespace skgpu::graphite
197