blob: e1c733a676114dd559795fcaee1eb7b19181221e [file] [log] [blame]
egdaniel3658f382014-09-15 07:01:59 -07001/*
egdaniel8dd688b2015-01-22 10:16:09 -08002 * Copyright 2015 Google Inc.
egdaniel3658f382014-09-15 07:01:59 -07003 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
egdaniel8dd688b2015-01-22 10:16:09 -08008#include "GrPipeline.h"
egdaniel3658f382014-09-15 07:01:59 -07009
bsalomoneb1cb5c2015-05-22 08:01:09 -070010#include "GrCaps.h"
robertphillips498d7ac2015-10-30 10:11:30 -070011#include "GrDrawTarget.h"
joshualitt4973d9d2014-11-08 09:24:25 -080012#include "GrGpu.h"
egdaniel8dd688b2015-01-22 10:16:09 -080013#include "GrPipelineBuilder.h"
egdanielb6cbc382014-11-13 11:00:34 -080014#include "GrProcOptInfo.h"
egdaniel95131432014-12-09 11:15:43 -080015#include "GrXferProcessor.h"
egdaniel3658f382014-09-15 07:01:59 -070016
joshualitt74417822015-08-07 11:42:16 -070017#include "batches/GrBatch.h"
18
bsalomona387a112015-08-11 14:47:42 -070019GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
ethannicholasff210322015-11-24 12:10:10 -080020 GrXPOverridesForBatch* overrides) {
bsalomona387a112015-08-11 14:47:42 -070021 const GrPipelineBuilder& builder = *args.fPipelineBuilder;
bsalomonc6998732015-08-10 12:01:15 -070022
egdaniel95131432014-12-09 11:15:43 -080023 // Create XferProcessor from DS's XPFactory
egdanielc4b72722015-11-23 13:20:41 -080024 const GrXPFactory* xpFactory = builder.getXPFactory();
25 SkAutoTUnref<GrXferProcessor> xferProcessor;
26 if (xpFactory) {
ethannicholasde4166a2015-11-30 08:57:38 -080027 xferProcessor.reset(xpFactory->createXferProcessor(args.fOpts,
egdanielc4b72722015-11-23 13:20:41 -080028 builder.hasMixedSamples(),
29 &args.fDstTexture,
30 *args.fCaps));
bsalomon2047b782015-12-21 13:12:54 -080031 if (!xferProcessor) {
32 return nullptr;
33 }
egdanielc4b72722015-11-23 13:20:41 -080034 } else {
bsalomon2047b782015-12-21 13:12:54 -080035 // This may return nullptr in the common case of src-over implemented using hw blending.
egdanielc4b72722015-11-23 13:20:41 -080036 xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
37 *args.fCaps,
ethannicholasde4166a2015-11-30 08:57:38 -080038 args.fOpts,
egdanielc4b72722015-11-23 13:20:41 -080039 builder.hasMixedSamples(),
40 &args.fDstTexture));
41 }
bsalomon2047b782015-12-21 13:12:54 -080042 GrColor overrideColor = GrColor_ILLEGAL;
ethannicholasff210322015-11-24 12:10:10 -080043 if (args.fOpts.fColorPOI.firstEffectiveProcessorIndex() != 0) {
44 overrideColor = args.fOpts.fColorPOI.inputColorToFirstEffectiveProccesor();
joshualitt9b989322014-12-15 14:16:27 -080045 }
46
bsalomon7765a472015-07-08 11:26:37 -070047 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
egdaniel95131432014-12-09 11:15:43 -080048
bsalomon2047b782015-12-21 13:12:54 -080049 const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() :
50 &GrPorterDuffXPFactory::SimpleSrcOverXP();
51 optFlags = xpForOpts->getOptimizations(args.fOpts,
52 builder.getStencil().doesWrite(),
53 &overrideColor,
54 *args.fCaps);
bsalomonc8d3f572015-08-13 06:44:04 -070055
56 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
57 // so we must check the draw type. In cases where we will skip drawing we simply return a
58 // null GrPipeline.
59 if (GrXferProcessor::kSkipDraw_OptFlag & optFlags) {
60 return nullptr;
egdaniel95131432014-12-09 11:15:43 -080061 }
bsalomonb03c4a32014-11-20 09:56:11 -080062
bsalomon7765a472015-07-08 11:26:37 -070063 // No need to have an override color if it isn't even going to be used.
64 if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) {
65 overrideColor = GrColor_ILLEGAL;
66 }
67
halcanary385fe4d2015-08-26 13:07:48 -070068 GrPipeline* pipeline = new (memory) GrPipeline;
egdanielc4b72722015-11-23 13:20:41 -080069 pipeline->fXferProcessor.reset(xferProcessor);
bsalomonb03c4a32014-11-20 09:56:11 -080070
bsalomonc6998732015-08-10 12:01:15 -070071 pipeline->fRenderTarget.reset(builder.fRenderTarget.get());
72 SkASSERT(pipeline->fRenderTarget);
cdaltond4727922015-11-10 12:49:06 -080073 pipeline->fScissorState = *args.fScissor;
bsalomonc6998732015-08-10 12:01:15 -070074 pipeline->fStencilSettings = builder.getStencil();
75 pipeline->fDrawFace = builder.getDrawFace();
joshualitt9176e2c2014-11-20 07:28:52 -080076
bsalomonc6998732015-08-10 12:01:15 -070077 pipeline->fFlags = 0;
cdaltond4727922015-11-10 12:49:06 -080078 if (builder.isHWAntialias()) {
bsalomonc6998732015-08-10 12:01:15 -070079 pipeline->fFlags |= kHWAA_Flag;
bsalomon04ddf892014-11-19 12:36:22 -080080 }
bsalomonc6998732015-08-10 12:01:15 -070081 if (builder.snapVerticesToPixelCenters()) {
82 pipeline->fFlags |= kSnapVertices_Flag;
bsalomond79c5492015-04-27 10:07:04 -070083 }
bsalomon04ddf892014-11-19 12:36:22 -080084
ethannicholasff210322015-11-24 12:10:10 -080085 int firstColorProcessorIdx = args.fOpts.fColorPOI.firstEffectiveProcessorIndex();
egdaniel912b3d22014-11-17 07:45:53 -080086
bsalomonac856c92015-08-27 06:30:17 -070087 // TODO: Once we can handle single or four channel input into coverage GrFragmentProcessors
88 // then we can use GrPipelineBuilder's coverageProcInfo (like color above) to set this initial
89 // information.
90 int firstCoverageProcessorIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -080091
ethannicholasff210322015-11-24 12:10:10 -080092 pipeline->adjustProgramFromOptimizations(builder, optFlags, args.fOpts.fColorPOI,
93 args.fOpts.fCoveragePOI, &firstColorProcessorIdx,
94 &firstCoverageProcessorIdx);
egdaniel95131432014-12-09 11:15:43 -080095
joshualitt290c09b2014-12-19 13:45:20 -080096 bool usesLocalCoords = false;
97
bsalomonac856c92015-08-27 06:30:17 -070098 // Copy GrFragmentProcessors from GrPipelineBuilder to Pipeline
99 pipeline->fNumColorProcessors = builder.numColorFragmentProcessors() - firstColorProcessorIdx;
100 int numTotalProcessors = pipeline->fNumColorProcessors +
101 builder.numCoverageFragmentProcessors() - firstCoverageProcessorIdx;
102 pipeline->fFragmentProcessors.reset(numTotalProcessors);
103 int currFPIdx = 0;
104 for (int i = firstColorProcessorIdx; i < builder.numColorFragmentProcessors();
105 ++i, ++currFPIdx) {
106 const GrFragmentProcessor* fp = builder.getColorFragmentProcessor(i);
107 pipeline->fFragmentProcessors[currFPIdx].reset(fp);
joshualitt2fe79232015-08-05 12:02:27 -0700108 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
bsalomonae59b772014-11-19 08:23:49 -0800109 }
egdaniel95131432014-12-09 11:15:43 -0800110
bsalomonac856c92015-08-27 06:30:17 -0700111 for (int i = firstCoverageProcessorIdx; i < builder.numCoverageFragmentProcessors();
112 ++i, ++currFPIdx) {
113 const GrFragmentProcessor* fp = builder.getCoverageFragmentProcessor(i);
114 pipeline->fFragmentProcessors[currFPIdx].reset(fp);
joshualitt2fe79232015-08-05 12:02:27 -0700115 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
egdaniel9cf45bf2014-10-08 06:49:10 -0700116 }
joshualitt79f8fae2014-10-28 17:59:26 -0700117
bsalomon7765a472015-07-08 11:26:37 -0700118 // Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
ethannicholasff210322015-11-24 12:10:10 -0800119 overrides->fFlags = 0;
bsalomon7765a472015-07-08 11:26:37 -0700120 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
ethannicholasff210322015-11-24 12:10:10 -0800121 overrides->fFlags |= GrXPOverridesForBatch::kReadsColor_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700122 }
123 if (GrColor_ILLEGAL != overrideColor) {
ethannicholasff210322015-11-24 12:10:10 -0800124 overrides->fFlags |= GrXPOverridesForBatch::kUseOverrideColor_Flag;
125 overrides->fOverrideColor = overrideColor;
bsalomon7765a472015-07-08 11:26:37 -0700126 }
127 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag)) {
ethannicholasff210322015-11-24 12:10:10 -0800128 overrides->fFlags |= GrXPOverridesForBatch::kReadsCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700129 }
130 if (usesLocalCoords) {
ethannicholasff210322015-11-24 12:10:10 -0800131 overrides->fFlags |= GrXPOverridesForBatch::kReadsLocalCoords_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700132 }
133 if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
ethannicholasff210322015-11-24 12:10:10 -0800134 overrides->fFlags |= GrXPOverridesForBatch::kCanTweakAlphaForCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700135 }
bsalomon2d563032015-08-13 07:08:31 -0700136
137 GrXPFactory::InvariantBlendedColor blendedColor;
egdanielc4b72722015-11-23 13:20:41 -0800138 if (xpFactory) {
ethannicholasff210322015-11-24 12:10:10 -0800139 xpFactory->getInvariantBlendedColor(args.fOpts.fColorPOI, &blendedColor);
egdanielc4b72722015-11-23 13:20:41 -0800140 } else {
ethannicholasff210322015-11-24 12:10:10 -0800141 GrPorterDuffXPFactory::SrcOverInvariantBlendedColor(args.fOpts.fColorPOI.color(),
142 args.fOpts.fColorPOI.validFlags(),
143 args.fOpts.fColorPOI.isOpaque(),
egdanielc4b72722015-11-23 13:20:41 -0800144 &blendedColor);
145 }
bsalomon2d563032015-08-13 07:08:31 -0700146 if (blendedColor.fWillBlendWithDst) {
ethannicholasff210322015-11-24 12:10:10 -0800147 overrides->fFlags |= GrXPOverridesForBatch::kWillColorBlendWithDst_Flag;
bsalomon2d563032015-08-13 07:08:31 -0700148 }
149
bsalomonc6998732015-08-10 12:01:15 -0700150 return pipeline;
egdanielc0648242014-09-22 13:17:02 -0700151}
152
robertphillips498d7ac2015-10-30 10:11:30 -0700153static void add_dependencies_for_processor(const GrFragmentProcessor* proc, GrRenderTarget* rt) {
154 for (int i = 0; i < proc->numChildProcessors(); ++i) {
155 // need to recurse
156 add_dependencies_for_processor(&proc->childProcessor(i), rt);
157 }
158
159 for (int i = 0; i < proc->numTextures(); ++i) {
160 GrTexture* texture = proc->textureAccess(i).getTexture();
161 SkASSERT(rt->getLastDrawTarget());
162 rt->getLastDrawTarget()->addDependency(texture);
163 }
164}
165
166void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const {
167 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
168 add_dependencies_for_processor(fFragmentProcessors[i].get(), rt);
169 }
170
bsalomon2047b782015-12-21 13:12:54 -0800171 const GrXferProcessor& xfer = this->getXferProcessor();
robertphillips498d7ac2015-10-30 10:11:30 -0700172
bsalomon2047b782015-12-21 13:12:54 -0800173 for (int i = 0; i < xfer.numTextures(); ++i) {
174 GrTexture* texture = xfer.textureAccess(i).getTexture();
175 SkASSERT(rt->getLastDrawTarget());
176 rt->getLastDrawTarget()->addDependency(texture);
robertphillips498d7ac2015-10-30 10:11:30 -0700177 }
178}
179
egdaniel8dd688b2015-01-22 10:16:09 -0800180void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
181 GrXferProcessor::OptFlags flags,
182 const GrProcOptInfo& colorPOI,
183 const GrProcOptInfo& coveragePOI,
bsalomonac856c92015-08-27 06:30:17 -0700184 int* firstColorProcessorIdx,
185 int* firstCoverageProcessorIdx) {
egdaniel56cf6dc2015-11-30 10:15:58 -0800186 fIgnoresCoverage = SkToBool(flags & GrXferProcessor::kIgnoreCoverage_OptFlag);
bsalomon2047b782015-12-21 13:12:54 -0800187 fReadsFragPosition = this->getXferProcessor().willReadFragmentPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700188
joshualitt9b989322014-12-15 14:16:27 -0800189 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
190 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
bsalomonac856c92015-08-27 06:30:17 -0700191 *firstColorProcessorIdx = pipelineBuilder.numColorFragmentProcessors();
egdaniel95131432014-12-09 11:15:43 -0800192 } else {
egdaniel0d81b292015-11-30 09:37:46 -0800193 if (colorPOI.readsFragPosition()) {
egdaniel060a52c2015-04-07 07:31:11 -0700194 fReadsFragPosition = true;
195 }
egdaniela7dc0a82014-09-17 08:25:05 -0700196 }
egdaniel95131432014-12-09 11:15:43 -0800197
joshualitt9b989322014-12-15 14:16:27 -0800198 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
bsalomonac856c92015-08-27 06:30:17 -0700199 *firstCoverageProcessorIdx = pipelineBuilder.numCoverageFragmentProcessors();
egdaniel95131432014-12-09 11:15:43 -0800200 } else {
egdaniel95131432014-12-09 11:15:43 -0800201 if (coveragePOI.readsFragPosition()) {
bsalomon50785a32015-02-06 07:02:37 -0800202 fReadsFragPosition = true;
egdaniel95131432014-12-09 11:15:43 -0800203 }
egdaniela7dc0a82014-09-17 08:25:05 -0700204 }
205}
206
egdaniel89af44a2014-09-26 06:15:04 -0700207////////////////////////////////////////////////////////////////////////////////
208
bsalomoncb02b382015-08-12 11:14:50 -0700209bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b,
210 bool ignoreCoordTransforms) {
211 SkASSERT(&a != &b);
joshualitt8cab9a72015-07-16 09:13:50 -0700212
bsalomoncb02b382015-08-12 11:14:50 -0700213 if (a.getRenderTarget() != b.getRenderTarget() ||
bsalomonac856c92015-08-27 06:30:17 -0700214 a.fFragmentProcessors.count() != b.fFragmentProcessors.count() ||
215 a.fNumColorProcessors != b.fNumColorProcessors ||
bsalomoncb02b382015-08-12 11:14:50 -0700216 a.fScissorState != b.fScissorState ||
217 a.fFlags != b.fFlags ||
218 a.fStencilSettings != b.fStencilSettings ||
219 a.fDrawFace != b.fDrawFace) {
egdaniel89af44a2014-09-26 06:15:04 -0700220 return false;
221 }
222
bsalomon2047b782015-12-21 13:12:54 -0800223 // Most of the time both are nullptr
224 if (a.fXferProcessor.get() || b.fXferProcessor.get()) {
225 if (!a.getXferProcessor().isEqual(b.getXferProcessor())) {
226 return false;
227 }
egdanielc2304142014-12-11 13:15:13 -0800228 }
229
bsalomonac856c92015-08-27 06:30:17 -0700230 for (int i = 0; i < a.numFragmentProcessors(); i++) {
231 if (!a.getFragmentProcessor(i).isEqual(b.getFragmentProcessor(i), ignoreCoordTransforms)) {
egdaniel89af44a2014-09-26 06:15:04 -0700232 return false;
233 }
234 }
egdaniel89af44a2014-09-26 06:15:04 -0700235 return true;
236}
237