blob: 8f149f5c4b7ebd236c9732944a5b71ed3fae8a17 [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
bsalomona387a112015-08-11 14:47:42 -070018GrPipeline* GrPipeline::CreateAt(void* memory, const CreateArgs& args,
bsalomonc6998732015-08-10 12:01:15 -070019 GrPipelineOptimizations* opts) {
bsalomona387a112015-08-11 14:47:42 -070020 const GrPipelineBuilder& builder = *args.fPipelineBuilder;
bsalomonc6998732015-08-10 12:01:15 -070021
egdaniel95131432014-12-09 11:15:43 -080022 // Create XferProcessor from DS's XPFactory
23 SkAutoTUnref<GrXferProcessor> xferProcessor(
bsalomona387a112015-08-11 14:47:42 -070024 builder.getXPFactory()->createXferProcessor(args.fColorPOI, args.fCoveragePOI,
25 builder.hasMixedSamples(), &args.fDstTexture,
26 *args.fCaps));
bsalomonc8d3f572015-08-13 06:44:04 -070027 if (!xferProcessor) {
28 return nullptr;
29 }
egdaniel95131432014-12-09 11:15:43 -080030
joshualitt9b989322014-12-15 14:16:27 -080031 GrColor overrideColor = GrColor_ILLEGAL;
bsalomona387a112015-08-11 14:47:42 -070032 if (args.fColorPOI.firstEffectiveStageIndex() != 0) {
33 overrideColor = args.fColorPOI.inputColorToEffectiveStage();
joshualitt9b989322014-12-15 14:16:27 -080034 }
35
bsalomon7765a472015-07-08 11:26:37 -070036 GrXferProcessor::OptFlags optFlags = GrXferProcessor::kNone_OptFlags;
egdaniel95131432014-12-09 11:15:43 -080037
bsalomonc8d3f572015-08-13 06:44:04 -070038 optFlags = xferProcessor->getOptimizations(args.fColorPOI,
39 args.fCoveragePOI,
40 builder.getStencil().doesWrite(),
41 &overrideColor,
42 *args.fCaps);
43
44 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
45 // so we must check the draw type. In cases where we will skip drawing we simply return a
46 // null GrPipeline.
47 if (GrXferProcessor::kSkipDraw_OptFlag & optFlags) {
48 return nullptr;
egdaniel95131432014-12-09 11:15:43 -080049 }
bsalomonb03c4a32014-11-20 09:56:11 -080050
bsalomon7765a472015-07-08 11:26:37 -070051 // No need to have an override color if it isn't even going to be used.
52 if (SkToBool(GrXferProcessor::kIgnoreColor_OptFlag & optFlags)) {
53 overrideColor = GrColor_ILLEGAL;
54 }
55
bsalomonc8d3f572015-08-13 06:44:04 -070056 GrPipeline* pipeline = SkNEW_PLACEMENT(memory, GrPipeline);
57 pipeline->fXferProcessor.reset(xferProcessor.get());
bsalomonb03c4a32014-11-20 09:56:11 -080058
bsalomonc6998732015-08-10 12:01:15 -070059 pipeline->fRenderTarget.reset(builder.fRenderTarget.get());
60 SkASSERT(pipeline->fRenderTarget);
bsalomona387a112015-08-11 14:47:42 -070061 pipeline->fScissorState = *args.fScissor;
bsalomonc6998732015-08-10 12:01:15 -070062 pipeline->fStencilSettings = builder.getStencil();
63 pipeline->fDrawFace = builder.getDrawFace();
joshualitt9176e2c2014-11-20 07:28:52 -080064
bsalomonc6998732015-08-10 12:01:15 -070065 pipeline->fFlags = 0;
66 if (builder.isHWAntialias()) {
67 pipeline->fFlags |= kHWAA_Flag;
bsalomon04ddf892014-11-19 12:36:22 -080068 }
bsalomonc6998732015-08-10 12:01:15 -070069 if (builder.isDither()) {
70 pipeline->fFlags |= kDither_Flag;
bsalomon04ddf892014-11-19 12:36:22 -080071 }
bsalomonc6998732015-08-10 12:01:15 -070072 if (builder.snapVerticesToPixelCenters()) {
73 pipeline->fFlags |= kSnapVertices_Flag;
bsalomond79c5492015-04-27 10:07:04 -070074 }
bsalomon04ddf892014-11-19 12:36:22 -080075
bsalomona387a112015-08-11 14:47:42 -070076 int firstColorStageIdx = args.fColorPOI.firstEffectiveStageIndex();
egdaniel912b3d22014-11-17 07:45:53 -080077
78 // TODO: Once we can handle single or four channel input into coverage stages then we can use
egdaniel8dd688b2015-01-22 10:16:09 -080079 // GrPipelineBuilder's coverageProcInfo (like color above) to set this initial information.
egdaniel912b3d22014-11-17 07:45:53 -080080 int firstCoverageStageIdx = 0;
egdaniel912b3d22014-11-17 07:45:53 -080081
bsalomona387a112015-08-11 14:47:42 -070082 pipeline->adjustProgramFromOptimizations(builder, optFlags, args.fColorPOI, args.fCoveragePOI,
bsalomonc6998732015-08-10 12:01:15 -070083 &firstColorStageIdx, &firstCoverageStageIdx);
egdaniel95131432014-12-09 11:15:43 -080084
joshualitt290c09b2014-12-19 13:45:20 -080085 bool usesLocalCoords = false;
86
egdaniel8dd688b2015-01-22 10:16:09 -080087 // Copy Stages from PipelineBuilder to Pipeline
bsalomonc6998732015-08-10 12:01:15 -070088 for (int i = firstColorStageIdx; i < builder.numColorFragmentStages(); ++i) {
89 const GrFragmentStage& fps = builder.fColorStages[i];
joshualitt2fe79232015-08-05 12:02:27 -070090 const GrFragmentProcessor* fp = fps.processor();
bsalomonc6998732015-08-10 12:01:15 -070091 SkNEW_APPEND_TO_TARRAY(&pipeline->fFragmentStages, GrPendingFragmentStage, (fps));
joshualitt2fe79232015-08-05 12:02:27 -070092 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
bsalomonc6998732015-08-10 12:01:15 -070093 fp->gatherCoordTransforms(&pipeline->fCoordTransforms);
bsalomonae59b772014-11-19 08:23:49 -080094 }
egdaniel95131432014-12-09 11:15:43 -080095
bsalomonc6998732015-08-10 12:01:15 -070096 pipeline->fNumColorStages = pipeline->fFragmentStages.count();
97 for (int i = firstCoverageStageIdx; i < builder.numCoverageFragmentStages(); ++i) {
98 const GrFragmentStage& fps = builder.fCoverageStages[i];
joshualitt2fe79232015-08-05 12:02:27 -070099 const GrFragmentProcessor* fp = fps.processor();
bsalomonc6998732015-08-10 12:01:15 -0700100 SkNEW_APPEND_TO_TARRAY(&pipeline->fFragmentStages, GrPendingFragmentStage, (fps));
joshualitt2fe79232015-08-05 12:02:27 -0700101 usesLocalCoords = usesLocalCoords || fp->usesLocalCoords();
bsalomonc6998732015-08-10 12:01:15 -0700102 fp->gatherCoordTransforms(&pipeline->fCoordTransforms);
egdaniel9cf45bf2014-10-08 06:49:10 -0700103 }
joshualitt79f8fae2014-10-28 17:59:26 -0700104
bsalomon7765a472015-07-08 11:26:37 -0700105 // Setup info we need to pass to GrPrimitiveProcessors that are used with this GrPipeline.
bsalomonc6998732015-08-10 12:01:15 -0700106 opts->fFlags = 0;
bsalomon7765a472015-07-08 11:26:37 -0700107 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreColor_OptFlag)) {
bsalomonc6998732015-08-10 12:01:15 -0700108 opts->fFlags |= GrPipelineOptimizations::kReadsColor_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700109 }
110 if (GrColor_ILLEGAL != overrideColor) {
bsalomonc6998732015-08-10 12:01:15 -0700111 opts->fFlags |= GrPipelineOptimizations::kUseOverrideColor_Flag;
112 opts->fOverrideColor = overrideColor;
bsalomon7765a472015-07-08 11:26:37 -0700113 }
114 if (!SkToBool(optFlags & GrXferProcessor::kIgnoreCoverage_OptFlag)) {
bsalomonc6998732015-08-10 12:01:15 -0700115 opts->fFlags |= GrPipelineOptimizations::kReadsCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700116 }
117 if (usesLocalCoords) {
bsalomonc6998732015-08-10 12:01:15 -0700118 opts->fFlags |= GrPipelineOptimizations::kReadsLocalCoords_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700119 }
120 if (SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag)) {
bsalomonc6998732015-08-10 12:01:15 -0700121 opts->fFlags |= GrPipelineOptimizations::kCanTweakAlphaForCoverage_Flag;
bsalomon7765a472015-07-08 11:26:37 -0700122 }
bsalomon2d563032015-08-13 07:08:31 -0700123
124 GrXPFactory::InvariantBlendedColor blendedColor;
125 builder.fXPFactory->getInvariantBlendedColor(args.fColorPOI, &blendedColor);
126 if (blendedColor.fWillBlendWithDst) {
127 opts->fFlags |= GrPipelineOptimizations::kWillColorBlendWithDst_Flag;
128 }
129
bsalomonc6998732015-08-10 12:01:15 -0700130 return pipeline;
egdanielc0648242014-09-22 13:17:02 -0700131}
132
egdaniel8dd688b2015-01-22 10:16:09 -0800133void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
134 GrXferProcessor::OptFlags flags,
135 const GrProcOptInfo& colorPOI,
136 const GrProcOptInfo& coveragePOI,
137 int* firstColorStageIdx,
138 int* firstCoverageStageIdx) {
egdaniel060a52c2015-04-07 07:31:11 -0700139 fReadsFragPosition = fXferProcessor->willReadFragmentPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700140
joshualitt9b989322014-12-15 14:16:27 -0800141 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
142 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
bsalomon6be6f7c2015-02-26 13:05:21 -0800143 *firstColorStageIdx = pipelineBuilder.numColorFragmentStages();
egdaniel95131432014-12-09 11:15:43 -0800144 } else {
egdaniel060a52c2015-04-07 07:31:11 -0700145 if (coveragePOI.readsFragPosition()) {
146 fReadsFragPosition = true;
147 }
egdaniela7dc0a82014-09-17 08:25:05 -0700148 }
egdaniel95131432014-12-09 11:15:43 -0800149
joshualitt9b989322014-12-15 14:16:27 -0800150 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
bsalomon6be6f7c2015-02-26 13:05:21 -0800151 *firstCoverageStageIdx = pipelineBuilder.numCoverageFragmentStages();
egdaniel95131432014-12-09 11:15:43 -0800152 } else {
egdaniel95131432014-12-09 11:15:43 -0800153 if (coveragePOI.readsFragPosition()) {
bsalomon50785a32015-02-06 07:02:37 -0800154 fReadsFragPosition = true;
egdaniel95131432014-12-09 11:15:43 -0800155 }
egdaniela7dc0a82014-09-17 08:25:05 -0700156 }
157}
158
egdaniel89af44a2014-09-26 06:15:04 -0700159////////////////////////////////////////////////////////////////////////////////
160
bsalomoncb02b382015-08-12 11:14:50 -0700161bool GrPipeline::AreEqual(const GrPipeline& a, const GrPipeline& b,
162 bool ignoreCoordTransforms) {
163 SkASSERT(&a != &b);
joshualitt8cab9a72015-07-16 09:13:50 -0700164
bsalomoncb02b382015-08-12 11:14:50 -0700165 if (a.getRenderTarget() != b.getRenderTarget() ||
166 a.fFragmentStages.count() != b.fFragmentStages.count() ||
167 a.fNumColorStages != b.fNumColorStages ||
168 a.fScissorState != b.fScissorState ||
169 a.fFlags != b.fFlags ||
170 a.fStencilSettings != b.fStencilSettings ||
171 a.fDrawFace != b.fDrawFace) {
egdaniel89af44a2014-09-26 06:15:04 -0700172 return false;
173 }
174
bsalomoncb02b382015-08-12 11:14:50 -0700175 if (!a.getXferProcessor()->isEqual(*b.getXferProcessor())) {
egdanielc2304142014-12-11 13:15:13 -0800176 return false;
177 }
178
bsalomoncb02b382015-08-12 11:14:50 -0700179 for (int i = 0; i < a.numFragmentStages(); i++) {
180 if (!a.getFragmentStage(i).processor()->isEqual(*b.getFragmentStage(i).processor(),
joshualitt2fe79232015-08-05 12:02:27 -0700181 ignoreCoordTransforms)) {
egdaniel89af44a2014-09-26 06:15:04 -0700182 return false;
183 }
184 }
egdaniel89af44a2014-09-26 06:15:04 -0700185 return true;
186}
187