blob: 0781c6fb2798765f85962b725681e2831cf422bb [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"
joshualitt4973d9d2014-11-08 09:24:25 -080011#include "GrGpu.h"
egdaniel8dd688b2015-01-22 10:16:09 -080012#include "GrPipelineBuilder.h"
egdanielb6cbc382014-11-13 11:00:34 -080013#include "GrProcOptInfo.h"
egdaniel95131432014-12-09 11:15:43 -080014#include "GrXferProcessor.h"
egdaniel3658f382014-09-15 07:01:59 -070015
joshualitt74417822015-08-07 11:42:16 -070016#include "batches/GrBatch.h"
17
bsalomonc6998732015-08-10 12:01:15 -070018GrPipeline* GrPipeline::CreateAt(void* memory,
19 const GrPipelineBuilder& builder,
20 const GrProcOptInfo& colorPOI,
21 const GrProcOptInfo& coveragePOI,
22 const GrCaps& caps,
23 const GrScissorState& scissor,
24 const GrXferProcessor::DstTexture* dst,
25 GrPipelineOptimizations* opts) {
26 GrPipeline* pipeline = SkNEW_PLACEMENT(memory, GrPipeline);
27
egdaniel95131432014-12-09 11:15:43 -080028 // Create XferProcessor from DS's XPFactory
29 SkAutoTUnref<GrXferProcessor> xferProcessor(
bsalomonc6998732015-08-10 12:01:15 -070030 builder.getXPFactory()->createXferProcessor(
31 colorPOI, coveragePOI, builder.hasMixedSamples(), dst, caps));
egdaniel95131432014-12-09 11:15:43 -080032
joshualitt9b989322014-12-15 14:16:27 -080033 GrColor overrideColor = GrColor_ILLEGAL;
34 if (colorPOI.firstEffectiveStageIndex() != 0) {
35 overrideColor = colorPOI.inputColorToEffectiveStage();
36 }
37
bsalomon7765a472015-07-08 11:26:37 -070038 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
egdaniel95131432014-12-09 11:15:43 -080039 if (xferProcessor) {
bsalomonc6998732015-08-10 12:01:15 -070040 pipeline->fXferProcessor.reset(xferProcessor.get());
egdaniel95131432014-12-09 11:15:43 -080041
42 optFlags = xferProcessor->getOptimizations(colorPOI,
43 coveragePOI,
bsalomonc6998732015-08-10 12:01:15 -070044 builder.getStencil().doesWrite(),
joshualitt9b989322014-12-15 14:16:27 -080045 &overrideColor,
egdanielc2304142014-12-11 13:15:13 -080046 caps);
egdaniel95131432014-12-09 11:15:43 -080047 }
bsalomonb03c4a32014-11-20 09:56:11 -080048
bsalomon7765a472015-07-08 11:26:37 -070049 // No need to have an override color if it isn't even going to be used.
50 if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) {
51 overrideColor = GrColor_ILLEGAL;
52 }
53
egdaniel8dd688b2015-01-22 10:16:09 -080054 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
bsalomonb03c4a32014-11-20 09:56:11 -080055 // so we must check the draw type. In cases where we will skip drawing we simply return a
egdaniel8dd688b2015-01-22 10:16:09 -080056 // null GrPipeline.
bsalomon3e791242014-12-17 13:43:13 -080057 if (!xferProcessor || (GrXferProcessor::kSkipDraw_OptFlag & optFlags)) {
bsalomonb03c4a32014-11-20 09:56:11 -080058 // Set the fields that don't default init and return. The lack of a render target will
59 // indicate that this can be skipped.
bsalomonc6998732015-08-10 12:01:15 -070060 pipeline->fFlags = 0;
61 pipeline->fDrawFace = GrPipelineBuilder::kInvalid_DrawFace;
62 return pipeline;
bsalomonb03c4a32014-11-20 09:56:11 -080063 }
64
bsalomonc6998732015-08-10 12:01:15 -070065 pipeline->fRenderTarget.reset(builder.fRenderTarget.get());
66 SkASSERT(pipeline->fRenderTarget);
67 pipeline->fScissorState = scissor;
68 pipeline->fStencilSettings = builder.getStencil();
69 pipeline->fDrawFace = builder.getDrawFace();
joshualitt9176e2c2014-11-20 07:28:52 -080070
bsalomonc6998732015-08-10 12:01:15 -070071 pipeline->fFlags = 0;
72 if (builder.isHWAntialias()) {
73 pipeline->fFlags |= kHWAA_Flag;
bsalomon04ddf892014-11-19 12:36:22 -080074 }
bsalomonc6998732015-08-10 12:01:15 -070075 if (builder.isDither()) {
76 pipeline->fFlags |= kDither_Flag;
bsalomon04ddf892014-11-19 12:36:22 -080077 }
bsalomonc6998732015-08-10 12:01:15 -070078 if (builder.snapVerticesToPixelCenters()) {
79 pipeline->fFlags |= kSnapVertices_Flag;
bsalomond79c5492015-04-27 10:07:04 -070080 }
bsalomon04ddf892014-11-19 12:36:22 -080081
egdaniel912b3d22014-11-17 07:45:53 -080082 int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
egdaniel912b3d22014-11-17 07:45:53 -080083
84 // TODO: Once we can handle single or four channel input into coverage stages then we can use
egdaniel8dd688b2015-01-22 10:16:09 -080085 // GrPipelineBuilder's coverageProcInfo (like color above) to set this initial information.
egdaniel912b3d22014-11-17 07:45:53 -080086 int firstCoverageStageIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -080087
bsalomonc6998732015-08-10 12:01:15 -070088 pipeline->adjustProgramFromOptimizations(builder, optFlags, colorPOI, coveragePOI,
89 &firstColorStageIdx, &firstCoverageStageIdx);
egdaniel95131432014-12-09 11:15:43 -080090
joshualitt290c09b2014-12-19 13:45:20 -080091 bool usesLocalCoords = false;
92
egdaniel8dd688b2015-01-22 10:16:09 -080093 // Copy Stages from PipelineBuilder to Pipeline
bsalomonc6998732015-08-10 12:01:15 -070094 for (int i = firstColorStageIdx; i < builder.numColorFragmentStages(); ++i) {
95 const GrFragmentStage& fps = builder.fColorStages[i];
joshualitt2fe79232015-08-05 12:02:27 -070096 const GrFragmentProcessor* fp = fps.processor();
bsalomonc6998732015-08-10 12:01:15 -070097 SkNEW_APPEND_TO_TARRAY(&pipeline->fFragmentStages, GrPendingFragmentStage, (fps));
joshualitt2fe79232015-08-05 12:02:27 -070098 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
bsalomonc6998732015-08-10 12:01:15 -070099 fp->gatherCoordTransforms(&pipeline->fCoordTransforms);
bsalomonae59b772014-11-19 08:23:49 -0800100 }
egdaniel95131432014-12-09 11:15:43 -0800101
bsalomonc6998732015-08-10 12:01:15 -0700102 pipeline->fNumColorStages = pipeline->fFragmentStages.count();
103 for (int i = firstCoverageStageIdx; i < builder.numCoverageFragmentStages(); ++i) {
104 const GrFragmentStage& fps = builder.fCoverageStages[i];
joshualitt2fe79232015-08-05 12:02:27 -0700105 const GrFragmentProcessor* fp = fps.processor();
bsalomonc6998732015-08-10 12:01:15 -0700106 SkNEW_APPEND_TO_TARRAY(&pipeline->fFragmentStages, GrPendingFragmentStage, (fps));
joshualitt2fe79232015-08-05 12:02:27 -0700107 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
bsalomonc6998732015-08-10 12:01:15 -0700108 fp->gatherCoordTransforms(&pipeline->fCoordTransforms);
egdaniel9cf45bf2014-10-08 06:49:10 -0700109 }
joshualitt79f8fae2014-10-28 17:59:26 -0700110
bsalomon7765a472015-07-08 11:26:37 -0700111 // Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
bsalomonc6998732015-08-10 12:01:15 -0700112 opts->fFlags = 0;
bsalomon7765a472015-07-08 11:26:37 -0700113 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
bsalomonc6998732015-08-10 12:01:15 -0700114 opts->fFlags |= GrPipelineOptimizations::kReadsColor_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700115 }
116 if (GrColor_ILLEGAL != overrideColor) {
bsalomonc6998732015-08-10 12:01:15 -0700117 opts->fFlags |= GrPipelineOptimizations::kUseOverrideColor_Flag;
118 opts->fOverrideColor = overrideColor;
bsalomon7765a472015-07-08 11:26:37 -0700119 }
120 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag)) {
bsalomonc6998732015-08-10 12:01:15 -0700121 opts->fFlags |= GrPipelineOptimizations::kReadsCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700122 }
123 if (usesLocalCoords) {
bsalomonc6998732015-08-10 12:01:15 -0700124 opts->fFlags |= GrPipelineOptimizations::kReadsLocalCoords_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700125 }
126 if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
bsalomonc6998732015-08-10 12:01:15 -0700127 opts->fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700128 }
bsalomonc6998732015-08-10 12:01:15 -0700129 return pipeline;
egdanielc0648242014-09-22 13:17:02 -0700130}
131
egdaniel8dd688b2015-01-22 10:16:09 -0800132void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
133 GrXferProcessor::OptFlags flags,
134 const GrProcOptInfo& colorPOI,
135 const GrProcOptInfo& coveragePOI,
136 int* firstColorStageIdx,
137 int* firstCoverageStageIdx) {
egdaniel060a52c2015-04-07 07:31:11 -0700138 fReadsFragPosition = fXferProcessor->willReadFragmentPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700139
joshualitt9b989322014-12-15 14:16:27 -0800140 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
141 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
bsalomon6be6f7c2015-02-26 13:05:21 -0800142 *firstColorStageIdx = pipelineBuilder.numColorFragmentStages();
egdaniel95131432014-12-09 11:15:43 -0800143 } else {
egdaniel060a52c2015-04-07 07:31:11 -0700144 if (coveragePOI.readsFragPosition()) {
145 fReadsFragPosition = true;
146 }
egdaniela7dc0a82014-09-17 08:25:05 -0700147 }
egdaniel95131432014-12-09 11:15:43 -0800148
joshualitt9b989322014-12-15 14:16:27 -0800149 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
bsalomon6be6f7c2015-02-26 13:05:21 -0800150 *firstCoverageStageIdx = pipelineBuilder.numCoverageFragmentStages();
egdaniel95131432014-12-09 11:15:43 -0800151 } else {
egdaniel95131432014-12-09 11:15:43 -0800152 if (coveragePOI.readsFragPosition()) {
bsalomon50785a32015-02-06 07:02:37 -0800153 fReadsFragPosition = true;
egdaniel95131432014-12-09 11:15:43 -0800154 }
egdaniela7dc0a82014-09-17 08:25:05 -0700155 }
156}
157
egdaniel89af44a2014-09-26 06:15:04 -0700158////////////////////////////////////////////////////////////////////////////////
159
joshualitt2fe79232015-08-05 12:02:27 -0700160bool GrPipeline::isEqual(const GrPipeline& that, bool ignoreCoordTransforms) const {
joshualitt8cab9a72015-07-16 09:13:50 -0700161 // If we point to the same pipeline, then we are necessarily equal
162 if (this == &that) {
163 return true;
164 }
165
egdaniel89af44a2014-09-26 06:15:04 -0700166 if (this->getRenderTarget() != that.getRenderTarget() ||
joshualittdafa4d02014-12-04 08:59:10 -0800167 this->fFragmentStages.count() != that.fFragmentStages.count() ||
168 this->fNumColorStages != that.fNumColorStages ||
joshualitt54e0c122014-11-19 09:38:51 -0800169 this->fScissorState != that.fScissorState ||
bsalomon04ddf892014-11-19 12:36:22 -0800170 this->fFlags != that.fFlags ||
egdaniel89af44a2014-09-26 06:15:04 -0700171 this->fStencilSettings != that.fStencilSettings ||
bsalomon50785a32015-02-06 07:02:37 -0800172 this->fDrawFace != that.fDrawFace) {
egdaniel89af44a2014-09-26 06:15:04 -0700173 return false;
174 }
175
egdanielc2304142014-12-11 13:15:13 -0800176 if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) {
177 return false;
178 }
179
egdanield9aa2182014-10-09 13:47:05 -0700180 for (int i = 0; i < this->numFragmentStages(); i++) {
joshualitt2fe79232015-08-05 12:02:27 -0700181 if (!this->getFragmentStage(i).processor()->isEqual(*that.getFragmentStage(i).processor(),
182 ignoreCoordTransforms)) {
egdaniel89af44a2014-09-26 06:15:04 -0700183 return false;
184 }
185 }
egdaniel89af44a2014-09-26 06:15:04 -0700186 return true;
187}
188