blob: f17f402b4ddec644845d6164b0b9fb6e88ab4b8e [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"
joshualitt4d8da812015-01-28 12:53:54 -080011#include "GrBatch.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,
egdaniele36914c2015-02-13 09:00:33 -080018 const GrProcOptInfo& colorPOI,
19 const GrProcOptInfo& coveragePOI,
bsalomon4b91f762015-05-19 09:29:46 -070020 const GrCaps& caps,
joshualitt4d8da812015-01-28 12:53:54 -080021 const GrScissorState& scissorState,
22 const GrDeviceCoordTexture* dstCopy) {
egdaniel95131432014-12-09 11:15:43 -080023 // Create XferProcessor from DS's XPFactory
24 SkAutoTUnref<GrXferProcessor> xferProcessor(
bsalomon50785a32015-02-06 07:02:37 -080025 pipelineBuilder.getXPFactory()->createXferProcessor(colorPOI, coveragePOI, dstCopy, caps));
egdaniel95131432014-12-09 11:15:43 -080026
joshualitt9b989322014-12-15 14:16:27 -080027 GrColor overrideColor = GrColor_ILLEGAL;
28 if (colorPOI.firstEffectiveStageIndex() != 0) {
29 overrideColor = colorPOI.inputColorToEffectiveStage();
30 }
31
egdaniel95131432014-12-09 11:15:43 -080032 GrXferProcessor::OptFlags optFlags;
33 if (xferProcessor) {
34 fXferProcessor.reset(xferProcessor.get());
35
36 optFlags = xferProcessor->getOptimizations(colorPOI,
37 coveragePOI,
egdaniel8dd688b2015-01-22 10:16:09 -080038 pipelineBuilder.getStencil().doesWrite(),
joshualitt9b989322014-12-15 14:16:27 -080039 &overrideColor,
egdanielc2304142014-12-11 13:15:13 -080040 caps);
egdaniel95131432014-12-09 11:15:43 -080041 }
bsalomonb03c4a32014-11-20 09:56:11 -080042
egdaniel8dd688b2015-01-22 10:16:09 -080043 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
bsalomonb03c4a32014-11-20 09:56:11 -080044 // so we must check the draw type. In cases where we will skip drawing we simply return a
egdaniel8dd688b2015-01-22 10:16:09 -080045 // null GrPipeline.
bsalomon3e791242014-12-17 13:43:13 -080046 if (!xferProcessor || (GrXferProcessor::kSkipDraw_OptFlag & optFlags)) {
bsalomonb03c4a32014-11-20 09:56:11 -080047 // Set the fields that don't default init and return. The lack of a render target will
48 // indicate that this can be skipped.
49 fFlags = 0;
egdaniel8dd688b2015-01-22 10:16:09 -080050 fDrawFace = GrPipelineBuilder::kInvalid_DrawFace;
bsalomonb03c4a32014-11-20 09:56:11 -080051 return;
52 }
53
egdaniel8dd688b2015-01-22 10:16:09 -080054 fRenderTarget.reset(pipelineBuilder.fRenderTarget.get());
bsalomonb03c4a32014-11-20 09:56:11 -080055 SkASSERT(fRenderTarget);
joshualitt54e0c122014-11-19 09:38:51 -080056 fScissorState = scissorState;
egdaniel8dd688b2015-01-22 10:16:09 -080057 fStencilSettings = pipelineBuilder.getStencil();
58 fDrawFace = pipelineBuilder.getDrawFace();
joshualitt9176e2c2014-11-20 07:28:52 -080059
bsalomon04ddf892014-11-19 12:36:22 -080060 fFlags = 0;
egdaniel8dd688b2015-01-22 10:16:09 -080061 if (pipelineBuilder.isHWAntialias()) {
bsalomon04ddf892014-11-19 12:36:22 -080062 fFlags |= kHWAA_Flag;
63 }
egdaniel8dd688b2015-01-22 10:16:09 -080064 if (pipelineBuilder.isDither()) {
bsalomon04ddf892014-11-19 12:36:22 -080065 fFlags |= kDither_Flag;
66 }
bsalomond79c5492015-04-27 10:07:04 -070067 if (pipelineBuilder.snapVerticesToPixelCenters()) {
68 fFlags |= kSnapVertices_Flag;
69 }
bsalomon04ddf892014-11-19 12:36:22 -080070
egdaniel912b3d22014-11-17 07:45:53 -080071 int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
egdaniel912b3d22014-11-17 07:45:53 -080072
73 // TODO: Once we can handle single or four channel input into coverage stages then we can use
egdaniel8dd688b2015-01-22 10:16:09 -080074 // GrPipelineBuilder's coverageProcInfo (like color above) to set this initial information.
egdaniel912b3d22014-11-17 07:45:53 -080075 int firstCoverageStageIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -080076
egdaniel8dd688b2015-01-22 10:16:09 -080077 this->adjustProgramFromOptimizations(pipelineBuilder, optFlags, colorPOI, coveragePOI,
egdaniel95131432014-12-09 11:15:43 -080078 &firstColorStageIdx, &firstCoverageStageIdx);
79
joshualitt290c09b2014-12-19 13:45:20 -080080 bool usesLocalCoords = false;
81
egdaniel8dd688b2015-01-22 10:16:09 -080082 // Copy Stages from PipelineBuilder to Pipeline
bsalomon6be6f7c2015-02-26 13:05:21 -080083 for (int i = firstColorStageIdx; i < pipelineBuilder.numColorFragmentStages(); ++i) {
bsalomonae59b772014-11-19 08:23:49 -080084 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
85 GrPendingFragmentStage,
egdaniel8dd688b2015-01-22 10:16:09 -080086 (pipelineBuilder.fColorStages[i]));
joshualitt290c09b2014-12-19 13:45:20 -080087 usesLocalCoords = usesLocalCoords ||
egdaniel8dd688b2015-01-22 10:16:09 -080088 pipelineBuilder.fColorStages[i].processor()->usesLocalCoords();
bsalomonae59b772014-11-19 08:23:49 -080089 }
egdaniel95131432014-12-09 11:15:43 -080090
egdanield9aa2182014-10-09 13:47:05 -070091 fNumColorStages = fFragmentStages.count();
bsalomon6be6f7c2015-02-26 13:05:21 -080092 for (int i = firstCoverageStageIdx; i < pipelineBuilder.numCoverageFragmentStages(); ++i) {
bsalomonae59b772014-11-19 08:23:49 -080093 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
94 GrPendingFragmentStage,
egdaniel8dd688b2015-01-22 10:16:09 -080095 (pipelineBuilder.fCoverageStages[i]));
joshualitt290c09b2014-12-19 13:45:20 -080096 usesLocalCoords = usesLocalCoords ||
egdaniel8dd688b2015-01-22 10:16:09 -080097 pipelineBuilder.fCoverageStages[i].processor()->usesLocalCoords();
egdaniel9cf45bf2014-10-08 06:49:10 -070098 }
joshualitt79f8fae2014-10-28 17:59:26 -070099
joshualitt87f48d92014-12-04 10:41:40 -0800100 // let the GP init the batch tracker
joshualitt873ad0e2015-01-20 09:08:51 -0800101 fInitBT.fColorIgnored = SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag);
102 fInitBT.fOverrideColor = fInitBT.fColorIgnored ? GrColor_ILLEGAL : overrideColor;
103 fInitBT.fCoverageIgnored = SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag);
104 fInitBT.fUsesLocalCoords = usesLocalCoords;
egdanielf7c2d552015-02-13 12:11:00 -0800105 fInitBT.fCanTweakAlphaForCoverage =
106 SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag);
egdanielc0648242014-09-22 13:17:02 -0700107}
108
egdaniel8dd688b2015-01-22 10:16:09 -0800109void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
110 GrXferProcessor::OptFlags flags,
111 const GrProcOptInfo& colorPOI,
112 const GrProcOptInfo& coveragePOI,
113 int* firstColorStageIdx,
114 int* firstCoverageStageIdx) {
egdaniel060a52c2015-04-07 07:31:11 -0700115 fReadsFragPosition = fXferProcessor->willReadFragmentPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700116
joshualitt9b989322014-12-15 14:16:27 -0800117 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
118 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
bsalomon6be6f7c2015-02-26 13:05:21 -0800119 *firstColorStageIdx = pipelineBuilder.numColorFragmentStages();
egdaniel95131432014-12-09 11:15:43 -0800120 } else {
egdaniel060a52c2015-04-07 07:31:11 -0700121 if (coveragePOI.readsFragPosition()) {
122 fReadsFragPosition = true;
123 }
egdaniela7dc0a82014-09-17 08:25:05 -0700124 }
egdaniel95131432014-12-09 11:15:43 -0800125
joshualitt9b989322014-12-15 14:16:27 -0800126 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
bsalomon6be6f7c2015-02-26 13:05:21 -0800127 *firstCoverageStageIdx = pipelineBuilder.numCoverageFragmentStages();
egdaniel95131432014-12-09 11:15:43 -0800128 } else {
egdaniel95131432014-12-09 11:15:43 -0800129 if (coveragePOI.readsFragPosition()) {
bsalomon50785a32015-02-06 07:02:37 -0800130 fReadsFragPosition = true;
egdaniel95131432014-12-09 11:15:43 -0800131 }
egdaniela7dc0a82014-09-17 08:25:05 -0700132 }
133}
134
egdaniel89af44a2014-09-26 06:15:04 -0700135////////////////////////////////////////////////////////////////////////////////
136
egdaniel8dd688b2015-01-22 10:16:09 -0800137bool GrPipeline::isEqual(const GrPipeline& that) const {
egdaniel89af44a2014-09-26 06:15:04 -0700138 if (this->getRenderTarget() != that.getRenderTarget() ||
joshualittdafa4d02014-12-04 08:59:10 -0800139 this->fFragmentStages.count() != that.fFragmentStages.count() ||
140 this->fNumColorStages != that.fNumColorStages ||
joshualitt54e0c122014-11-19 09:38:51 -0800141 this->fScissorState != that.fScissorState ||
bsalomon04ddf892014-11-19 12:36:22 -0800142 this->fFlags != that.fFlags ||
egdaniel89af44a2014-09-26 06:15:04 -0700143 this->fStencilSettings != that.fStencilSettings ||
bsalomon50785a32015-02-06 07:02:37 -0800144 this->fDrawFace != that.fDrawFace) {
egdaniel89af44a2014-09-26 06:15:04 -0700145 return false;
146 }
147
egdanielc2304142014-12-11 13:15:13 -0800148 if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) {
149 return false;
150 }
151
bsalomonae59b772014-11-19 08:23:49 -0800152 // The program desc comparison should have already assured that the stage counts match.
153 SkASSERT(this->numFragmentStages() == that.numFragmentStages());
egdanield9aa2182014-10-09 13:47:05 -0700154 for (int i = 0; i < this->numFragmentStages(); i++) {
bsalomonae59b772014-11-19 08:23:49 -0800155
156 if (this->getFragmentStage(i) != that.getFragmentStage(i)) {
egdaniel89af44a2014-09-26 06:15:04 -0700157 return false;
158 }
159 }
egdaniel89af44a2014-09-26 06:15:04 -0700160 return true;
161}
162