blob: 073349be1ed900062964098d85773e416eedd75b [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,
bsalomonc6998732015-08-10 12:01:15 -070020 GrPipelineOptimizations* opts) {
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
24 SkAutoTUnref<GrXferProcessor> xferProcessor(
bsalomona387a112015-08-11 14:47:42 -070025 builder.getXPFactory()->createXferProcessor(args.fColorPOI, args.fCoveragePOI,
26 builder.hasMixedSamples(), &args.fDstTexture,
27 *args.fCaps));
bsalomonc8d3f572015-08-13 06:44:04 -070028 if (!xferProcessor) {
29 return nullptr;
30 }
egdaniel95131432014-12-09 11:15:43 -080031
joshualitt9b989322014-12-15 14:16:27 -080032 GrColor overrideColor = GrColor_ILLEGAL;
bsalomonac856c92015-08-27 06:30:17 -070033 if (args.fColorPOI.firstEffectiveProcessorIndex() != 0) {
34 overrideColor = args.fColorPOI.inputColorToFirstEffectiveProccesor();
joshualitt9b989322014-12-15 14:16:27 -080035 }
36
bsalomon7765a472015-07-08 11:26:37 -070037 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
egdaniel95131432014-12-09 11:15:43 -080038
bsalomonc8d3f572015-08-13 06:44:04 -070039 optFlags = xferProcessor->getOptimizations(args.fColorPOI,
40 args.fCoveragePOI,
41 builder.getStencil().doesWrite(),
42 &overrideColor,
43 *args.fCaps);
44
45 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
46 // so we must check the draw type. In cases where we will skip drawing we simply return a
47 // null GrPipeline.
48 if (GrXferProcessor::kSkipDraw_OptFlag & optFlags) {
49 return nullptr;
egdaniel95131432014-12-09 11:15:43 -080050 }
bsalomonb03c4a32014-11-20 09:56:11 -080051
bsalomon7765a472015-07-08 11:26:37 -070052 // No need to have an override color if it isn't even going to be used.
53 if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) {
54 overrideColor = GrColor_ILLEGAL;
55 }
56
halcanary385fe4d2015-08-26 13:07:48 -070057 GrPipeline* pipeline = new (memory) GrPipeline;
bsalomonc8d3f572015-08-13 06:44:04 -070058 pipeline->fXferProcessor.reset(xferProcessor.get());
bsalomonb03c4a32014-11-20 09:56:11 -080059
bsalomonc6998732015-08-10 12:01:15 -070060 pipeline->fRenderTarget.reset(builder.fRenderTarget.get());
61 SkASSERT(pipeline->fRenderTarget);
bsalomona387a112015-08-11 14:47:42 -070062 pipeline->fScissorState = *args.fScissor;
bsalomonc6998732015-08-10 12:01:15 -070063 pipeline->fStencilSettings = builder.getStencil();
64 pipeline->fDrawFace = builder.getDrawFace();
joshualitt9176e2c2014-11-20 07:28:52 -080065
bsalomonc6998732015-08-10 12:01:15 -070066 pipeline->fFlags = 0;
67 if (builder.isHWAntialias()) {
68 pipeline->fFlags |= kHWAA_Flag;
bsalomon04ddf892014-11-19 12:36:22 -080069 }
bsalomonc6998732015-08-10 12:01:15 -070070 if (builder.snapVerticesToPixelCenters()) {
71 pipeline->fFlags |= kSnapVertices_Flag;
bsalomond79c5492015-04-27 10:07:04 -070072 }
bsalomon04ddf892014-11-19 12:36:22 -080073
bsalomonac856c92015-08-27 06:30:17 -070074 int firstColorProcessorIdx = args.fColorPOI.firstEffectiveProcessorIndex();
egdaniel912b3d22014-11-17 07:45:53 -080075
bsalomonac856c92015-08-27 06:30:17 -070076 // TODO: Once we can handle single or four channel input into coverage GrFragmentProcessors
77 // then we can use GrPipelineBuilder's coverageProcInfo (like color above) to set this initial
78 // information.
79 int firstCoverageProcessorIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -080080
bsalomona387a112015-08-11 14:47:42 -070081 pipeline->adjustProgramFromOptimizations(builder, optFlags, args.fColorPOI, args.fCoveragePOI,
bsalomonac856c92015-08-27 06:30:17 -070082 &firstColorProcessorIdx, &firstCoverageProcessorIdx);
egdaniel95131432014-12-09 11:15:43 -080083
joshualitt290c09b2014-12-19 13:45:20 -080084 bool usesLocalCoords = false;
85
bsalomonac856c92015-08-27 06:30:17 -070086 // Copy GrFragmentProcessors from GrPipelineBuilder to Pipeline
87 pipeline->fNumColorProcessors = builder.numColorFragmentProcessors() - firstColorProcessorIdx;
88 int numTotalProcessors = pipeline->fNumColorProcessors +
89 builder.numCoverageFragmentProcessors() - firstCoverageProcessorIdx;
90 pipeline->fFragmentProcessors.reset(numTotalProcessors);
91 int currFPIdx = 0;
92 for (int i = firstColorProcessorIdx; i < builder.numColorFragmentProcessors();
93 ++i, ++currFPIdx) {
94 const GrFragmentProcessor* fp = builder.getColorFragmentProcessor(i);
95 pipeline->fFragmentProcessors[currFPIdx].reset(fp);
joshualitt2fe79232015-08-05 12:02:27 -070096 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
bsalomonae59b772014-11-19 08:23:49 -080097 }
egdaniel95131432014-12-09 11:15:43 -080098
bsalomonac856c92015-08-27 06:30:17 -070099 for (int i = firstCoverageProcessorIdx; i < builder.numCoverageFragmentProcessors();
100 ++i, ++currFPIdx) {
101 const GrFragmentProcessor* fp = builder.getCoverageFragmentProcessor(i);
102 pipeline->fFragmentProcessors[currFPIdx].reset(fp);
joshualitt2fe79232015-08-05 12:02:27 -0700103 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
egdaniel9cf45bf2014-10-08 06:49:10 -0700104 }
joshualitt79f8fae2014-10-28 17:59:26 -0700105
bsalomon7765a472015-07-08 11:26:37 -0700106 // Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
bsalomonc6998732015-08-10 12:01:15 -0700107 opts->fFlags = 0;
bsalomon7765a472015-07-08 11:26:37 -0700108 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
bsalomonc6998732015-08-10 12:01:15 -0700109 opts->fFlags |= GrPipelineOptimizations::kReadsColor_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700110 }
111 if (GrColor_ILLEGAL != overrideColor) {
bsalomonc6998732015-08-10 12:01:15 -0700112 opts->fFlags |= GrPipelineOptimizations::kUseOverrideColor_Flag;
113 opts->fOverrideColor = overrideColor;
bsalomon7765a472015-07-08 11:26:37 -0700114 }
115 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag)) {
bsalomonc6998732015-08-10 12:01:15 -0700116 opts->fFlags |= GrPipelineOptimizations::kReadsCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700117 }
118 if (usesLocalCoords) {
bsalomonc6998732015-08-10 12:01:15 -0700119 opts->fFlags |= GrPipelineOptimizations::kReadsLocalCoords_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700120 }
121 if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
bsalomonc6998732015-08-10 12:01:15 -0700122 opts->fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700123 }
bsalomon2d563032015-08-13 07:08:31 -0700124
125 GrXPFactory::InvariantBlendedColor blendedColor;
126 builder.fXPFactory->getInvariantBlendedColor(args.fColorPOI, &blendedColor);
127 if (blendedColor.fWillBlendWithDst) {
128 opts->fFlags |= GrPipelineOptimizations::kWillColorBlendWithDst_Flag;
129 }
130
bsalomonc6998732015-08-10 12:01:15 -0700131 return pipeline;
egdanielc0648242014-09-22 13:17:02 -0700132}
133
robertphillips498d7ac2015-10-30 10:11:30 -0700134static void add_dependencies_for_processor(const GrFragmentProcessor* proc, GrRenderTarget* rt) {
135 for (int i = 0; i < proc->numChildProcessors(); ++i) {
136 // need to recurse
137 add_dependencies_for_processor(&proc->childProcessor(i), rt);
138 }
139
140 for (int i = 0; i < proc->numTextures(); ++i) {
141 GrTexture* texture = proc->textureAccess(i).getTexture();
142 SkASSERT(rt->getLastDrawTarget());
143 rt->getLastDrawTarget()->addDependency(texture);
144 }
145}
146
147void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const {
148 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
149 add_dependencies_for_processor(fFragmentProcessors[i].get(), rt);
150 }
151
152 if (fXferProcessor.get()) {
153 const GrXferProcessor* xfer = fXferProcessor.get();
154
155 for (int i = 0; i < xfer->numTextures(); ++i) {
156 GrTexture* texture = xfer->textureAccess(i).getTexture();
157 SkASSERT(rt->getLastDrawTarget());
158 rt->getLastDrawTarget()->addDependency(texture);
159 }
160 }
161}
162
egdaniel8dd688b2015-01-22 10:16:09 -0800163void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
164 GrXferProcessor::OptFlags flags,
165 const GrProcOptInfo& colorPOI,
166 const GrProcOptInfo& coveragePOI,
bsalomonac856c92015-08-27 06:30:17 -0700167 int* firstColorProcessorIdx,
168 int* firstCoverageProcessorIdx) {
egdaniel060a52c2015-04-07 07:31:11 -0700169 fReadsFragPosition = fXferProcessor->willReadFragmentPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700170
joshualitt9b989322014-12-15 14:16:27 -0800171 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
172 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
bsalomonac856c92015-08-27 06:30:17 -0700173 *firstColorProcessorIdx = pipelineBuilder.numColorFragmentProcessors();
egdaniel95131432014-12-09 11:15:43 -0800174 } else {
egdaniel060a52c2015-04-07 07:31:11 -0700175 if (coveragePOI.readsFragPosition()) {
176 fReadsFragPosition = true;
177 }
egdaniela7dc0a82014-09-17 08:25:05 -0700178 }
egdaniel95131432014-12-09 11:15:43 -0800179
joshualitt9b989322014-12-15 14:16:27 -0800180 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
bsalomonac856c92015-08-27 06:30:17 -0700181 *firstCoverageProcessorIdx = pipelineBuilder.numCoverageFragmentProcessors();
egdaniel95131432014-12-09 11:15:43 -0800182 } else {
egdaniel95131432014-12-09 11:15:43 -0800183 if (coveragePOI.readsFragPosition()) {
bsalomon50785a32015-02-06 07:02:37 -0800184 fReadsFragPosition = true;
egdaniel95131432014-12-09 11:15:43 -0800185 }
egdaniela7dc0a82014-09-17 08:25:05 -0700186 }
187}
188
egdaniel89af44a2014-09-26 06:15:04 -0700189////////////////////////////////////////////////////////////////////////////////
190
bsalomoncb02b382015-08-12 11:14:50 -0700191bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b,
192 bool ignoreCoordTransforms) {
193 SkASSERT(&a != &b);
joshualitt8cab9a72015-07-16 09:13:50 -0700194
bsalomoncb02b382015-08-12 11:14:50 -0700195 if (a.getRenderTarget() != b.getRenderTarget() ||
bsalomonac856c92015-08-27 06:30:17 -0700196 a.fFragmentProcessors.count() != b.fFragmentProcessors.count() ||
197 a.fNumColorProcessors != b.fNumColorProcessors ||
bsalomoncb02b382015-08-12 11:14:50 -0700198 a.fScissorState != b.fScissorState ||
199 a.fFlags != b.fFlags ||
200 a.fStencilSettings != b.fStencilSettings ||
201 a.fDrawFace != b.fDrawFace) {
egdaniel89af44a2014-09-26 06:15:04 -0700202 return false;
203 }
204
bsalomoncb02b382015-08-12 11:14:50 -0700205 if (!a.getXferProcessor()->isEqual(*b.getXferProcessor())) {
egdanielc2304142014-12-11 13:15:13 -0800206 return false;
207 }
208
bsalomonac856c92015-08-27 06:30:17 -0700209 for (int i = 0; i < a.numFragmentProcessors(); i++) {
210 if (!a.getFragmentProcessor(i).isEqual(b.getFragmentProcessor(i), ignoreCoordTransforms)) {
egdaniel89af44a2014-09-26 06:15:04 -0700211 return false;
212 }
213 }
egdaniel89af44a2014-09-26 06:15:04 -0700214 return true;
215}
216