blob: 911169e3368f6a2c30203d73a226813357d8c509 [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
joshualittd5a7db42015-01-27 15:39:06 -080010#include "GrBatch.h"
egdanielc0648242014-09-22 13:17:02 -070011#include "GrDrawTargetCaps.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
egdaniel8dd688b2015-01-22 10:16:09 -080017GrPipeline::GrPipeline(const GrPipelineBuilder& pipelineBuilder,
joshualittd5a7db42015-01-27 15:39:06 -080018 const GrPrimitiveProcessor* primProc,
19 const GrDrawTargetCaps& caps,
20 const GrScissorState& scissorState,
21 const GrDeviceCoordTexture* dstCopy) {
egdaniel8dd688b2015-01-22 10:16:09 -080022 const GrProcOptInfo& colorPOI = pipelineBuilder.colorProcInfo(primProc);
23 const GrProcOptInfo& coveragePOI = pipelineBuilder.coverageProcInfo(primProc);
egdaniel95131432014-12-09 11:15:43 -080024
joshualittd5a7db42015-01-27 15:39:06 -080025 this->internalConstructor(pipelineBuilder, colorPOI, coveragePOI, caps, scissorState, dstCopy);
26}
27
28GrPipeline::GrPipeline(GrBatch* batch,
29 const GrPipelineBuilder& pipelineBuilder,
30 const GrDrawTargetCaps& caps,
31 const GrScissorState& scissorState,
32 const GrDeviceCoordTexture* dstCopy) {
33 GrBatchOpt batchOpt;
34 batchOpt.fCanTweakAlphaForCoverage = pipelineBuilder.canTweakAlphaForCoverage();
35 batch->initBatchOpt(batchOpt);
36
37 const GrProcOptInfo& colorPOI = pipelineBuilder.colorProcInfo(batch);
38 const GrProcOptInfo& coveragePOI = pipelineBuilder.coverageProcInfo(batch);
39
40 this->internalConstructor(pipelineBuilder, colorPOI, coveragePOI, caps, scissorState, dstCopy);
41}
42
43void GrPipeline::internalConstructor(const GrPipelineBuilder& pipelineBuilder,
44 const GrProcOptInfo& colorPOI,
45 const GrProcOptInfo& coveragePOI,
46 const GrDrawTargetCaps& caps,
47 const GrScissorState& scissorState,
48 const GrDeviceCoordTexture* dstCopy) {
egdaniel95131432014-12-09 11:15:43 -080049 // Create XferProcessor from DS's XPFactory
50 SkAutoTUnref<GrXferProcessor> xferProcessor(
egdaniel8dd688b2015-01-22 10:16:09 -080051 pipelineBuilder.getXPFactory()->createXferProcessor(colorPOI, coveragePOI));
egdaniel95131432014-12-09 11:15:43 -080052
joshualitt9b989322014-12-15 14:16:27 -080053 GrColor overrideColor = GrColor_ILLEGAL;
54 if (colorPOI.firstEffectiveStageIndex() != 0) {
55 overrideColor = colorPOI.inputColorToEffectiveStage();
56 }
57
egdaniel95131432014-12-09 11:15:43 -080058 GrXferProcessor::OptFlags optFlags;
59 if (xferProcessor) {
60 fXferProcessor.reset(xferProcessor.get());
61
62 optFlags = xferProcessor->getOptimizations(colorPOI,
63 coveragePOI,
egdaniel8dd688b2015-01-22 10:16:09 -080064 pipelineBuilder.getStencil().doesWrite(),
joshualitt9b989322014-12-15 14:16:27 -080065 &overrideColor,
egdanielc2304142014-12-11 13:15:13 -080066 caps);
egdaniel95131432014-12-09 11:15:43 -080067 }
bsalomonb03c4a32014-11-20 09:56:11 -080068
egdaniel8dd688b2015-01-22 10:16:09 -080069 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
bsalomonb03c4a32014-11-20 09:56:11 -080070 // so we must check the draw type. In cases where we will skip drawing we simply return a
egdaniel8dd688b2015-01-22 10:16:09 -080071 // null GrPipeline.
bsalomon3e791242014-12-17 13:43:13 -080072 if (!xferProcessor || (GrXferProcessor::kSkipDraw_OptFlag & optFlags)) {
bsalomonb03c4a32014-11-20 09:56:11 -080073 // Set the fields that don't default init and return. The lack of a render target will
74 // indicate that this can be skipped.
75 fFlags = 0;
egdaniel8dd688b2015-01-22 10:16:09 -080076 fDrawFace = GrPipelineBuilder::kInvalid_DrawFace;
bsalomonb03c4a32014-11-20 09:56:11 -080077 return;
78 }
79
egdaniel8dd688b2015-01-22 10:16:09 -080080 fRenderTarget.reset(pipelineBuilder.fRenderTarget.get());
bsalomonb03c4a32014-11-20 09:56:11 -080081 SkASSERT(fRenderTarget);
joshualitt54e0c122014-11-19 09:38:51 -080082 fScissorState = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -080083 fStencilSettings = pipelineBuilder.getStencil();
84 fDrawFace = pipelineBuilder.getDrawFace();
85 // TODO move this out of GrPipeline
joshualitt9176e2c2014-11-20 07:28:52 -080086 if (dstCopy) {
87 fDstCopy = *dstCopy;
88 }
89
bsalomon04ddf892014-11-19 12:36:22 -080090 fFlags = 0;
egdaniel8dd688b2015-01-22 10:16:09 -080091 if (pipelineBuilder.isHWAntialias()) {
bsalomon04ddf892014-11-19 12:36:22 -080092 fFlags |= kHWAA_Flag;
93 }
egdaniel8dd688b2015-01-22 10:16:09 -080094 if (pipelineBuilder.isDither()) {
bsalomon04ddf892014-11-19 12:36:22 -080095 fFlags |= kDither_Flag;
96 }
97
egdaniel912b3d22014-11-17 07:45:53 -080098 int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
egdaniel912b3d22014-11-17 07:45:53 -080099
100 // TODO: Once we can handle single or four channel input into coverage stages then we can use
egdaniel8dd688b2015-01-22 10:16:09 -0800101 // GrPipelineBuilder's coverageProcInfo (like color above) to set this initial information.
egdaniel912b3d22014-11-17 07:45:53 -0800102 int firstCoverageStageIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -0800103
egdaniel95131432014-12-09 11:15:43 -0800104 GrXferProcessor::BlendInfo blendInfo;
105 fXferProcessor->getBlendInfo(&blendInfo);
egdaniel95131432014-12-09 11:15:43 -0800106
egdaniel8dd688b2015-01-22 10:16:09 -0800107 this->adjustProgramFromOptimizations(pipelineBuilder, optFlags, colorPOI, coveragePOI,
egdaniel95131432014-12-09 11:15:43 -0800108 &firstColorStageIdx, &firstCoverageStageIdx);
109
egdaniel71e236c2015-01-20 06:34:51 -0800110 fDescInfo.fReadsDst = fXferProcessor->willReadDstColor();
111
joshualitt290c09b2014-12-19 13:45:20 -0800112 bool usesLocalCoords = false;
113
egdaniel8dd688b2015-01-22 10:16:09 -0800114 // Copy Stages from PipelineBuilder to Pipeline
115 for (int i = firstColorStageIdx; i < pipelineBuilder.numColorStages(); ++i) {
bsalomonae59b772014-11-19 08:23:49 -0800116 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
117 GrPendingFragmentStage,
egdaniel8dd688b2015-01-22 10:16:09 -0800118 (pipelineBuilder.fColorStages[i]));
joshualitt290c09b2014-12-19 13:45:20 -0800119 usesLocalCoords = usesLocalCoords ||
egdaniel8dd688b2015-01-22 10:16:09 -0800120 pipelineBuilder.fColorStages[i].processor()->usesLocalCoords();
bsalomonae59b772014-11-19 08:23:49 -0800121 }
egdaniel95131432014-12-09 11:15:43 -0800122
egdanield9aa2182014-10-09 13:47:05 -0700123 fNumColorStages = fFragmentStages.count();
egdaniel8dd688b2015-01-22 10:16:09 -0800124 for (int i = firstCoverageStageIdx; i < pipelineBuilder.numCoverageStages(); ++i) {
bsalomonae59b772014-11-19 08:23:49 -0800125 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
126 GrPendingFragmentStage,
egdaniel8dd688b2015-01-22 10:16:09 -0800127 (pipelineBuilder.fCoverageStages[i]));
joshualitt290c09b2014-12-19 13:45:20 -0800128 usesLocalCoords = usesLocalCoords ||
egdaniel8dd688b2015-01-22 10:16:09 -0800129 pipelineBuilder.fCoverageStages[i].processor()->usesLocalCoords();
egdaniel9cf45bf2014-10-08 06:49:10 -0700130 }
joshualitt79f8fae2014-10-28 17:59:26 -0700131
joshualitt87f48d92014-12-04 10:41:40 -0800132 // let the GP init the batch tracker
joshualitt873ad0e2015-01-20 09:08:51 -0800133 fInitBT.fColorIgnored = SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag);
134 fInitBT.fOverrideColor = fInitBT.fColorIgnored ? GrColor_ILLEGAL : overrideColor;
135 fInitBT.fCoverageIgnored = SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag);
136 fInitBT.fUsesLocalCoords = usesLocalCoords;
egdanielc0648242014-09-22 13:17:02 -0700137}
138
egdaniel8dd688b2015-01-22 10:16:09 -0800139void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
140 GrXferProcessor::OptFlags flags,
141 const GrProcOptInfo& colorPOI,
142 const GrProcOptInfo& coveragePOI,
143 int* firstColorStageIdx,
144 int* firstCoverageStageIdx) {
joshualittdafa4d02014-12-04 08:59:10 -0800145 fDescInfo.fReadsFragPosition = false;
egdaniela7dc0a82014-09-17 08:25:05 -0700146
joshualitt9b989322014-12-15 14:16:27 -0800147 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
148 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
egdaniel8dd688b2015-01-22 10:16:09 -0800149 *firstColorStageIdx = pipelineBuilder.numColorStages();
egdaniel95131432014-12-09 11:15:43 -0800150 } else {
egdaniel95131432014-12-09 11:15:43 -0800151 fDescInfo.fReadsFragPosition = colorPOI.readsFragPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700152 }
egdaniel95131432014-12-09 11:15:43 -0800153
joshualitt9b989322014-12-15 14:16:27 -0800154 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
egdaniel8dd688b2015-01-22 10:16:09 -0800155 *firstCoverageStageIdx = pipelineBuilder.numCoverageStages();
egdaniel95131432014-12-09 11:15:43 -0800156 } else {
egdaniel95131432014-12-09 11:15:43 -0800157 if (coveragePOI.readsFragPosition()) {
158 fDescInfo.fReadsFragPosition = true;
159 }
egdaniela7dc0a82014-09-17 08:25:05 -0700160 }
161}
162
egdaniel89af44a2014-09-26 06:15:04 -0700163////////////////////////////////////////////////////////////////////////////////
164
egdaniel8dd688b2015-01-22 10:16:09 -0800165bool GrPipeline::isEqual(const GrPipeline& that) const {
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 ||
joshualitt9176e2c2014-11-20 07:28:52 -0800172 this->fDrawFace != that.fDrawFace ||
173 this->fDstCopy.texture() != that.fDstCopy.texture()) {
egdaniel89af44a2014-09-26 06:15:04 -0700174 return false;
175 }
176
egdanielc2304142014-12-11 13:15:13 -0800177 if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) {
178 return false;
179 }
180
bsalomonae59b772014-11-19 08:23:49 -0800181 // The program desc comparison should have already assured that the stage counts match.
182 SkASSERT(this->numFragmentStages() == that.numFragmentStages());
egdanield9aa2182014-10-09 13:47:05 -0700183 for (int i = 0; i < this->numFragmentStages(); i++) {
bsalomonae59b772014-11-19 08:23:49 -0800184
185 if (this->getFragmentStage(i) != that.getFragmentStage(i)) {
egdaniel89af44a2014-09-26 06:15:04 -0700186 return false;
187 }
188 }
egdaniel89af44a2014-09-26 06:15:04 -0700189 return true;
190}
191