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