blob: 08ffeb58b5d3ca8f9e5a94f3038497b81862da84 [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"
Brian Osman11052242016-10-27 14:47:55 -040011#include "GrRenderTargetContext.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"
Robert Phillipsf2361d22016-10-25 14:20:06 -040015#include "GrRenderTargetOpList.h"
cdalton193d9cf2016-05-12 11:52:02 -070016#include "GrRenderTargetPriv.h"
egdaniel95131432014-12-09 11:15:43 -080017#include "GrXferProcessor.h"
egdaniel3658f382014-09-15 07:01:59 -070018
joshualitt74417822015-08-07 11:42:16 -070019#include "batches/GrBatch.h"
20
bsalomona387a112015-08-11 14:47:42 -070021GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
ethannicholasff210322015-11-24 12:10:10 -080022 GrXPOverridesForBatch* overrides) {
bsalomona387a112015-08-11 14:47:42 -070023 const GrPipelineBuilder& builder = *args.fPipelineBuilder;
bsalomonc6998732015-08-10 12:01:15 -070024
cdalton93a379b2016-05-11 13:58:08 -070025 GrPipeline* pipeline = new (memory) GrPipeline;
Brian Osman11052242016-10-27 14:47:55 -040026 GrRenderTarget* rt = args.fRenderTargetContext->accessRenderTarget();
robertphillips55fdccc2016-06-06 06:16:20 -070027 pipeline->fRenderTarget.reset(rt);
cdalton93a379b2016-05-11 13:58:08 -070028 SkASSERT(pipeline->fRenderTarget);
29 pipeline->fScissorState = *args.fScissor;
csmartdaltonbf4a8f92016-09-06 10:01:06 -070030 pipeline->fWindowRectsState = *args.fWindowRectsState;
cdalton93a379b2016-05-11 13:58:08 -070031 if (builder.hasUserStencilSettings() || args.fHasStencilClip) {
robertphillips55fdccc2016-06-06 06:16:20 -070032 const GrRenderTargetPriv& rtPriv = rt->renderTargetPriv();
cdalton93a379b2016-05-11 13:58:08 -070033 pipeline->fStencilSettings.reset(*builder.getUserStencil(), args.fHasStencilClip,
cdalton193d9cf2016-05-12 11:52:02 -070034 rtPriv.numStencilBits());
cdalton93a379b2016-05-11 13:58:08 -070035 SkASSERT(!pipeline->fStencilSettings.usesWrapOp() || args.fCaps->stencilWrapOpsSupport());
36 }
37 pipeline->fDrawFace = builder.getDrawFace();
38
39 pipeline->fFlags = 0;
40 if (builder.isHWAntialias()) {
41 pipeline->fFlags |= kHWAA_Flag;
42 }
43 if (builder.snapVerticesToPixelCenters()) {
44 pipeline->fFlags |= kSnapVertices_Flag;
45 }
46 if (builder.getDisableOutputConversionToSRGB()) {
47 pipeline->fFlags |= kDisableOutputConversionToSRGB_Flag;
48 }
49 if (builder.getAllowSRGBInputs()) {
50 pipeline->fFlags |= kAllowSRGBInputs_Flag;
51 }
dvonbeck9b03e7b2016-08-01 11:01:56 -070052 if (builder.getUsesDistanceVectorField()) {
53 pipeline->fFlags |= kUsesDistanceVectorField_Flag;
54 }
cdalton193d9cf2016-05-12 11:52:02 -070055 if (args.fHasStencilClip) {
56 pipeline->fFlags |= kHasStencilClip_Flag;
57 }
cdalton93a379b2016-05-11 13:58:08 -070058
egdaniel95131432014-12-09 11:15:43 -080059 // Create XferProcessor from DS's XPFactory
Brian Osman11052242016-10-27 14:47:55 -040060 bool hasMixedSamples = args.fRenderTargetContext->hasMixedSamples() &&
cdalton93a379b2016-05-11 13:58:08 -070061 (builder.isHWAntialias() || !pipeline->fStencilSettings.isDisabled());
egdanielc4b72722015-11-23 13:20:41 -080062 const GrXPFactory* xpFactory = builder.getXPFactory();
63 SkAutoTUnref<GrXferProcessor> xferProcessor;
64 if (xpFactory) {
ethannicholasde4166a2015-11-30 08:57:38 -080065 xferProcessor.reset(xpFactory->createXferProcessor(args.fOpts,
cdalton3ccf2e72016-05-06 09:41:16 -070066 hasMixedSamples,
egdanielc4b72722015-11-23 13:20:41 -080067 &args.fDstTexture,
68 *args.fCaps));
bsalomon2047b782015-12-21 13:12:54 -080069 if (!xferProcessor) {
cdalton93a379b2016-05-11 13:58:08 -070070 pipeline->~GrPipeline();
bsalomon2047b782015-12-21 13:12:54 -080071 return nullptr;
72 }
egdanielc4b72722015-11-23 13:20:41 -080073 } else {
bsalomon2047b782015-12-21 13:12:54 -080074 // This may return nullptr in the common case of src-over implemented using hw blending.
egdanielc4b72722015-11-23 13:20:41 -080075 xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
76 *args.fCaps,
ethannicholasde4166a2015-11-30 08:57:38 -080077 args.fOpts,
cdalton3ccf2e72016-05-06 09:41:16 -070078 hasMixedSamples,
egdanielc4b72722015-11-23 13:20:41 -080079 &args.fDstTexture));
80 }
cdalton3ccf2e72016-05-06 09:41:16 -070081 GrColor overrideColor = GrColor_ILLEGAL;
ethannicholasff210322015-11-24 12:10:10 -080082 if (args.fOpts.fColorPOI.firstEffectiveProcessorIndex() != 0) {
83 overrideColor = args.fOpts.fColorPOI.inputColorToFirstEffectiveProccesor();
joshualitt9b989322014-12-15 14:16:27 -080084 }
85
bsalomon7765a472015-07-08 11:26:37 -070086 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
egdaniel95131432014-12-09 11:15:43 -080087
halcanary9d524f22016-03-29 09:03:52 -070088 const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() :
bsalomon2047b782015-12-21 13:12:54 -080089 &GrPorterDuffXPFactory::SimpleSrcOverXP();
90 optFlags = xpForOpts->getOptimizations(args.fOpts,
cdalton93a379b2016-05-11 13:58:08 -070091 pipeline->fStencilSettings.doesWrite(),
bsalomon2047b782015-12-21 13:12:54 -080092 &overrideColor,
93 *args.fCaps);
bsalomonc8d3f572015-08-13 06:44:04 -070094
95 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
96 // so we must check the draw type. In cases where we will skip drawing we simply return a
97 // null GrPipeline.
98 if (GrXferProcessor::kSkipDraw_OptFlag & optFlags) {
cdalton93a379b2016-05-11 13:58:08 -070099 pipeline->~GrPipeline();
bsalomonc8d3f572015-08-13 06:44:04 -0700100 return nullptr;
egdaniel95131432014-12-09 11:15:43 -0800101 }
bsalomonb03c4a32014-11-20 09:56:11 -0800102
bsalomon7765a472015-07-08 11:26:37 -0700103 // No need to have an override color if it isn't even going to be used.
104 if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) {
105 overrideColor = GrColor_ILLEGAL;
106 }
107
egdanielc4b72722015-11-23 13:20:41 -0800108 pipeline->fXferProcessor.reset(xferProcessor);
bsalomonb03c4a32014-11-20 09:56:11 -0800109
ethannicholasff210322015-11-24 12:10:10 -0800110 int firstColorProcessorIdx = args.fOpts.fColorPOI.firstEffectiveProcessorIndex();
egdaniel912b3d22014-11-17 07:45:53 -0800111
bsalomonac856c92015-08-27 06:30:17 -0700112 // TODO: Once we can handle single or four channel input into coverage GrFragmentProcessors
113 // then we can use GrPipelineBuilder's coverageProcInfo (like color above) to set this initial
114 // information.
115 int firstCoverageProcessorIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -0800116
halcanary9d524f22016-03-29 09:03:52 -0700117 pipeline->adjustProgramFromOptimizations(builder, optFlags, args.fOpts.fColorPOI,
118 args.fOpts.fCoveragePOI, &firstColorProcessorIdx,
ethannicholasff210322015-11-24 12:10:10 -0800119 &firstCoverageProcessorIdx);
egdaniel95131432014-12-09 11:15:43 -0800120
joshualitt290c09b2014-12-19 13:45:20 -0800121 bool usesLocalCoords = false;
122
bsalomonac856c92015-08-27 06:30:17 -0700123 // Copy GrFragmentProcessors from GrPipelineBuilder to Pipeline
124 pipeline->fNumColorProcessors = builder.numColorFragmentProcessors() - firstColorProcessorIdx;
125 int numTotalProcessors = pipeline->fNumColorProcessors +
126 builder.numCoverageFragmentProcessors() - firstCoverageProcessorIdx;
127 pipeline->fFragmentProcessors.reset(numTotalProcessors);
128 int currFPIdx = 0;
129 for (int i = firstColorProcessorIdx; i < builder.numColorFragmentProcessors();
130 ++i, ++currFPIdx) {
131 const GrFragmentProcessor* fp = builder.getColorFragmentProcessor(i);
132 pipeline->fFragmentProcessors[currFPIdx].reset(fp);
joshualitt2fe79232015-08-05 12:02:27 -0700133 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
bsalomonae59b772014-11-19 08:23:49 -0800134 }
egdaniel95131432014-12-09 11:15:43 -0800135
bsalomonac856c92015-08-27 06:30:17 -0700136 for (int i = firstCoverageProcessorIdx; i < builder.numCoverageFragmentProcessors();
137 ++i, ++currFPIdx) {
138 const GrFragmentProcessor* fp = builder.getCoverageFragmentProcessor(i);
139 pipeline->fFragmentProcessors[currFPIdx].reset(fp);
joshualitt2fe79232015-08-05 12:02:27 -0700140 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
egdaniel9cf45bf2014-10-08 06:49:10 -0700141 }
joshualitt79f8fae2014-10-28 17:59:26 -0700142
bsalomon7765a472015-07-08 11:26:37 -0700143 // Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
ethannicholasff210322015-11-24 12:10:10 -0800144 overrides->fFlags = 0;
bsalomon7765a472015-07-08 11:26:37 -0700145 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
ethannicholasff210322015-11-24 12:10:10 -0800146 overrides->fFlags |= GrXPOverridesForBatch::kReadsColor_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700147 }
148 if (GrColor_ILLEGAL != overrideColor) {
ethannicholasff210322015-11-24 12:10:10 -0800149 overrides->fFlags |= GrXPOverridesForBatch::kUseOverrideColor_Flag;
150 overrides->fOverrideColor = overrideColor;
bsalomon7765a472015-07-08 11:26:37 -0700151 }
152 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag)) {
ethannicholasff210322015-11-24 12:10:10 -0800153 overrides->fFlags |= GrXPOverridesForBatch::kReadsCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700154 }
155 if (usesLocalCoords) {
ethannicholasff210322015-11-24 12:10:10 -0800156 overrides->fFlags |= GrXPOverridesForBatch::kReadsLocalCoords_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700157 }
158 if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
halcanary9d524f22016-03-29 09:03:52 -0700159 overrides->fFlags |= GrXPOverridesForBatch::kCanTweakAlphaForCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700160 }
bsalomon2d563032015-08-13 07:08:31 -0700161
162 GrXPFactory::InvariantBlendedColor blendedColor;
egdanielc4b72722015-11-23 13:20:41 -0800163 if (xpFactory) {
ethannicholasff210322015-11-24 12:10:10 -0800164 xpFactory->getInvariantBlendedColor(args.fOpts.fColorPOI, &blendedColor);
egdanielc4b72722015-11-23 13:20:41 -0800165 } else {
ethannicholasff210322015-11-24 12:10:10 -0800166 GrPorterDuffXPFactory::SrcOverInvariantBlendedColor(args.fOpts.fColorPOI.color(),
167 args.fOpts.fColorPOI.validFlags(),
168 args.fOpts.fColorPOI.isOpaque(),
halcanary9d524f22016-03-29 09:03:52 -0700169 &blendedColor);
egdanielc4b72722015-11-23 13:20:41 -0800170 }
bsalomon2d563032015-08-13 07:08:31 -0700171 if (blendedColor.fWillBlendWithDst) {
ethannicholasff210322015-11-24 12:10:10 -0800172 overrides->fFlags |= GrXPOverridesForBatch::kWillColorBlendWithDst_Flag;
bsalomon2d563032015-08-13 07:08:31 -0700173 }
174
bsalomonc6998732015-08-10 12:01:15 -0700175 return pipeline;
egdanielc0648242014-09-22 13:17:02 -0700176}
177
robertphillips498d7ac2015-10-30 10:11:30 -0700178static void add_dependencies_for_processor(const GrFragmentProcessor* proc, GrRenderTarget* rt) {
bsalomonb58a2b42016-09-26 06:55:02 -0700179 GrFragmentProcessor::TextureAccessIter iter(proc);
180 while (const GrTextureAccess* access = iter.next()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400181 SkASSERT(rt->getLastOpList());
182 rt->getLastOpList()->addDependency(access->getTexture());
robertphillips498d7ac2015-10-30 10:11:30 -0700183 }
184}
185
186void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const {
187 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
188 add_dependencies_for_processor(fFragmentProcessors[i].get(), rt);
189 }
190
bsalomon2047b782015-12-21 13:12:54 -0800191 const GrXferProcessor& xfer = this->getXferProcessor();
robertphillips498d7ac2015-10-30 10:11:30 -0700192
bsalomon2047b782015-12-21 13:12:54 -0800193 for (int i = 0; i < xfer.numTextures(); ++i) {
halcanary9d524f22016-03-29 09:03:52 -0700194 GrTexture* texture = xfer.textureAccess(i).getTexture();
Robert Phillipsf2361d22016-10-25 14:20:06 -0400195 SkASSERT(rt->getLastOpList());
196 rt->getLastOpList()->addDependency(texture);
robertphillips498d7ac2015-10-30 10:11:30 -0700197 }
198}
199
egdaniel8dd688b2015-01-22 10:16:09 -0800200void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
201 GrXferProcessor::OptFlags flags,
202 const GrProcOptInfo& colorPOI,
203 const GrProcOptInfo& coveragePOI,
bsalomonac856c92015-08-27 06:30:17 -0700204 int* firstColorProcessorIdx,
205 int* firstCoverageProcessorIdx) {
egdaniel56cf6dc2015-11-30 10:15:58 -0800206 fIgnoresCoverage = SkToBool(flags & GrXferProcessor::kIgnoreCoverage_OptFlag);
egdaniela7dc0a82014-09-17 08:25:05 -0700207
joshualitt9b989322014-12-15 14:16:27 -0800208 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
209 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
bsalomonac856c92015-08-27 06:30:17 -0700210 *firstColorProcessorIdx = pipelineBuilder.numColorFragmentProcessors();
egdaniela7dc0a82014-09-17 08:25:05 -0700211 }
egdaniel95131432014-12-09 11:15:43 -0800212
joshualitt9b989322014-12-15 14:16:27 -0800213 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
bsalomonac856c92015-08-27 06:30:17 -0700214 *firstCoverageProcessorIdx = pipelineBuilder.numCoverageFragmentProcessors();
egdaniela7dc0a82014-09-17 08:25:05 -0700215 }
216}
217
egdaniel89af44a2014-09-26 06:15:04 -0700218////////////////////////////////////////////////////////////////////////////////
219
bsalomon7312ff82016-09-12 08:55:38 -0700220bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b) {
bsalomoncb02b382015-08-12 11:14:50 -0700221 SkASSERT(&a != &b);
joshualitt8cab9a72015-07-16 09:13:50 -0700222
bsalomoncb02b382015-08-12 11:14:50 -0700223 if (a.getRenderTarget() != b.getRenderTarget() ||
bsalomonac856c92015-08-27 06:30:17 -0700224 a.fFragmentProcessors.count() != b.fFragmentProcessors.count() ||
225 a.fNumColorProcessors != b.fNumColorProcessors ||
bsalomoncb02b382015-08-12 11:14:50 -0700226 a.fScissorState != b.fScissorState ||
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700227 !a.fWindowRectsState.cheapEqualTo(b.fWindowRectsState) ||
bsalomoncb02b382015-08-12 11:14:50 -0700228 a.fFlags != b.fFlags ||
229 a.fStencilSettings != b.fStencilSettings ||
csmartdaltonafd63402016-07-06 09:47:38 -0700230 a.fDrawFace != b.fDrawFace ||
231 a.fIgnoresCoverage != b.fIgnoresCoverage) {
egdaniel89af44a2014-09-26 06:15:04 -0700232 return false;
233 }
234
bsalomon2047b782015-12-21 13:12:54 -0800235 // Most of the time both are nullptr
236 if (a.fXferProcessor.get() || b.fXferProcessor.get()) {
237 if (!a.getXferProcessor().isEqual(b.getXferProcessor())) {
238 return false;
239 }
egdanielc2304142014-12-11 13:15:13 -0800240 }
241
bsalomonac856c92015-08-27 06:30:17 -0700242 for (int i = 0; i < a.numFragmentProcessors(); i++) {
bsalomon7312ff82016-09-12 08:55:38 -0700243 if (!a.getFragmentProcessor(i).isEqual(b.getFragmentProcessor(i))) {
egdaniel89af44a2014-09-26 06:15:04 -0700244 return false;
245 }
246 }
egdaniel89af44a2014-09-26 06:15:04 -0700247 return true;
248}