blob: c764b432a17abcff1e4dc6f0b25ce13ada6ff0eb [file] [log] [blame]
egdaniel3658f382014-09-15 07:01:59 -07001/*
2 * Copyright 2014 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 "GrOptDrawState.h"
9
joshualitt4973d9d2014-11-08 09:24:25 -080010#include "GrDefaultGeoProcFactory.h"
egdaniel3658f382014-09-15 07:01:59 -070011#include "GrDrawState.h"
egdanielc0648242014-09-22 13:17:02 -070012#include "GrDrawTargetCaps.h"
joshualitt4973d9d2014-11-08 09:24:25 -080013#include "GrGpu.h"
egdaniel3658f382014-09-15 07:01:59 -070014
egdaniel170f90b2014-09-16 12:54:40 -070015GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
16 BlendOptFlags blendOptFlags,
17 GrBlendCoeff optSrcCoeff,
egdanielc0648242014-09-22 13:17:02 -070018 GrBlendCoeff optDstCoeff,
joshualitt79f8fae2014-10-28 17:59:26 -070019 GrGpu* gpu,
20 const GrDeviceCoordTexture* dstCopy,
21 GrGpu::DrawType drawType) {
bsalomonbcf0a522014-10-08 08:40:09 -070022 fRenderTarget.set(SkSafeRef(drawState.getRenderTarget()), kWrite_GrIOType);
egdaniel3658f382014-09-15 07:01:59 -070023 fColor = drawState.getColor();
24 fCoverage = drawState.getCoverage();
25 fViewMatrix = drawState.getViewMatrix();
26 fBlendConstant = drawState.getBlendConstant();
27 fFlagBits = drawState.getFlagBits();
28 fVAPtr = drawState.getVertexAttribs();
29 fVACount = drawState.getVertexAttribCount();
30 fVAStride = drawState.getVertexStride();
31 fStencilSettings = drawState.getStencil();
egdaniel89af44a2014-09-26 06:15:04 -070032 fDrawFace = (DrawFace)drawState.getDrawFace();
egdaniel170f90b2014-09-16 12:54:40 -070033 fBlendOptFlags = blendOptFlags;
34 fSrcBlend = optSrcCoeff;
35 fDstBlend = optDstCoeff;
joshualitt79f8fae2014-10-28 17:59:26 -070036 GrProgramDesc::DescInfo descInfo;
egdaniel3658f382014-09-15 07:01:59 -070037
joshualitt79f8fae2014-10-28 17:59:26 -070038 memcpy(descInfo.fFixedFunctionVertexAttribIndices,
egdaniel89af44a2014-09-26 06:15:04 -070039 drawState.getFixedFunctionVertexAttribIndices(),
joshualitt79f8fae2014-10-28 17:59:26 -070040 sizeof(descInfo.fFixedFunctionVertexAttribIndices));
egdaniel3658f382014-09-15 07:01:59 -070041
joshualitt79f8fae2014-10-28 17:59:26 -070042 descInfo.fInputColorIsUsed = true;
43 descInfo.fInputCoverageIsUsed = true;
egdaniel3658f382014-09-15 07:01:59 -070044
egdaniel9cf45bf2014-10-08 06:49:10 -070045 int firstColorStageIdx = 0;
46 int firstCoverageStageIdx = 0;
47 bool separateCoverageFromColor;
48
49 uint8_t fixedFunctionVAToRemove = 0;
50
joshualitt79f8fae2014-10-28 17:59:26 -070051 this->computeEffectiveColorStages(drawState, &descInfo, &firstColorStageIdx,
52 &fixedFunctionVAToRemove);
53 this->computeEffectiveCoverageStages(drawState, &descInfo, &firstCoverageStageIdx);
54 this->adjustFromBlendOpts(drawState, &descInfo, &firstColorStageIdx, &firstCoverageStageIdx,
egdaniel9cf45bf2014-10-08 06:49:10 -070055 &fixedFunctionVAToRemove);
56 // Should not be setting any more FFVA to be removed at this point
egdanielc0651c12014-10-21 07:47:10 -070057 if (0 != fixedFunctionVAToRemove) {
joshualitt79f8fae2014-10-28 17:59:26 -070058 this->removeFixedFunctionVertexAttribs(fixedFunctionVAToRemove, &descInfo);
egdanielc0651c12014-10-21 07:47:10 -070059 }
joshualitt79f8fae2014-10-28 17:59:26 -070060 this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx, &descInfo);
61 this->setOutputStateInfo(drawState, *gpu->caps(), firstCoverageStageIdx, &descInfo,
62 &separateCoverageFromColor);
egdaniel9cf45bf2014-10-08 06:49:10 -070063
64 // Copy GeometryProcesssor from DS or ODS
egdaniel3658f382014-09-15 07:01:59 -070065 if (drawState.hasGeometryProcessor()) {
joshualitta5305a12014-10-10 17:47:00 -070066 fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
joshualitt4973d9d2014-11-08 09:24:25 -080067 } else if (!GrGpu::IsPathRenderingDrawType(drawType)) {
68 // Install default GP, this will be ignored if we are rendering with fragment shader only
69 // TODO(joshualitt) rendering code should do this
70 fGeometryProcessor.reset(GrDefaultGeoProcFactory::Create());
egdaniel3658f382014-09-15 07:01:59 -070071 } else {
72 fGeometryProcessor.reset(NULL);
73 }
74
egdaniel9cf45bf2014-10-08 06:49:10 -070075 // Copy Color Stages from DS to ODS
76 if (firstColorStageIdx < drawState.numColorStages()) {
egdanield9aa2182014-10-09 13:47:05 -070077 fFragmentStages.reset(&drawState.getColorStage(firstColorStageIdx),
78 drawState.numColorStages() - firstColorStageIdx);
egdaniel9cf45bf2014-10-08 06:49:10 -070079 } else {
egdanield9aa2182014-10-09 13:47:05 -070080 fFragmentStages.reset();
egdaniel9cf45bf2014-10-08 06:49:10 -070081 }
82
egdanield9aa2182014-10-09 13:47:05 -070083 fNumColorStages = fFragmentStages.count();
84
egdaniel9cf45bf2014-10-08 06:49:10 -070085 // Copy Coverage Stages from DS to ODS
egdanield9aa2182014-10-09 13:47:05 -070086 if (firstCoverageStageIdx < drawState.numCoverageStages()) {
87 fFragmentStages.push_back_n(drawState.numCoverageStages() - firstCoverageStageIdx,
88 &drawState.getCoverageStage(firstCoverageStageIdx));
89 if (!separateCoverageFromColor) {
90 fNumColorStages = fFragmentStages.count();
egdaniel9cf45bf2014-10-08 06:49:10 -070091 }
92 }
joshualitt79f8fae2014-10-28 17:59:26 -070093
94 // now create a key
95 gpu->buildProgramDesc(*this, descInfo, drawType, dstCopy, &fDesc);
egdaniel3658f382014-09-15 07:01:59 -070096};
97
joshualitt79f8fae2014-10-28 17:59:26 -070098GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState,
99 GrGpu* gpu,
100 const GrDeviceCoordTexture* dstCopy,
egdanielb109ac22014-10-07 06:45:44 -0700101 GrGpu::DrawType drawType) {
egdaniel69bb90c2014-11-11 07:32:45 -0800102 GrBlendCoeff srcCoeff;
103 GrBlendCoeff dstCoeff;
104 BlendOptFlags blendFlags = (BlendOptFlags) drawState.getBlendOpts(false,
105 &srcCoeff,
106 &dstCoeff);
egdanielb109ac22014-10-07 06:45:44 -0700107
egdaniel69bb90c2014-11-11 07:32:45 -0800108 // If our blend coeffs are set to 0,1 we know we will not end up drawing unless we are
109 // stenciling. When path rendering the stencil settings are not always set on the draw state
110 // so we must check the draw type. In cases where we will skip drawing we simply return a
111 // null GrOptDrawState.
112 if (kZero_GrBlendCoeff == srcCoeff && kOne_GrBlendCoeff == dstCoeff &&
113 !drawState.getStencil().doesWrite() && GrGpu::kStencilPath_DrawType != drawType) {
114 return NULL;
egdanielb109ac22014-10-07 06:45:44 -0700115 }
egdaniel69bb90c2014-11-11 07:32:45 -0800116
117 return SkNEW_ARGS(GrOptDrawState, (drawState, blendFlags, srcCoeff,
118 dstCoeff, gpu, dstCopy, drawType));
egdanielb109ac22014-10-07 06:45:44 -0700119}
120
egdaniel9cf45bf2014-10-08 06:49:10 -0700121void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds,
122 const GrDrawTargetCaps& caps,
123 int firstCoverageStageIdx,
joshualitt79f8fae2014-10-28 17:59:26 -0700124 GrProgramDesc::DescInfo* descInfo,
egdaniel9cf45bf2014-10-08 06:49:10 -0700125 bool* separateCoverageFromColor) {
egdanielc0648242014-09-22 13:17:02 -0700126 // Set this default and then possibly change our mind if there is coverage.
joshualitt79f8fae2014-10-28 17:59:26 -0700127 descInfo->fPrimaryOutputType = GrProgramDesc::kModulate_PrimaryOutputType;
128 descInfo->fSecondaryOutputType = GrProgramDesc::kNone_SecondaryOutputType;
egdanielc0648242014-09-22 13:17:02 -0700129
130 // If we do have coverage determine whether it matters.
egdaniel9cf45bf2014-10-08 06:49:10 -0700131 *separateCoverageFromColor = this->hasGeometryProcessor();
egdanielc0648242014-09-22 13:17:02 -0700132 if (!this->isCoverageDrawing() &&
egdaniel9cf45bf2014-10-08 06:49:10 -0700133 (ds.numCoverageStages() - firstCoverageStageIdx > 0 ||
134 ds.hasGeometryProcessor() ||
joshualitt79f8fae2014-10-28 17:59:26 -0700135 descInfo->hasCoverageVertexAttribute())) {
egdanielc0648242014-09-22 13:17:02 -0700136
137 if (caps.dualSourceBlendingSupport()) {
138 if (kZero_GrBlendCoeff == fDstBlend) {
139 // write the coverage value to second color
joshualitt79f8fae2014-10-28 17:59:26 -0700140 descInfo->fSecondaryOutputType = GrProgramDesc::kCoverage_SecondaryOutputType;
egdaniel9cf45bf2014-10-08 06:49:10 -0700141 *separateCoverageFromColor = true;
egdanielc0648242014-09-22 13:17:02 -0700142 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
143 } else if (kSA_GrBlendCoeff == fDstBlend) {
144 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
joshualitt79f8fae2014-10-28 17:59:26 -0700145 descInfo->fSecondaryOutputType = GrProgramDesc::kCoverageISA_SecondaryOutputType;
egdaniel9cf45bf2014-10-08 06:49:10 -0700146 *separateCoverageFromColor = true;
egdanielc0648242014-09-22 13:17:02 -0700147 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
148 } else if (kSC_GrBlendCoeff == fDstBlend) {
149 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
joshualitt79f8fae2014-10-28 17:59:26 -0700150 descInfo->fSecondaryOutputType = GrProgramDesc::kCoverageISC_SecondaryOutputType;
egdaniel9cf45bf2014-10-08 06:49:10 -0700151 *separateCoverageFromColor = true;
egdanielc0648242014-09-22 13:17:02 -0700152 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
153 }
joshualitt79f8fae2014-10-28 17:59:26 -0700154 } else if (descInfo->fReadsDst &&
egdanielc0648242014-09-22 13:17:02 -0700155 kOne_GrBlendCoeff == fSrcBlend &&
156 kZero_GrBlendCoeff == fDstBlend) {
joshualitt79f8fae2014-10-28 17:59:26 -0700157 descInfo->fPrimaryOutputType = GrProgramDesc::kCombineWithDst_PrimaryOutputType;
egdaniel9cf45bf2014-10-08 06:49:10 -0700158 *separateCoverageFromColor = true;
egdanielc0648242014-09-22 13:17:02 -0700159 }
160 }
egdanielc0648242014-09-22 13:17:02 -0700161}
162
egdaniel9cf45bf2014-10-08 06:49:10 -0700163void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds,
joshualitt79f8fae2014-10-28 17:59:26 -0700164 GrProgramDesc::DescInfo* descInfo,
egdaniel9cf45bf2014-10-08 06:49:10 -0700165 int* firstColorStageIdx,
166 int* firstCoverageStageIdx,
167 uint8_t* fixedFunctionVAToRemove) {
egdaniel170f90b2014-09-16 12:54:40 -0700168 switch (fBlendOptFlags) {
169 case kNone_BlendOpt:
170 case kSkipDraw_BlendOptFlag:
171 break;
172 case kCoverageAsAlpha_BlendOptFlag:
173 fFlagBits |= kCoverageDrawing_StateBit;
174 break;
175 case kEmitCoverage_BlendOptFlag:
176 fColor = 0xffffffff;
joshualitt79f8fae2014-10-28 17:59:26 -0700177 descInfo->fInputColorIsUsed = true;
egdaniel9cf45bf2014-10-08 06:49:10 -0700178 *firstColorStageIdx = ds.numColorStages();
179 *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
egdaniel170f90b2014-09-16 12:54:40 -0700180 break;
181 case kEmitTransBlack_BlendOptFlag:
182 fColor = 0;
183 fCoverage = 0xff;
joshualitt79f8fae2014-10-28 17:59:26 -0700184 descInfo->fInputColorIsUsed = true;
185 descInfo->fInputCoverageIsUsed = true;
egdaniel9cf45bf2014-10-08 06:49:10 -0700186 *firstColorStageIdx = ds.numColorStages();
187 *firstCoverageStageIdx = ds.numCoverageStages();
188 *fixedFunctionVAToRemove |= (0x1 << kColor_GrVertexAttribBinding |
189 0x1 << kCoverage_GrVertexAttribBinding);
egdaniel170f90b2014-09-16 12:54:40 -0700190 break;
191 default:
192 SkFAIL("Unknown BlendOptFlag");
egdaniel170f90b2014-09-16 12:54:40 -0700193 }
194}
195
joshualitt79f8fae2014-10-28 17:59:26 -0700196void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag,
197 GrProgramDesc::DescInfo* descInfo) {
egdaniel3658f382014-09-15 07:01:59 -0700198 int numToRemove = 0;
199 uint8_t maskCheck = 0x1;
200 // Count the number of vertex attributes that we will actually remove
201 for (int i = 0; i < kGrFixedFunctionVertexAttribBindingCnt; ++i) {
joshualitt79f8fae2014-10-28 17:59:26 -0700202 if ((maskCheck & removeVAFlag) && -1 != descInfo->fFixedFunctionVertexAttribIndices[i]) {
egdaniel3658f382014-09-15 07:01:59 -0700203 ++numToRemove;
204 }
205 maskCheck <<= 1;
206 }
egdaniel170f90b2014-09-16 12:54:40 -0700207
egdaniel3658f382014-09-15 07:01:59 -0700208 fOptVA.reset(fVACount - numToRemove);
209
210 GrVertexAttrib* dst = fOptVA.get();
211 const GrVertexAttrib* src = fVAPtr;
212
213 for (int i = 0, newIdx = 0; i < fVACount; ++i, ++src) {
214 const GrVertexAttrib& currAttrib = *src;
215 if (currAttrib.fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
216 uint8_t maskCheck = 0x1 << currAttrib.fBinding;
217 if (maskCheck & removeVAFlag) {
joshualitt79f8fae2014-10-28 17:59:26 -0700218 SkASSERT(-1 != descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding]);
219 descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
egdaniel3658f382014-09-15 07:01:59 -0700220 continue;
221 }
joshualitt79f8fae2014-10-28 17:59:26 -0700222 descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
egdaniel3658f382014-09-15 07:01:59 -0700223 }
224 memcpy(dst, src, sizeof(GrVertexAttrib));
egdaniel3658f382014-09-15 07:01:59 -0700225 ++newIdx;
226 ++dst;
227 }
228 fVACount -= numToRemove;
229 fVAPtr = fOptVA.get();
230}
231
joshualitt79f8fae2014-10-28 17:59:26 -0700232void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds,
233 GrProgramDesc::DescInfo* descInfo,
234 int* firstColorStageIdx,
egdaniel9cf45bf2014-10-08 06:49:10 -0700235 uint8_t* fixedFunctionVAToRemove) {
egdaniel3658f382014-09-15 07:01:59 -0700236 // Set up color and flags for ConstantColorComponent checks
egdaniel1a8ecdf2014-10-03 06:24:12 -0700237 GrProcessor::InvariantOutput inout;
238 inout.fIsSingleComponent = false;
joshualitt79f8fae2014-10-28 17:59:26 -0700239 if (!descInfo->hasColorVertexAttribute()) {
egdaniel1a8ecdf2014-10-03 06:24:12 -0700240 inout.fColor = ds.getColor();
241 inout.fValidFlags = kRGBA_GrColorComponentFlags;
egdaniel3658f382014-09-15 07:01:59 -0700242 } else {
243 if (ds.vertexColorsAreOpaque()) {
egdaniel1a8ecdf2014-10-03 06:24:12 -0700244 inout.fColor = 0xFF << GrColor_SHIFT_A;
245 inout.fValidFlags = kA_GrColorComponentFlag;
egdaniel3658f382014-09-15 07:01:59 -0700246 } else {
egdaniel1a8ecdf2014-10-03 06:24:12 -0700247 inout.fValidFlags = 0;
248 // not strictly necessary but we get false alarms from tools about uninit.
249 inout.fColor = 0;
egdaniel3658f382014-09-15 07:01:59 -0700250 }
251 }
252
253 for (int i = 0; i < ds.numColorStages(); ++i) {
joshualitt47bb3822014-10-07 16:43:25 -0700254 const GrFragmentProcessor* fp = ds.getColorStage(i).getProcessor();
egdaniel9e4d6d12014-10-15 13:49:02 -0700255 fp->computeInvariantOutput(&inout);
256 if (!inout.fWillUseInputColor) {
egdaniel9cf45bf2014-10-08 06:49:10 -0700257 *firstColorStageIdx = i;
joshualitt79f8fae2014-10-28 17:59:26 -0700258 descInfo->fInputColorIsUsed = false;
egdaniel3658f382014-09-15 07:01:59 -0700259 }
egdaniel1a8ecdf2014-10-03 06:24:12 -0700260 if (kRGBA_GrColorComponentFlags == inout.fValidFlags) {
egdaniel9cf45bf2014-10-08 06:49:10 -0700261 *firstColorStageIdx = i + 1;
egdaniel1a8ecdf2014-10-03 06:24:12 -0700262 fColor = inout.fColor;
joshualitt79f8fae2014-10-28 17:59:26 -0700263 descInfo->fInputColorIsUsed = true;
egdaniel9cf45bf2014-10-08 06:49:10 -0700264 *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
egdaniel9e4d6d12014-10-15 13:49:02 -0700265 // Since we are clearing all previous color stages we are in a state where we have found
266 // zero stages that don't multiply the inputColor.
267 inout.fNonMulStageFound = false;
egdaniel3658f382014-09-15 07:01:59 -0700268 }
269 }
egdaniel3658f382014-09-15 07:01:59 -0700270}
271
egdaniel9cf45bf2014-10-08 06:49:10 -0700272void GrOptDrawState::computeEffectiveCoverageStages(const GrDrawState& ds,
joshualitt79f8fae2014-10-28 17:59:26 -0700273 GrProgramDesc::DescInfo* descInfo,
egdaniel9cf45bf2014-10-08 06:49:10 -0700274 int* firstCoverageStageIdx) {
egdaniel3658f382014-09-15 07:01:59 -0700275 // We do not try to optimize out constantColor coverage effects here. It is extremely rare
276 // to have a coverage effect that returns a constant value for all four channels. Thus we
277 // save having to make extra virtual calls by not checking for it.
278
279 // Don't do any optimizations on coverage stages. It should not be the case where we do not use
280 // input coverage in an effect
281#ifdef OptCoverageStages
egdaniel9e4d6d12014-10-15 13:49:02 -0700282 GrProcessor::InvariantOutput inout;
egdaniel3658f382014-09-15 07:01:59 -0700283 for (int i = 0; i < ds.numCoverageStages(); ++i) {
egdaniel9e4d6d12014-10-15 13:49:02 -0700284 const GrFragmentProcessor* fp = ds.getCoverageStage(i).getProcessor();
285 fp->computeInvariantOutput(&inout);
286 if (!inout.fWillUseInputColor) {
egdaniel9cf45bf2014-10-08 06:49:10 -0700287 *firstCoverageStageIdx = i;
joshualitt79f8fae2014-10-28 17:59:26 -0700288 descInfo->fInputCoverageIsUsed = false;
egdaniel3658f382014-09-15 07:01:59 -0700289 }
290 }
291#endif
egdaniel3658f382014-09-15 07:01:59 -0700292}
293
joshualittb0a8a372014-09-23 09:50:21 -0700294static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool* readsFragPosition) {
joshualitt47bb3822014-10-07 16:43:25 -0700295 if (stage.getProcessor()->willReadDstColor()) {
egdaniela7dc0a82014-09-17 08:25:05 -0700296 *readsDst = true;
297 }
joshualitt47bb3822014-10-07 16:43:25 -0700298 if (stage.getProcessor()->willReadFragmentPosition()) {
egdaniela7dc0a82014-09-17 08:25:05 -0700299 *readsFragPosition = true;
300 }
301}
joshualittb0a8a372014-09-23 09:50:21 -0700302
egdaniel9cf45bf2014-10-08 06:49:10 -0700303void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx,
joshualitt79f8fae2014-10-28 17:59:26 -0700304 int firstCoverageStageIdx, GrProgramDesc::DescInfo* descInfo) {
egdaniela7dc0a82014-09-17 08:25:05 -0700305 // We will need a local coord attrib if there is one currently set on the optState and we are
306 // actually generating some effect code
joshualitt79f8fae2014-10-28 17:59:26 -0700307 descInfo->fRequiresLocalCoordAttrib = descInfo->hasLocalCoordAttribute() &&
egdaniel9cf45bf2014-10-08 06:49:10 -0700308 ds.numTotalStages() - firstColorStageIdx - firstCoverageStageIdx > 0;
egdaniela7dc0a82014-09-17 08:25:05 -0700309
joshualitt79f8fae2014-10-28 17:59:26 -0700310 descInfo->fReadsDst = false;
311 descInfo->fReadsFragPosition = false;
egdaniela7dc0a82014-09-17 08:25:05 -0700312
egdaniel9cf45bf2014-10-08 06:49:10 -0700313 for (int s = firstColorStageIdx; s < ds.numColorStages(); ++s) {
314 const GrFragmentStage& stage = ds.getColorStage(s);
joshualitt79f8fae2014-10-28 17:59:26 -0700315 get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPosition);
egdaniela7dc0a82014-09-17 08:25:05 -0700316 }
egdaniel9cf45bf2014-10-08 06:49:10 -0700317 for (int s = firstCoverageStageIdx; s < ds.numCoverageStages(); ++s) {
318 const GrFragmentStage& stage = ds.getCoverageStage(s);
joshualitt79f8fae2014-10-28 17:59:26 -0700319 get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPosition);
egdaniela7dc0a82014-09-17 08:25:05 -0700320 }
egdaniel9cf45bf2014-10-08 06:49:10 -0700321 if (ds.hasGeometryProcessor()) {
joshualitta5305a12014-10-10 17:47:00 -0700322 const GrGeometryProcessor& gp = *ds.getGeometryProcessor();
joshualitt79f8fae2014-10-28 17:59:26 -0700323 descInfo->fReadsFragPosition = descInfo->fReadsFragPosition || gp.willReadFragmentPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700324 }
325}
326
egdaniel89af44a2014-09-26 06:15:04 -0700327////////////////////////////////////////////////////////////////////////////////
328
egdaniel3658f382014-09-15 07:01:59 -0700329bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
330 return this->isEqual(that);
331}
332
egdaniel89af44a2014-09-26 06:15:04 -0700333bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
joshualitt79f8fae2014-10-28 17:59:26 -0700334 if (this->fDesc != that.fDesc) {
335 return false;
336 }
337 bool usingVertexColors = that.fDesc.header().fColorAttributeIndex != -1;
egdaniel89af44a2014-09-26 06:15:04 -0700338 if (!usingVertexColors && this->fColor != that.fColor) {
339 return false;
340 }
341
342 if (this->getRenderTarget() != that.getRenderTarget() ||
egdaniel89af44a2014-09-26 06:15:04 -0700343 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
344 this->fSrcBlend != that.fSrcBlend ||
345 this->fDstBlend != that.fDstBlend ||
346 this->fBlendConstant != that.fBlendConstant ||
347 this->fFlagBits != that.fFlagBits ||
348 this->fVACount != that.fVACount ||
349 this->fVAStride != that.fVAStride ||
350 memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib)) ||
351 this->fStencilSettings != that.fStencilSettings ||
joshualitt79f8fae2014-10-28 17:59:26 -0700352 this->fDrawFace != that.fDrawFace) {
egdaniel89af44a2014-09-26 06:15:04 -0700353 return false;
354 }
355
joshualitt79f8fae2014-10-28 17:59:26 -0700356 bool usingVertexCoverage = this->fDesc.header().fCoverageAttributeIndex != -1;
egdaniel89af44a2014-09-26 06:15:04 -0700357 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
358 return false;
359 }
360
egdaniel89af44a2014-09-26 06:15:04 -0700361 if (this->hasGeometryProcessor()) {
362 if (!that.hasGeometryProcessor()) {
363 return false;
joshualitta5305a12014-10-10 17:47:00 -0700364 } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
egdaniel89af44a2014-09-26 06:15:04 -0700365 return false;
366 }
367 } else if (that.hasGeometryProcessor()) {
368 return false;
369 }
370
joshualitt79f8fae2014-10-28 17:59:26 -0700371 bool explicitLocalCoords = this->fDesc.header().fLocalCoordAttributeIndex != -1;
egdanield9aa2182014-10-09 13:47:05 -0700372 for (int i = 0; i < this->numFragmentStages(); i++) {
joshualitta5305a12014-10-10 17:47:00 -0700373 if (!GrFragmentStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
374 explicitLocalCoords)) {
egdaniel89af44a2014-09-26 06:15:04 -0700375 return false;
376 }
377 }
egdaniel89af44a2014-09-26 06:15:04 -0700378 return true;
379}
380