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