blob: af8529ad35f8eff7dd5cd4f1a6938cd3432b68f4 [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
Brian Salomon652ecb52017-01-17 12:39:53 -050010#include "GrAppliedClip.h"
bsalomoneb1cb5c2015-05-22 08:01:09 -070011#include "GrCaps.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"
Brian Salomon652ecb52017-01-17 12:39:53 -050015#include "GrRenderTargetContext.h"
Robert Phillipsf2361d22016-10-25 14:20:06 -040016#include "GrRenderTargetOpList.h"
cdalton193d9cf2016-05-12 11:52:02 -070017#include "GrRenderTargetPriv.h"
egdaniel95131432014-12-09 11:15:43 -080018#include "GrXferProcessor.h"
egdaniel3658f382014-09-15 07:01:59 -070019
Brian Salomon89527432016-12-16 09:52:16 -050020#include "ops/GrOp.h"
joshualitt74417822015-08-07 11:42:16 -070021
bsalomona387a112015-08-11 14:47:42 -070022GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
Brian Salomon92aee3d2016-12-21 09:20:25 -050023 GrPipelineOptimizations* optimizations) {
csmartdaltonc633abb2016-11-01 08:55:55 -070024 GrRenderTarget* rt = args.fRenderTargetContext->accessRenderTarget();
Robert Phillipse60ad622016-11-17 10:22:48 -050025 if (!rt) {
26 return nullptr;
27 }
Brian Salomon92aee3d2016-12-21 09:20:25 -050028
cdalton93a379b2016-05-11 13:58:08 -070029 GrPipeline* pipeline = new (memory) GrPipeline;
robertphillips55fdccc2016-06-06 06:16:20 -070030 pipeline->fRenderTarget.reset(rt);
cdalton93a379b2016-05-11 13:58:08 -070031 SkASSERT(pipeline->fRenderTarget);
Brian Salomon652ecb52017-01-17 12:39:53 -050032 pipeline->fScissorState = args.fAppliedClip->scissorState();
33 pipeline->fWindowRectsState = args.fAppliedClip->windowRectsState();
Brian Salomon189098e72017-01-19 09:55:19 -050034 pipeline->fUserStencilSettings = args.fUserStencil;
35 pipeline->fDrawFace = static_cast<int16_t>(args.fDrawFace);
cdalton93a379b2016-05-11 13:58:08 -070036
Brian Salomon189098e72017-01-19 09:55:19 -050037 pipeline->fFlags = args.fFlags;
38 if (args.fProcessors->usesDistanceVectorField()) {
dvonbeck9b03e7b2016-08-01 11:01:56 -070039 pipeline->fFlags |= kUsesDistanceVectorField_Flag;
40 }
Brian Salomon652ecb52017-01-17 12:39:53 -050041 if (args.fAppliedClip->hasStencilClip()) {
cdalton193d9cf2016-05-12 11:52:02 -070042 pipeline->fFlags |= kHasStencilClip_Flag;
43 }
Brian Salomon189098e72017-01-19 09:55:19 -050044 if (!args.fUserStencil->isDisabled(args.fAppliedClip->hasStencilClip())) {
csmartdaltonc633abb2016-11-01 08:55:55 -070045 pipeline->fFlags |= kStencilEnabled_Flag;
46 }
Brian Salomonf87e2b92017-01-19 11:31:50 -050047 if (args.fProcessors->disableOutputConversionToSRGB()) {
48 pipeline->fFlags |= kDisableOutputConversionToSRGB_Flag;
49 }
50 if (args.fProcessors->allowSRGBInputs()) {
51 pipeline->fFlags |= kAllowSRGBInputs_Flag;
52 }
cdalton93a379b2016-05-11 13:58:08 -070053
Brian Salomon189098e72017-01-19 09:55:19 -050054 bool isHWAA = kHWAntialias_Flag & args.fFlags;
55
egdaniel95131432014-12-09 11:15:43 -080056 // Create XferProcessor from DS's XPFactory
Brian Osman11052242016-10-27 14:47:55 -040057 bool hasMixedSamples = args.fRenderTargetContext->hasMixedSamples() &&
Brian Salomon189098e72017-01-19 09:55:19 -050058 (isHWAA || pipeline->isStencilEnabled());
59 const GrXPFactory* xpFactory = args.fProcessors->xpFactory();
Hal Canary144caf52016-11-07 17:57:18 -050060 sk_sp<GrXferProcessor> xferProcessor;
egdanielc4b72722015-11-23 13:20:41 -080061 if (xpFactory) {
Brian Salomon92aee3d2016-12-21 09:20:25 -050062 xferProcessor.reset(xpFactory->createXferProcessor(
63 args.fAnalysis, hasMixedSamples, &args.fDstTexture, *args.fCaps));
bsalomon2047b782015-12-21 13:12:54 -080064 if (!xferProcessor) {
cdalton93a379b2016-05-11 13:58:08 -070065 pipeline->~GrPipeline();
bsalomon2047b782015-12-21 13:12:54 -080066 return nullptr;
67 }
egdanielc4b72722015-11-23 13:20:41 -080068 } else {
bsalomon2047b782015-12-21 13:12:54 -080069 // This may return nullptr in the common case of src-over implemented using hw blending.
egdanielc4b72722015-11-23 13:20:41 -080070 xferProcessor.reset(GrPorterDuffXPFactory::CreateSrcOverXferProcessor(
Brian Salomon92aee3d2016-12-21 09:20:25 -050071 *args.fCaps, args.fAnalysis, hasMixedSamples, &args.fDstTexture));
egdanielc4b72722015-11-23 13:20:41 -080072 }
cdalton3ccf2e72016-05-06 09:41:16 -070073 GrColor overrideColor = GrColor_ILLEGAL;
Brian Salomon92aee3d2016-12-21 09:20:25 -050074 if (args.fAnalysis.fColorPOI.firstEffectiveProcessorIndex() != 0) {
75 overrideColor = args.fAnalysis.fColorPOI.inputColorToFirstEffectiveProccesor();
joshualitt9b989322014-12-15 14:16:27 -080076 }
77
bsalomon7765a472015-07-08 11:26:37 -070078 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
egdaniel95131432014-12-09 11:15:43 -080079
halcanary9d524f22016-03-29 09:03:52 -070080 const GrXferProcessor* xpForOpts = xferProcessor ? xferProcessor.get() :
bsalomon2047b782015-12-21 13:12:54 -080081 &GrPorterDuffXPFactory::SimpleSrcOverXP();
Brian Salomon652ecb52017-01-17 12:39:53 -050082 optFlags = xpForOpts->getOptimizations(
Brian Salomon189098e72017-01-19 09:55:19 -050083 args.fAnalysis, args.fUserStencil->doesWrite(args.fAppliedClip->hasStencilClip()),
Brian Salomon652ecb52017-01-17 12:39:53 -050084 &overrideColor, *args.fCaps);
bsalomonc8d3f572015-08-13 06:44:04 -070085
86 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
87 // so we must check the draw type. In cases where we will skip drawing we simply return a
88 // null GrPipeline.
89 if (GrXferProcessor::kSkipDraw_OptFlag & optFlags) {
cdalton93a379b2016-05-11 13:58:08 -070090 pipeline->~GrPipeline();
bsalomonc8d3f572015-08-13 06:44:04 -070091 return nullptr;
egdaniel95131432014-12-09 11:15:43 -080092 }
bsalomonb03c4a32014-11-20 09:56:11 -080093
bsalomon7765a472015-07-08 11:26:37 -070094 // No need to have an override color if it isn't even going to be used.
95 if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) {
96 overrideColor = GrColor_ILLEGAL;
97 }
98
Hal Canary144caf52016-11-07 17:57:18 -050099 pipeline->fXferProcessor.reset(xferProcessor.get());
bsalomonb03c4a32014-11-20 09:56:11 -0800100
Brian Salomon92aee3d2016-12-21 09:20:25 -0500101 int firstColorProcessorIdx = args.fAnalysis.fColorPOI.firstEffectiveProcessorIndex();
egdaniel912b3d22014-11-17 07:45:53 -0800102
bsalomonac856c92015-08-27 06:30:17 -0700103 // TODO: Once we can handle single or four channel input into coverage GrFragmentProcessors
104 // then we can use GrPipelineBuilder's coverageProcInfo (like color above) to set this initial
105 // information.
106 int firstCoverageProcessorIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -0800107
Brian Salomonbfd51832017-01-04 13:22:08 -0500108 if ((optFlags & GrXferProcessor::kIgnoreColor_OptFlag) ||
109 (optFlags & GrXferProcessor::kOverrideColor_OptFlag)) {
Brian Salomon189098e72017-01-19 09:55:19 -0500110 firstColorProcessorIdx = args.fProcessors->numColorFragmentProcessors();
Brian Salomonbfd51832017-01-04 13:22:08 -0500111 }
egdaniel95131432014-12-09 11:15:43 -0800112
joshualitt290c09b2014-12-19 13:45:20 -0800113 bool usesLocalCoords = false;
114
bsalomonac856c92015-08-27 06:30:17 -0700115 // Copy GrFragmentProcessors from GrPipelineBuilder to Pipeline
Brian Salomon189098e72017-01-19 09:55:19 -0500116 pipeline->fNumColorProcessors =
117 args.fProcessors->numColorFragmentProcessors() - firstColorProcessorIdx;
bsalomonac856c92015-08-27 06:30:17 -0700118 int numTotalProcessors = pipeline->fNumColorProcessors +
Brian Salomon189098e72017-01-19 09:55:19 -0500119 args.fProcessors->numCoverageFragmentProcessors() -
120 firstCoverageProcessorIdx;
Brian Salomon652ecb52017-01-17 12:39:53 -0500121 if (args.fAppliedClip->clipCoverageFragmentProcessor()) {
122 ++numTotalProcessors;
123 }
bsalomonac856c92015-08-27 06:30:17 -0700124 pipeline->fFragmentProcessors.reset(numTotalProcessors);
125 int currFPIdx = 0;
Brian Salomon189098e72017-01-19 09:55:19 -0500126 for (int i = firstColorProcessorIdx; i < args.fProcessors->numColorFragmentProcessors();
bsalomonac856c92015-08-27 06:30:17 -0700127 ++i, ++currFPIdx) {
Brian Salomon189098e72017-01-19 09:55:19 -0500128 const GrFragmentProcessor* fp = args.fProcessors->colorFragmentProcessor(i);
bsalomonac856c92015-08-27 06:30:17 -0700129 pipeline->fFragmentProcessors[currFPIdx].reset(fp);
joshualitt2fe79232015-08-05 12:02:27 -0700130 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
bsalomonae59b772014-11-19 08:23:49 -0800131 }
egdaniel95131432014-12-09 11:15:43 -0800132
Brian Salomon189098e72017-01-19 09:55:19 -0500133 for (int i = firstCoverageProcessorIdx; i < args.fProcessors->numCoverageFragmentProcessors();
bsalomonac856c92015-08-27 06:30:17 -0700134 ++i, ++currFPIdx) {
Brian Salomon189098e72017-01-19 09:55:19 -0500135 const GrFragmentProcessor* fp = args.fProcessors->coverageFragmentProcessor(i);
bsalomonac856c92015-08-27 06:30:17 -0700136 pipeline->fFragmentProcessors[currFPIdx].reset(fp);
joshualitt2fe79232015-08-05 12:02:27 -0700137 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
egdaniel9cf45bf2014-10-08 06:49:10 -0700138 }
Brian Salomon652ecb52017-01-17 12:39:53 -0500139 if (const GrFragmentProcessor* fp = args.fAppliedClip->clipCoverageFragmentProcessor()) {
140 pipeline->fFragmentProcessors[currFPIdx].reset(fp);
141 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
142 }
joshualitt79f8fae2014-10-28 17:59:26 -0700143
bsalomon7765a472015-07-08 11:26:37 -0700144 // Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
Brian Salomon92aee3d2016-12-21 09:20:25 -0500145 optimizations->fFlags = 0;
bsalomon7765a472015-07-08 11:26:37 -0700146 if (GrColor_ILLEGAL != overrideColor) {
Brian Salomon92aee3d2016-12-21 09:20:25 -0500147 optimizations->fFlags |= GrPipelineOptimizations::kUseOverrideColor_Flag;
148 optimizations->fOverrideColor = overrideColor;
bsalomon7765a472015-07-08 11:26:37 -0700149 }
bsalomon7765a472015-07-08 11:26:37 -0700150 if (usesLocalCoords) {
Brian Salomon92aee3d2016-12-21 09:20:25 -0500151 optimizations->fFlags |= GrPipelineOptimizations::kReadsLocalCoords_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700152 }
153 if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
Brian Salomon92aee3d2016-12-21 09:20:25 -0500154 optimizations->fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700155 }
bsalomon2d563032015-08-13 07:08:31 -0700156
157 GrXPFactory::InvariantBlendedColor blendedColor;
egdanielc4b72722015-11-23 13:20:41 -0800158 if (xpFactory) {
Brian Salomon92aee3d2016-12-21 09:20:25 -0500159 xpFactory->getInvariantBlendedColor(args.fAnalysis.fColorPOI, &blendedColor);
egdanielc4b72722015-11-23 13:20:41 -0800160 } else {
Brian Salomon92aee3d2016-12-21 09:20:25 -0500161 GrPorterDuffXPFactory::SrcOverInvariantBlendedColor(args.fAnalysis.fColorPOI.color(),
162 args.fAnalysis.fColorPOI.validFlags(),
163 args.fAnalysis.fColorPOI.isOpaque(),
halcanary9d524f22016-03-29 09:03:52 -0700164 &blendedColor);
egdanielc4b72722015-11-23 13:20:41 -0800165 }
bsalomon2d563032015-08-13 07:08:31 -0700166 if (blendedColor.fWillBlendWithDst) {
Brian Salomon92aee3d2016-12-21 09:20:25 -0500167 optimizations->fFlags |= GrPipelineOptimizations::kWillColorBlendWithDst_Flag;
bsalomon2d563032015-08-13 07:08:31 -0700168 }
169
bsalomonc6998732015-08-10 12:01:15 -0700170 return pipeline;
egdanielc0648242014-09-22 13:17:02 -0700171}
172
robertphillips498d7ac2015-10-30 10:11:30 -0700173static void add_dependencies_for_processor(const GrFragmentProcessor* proc, GrRenderTarget* rt) {
bsalomonb58a2b42016-09-26 06:55:02 -0700174 GrFragmentProcessor::TextureAccessIter iter(proc);
Brian Salomon0bbecb22016-11-17 11:38:22 -0500175 while (const GrProcessor::TextureSampler* sampler = iter.next()) {
Robert Phillipsf2361d22016-10-25 14:20:06 -0400176 SkASSERT(rt->getLastOpList());
Brian Salomondb4183d2016-11-17 12:48:40 -0500177 rt->getLastOpList()->addDependency(sampler->texture());
robertphillips498d7ac2015-10-30 10:11:30 -0700178 }
179}
180
181void GrPipeline::addDependenciesTo(GrRenderTarget* rt) const {
182 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
183 add_dependencies_for_processor(fFragmentProcessors[i].get(), rt);
184 }
185
bsalomon2047b782015-12-21 13:12:54 -0800186 const GrXferProcessor& xfer = this->getXferProcessor();
robertphillips498d7ac2015-10-30 10:11:30 -0700187
Brian Salomon0bbecb22016-11-17 11:38:22 -0500188 for (int i = 0; i < xfer.numTextureSamplers(); ++i) {
Brian Salomondb4183d2016-11-17 12:48:40 -0500189 GrTexture* texture = xfer.textureSampler(i).texture();
Robert Phillipsf2361d22016-10-25 14:20:06 -0400190 SkASSERT(rt->getLastOpList());
191 rt->getLastOpList()->addDependency(texture);
robertphillips498d7ac2015-10-30 10:11:30 -0700192 }
193}
194
egdaniel89af44a2014-09-26 06:15:04 -0700195////////////////////////////////////////////////////////////////////////////////
196
bsalomon7312ff82016-09-12 08:55:38 -0700197bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b) {
bsalomoncb02b382015-08-12 11:14:50 -0700198 SkASSERT(&a != &b);
joshualitt8cab9a72015-07-16 09:13:50 -0700199
bsalomoncb02b382015-08-12 11:14:50 -0700200 if (a.getRenderTarget() != b.getRenderTarget() ||
bsalomonac856c92015-08-27 06:30:17 -0700201 a.fFragmentProcessors.count() != b.fFragmentProcessors.count() ||
202 a.fNumColorProcessors != b.fNumColorProcessors ||
bsalomoncb02b382015-08-12 11:14:50 -0700203 a.fScissorState != b.fScissorState ||
csmartdaltonbf4a8f92016-09-06 10:01:06 -0700204 !a.fWindowRectsState.cheapEqualTo(b.fWindowRectsState) ||
bsalomoncb02b382015-08-12 11:14:50 -0700205 a.fFlags != b.fFlags ||
csmartdaltonc633abb2016-11-01 08:55:55 -0700206 a.fUserStencilSettings != b.fUserStencilSettings ||
Brian Salomon8c852be2017-01-04 10:44:42 -0500207 a.fDrawFace != b.fDrawFace) {
egdaniel89af44a2014-09-26 06:15:04 -0700208 return false;
209 }
210
bsalomon2047b782015-12-21 13:12:54 -0800211 // Most of the time both are nullptr
212 if (a.fXferProcessor.get() || b.fXferProcessor.get()) {
213 if (!a.getXferProcessor().isEqual(b.getXferProcessor())) {
214 return false;
215 }
egdanielc2304142014-12-11 13:15:13 -0800216 }
217
bsalomonac856c92015-08-27 06:30:17 -0700218 for (int i = 0; i < a.numFragmentProcessors(); i++) {
bsalomon7312ff82016-09-12 08:55:38 -0700219 if (!a.getFragmentProcessor(i).isEqual(b.getFragmentProcessor(i))) {
egdaniel89af44a2014-09-26 06:15:04 -0700220 return false;
221 }
222 }
egdaniel89af44a2014-09-26 06:15:04 -0700223 return true;
224}