1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
|
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrPipelineBuilder_DEFINED
#define GrPipelineBuilder_DEFINED
#include "GrBlend.h"
#include "GrCaps.h"
#include "GrClip.h"
#include "GrGpuResourceRef.h"
#include "GrProcOptInfo.h"
#include "GrRenderTarget.h"
#include "GrStencil.h"
#include "GrXferProcessor.h"
#include "SkMatrix.h"
#include "effects/GrCoverageSetOpXP.h"
#include "effects/GrDisableColorXP.h"
#include "effects/GrPorterDuffXferProcessor.h"
#include "effects/GrSimpleTextureEffect.h"
class GrDrawBatch;
class GrCaps;
class GrPaint;
class GrTexture;
class GrPipelineBuilder : public SkNoncopyable {
public:
GrPipelineBuilder();
/**
* Initializes the GrPipelineBuilder based on a GrPaint, render target, and clip. Note
* that GrPipelineBuilder encompasses more than GrPaint. Aspects of GrPipelineBuilder that have
* no GrPaint equivalents are set to default values with the exception of vertex attribute state
* which is unmodified by this function and clipping which will be enabled.
*/
GrPipelineBuilder(const GrPaint&, GrRenderTarget*, const GrClip&);
virtual ~GrPipelineBuilder();
///////////////////////////////////////////////////////////////////////////
/// @name Fragment Processors
///
/// GrFragmentProcessors are used to compute per-pixel color and per-pixel fractional coverage.
/// There are two chains of FPs, one for color and one for coverage. The first FP in each
/// chain gets the initial color/coverage from the GrPrimitiveProcessor. It computes an output
/// color/coverage which is fed to the next FP in the chain. The last color and coverage FPs
/// feed their output to the GrXferProcessor which controls blending.
////
int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); }
int numCoverageFragmentProcessors() const { return fCoverageFragmentProcessors.count(); }
int numFragmentProcessors() const { return this->numColorFragmentProcessors() +
this->numCoverageFragmentProcessors(); }
const GrFragmentProcessor* getColorFragmentProcessor(int idx) const {
return fColorFragmentProcessors[idx];
}
const GrFragmentProcessor* getCoverageFragmentProcessor(int idx) const {
return fCoverageFragmentProcessors[idx];
}
const GrFragmentProcessor* addColorFragmentProcessor(const GrFragmentProcessor* processor) {
SkASSERT(processor);
fColorFragmentProcessors.push_back(SkRef(processor));
return processor;
}
const GrFragmentProcessor* addCoverageFragmentProcessor(const GrFragmentProcessor* processor) {
SkASSERT(processor);
fCoverageFragmentProcessors.push_back(SkRef(processor));
return processor;
}
/**
* Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
*/
void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
this->addColorFragmentProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
}
void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
}
void addColorTextureProcessor(GrTexture* texture,
const SkMatrix& matrix,
const GrTextureParams& params) {
this->addColorFragmentProcessor(GrSimpleTextureEffect::Create(texture, matrix,
params))->unref();
}
void addCoverageTextureProcessor(GrTexture* texture,
const SkMatrix& matrix,
const GrTextureParams& params) {
this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Create(texture, matrix,
params))->unref();
}
/**
* When this object is destroyed it will remove any color/coverage FPs from the pipeline builder
* that were added after its constructor.
* This class can transiently modify its "const" GrPipelineBuilder object but will restore it
* when done - so it is notionally "const" correct.
*/
class AutoRestoreFragmentProcessorState : public ::SkNoncopyable {
public:
AutoRestoreFragmentProcessorState()
: fPipelineBuilder(nullptr)
, fColorEffectCnt(0)
, fCoverageEffectCnt(0) {}
AutoRestoreFragmentProcessorState(const GrPipelineBuilder& ds)
: fPipelineBuilder(nullptr)
, fColorEffectCnt(0)
, fCoverageEffectCnt(0) {
this->set(&ds);
}
~AutoRestoreFragmentProcessorState() { this->set(nullptr); }
void set(const GrPipelineBuilder* ds);
bool isSet() const { return SkToBool(fPipelineBuilder); }
const GrFragmentProcessor* addCoverageFragmentProcessor(
const GrFragmentProcessor* processor) {
SkASSERT(this->isSet());
return fPipelineBuilder->addCoverageFragmentProcessor(processor);
}
private:
// notionally const (as marginalia)
GrPipelineBuilder* fPipelineBuilder;
int fColorEffectCnt;
int fCoverageEffectCnt;
};
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Blending
////
/**
* Installs a GrXPFactory. This object controls how src color, fractional pixel coverage,
* and the dst color are blended.
*/
const GrXPFactory* setXPFactory(const GrXPFactory* xpFactory) {
fXPFactory.reset(SkSafeRef(xpFactory));
return xpFactory;
}
/**
* Sets a GrXPFactory that will ignore src color and perform a set operation between the draws
* output coverage and the destination. This is useful to render coverage masks as CSG.
*/
void setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCoverage = false) {
fXPFactory.reset(GrCoverageSetOpXPFactory::Create(regionOp, invertCoverage));
}
/**
* Sets a GrXPFactory that disables color writes to the destination. This is useful when
* rendering to the stencil buffer.
*/
void setDisableColorXPFactory() {
fXPFactory.reset(GrDisableColorXPFactory::Create());
}
const GrXPFactory* getXPFactory() const {
return fXPFactory;
}
/**
* Checks whether the xp will need destination in a texture to correctly blend.
*/
bool willXPNeedDstTexture(const GrCaps& caps,
const GrPipelineOptimizations& optimizations) const;
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Render Target
////
/**
* Retrieves the currently set render-target.
*
* @return The currently set render target.
*/
GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
/**
* Sets the render-target used at the next drawing call
*
* @param target The render target to set.
*/
void setRenderTarget(GrRenderTarget* target) { fRenderTarget.reset(SkSafeRef(target)); }
/**
* Returns whether the rasterizer and stencil test (if any) will run at a higher sample rate
* than the color buffer. In is scenario, the higher sample rate is resolved during blending.
*/
bool hasMixedSamples() const {
return fRenderTarget->hasMixedSamples() &&
(this->isHWAntialias() || !fStencilSettings.isDisabled());
}
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Stencil
////
const GrStencilSettings& getStencil() const { return fStencilSettings; }
/**
* Sets the stencil settings to use for the next draw.
* Changing the clip has the side-effect of possibly zeroing
* out the client settable stencil bits. So multipass algorithms
* using stencil should not change the clip between passes.
* @param settings the stencil settings to use.
*/
void setStencil(const GrStencilSettings& settings) { fStencilSettings = settings; }
GrStencilSettings* stencil() { return &fStencilSettings; }
/**
* AutoRestoreStencil
*
* This simple struct saves and restores the stencil settings
* This class can transiently modify its "const" GrPipelineBuilder object but will restore it
* when done - so it is notionally "const" correct.
*/
class AutoRestoreStencil : public ::SkNoncopyable {
public:
AutoRestoreStencil() : fPipelineBuilder(nullptr) {}
AutoRestoreStencil(const GrPipelineBuilder& ds) : fPipelineBuilder(nullptr) { this->set(&ds); }
~AutoRestoreStencil() { this->set(nullptr); }
void set(const GrPipelineBuilder* ds) {
if (fPipelineBuilder) {
fPipelineBuilder->setStencil(fStencilSettings);
}
fPipelineBuilder = const_cast<GrPipelineBuilder*>(ds);
if (ds) {
fStencilSettings = ds->getStencil();
}
}
bool isSet() const { return SkToBool(fPipelineBuilder); }
void setStencil(const GrStencilSettings& settings) {
SkASSERT(this->isSet());
fPipelineBuilder->setStencil(settings);
}
private:
// notionally const (as marginalia)
GrPipelineBuilder* fPipelineBuilder;
GrStencilSettings fStencilSettings;
};
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name State Flags
////
/**
* Flags that affect rendering. Controlled using enable/disableState(). All
* default to disabled.
*/
enum Flags {
/**
* Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
* or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
* the 3D API.
*/
kHWAntialias_Flag = 0x01,
/**
* Modifies the vertex shader so that vertices will be positioned at pixel centers.
*/
kSnapVerticesToPixelCenters_Flag = 0x02,
kLast_Flag = kSnapVerticesToPixelCenters_Flag,
};
bool isHWAntialias() const { return SkToBool(fFlags & kHWAntialias_Flag); }
bool snapVerticesToPixelCenters() const {
return SkToBool(fFlags & kSnapVerticesToPixelCenters_Flag); }
/**
* Enable render state settings.
*
* @param flags bitfield of Flags specifying the states to enable
*/
void enableState(uint32_t flags) { fFlags |= flags; }
/**
* Disable render state settings.
*
* @param flags bitfield of Flags specifying the states to disable
*/
void disableState(uint32_t flags) { fFlags &= ~(flags); }
/**
* Enable or disable flags based on a boolean.
*
* @param flags bitfield of Flags to enable or disable
* @param enable if true enable stateBits, otherwise disable
*/
void setState(uint32_t flags, bool enable) {
if (enable) {
this->enableState(flags);
} else {
this->disableState(flags);
}
}
/// @}
///////////////////////////////////////////////////////////////////////////
/// @name Face Culling
////
enum DrawFace {
kInvalid_DrawFace = -1,
kBoth_DrawFace,
kCCW_DrawFace,
kCW_DrawFace,
};
/**
* Gets whether the target is drawing clockwise, counterclockwise,
* or both faces.
* @return the current draw face(s).
*/
DrawFace getDrawFace() const { return fDrawFace; }
/**
* Controls whether clockwise, counterclockwise, or both faces are drawn.
* @param face the face(s) to draw.
*/
void setDrawFace(DrawFace face) {
SkASSERT(kInvalid_DrawFace != face);
fDrawFace = face;
}
/// @}
///////////////////////////////////////////////////////////////////////////
bool usePLSDstRead(const GrDrawBatch* batch) const;
void setClip(const GrClip& clip) { fClip = clip; }
const GrClip& clip() const { return fClip; }
private:
// Some of the auto restore objects assume that no effects are removed during their lifetime.
// This is used to assert that this condition holds.
SkDEBUGCODE(mutable int fBlockEffectRemovalCnt;)
typedef SkSTArray<4, const GrFragmentProcessor*, true> FragmentProcessorArray;
SkAutoTUnref<GrRenderTarget> fRenderTarget;
uint32_t fFlags;
GrStencilSettings fStencilSettings;
DrawFace fDrawFace;
mutable SkAutoTUnref<const GrXPFactory> fXPFactory;
FragmentProcessorArray fColorFragmentProcessors;
FragmentProcessorArray fCoverageFragmentProcessors;
GrClip fClip;
friend class GrPipeline;
friend class GrDrawTarget;
};
#endif
|