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