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/SkMatrix.h"
12#include "include/core/SkRefCnt.h"
13#include "src/gpu/GrColor.h"
14#include "src/gpu/GrFragmentProcessor.h"
15#include "src/gpu/GrNonAtomicRef.h"
16#include "src/gpu/GrProcessorSet.h"
17#include "src/gpu/GrScissorState.h"
18#include "src/gpu/GrSurfaceProxyView.h"
19#include "src/gpu/GrUserStencilSettings.h"
20#include "src/gpu/GrWindowRectsState.h"
21#include "src/gpu/effects/GrCoverageSetOpXP.h"
22#include "src/gpu/effects/GrDisableColorXP.h"
23#include "src/gpu/effects/GrPorterDuffXferProcessor.h"
24#include "src/gpu/effects/GrTextureEffect.h"
25#include "src/gpu/geometry/GrRect.h"
26
27class GrAppliedClip;
28class GrAppliedHardClip;
29class GrOp;
30class GrRenderTargetContext;
31
32/**
33 * This immutable object contains information needed to set build a shader program and set API
34 * state for a draw. It is used along with a GrPrimitiveProcessor and a source of geometric
35 * data to draw.
36 */
37class GrPipeline {
38public:
39 ///////////////////////////////////////////////////////////////////////////
40 /// @name Creation
41
42 // Pipeline options that the caller may enable.
43 // NOTE: This enum is extended later by GrPipeline::Flags.
44 enum class InputFlags : uint8_t {
45 kNone = 0,
46 /**
47 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
48 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
49 * the 3D API.
50 */
51 kHWAntialias = (1 << 0),
52 /**
53 * Cause every pixel to be rasterized that is touched by the triangle anywhere (not just at
54 * pixel center). Additionally, if using MSAA, the sample mask will always have 100%
55 * coverage.
56 * NOTE: The primitive type must be a triangle type.
57 */
58 kConservativeRaster = (1 << 1),
59 /**
60 * Draws triangles as outlines.
61 */
62 kWireframe = (1 << 2),
63 /**
64 * Modifies the vertex shader so that vertices will be positioned at pixel centers.
65 */
66 kSnapVerticesToPixelCenters = (1 << 3), // This value must be last. (See kLastInputFlag.)
67 };
68
69 struct InitArgs {
70 InputFlags fInputFlags = InputFlags::kNone;
71 const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
72 const GrCaps* fCaps = nullptr;
73 GrXferProcessor::DstProxyView fDstProxyView;
74 GrSwizzle fWriteSwizzle;
75 };
76
77 /**
78 * Creates a simple pipeline with default settings and no processors. The provided blend mode
79 * must be "Porter Duff" (<= kLastCoeffMode). If using GrScissorTest::kEnabled, the caller must
80 * specify a scissor rectangle through the DynamicState struct.
81 **/
82 GrPipeline(GrScissorTest scissor,
83 SkBlendMode blend,
84 const GrSwizzle& writeSwizzle,
85 InputFlags flags = InputFlags::kNone,
86 const GrUserStencilSettings* stencil = &GrUserStencilSettings::kUnused)
87 : GrPipeline(scissor,
88 GrPorterDuffXPFactory::MakeNoCoverageXP(blend),
89 writeSwizzle,
90 flags,
91 stencil) {}
92
93 GrPipeline(GrScissorTest,
94 sk_sp<const GrXferProcessor>,
95 const GrSwizzle& writeSwizzle,
96 InputFlags = InputFlags::kNone,
97 const GrUserStencilSettings* = &GrUserStencilSettings::kUnused);
98
99 GrPipeline(const InitArgs& args, sk_sp<const GrXferProcessor>, const GrAppliedHardClip&);
100 GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
101
102 GrPipeline(const GrPipeline&) = delete;
103 GrPipeline& operator=(const GrPipeline&) = delete;
104
105 /// @}
106
107 ///////////////////////////////////////////////////////////////////////////
108 /// @name GrFragmentProcessors
109
110 int numColorFragmentProcessors() const { return fNumColorProcessors; }
111 int numCoverageFragmentProcessors() const {
112 return fFragmentProcessors.count() - fNumColorProcessors;
113 }
114 int numFragmentProcessors() const { return fFragmentProcessors.count(); }
115
116 const GrXferProcessor& getXferProcessor() const {
117 if (fXferProcessor) {
118 return *fXferProcessor.get();
119 } else {
120 // A null xp member means the common src-over case. GrXferProcessor's ref'ing
121 // mechanism is not thread safe so we do not hold a ref on this global.
122 return GrPorterDuffXPFactory::SimpleSrcOverXP();
123 }
124 }
125
126 /**
127 * This returns the GrSurfaceProxyView for the texture used to access the dst color. If the
128 * GrXferProcessor does not use the dst color then the proxy on the GrSurfaceProxyView will be
129 * nullptr.
130 */
131 const GrSurfaceProxyView& dstProxyView() const {
132 return fDstProxyView;
133 }
134
135 /**
136 * If the GrXferProcessor uses a texture to access the dst color, then this returns that
137 * texture and the offset to the dst contents within that texture.
138 */
139 GrTexture* peekDstTexture(SkIPoint* offset = nullptr) const {
140 if (offset) {
141 *offset = fDstTextureOffset;
142 }
143
144 if (GrTextureProxy* dstProxy = fDstProxyView.asTextureProxy()) {
145 return dstProxy->peekTexture();
146 }
147
148 return nullptr;
149 }
150
151 const GrFragmentProcessor& getColorFragmentProcessor(int idx) const {
152 SkASSERT(idx < this->numColorFragmentProcessors());
153 return *fFragmentProcessors[idx].get();
154 }
155
156 const GrFragmentProcessor& getCoverageFragmentProcessor(int idx) const {
157 SkASSERT(idx < this->numCoverageFragmentProcessors());
158 return *fFragmentProcessors[fNumColorProcessors + idx].get();
159 }
160
161 const GrFragmentProcessor& getFragmentProcessor(int idx) const {
162 return *fFragmentProcessors[idx].get();
163 }
164
165 /// @}
166
167 const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
168 void setUserStencil(const GrUserStencilSettings* stencil) {
169 fUserStencilSettings = stencil;
170 if (!fUserStencilSettings->isDisabled(fFlags & Flags::kHasStencilClip)) {
171 fFlags |= Flags::kStencilEnabled;
172 }
173 }
174
175 bool isScissorTestEnabled() const {
176 return SkToBool(fFlags & Flags::kScissorTestEnabled);
177 }
178
179 const GrWindowRectsState& getWindowRectsState() const { return fWindowRectsState; }
180
181 bool isHWAntialiasState() const { return fFlags & InputFlags::kHWAntialias; }
182 bool usesConservativeRaster() const { return fFlags & InputFlags::kConservativeRaster; }
183 bool isWireframe() const { return fFlags & InputFlags::kWireframe; }
184 bool snapVerticesToPixelCenters() const {
185 return fFlags & InputFlags::kSnapVerticesToPixelCenters;
186 }
187 bool hasStencilClip() const {
188 return SkToBool(fFlags & Flags::kHasStencilClip);
189 }
190 bool isStencilEnabled() const {
191 return SkToBool(fFlags & Flags::kStencilEnabled);
192 }
193#ifdef SK_DEBUG
194 bool allProxiesInstantiated() const {
195 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
196 if (!fFragmentProcessors[i]->isInstantiated()) {
197 return false;
198 }
199 }
200 if (fDstProxyView.proxy()) {
201 return fDstProxyView.proxy()->isInstantiated();
202 }
203
204 return true;
205 }
206#endif
207
208 GrXferBarrierType xferBarrierType(GrTexture*, const GrCaps&) const;
209
210 // Used by Vulkan and Metal to cache their respective pipeline objects
211 void genKey(GrProcessorKeyBuilder*, const GrCaps&) const;
212
213 const GrSwizzle& writeSwizzle() const { return fWriteSwizzle; }
214
215 void visitProxies(const GrOp::VisitProxyFunc&) const;
216
217private:
218 static constexpr uint8_t kLastInputFlag = (uint8_t)InputFlags::kSnapVerticesToPixelCenters;
219
220 /** This is a continuation of the public "InputFlags" enum. */
221 enum class Flags : uint8_t {
222 kHasStencilClip = (kLastInputFlag << 1),
223 kStencilEnabled = (kLastInputFlag << 2),
224 kScissorTestEnabled = (kLastInputFlag << 3),
225 };
226
227 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
228
229 friend bool operator&(Flags, InputFlags);
230
231 using FragmentProcessorArray = SkAutoSTArray<8, std::unique_ptr<const GrFragmentProcessor>>;
232
233 GrSurfaceProxyView fDstProxyView;
234 SkIPoint fDstTextureOffset;
235 GrWindowRectsState fWindowRectsState;
236 const GrUserStencilSettings* fUserStencilSettings;
237 Flags fFlags;
238 sk_sp<const GrXferProcessor> fXferProcessor;
239 FragmentProcessorArray fFragmentProcessors;
240
241 // This value is also the index in fFragmentProcessors where coverage processors begin.
242 int fNumColorProcessors = 0;
243
244 GrSwizzle fWriteSwizzle;
245};
246
247GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::InputFlags);
248GR_MAKE_BITFIELD_CLASS_OPS(GrPipeline::Flags);
249
250inline bool operator&(GrPipeline::Flags flags, GrPipeline::InputFlags inputFlag) {
251 return (flags & (GrPipeline::Flags)inputFlag);
252}
253
254#endif
255