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 #include "GrPipeline.h"
9
10 #include "GrAppliedClip.h"
11 #include "GrCaps.h"
12 #include "GrGpu.h"
13 #include "GrPipelineBuilder.h"
14 #include "GrRenderTargetContext.h"
15 #include "GrRenderTargetOpList.h"
16 #include "GrRenderTargetPriv.h"
17 #include "GrXferProcessor.h"
18
19 #include "ops/GrOp.h"
20
init(const InitArgs & args)21 GrPipelineOptimizations GrPipeline::init(const InitArgs& args) {
22 SkASSERT(args.fAnalysis);
23 SkASSERT(args.fRenderTarget);
24
25 fRenderTarget.reset(args.fRenderTarget);
26
27 fFlags = args.fFlags;
28 if (args.fAppliedClip) {
29 fScissorState = args.fAppliedClip->scissorState();
30 if (args.fAppliedClip->hasStencilClip()) {
31 fFlags |= kHasStencilClip_Flag;
32 }
33 fWindowRectsState = args.fAppliedClip->windowRectsState();
34 }
35 if (args.fProcessors->usesDistanceVectorField()) {
36 fFlags |= kUsesDistanceVectorField_Flag;
37 }
38 if (args.fProcessors->disableOutputConversionToSRGB()) {
39 fFlags |= kDisableOutputConversionToSRGB_Flag;
40 }
41 if (args.fProcessors->allowSRGBInputs()) {
42 fFlags |= kAllowSRGBInputs_Flag;
43 }
44 if (!args.fUserStencil->isDisabled(fFlags & kHasStencilClip_Flag)) {
45 fFlags |= kStencilEnabled_Flag;
46 }
47
48 fUserStencilSettings = args.fUserStencil;
49
50 fDrawFace = static_cast<int16_t>(args.fDrawFace);
51
52 bool isHWAA = kHWAntialias_Flag & args.fFlags;
53
54 // Create XferProcessor from DS's XPFactory
55 bool hasMixedSamples = args.fRenderTarget->isMixedSampled() && (isHWAA || isStencilEnabled());
56 const GrXPFactory* xpFactory = args.fProcessors->xpFactory();
57 sk_sp<GrXferProcessor> xferProcessor;
58 if (xpFactory) {
59 xferProcessor.reset(xpFactory->createXferProcessor(*args.fAnalysis, hasMixedSamples,
60 &args.fDstTexture, *args.fCaps));
61 SkASSERT(xferProcessor);
62 } else {
63 // This may return nullptr in the common case of src-over implemented using hw blending.
64 xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
65 *args.fCaps, *args.fAnalysis, hasMixedSamples, &args.fDstTexture));
66 }
67 GrColor overrideColor = GrColor_ILLEGAL;
68 int colorFPsToEliminate =
69 args.fAnalysis->getInputColorOverrideAndColorProcessorEliminationCount(&overrideColor);
70 colorFPsToEliminate = SkTMax(colorFPsToEliminate, 0);
71
72 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
73
74 const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() :
75 &GrPorterDuffXPFactory::SimpleSrcOverXP();
76 optFlags = xpForOpts->getOptimizations(*args.fAnalysis);
77
78 // No need to have an override color if it isn't even going to be used.
79 if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) {
80 overrideColor = GrColor_ILLEGAL;
81 }
82
83 fXferProcessor.reset(xferProcessor.get());
84
85 if ((optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
86 colorFPsToEliminate = args.fProcessors->numColorFragmentProcessors();
87 }
88
89 // Copy GrFragmentProcessors from GrPipelineBuilder to Pipeline, possibly removing some of the
90 // color fragment processors.
91 fNumColorProcessors = args.fProcessors->numColorFragmentProcessors() - colorFPsToEliminate;
92 int numTotalProcessors =
93 fNumColorProcessors + args.fProcessors->numCoverageFragmentProcessors();
94 if (args.fAppliedClip && args.fAppliedClip->clipCoverageFragmentProcessor()) {
95 ++numTotalProcessors;
96 }
97 fFragmentProcessors.reset(numTotalProcessors);
98 int currFPIdx = 0;
99 for (int i = colorFPsToEliminate; i < args.fProcessors->numColorFragmentProcessors();
100 ++i, ++currFPIdx) {
101 const GrFragmentProcessor* fp = args.fProcessors->colorFragmentProcessor(i);
102 fFragmentProcessors[currFPIdx].reset(fp);
103 }
104
105 for (int i = 0; i < args.fProcessors->numCoverageFragmentProcessors(); ++i, ++currFPIdx) {
106 const GrFragmentProcessor* fp = args.fProcessors->coverageFragmentProcessor(i);
107 fFragmentProcessors[currFPIdx].reset(fp);
108 }
109 if (args.fAppliedClip) {
110 if (const GrFragmentProcessor* fp = args.fAppliedClip->clipCoverageFragmentProcessor()) {
111 fFragmentProcessors[currFPIdx].reset(fp);
112 }
113 }
114
115 // Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
116 GrPipelineOptimizations optimizations;
117 optimizations.fFlags = 0;
118 if (GrColor_ILLEGAL != overrideColor) {
119 optimizations.fFlags |= GrPipelineOptimizations::kUseOverrideColor_Flag;
120 optimizations.fOverrideColor = overrideColor;
121 }
122 if (args.fAnalysis->usesLocalCoords()) {
123 optimizations.fFlags |= GrPipelineOptimizations::kReadsLocalCoords_Flag;
124 }
125 if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
126 optimizations.fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag;
127 }
128 return optimizations;
129 }
130
add_dependencies_for_processor(const GrFragmentProcessor * proc,GrRenderTarget * rt)131 static void add_dependencies_for_processor(const GrFragmentProcessor* proc, GrRenderTarget* rt) {
132 GrFragmentProcessor::TextureAccessIter iter(proc);
133 while (const GrProcessor::TextureSampler* sampler = iter.next()) {
134 SkASSERT(rt->getLastOpList());
135 rt->getLastOpList()->addDependency(sampler->texture());
136 }
137 }
138
addDependenciesTo(GrRenderTarget * rt) const139 void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const {
140 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
141 add_dependencies_for_processor(fFragmentProcessors[i].get(), rt);
142 }
143
144 const GrXferProcessor& xfer = this->getXferProcessor();
145
146 for (int i = 0; i < xfer.numTextureSamplers(); ++i) {
147 GrTexture* texture = xfer.textureSampler(i).texture();
148 SkASSERT(rt->getLastOpList());
149 rt->getLastOpList()->addDependency(texture);
150 }
151 }
152
GrPipeline(GrRenderTarget * rt,SkBlendMode blendmode)153 GrPipeline::GrPipeline(GrRenderTarget* rt, SkBlendMode blendmode)
154 : fRenderTarget(rt)
155 , fScissorState()
156 , fWindowRectsState()
157 , fUserStencilSettings(&GrUserStencilSettings::kUnused)
158 , fDrawFace(static_cast<uint16_t>(GrDrawFace::kBoth))
159 , fFlags()
160 , fXferProcessor(GrPorterDuffXPFactory::CreateNoCoverageXP(blendmode).get())
161 , fFragmentProcessors()
162 , fNumColorProcessors(0) {
163 }
164
165 ////////////////////////////////////////////////////////////////////////////////
166
AreEqual(const GrPipeline & a,const GrPipeline & b)167 bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b) {
168 SkASSERT(&a != &b);
169
170 if (a.getRenderTarget() != b.getRenderTarget() ||
171 a.fFragmentProcessors.count() != b.fFragmentProcessors.count() ||
172 a.fNumColorProcessors != b.fNumColorProcessors ||
173 a.fScissorState != b.fScissorState ||
174 a.fWindowRectsState != b.fWindowRectsState ||
175 a.fFlags != b.fFlags ||
176 a.fUserStencilSettings != b.fUserStencilSettings ||
177 a.fDrawFace != b.fDrawFace) {
178 return false;
179 }
180
181 // Most of the time both are nullptr
182 if (a.fXferProcessor.get() || b.fXferProcessor.get()) {
183 if (!a.getXferProcessor().isEqual(b.getXferProcessor())) {
184 return false;
185 }
186 }
187
188 for (int i = 0; i < a.numFragmentProcessors(); i++) {
189 if (!a.getFragmentProcessor(i).isEqual(b.getFragmentProcessor(i))) {
190 return false;
191 }
192 }
193 return true;
194 }
195