blob: 80971daf1d0c7f6184f5d96aa330beede7c7d17d [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
egdaniel8dd688b2015-01-22 10:16:09 -080018GrPipeline::GrPipeline(const GrPipelineBuilder& pipelineBuilder,
egdaniele36914c2015-02-13 09:00:33 -080019 const GrProcOptInfo& colorPOI,
20 const GrProcOptInfo& coveragePOI,
bsalomon4b91f762015-05-19 09:29:46 -070021 const GrCaps& caps,
joshualitt4d8da812015-01-28 12:53:54 -080022 const GrScissorState& scissorState,
bsalomon6a44c6a2015-05-26 09:49:05 -070023 const GrXferProcessor::DstTexture* dstTexture) {
egdaniel95131432014-12-09 11:15:43 -080024 // Create XferProcessor from DS's XPFactory
25 SkAutoTUnref<GrXferProcessor> xferProcessor(
bsalomon6a44c6a2015-05-26 09:49:05 -070026 pipelineBuilder.getXPFactory()->createXferProcessor(
cdalton86ae0a92015-06-08 15:11:04 -070027 colorPOI, coveragePOI, pipelineBuilder.hasMixedSamples(), dstTexture, caps));
egdaniel95131432014-12-09 11:15:43 -080028
joshualitt9b989322014-12-15 14:16:27 -080029 GrColor overrideColor = GrColor_ILLEGAL;
30 if (colorPOI.firstEffectiveStageIndex() != 0) {
31 overrideColor = colorPOI.inputColorToEffectiveStage();
32 }
33
bsalomon7765a472015-07-08 11:26:37 -070034 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
egdaniel95131432014-12-09 11:15:43 -080035 if (xferProcessor) {
36 fXferProcessor.reset(xferProcessor.get());
37
38 optFlags = xferProcessor->getOptimizations(colorPOI,
39 coveragePOI,
egdaniel8dd688b2015-01-22 10:16:09 -080040 pipelineBuilder.getStencil().doesWrite(),
joshualitt9b989322014-12-15 14:16:27 -080041 &overrideColor,
egdanielc2304142014-12-11 13:15:13 -080042 caps);
egdaniel95131432014-12-09 11:15:43 -080043 }
bsalomonb03c4a32014-11-20 09:56:11 -080044
bsalomon7765a472015-07-08 11:26:37 -070045 // No need to have an override color if it isn't even going to be used.
46 if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) {
47 overrideColor = GrColor_ILLEGAL;
48 }
49
egdaniel8dd688b2015-01-22 10:16:09 -080050 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
bsalomonb03c4a32014-11-20 09:56:11 -080051 // so we must check the draw type. In cases where we will skip drawing we simply return a
egdaniel8dd688b2015-01-22 10:16:09 -080052 // null GrPipeline.
bsalomon3e791242014-12-17 13:43:13 -080053 if (!xferProcessor || (GrXferProcessor::kSkipDraw_OptFlag & optFlags)) {
bsalomonb03c4a32014-11-20 09:56:11 -080054 // Set the fields that don't default init and return. The lack of a render target will
55 // indicate that this can be skipped.
56 fFlags = 0;
egdaniel8dd688b2015-01-22 10:16:09 -080057 fDrawFace = GrPipelineBuilder::kInvalid_DrawFace;
bsalomonb03c4a32014-11-20 09:56:11 -080058 return;
59 }
60
egdaniel8dd688b2015-01-22 10:16:09 -080061 fRenderTarget.reset(pipelineBuilder.fRenderTarget.get());
bsalomonb03c4a32014-11-20 09:56:11 -080062 SkASSERT(fRenderTarget);
joshualitt54e0c122014-11-19 09:38:51 -080063 fScissorState = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -080064 fStencilSettings = pipelineBuilder.getStencil();
65 fDrawFace = pipelineBuilder.getDrawFace();
joshualitt9176e2c2014-11-20 07:28:52 -080066
bsalomon04ddf892014-11-19 12:36:22 -080067 fFlags = 0;
egdaniel8dd688b2015-01-22 10:16:09 -080068 if (pipelineBuilder.isHWAntialias()) {
bsalomon04ddf892014-11-19 12:36:22 -080069 fFlags |= kHWAA_Flag;
70 }
egdaniel8dd688b2015-01-22 10:16:09 -080071 if (pipelineBuilder.isDither()) {
bsalomon04ddf892014-11-19 12:36:22 -080072 fFlags |= kDither_Flag;
73 }
bsalomond79c5492015-04-27 10:07:04 -070074 if (pipelineBuilder.snapVerticesToPixelCenters()) {
75 fFlags |= kSnapVertices_Flag;
76 }
bsalomon04ddf892014-11-19 12:36:22 -080077
egdaniel912b3d22014-11-17 07:45:53 -080078 int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
egdaniel912b3d22014-11-17 07:45:53 -080079
80 // TODO: Once we can handle single or four channel input into coverage stages then we can use
egdaniel8dd688b2015-01-22 10:16:09 -080081 // GrPipelineBuilder's coverageProcInfo (like color above) to set this initial information.
egdaniel912b3d22014-11-17 07:45:53 -080082 int firstCoverageStageIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -080083
egdaniel8dd688b2015-01-22 10:16:09 -080084 this->adjustProgramFromOptimizations(pipelineBuilder, optFlags, colorPOI, coveragePOI,
egdaniel95131432014-12-09 11:15:43 -080085 &firstColorStageIdx, &firstCoverageStageIdx);
86
joshualitt290c09b2014-12-19 13:45:20 -080087 bool usesLocalCoords = false;
88
egdaniel8dd688b2015-01-22 10:16:09 -080089 // Copy Stages from PipelineBuilder to Pipeline
bsalomon6be6f7c2015-02-26 13:05:21 -080090 for (int i = firstColorStageIdx; i < pipelineBuilder.numColorFragmentStages(); ++i) {
joshualitt2fe79232015-08-05 12:02:27 -070091 const GrFragmentStage& fps = pipelineBuilder.fColorStages[i];
92 const GrFragmentProcessor* fp = fps.processor();
93 SkNEW_APPEND_TO_TARRAY(&fFragmentStages, GrPendingFragmentStage, (fps));
94 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
95 fp->gatherCoordTransforms(&fCoordTransforms);
bsalomonae59b772014-11-19 08:23:49 -080096 }
egdaniel95131432014-12-09 11:15:43 -080097
egdanield9aa2182014-10-09 13:47:05 -070098 fNumColorStages = fFragmentStages.count();
bsalomon6be6f7c2015-02-26 13:05:21 -080099 for (int i = firstCoverageStageIdx; i < pipelineBuilder.numCoverageFragmentStages(); ++i) {
joshualitt2fe79232015-08-05 12:02:27 -0700100 const GrFragmentStage& fps = pipelineBuilder.fCoverageStages[i];
101 const GrFragmentProcessor* fp = fps.processor();
102 SkNEW_APPEND_TO_TARRAY(&fFragmentStages, GrPendingFragmentStage, (fps));
103 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
104 fp->gatherCoordTransforms(&fCoordTransforms);
egdaniel9cf45bf2014-10-08 06:49:10 -0700105 }
joshualitt79f8fae2014-10-28 17:59:26 -0700106
bsalomon7765a472015-07-08 11:26:37 -0700107 // Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
108 fInfoForPrimitiveProcessor.fFlags = 0;
109 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
110 fInfoForPrimitiveProcessor.fFlags |= GrPipelineInfo::kReadsColor_GrPipelineInfoFlag;
111 }
112 if (GrColor_ILLEGAL != overrideColor) {
113 fInfoForPrimitiveProcessor.fFlags |= GrPipelineInfo::kUseOverrideColor_GrPipelineInfoFlag;
114 fInfoForPrimitiveProcessor.fOverrideColor = overrideColor;
115 }
116 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag)) {
117 fInfoForPrimitiveProcessor.fFlags |= GrPipelineInfo::kReadsCoverage_GrPipelineInfoFlag;
118 }
119 if (usesLocalCoords) {
120 fInfoForPrimitiveProcessor.fFlags |= GrPipelineInfo::kReadsLocalCoords_GrPipelineInfoFlag;
121 }
122 if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
123 fInfoForPrimitiveProcessor.fFlags |=
124 GrPipelineInfo::kCanTweakAlphaForCoverage_GrPipelineInfoFlag;
125 }
egdanielc0648242014-09-22 13:17:02 -0700126}
127
egdaniel8dd688b2015-01-22 10:16:09 -0800128void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
129 GrXferProcessor::OptFlags flags,
130 const GrProcOptInfo& colorPOI,
131 const GrProcOptInfo& coveragePOI,
132 int* firstColorStageIdx,
133 int* firstCoverageStageIdx) {
egdaniel060a52c2015-04-07 07:31:11 -0700134 fReadsFragPosition = fXferProcessor->willReadFragmentPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700135
joshualitt9b989322014-12-15 14:16:27 -0800136 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
137 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
bsalomon6be6f7c2015-02-26 13:05:21 -0800138 *firstColorStageIdx = pipelineBuilder.numColorFragmentStages();
egdaniel95131432014-12-09 11:15:43 -0800139 } else {
egdaniel060a52c2015-04-07 07:31:11 -0700140 if (coveragePOI.readsFragPosition()) {
141 fReadsFragPosition = true;
142 }
egdaniela7dc0a82014-09-17 08:25:05 -0700143 }
egdaniel95131432014-12-09 11:15:43 -0800144
joshualitt9b989322014-12-15 14:16:27 -0800145 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
bsalomon6be6f7c2015-02-26 13:05:21 -0800146 *firstCoverageStageIdx = pipelineBuilder.numCoverageFragmentStages();
egdaniel95131432014-12-09 11:15:43 -0800147 } else {
egdaniel95131432014-12-09 11:15:43 -0800148 if (coveragePOI.readsFragPosition()) {
bsalomon50785a32015-02-06 07:02:37 -0800149 fReadsFragPosition = true;
egdaniel95131432014-12-09 11:15:43 -0800150 }
egdaniela7dc0a82014-09-17 08:25:05 -0700151 }
152}
153
egdaniel89af44a2014-09-26 06:15:04 -0700154////////////////////////////////////////////////////////////////////////////////
155
joshualitt2fe79232015-08-05 12:02:27 -0700156bool GrPipeline::isEqual(const GrPipeline& that, bool ignoreCoordTransforms) const {
joshualitt8cab9a72015-07-16 09:13:50 -0700157 // If we point to the same pipeline, then we are necessarily equal
158 if (this == &that) {
159 return true;
160 }
161
egdaniel89af44a2014-09-26 06:15:04 -0700162 if (this->getRenderTarget() != that.getRenderTarget() ||
joshualittdafa4d02014-12-04 08:59:10 -0800163 this->fFragmentStages.count() != that.fFragmentStages.count() ||
164 this->fNumColorStages != that.fNumColorStages ||
joshualitt54e0c122014-11-19 09:38:51 -0800165 this->fScissorState != that.fScissorState ||
bsalomon04ddf892014-11-19 12:36:22 -0800166 this->fFlags != that.fFlags ||
egdaniel89af44a2014-09-26 06:15:04 -0700167 this->fStencilSettings != that.fStencilSettings ||
bsalomon50785a32015-02-06 07:02:37 -0800168 this->fDrawFace != that.fDrawFace) {
egdaniel89af44a2014-09-26 06:15:04 -0700169 return false;
170 }
171
egdanielc2304142014-12-11 13:15:13 -0800172 if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) {
173 return false;
174 }
175
egdanield9aa2182014-10-09 13:47:05 -0700176 for (int i = 0; i < this->numFragmentStages(); i++) {
joshualitt2fe79232015-08-05 12:02:27 -0700177 if (!this->getFragmentStage(i).processor()->isEqual(*that.getFragmentStage(i).processor(),
178 ignoreCoordTransforms)) {
egdaniel89af44a2014-09-26 06:15:04 -0700179 return false;
180 }
181 }
egdaniel89af44a2014-09-26 06:15:04 -0700182 return true;
183}
184