1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "GrPipeline.h"
9
10 #include "GrBatch.h"
11 #include "GrDrawTargetCaps.h"
12 #include "GrGpu.h"
13 #include "GrPipelineBuilder.h"
14 #include "GrProcOptInfo.h"
15 #include "GrXferProcessor.h"
16
GrPipeline(const GrPipelineBuilder & pipelineBuilder,const GrProcOptInfo & colorPOI,const GrProcOptInfo & coveragePOI,const GrDrawTargetCaps & caps,const GrScissorState & scissorState,const GrDeviceCoordTexture * dstCopy)17 GrPipeline::GrPipeline(const GrPipelineBuilder& pipelineBuilder,
18 const GrProcOptInfo& colorPOI,
19 const GrProcOptInfo& coveragePOI,
20 const GrDrawTargetCaps& caps,
21 const GrScissorState& scissorState,
22 const GrDeviceCoordTexture* dstCopy) {
23 // Create XferProcessor from DS's XPFactory
24 SkAutoTUnref<GrXferProcessor> xferProcessor(
25 pipelineBuilder.getXPFactory()->createXferProcessor(colorPOI, coveragePOI, dstCopy, caps));
26
27 GrColor overrideColor = GrColor_ILLEGAL;
28 if (colorPOI.firstEffectiveStageIndex() != 0) {
29 overrideColor = colorPOI.inputColorToEffectiveStage();
30 }
31
32 GrXferProcessor::OptFlags optFlags;
33 if (xferProcessor) {
34 fXferProcessor.reset(xferProcessor.get());
35
36 optFlags = xferProcessor->getOptimizations(colorPOI,
37 coveragePOI,
38 pipelineBuilder.getStencil().doesWrite(),
39 &overrideColor,
40 caps);
41 }
42
43 // When path rendering the stencil settings are not always set on the GrPipelineBuilder
44 // so we must check the draw type. In cases where we will skip drawing we simply return a
45 // null GrPipeline.
46 if (!xferProcessor || (GrXferProcessor::kSkipDraw_OptFlag & optFlags)) {
47 // 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;
50 fDrawFace = GrPipelineBuilder::kInvalid_DrawFace;
51 return;
52 }
53
54 fRenderTarget.reset(pipelineBuilder.fRenderTarget.get());
55 SkASSERT(fRenderTarget);
56 fScissorState = scissorState;
57 fStencilSettings = pipelineBuilder.getStencil();
58 fDrawFace = pipelineBuilder.getDrawFace();
59
60 fFlags = 0;
61 if (pipelineBuilder.isHWAntialias()) {
62 fFlags |= kHWAA_Flag;
63 }
64 if (pipelineBuilder.isDither()) {
65 fFlags |= kDither_Flag;
66 }
67 if (pipelineBuilder.snapVerticesToPixelCenters()) {
68 fFlags |= kSnapVertices_Flag;
69 }
70
71 int firstColorStageIdx = colorPOI.firstEffectiveStageIndex();
72
73 // TODO: Once we can handle single or four channel input into coverage stages then we can use
74 // GrPipelineBuilder's coverageProcInfo (like color above) to set this initial information.
75 int firstCoverageStageIdx = 0;
76
77 this->adjustProgramFromOptimizations(pipelineBuilder, optFlags, colorPOI, coveragePOI,
78 &firstColorStageIdx, &firstCoverageStageIdx);
79
80 bool usesLocalCoords = false;
81
82 // Copy Stages from PipelineBuilder to Pipeline
83 for (int i = firstColorStageIdx; i < pipelineBuilder.numColorFragmentStages(); ++i) {
84 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
85 GrPendingFragmentStage,
86 (pipelineBuilder.fColorStages[i]));
87 usesLocalCoords = usesLocalCoords ||
88 pipelineBuilder.fColorStages[i].processor()->usesLocalCoords();
89 }
90
91 fNumColorStages = fFragmentStages.count();
92 for (int i = firstCoverageStageIdx; i < pipelineBuilder.numCoverageFragmentStages(); ++i) {
93 SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
94 GrPendingFragmentStage,
95 (pipelineBuilder.fCoverageStages[i]));
96 usesLocalCoords = usesLocalCoords ||
97 pipelineBuilder.fCoverageStages[i].processor()->usesLocalCoords();
98 }
99
100 // let the GP init the batch tracker
101 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;
105 fInitBT.fCanTweakAlphaForCoverage =
106 SkToBool(optFlags & GrXferProcessor::kCanTweakAlphaForCoverage_OptFlag);
107 }
108
adjustProgramFromOptimizations(const GrPipelineBuilder & pipelineBuilder,GrXferProcessor::OptFlags flags,const GrProcOptInfo & colorPOI,const GrProcOptInfo & coveragePOI,int * firstColorStageIdx,int * firstCoverageStageIdx)109 void GrPipeline::adjustProgramFromOptimizations(const GrPipelineBuilder& pipelineBuilder,
110 GrXferProcessor::OptFlags flags,
111 const GrProcOptInfo& colorPOI,
112 const GrProcOptInfo& coveragePOI,
113 int* firstColorStageIdx,
114 int* firstCoverageStageIdx) {
115 fReadsFragPosition = fXferProcessor->willReadFragmentPosition();
116
117 if ((flags & GrXferProcessor::kIgnoreColor_OptFlag) ||
118 (flags & GrXferProcessor::kOverrideColor_OptFlag)) {
119 *firstColorStageIdx = pipelineBuilder.numColorFragmentStages();
120 } else {
121 if (coveragePOI.readsFragPosition()) {
122 fReadsFragPosition = true;
123 }
124 }
125
126 if (flags & GrXferProcessor::kIgnoreCoverage_OptFlag) {
127 *firstCoverageStageIdx = pipelineBuilder.numCoverageFragmentStages();
128 } else {
129 if (coveragePOI.readsFragPosition()) {
130 fReadsFragPosition = true;
131 }
132 }
133 }
134
135 ////////////////////////////////////////////////////////////////////////////////
136
isEqual(const GrPipeline & that) const137 bool GrPipeline::isEqual(const GrPipeline& that) const {
138 if (this->getRenderTarget() != that.getRenderTarget() ||
139 this->fFragmentStages.count() != that.fFragmentStages.count() ||
140 this->fNumColorStages != that.fNumColorStages ||
141 this->fScissorState != that.fScissorState ||
142 this->fFlags != that.fFlags ||
143 this->fStencilSettings != that.fStencilSettings ||
144 this->fDrawFace != that.fDrawFace) {
145 return false;
146 }
147
148 if (!this->getXferProcessor()->isEqual(*that.getXferProcessor())) {
149 return false;
150 }
151
152 // The program desc comparison should have already assured that the stage counts match.
153 SkASSERT(this->numFragmentStages() == that.numFragmentStages());
154 for (int i = 0; i < this->numFragmentStages(); i++) {
155
156 if (this->getFragmentStage(i) != that.getFragmentStage(i)) {
157 return false;
158 }
159 }
160 return true;
161 }
162
163