xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrPipeline.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2015 Google Inc.
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 #ifndef GrPipeline_DEFINED
9 #define GrPipeline_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "include/private/base/SkDebug.h"
13 #include "include/private/base/SkMacros.h"
14 #include "include/private/base/SkPoint_impl.h"
15 #include "include/private/base/SkTemplates.h"
16 #include "include/private/base/SkTo.h"
17 #include "include/private/gpu/ganesh/GrTypesPriv.h"
18 #include "src/gpu/Swizzle.h"
19 #include "src/gpu/ganesh/GrCaps.h"
20 #include "src/gpu/ganesh/GrDstProxyView.h"
21 #include "src/gpu/ganesh/GrFragmentProcessor.h"
22 #include "src/gpu/ganesh/GrSurfaceProxy.h"
23 #include "src/gpu/ganesh/GrSurfaceProxyView.h"
24 #include "src/gpu/ganesh/GrTextureProxy.h"
25 #include "src/gpu/ganesh/GrWindowRectsState.h"
26 #include "src/gpu/ganesh/GrXferProcessor.h"
27 #include "src/gpu/ganesh/effects/GrPorterDuffXferProcessor.h"
28 
29 #include <cstdint>
30 #include <functional>
31 #include <memory>
32 
33 class GrAppliedClip;
34 class GrAppliedHardClip;
35 class GrGLSLProgramDataManager;
36 class GrProcessorSet;
37 class GrTexture;
38 class GrTextureEffect;
39 enum class SkBlendMode;
40 struct GrGLSLBuiltinUniformHandles;
41 
42 namespace skgpu {
43 class KeyBuilder;
44 }
45 
46 /**
47  * This immutable object contains information needed to build a shader program and set API
48  * state for a draw. It is used along with a GrGeometryProcessor and a source of geometric
49  * data to draw.
50  */
51 class GrPipeline {
52 public:
53     ///////////////////////////////////////////////////////////////////////////
54     /// @name Creation
55 
56     // Pipeline options that the caller may enable.
57     // NOTE: This enum is extended later by GrPipeline::Flags.
58     enum class InputFlags : uint8_t {
59         kNone = 0,
60         /**
61          * Cause every pixel to be rasterized that is touched by the triangle anywhere (not just at
62          * pixel center). Additionally, if using MSAA, the sample mask will always have 100%
63          * coverage.
64          * NOTE: The primitive type must be a triangle type.
65          */
66         kConservativeRaster = (1 << 1),
67         /**
68          * Draws triangles as outlines.
69          */
70         kWireframe = (1 << 2),
71         /**
72          * Modifies the vertex shader so that vertices will be positioned at pixel centers.
73          */
74         kSnapVerticesToPixelCenters = (1 << 3),  // This value must be last. (See kLastInputFlag.)
75     };
76 
77     struct InitArgs {
78         InputFlags fInputFlags = InputFlags::kNone;
79         const GrCaps* fCaps = nullptr;
80         GrDstProxyView fDstProxyView;
81         skgpu::Swizzle fWriteSwizzle;
82     };
83 
84     /**
85      * Creates a simple pipeline with default settings and no processors. The provided blend mode
86      * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must
87      * specify a scissor rectangle through the DynamicState struct.
88      **/
89     GrPipeline(GrScissorTest scissor,
90                SkBlendMode blend,
91                const skgpu::Swizzle& writeSwizzle,
92                InputFlags flags = InputFlags::kNone)
GrPipeline(scissor,GrPorterDuffXPFactory::MakeNoCoverageXP (blend),writeSwizzle,flags)93             : GrPipeline(scissor,
94                          GrPorterDuffXPFactory::MakeNoCoverageXP(blend),
95                          writeSwizzle,
96                          flags) {}
97 
98     GrPipeline(GrScissorTest,
99                sk_sp<const GrXferProcessor>,
100                const skgpu::Swizzle& writeSwizzle,
101                InputFlags = InputFlags::kNone);
102 
103     GrPipeline(const InitArgs& args, sk_sp<const GrXferProcessor>, const GrAppliedHardClip&);
104     GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
105 
106     GrPipeline(const GrPipeline&) = delete;
107     GrPipeline& operator=(const GrPipeline&) = delete;
108 
109     /// @}
110 
111     ///////////////////////////////////////////////////////////////////////////
112     /// @name GrFragmentProcessors
113 
numFragmentProcessors()114     int numFragmentProcessors() const { return fFragmentProcessors.count(); }
numColorFragmentProcessors()115     int numColorFragmentProcessors() const { return fNumColorProcessors; }
isColorFragmentProcessor(int idx)116     bool isColorFragmentProcessor(int idx) const { return idx < fNumColorProcessors; }
isCoverageFragmentProcessor(int idx)117     bool isCoverageFragmentProcessor(int idx) const { return idx >= fNumColorProcessors; }
118 
usesLocalCoords()119     bool usesLocalCoords() const {
120         // The sample coords for the top level FPs are implicitly the GP's local coords.
121         for (const auto& fp : fFragmentProcessors) {
122             if (fp->usesSampleCoords()) {
123                 return true;
124             }
125         }
126         return false;
127     }
128 
129     void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
130 
getXferProcessor()131     const GrXferProcessor& getXferProcessor() const {
132         if (fXferProcessor) {
133             return *fXferProcessor;
134         } else {
135             // A null xp member means the common src-over case. GrXferProcessor's ref'ing
136             // mechanism is not thread safe so we do not hold a ref on this global.
137             return GrPorterDuffXPFactory::SimpleSrcOverXP();
138         }
139     }
140 
141     // Helper functions to quickly know if this GrPipeline will access the dst as a texture or an
142     // input attachment.
usesDstTexture()143     bool usesDstTexture() const { return this->dstProxyView() && !this->usesDstInputAttachment(); }
usesDstInputAttachment()144     bool usesDstInputAttachment() const {
145         return this->dstSampleFlags() & GrDstSampleFlags::kAsInputAttachment;
146     }
147 
148     /**
149      * This returns the GrSurfaceProxyView for the texture used to access the dst color. If the
150      * GrXferProcessor does not use the dst color then the proxy on the GrSurfaceProxyView will be
151      * nullptr.
152      */
dstProxyView()153     const GrSurfaceProxyView& dstProxyView() const { return fDstProxy.proxyView(); }
154 
dstTextureOffset()155     SkIPoint dstTextureOffset() const { return fDstProxy.offset(); }
156 
dstSampleFlags()157     GrDstSampleFlags dstSampleFlags() const { return fDstProxy.dstSampleFlags(); }
158 
159     /** If this GrXferProcessor uses a texture to access the dst color, returns that texture. */
peekDstTexture()160     GrTexture* peekDstTexture() const {
161         if (!this->usesDstTexture()) {
162             return nullptr;
163         }
164 
165         if (GrTextureProxy* dstProxy = this->dstProxyView().asTextureProxy()) {
166             return dstProxy->peekTexture();
167         }
168 
169         return nullptr;
170     }
171 
getFragmentProcessor(int idx)172     const GrFragmentProcessor& getFragmentProcessor(int idx) const {
173         return *fFragmentProcessors[idx];
174     }
175 
176     /// @}
177 
isScissorTestEnabled()178     bool isScissorTestEnabled() const {
179         return SkToBool(fFlags & Flags::kScissorTestEnabled);
180     }
181 
getWindowRectsState()182     const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
183 
usesConservativeRaster()184     bool usesConservativeRaster() const { return fFlags & InputFlags::kConservativeRaster; }
isWireframe()185     bool isWireframe() const { return fFlags & InputFlags::kWireframe; }
snapVerticesToPixelCenters()186     bool snapVerticesToPixelCenters() const {
187         return fFlags & InputFlags::kSnapVerticesToPixelCenters;
188     }
hasStencilClip()189     bool hasStencilClip() const {
190         return SkToBool(fFlags & Flags::kHasStencilClip);
191     }
192 #ifdef SK_DEBUG
allProxiesInstantiated()193     bool allProxiesInstantiated() const {
194         for (int i = 0; i < fFragmentProcessors.count(); ++i) {
195             if (!fFragmentProcessors[i]->isInstantiated()) {
196                 return false;
197             }
198         }
199         if (this->dstProxyView().proxy()) {
200             return this->dstProxyView().proxy()->isInstantiated();
201         }
202 
203         return true;
204     }
205 #endif
206 
207     GrXferBarrierType xferBarrierType(const GrCaps&) const;
208 
209     // Used by Vulkan and Metal to cache their respective pipeline objects
210     void genKey(skgpu::KeyBuilder*, const GrCaps&) const;
211 
writeSwizzle()212     const skgpu::Swizzle& writeSwizzle() const { return fWriteSwizzle; }
213 
214     void visitProxies(const GrVisitProxyFunc&) const;
215 
216     void setDstTextureUniforms(const GrGLSLProgramDataManager& pdm,
217                                GrGLSLBuiltinUniformHandles* fBuiltinUniformHandles) const;
218 
219 private:
220     inline static constexpr uint8_t kLastInputFlag =
221             (uint8_t)InputFlags::kSnapVerticesToPixelCenters;
222 
223     /** This is a continuation of the public "InputFlags" enum. */
224     enum class Flags : uint8_t {
225         kHasStencilClip = (kLastInputFlag << 1),
226         kScissorTestEnabled = (kLastInputFlag << 2),
227     };
228 
229     SK_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
230 
231     friend bool operator&(Flags, InputFlags);
232 
233     // A pipeline can contain up to three processors: color, paint coverage, and clip coverage.
234     using FragmentProcessorArray =
235             skia_private::AutoSTArray<3, std::unique_ptr<const GrFragmentProcessor>>;
236 
237     GrDstProxyView fDstProxy;
238     GrWindowRectsState fWindowRectsState;
239     Flags fFlags;
240     sk_sp<const GrXferProcessor> fXferProcessor;
241     FragmentProcessorArray fFragmentProcessors;
242 
243     // This value is also the index in fFragmentProcessors where coverage processors begin.
244     int fNumColorProcessors = 0;
245 
246     skgpu::Swizzle fWriteSwizzle;
247 };
248 
249 SK_MAKE_BITFIELD_CLASS_OPS(GrPipeline::InputFlags)
SK_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags)250 SK_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags)
251 
252 inline bool operator&(GrPipeline::Flags flags, GrPipeline::InputFlags inputFlag) {
253     return (flags & (GrPipeline::Flags)inputFlag);
254 }
255 
256 #endif
257