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