blob: 529e9ed75e9bbe5bc773de378474da442afe91d2 [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
10#include "GrDrawState.h"
egdanielc0648242014-09-22 13:17:02 -070011#include "GrDrawTargetCaps.h"
joshualitt79f8fae2014-10-28 17:59:26 -070012#include "gl/GrGpuGL.h"
egdaniel3658f382014-09-15 07:01:59 -070013
egdaniel170f90b2014-09-16 12:54:40 -070014GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
15 BlendOptFlags blendOptFlags,
16 GrBlendCoeff optSrcCoeff,
egdanielc0648242014-09-22 13:17:02 -070017 GrBlendCoeff optDstCoeff,
joshualitt79f8fae2014-10-28 17:59:26 -070018 GrGpu* gpu,
19 const GrDeviceCoordTexture* dstCopy,
20 GrGpu::DrawType drawType) {
bsalomonbcf0a522014-10-08 08:40:09 -070021 fRenderTarget.set(SkSafeRef(drawState.getRenderTarget()), kWrite_GrIOType);
egdaniel3658f382014-09-15 07:01:59 -070022 fColor = drawState.getColor();
23 fCoverage = drawState.getCoverage();
24 fViewMatrix = drawState.getViewMatrix();
25 fBlendConstant = drawState.getBlendConstant();
26 fFlagBits = drawState.getFlagBits();
27 fVAPtr = drawState.getVertexAttribs();
28 fVACount = drawState.getVertexAttribCount();
29 fVAStride = drawState.getVertexStride();
30 fStencilSettings = drawState.getStencil();
egdaniel89af44a2014-09-26 06:15:04 -070031 fDrawFace = (DrawFace)drawState.getDrawFace();
egdaniel170f90b2014-09-16 12:54:40 -070032 fBlendOptFlags = blendOptFlags;
33 fSrcBlend = optSrcCoeff;
34 fDstBlend = optDstCoeff;
joshualitt79f8fae2014-10-28 17:59:26 -070035 GrProgramDesc::DescInfo descInfo;
egdaniel3658f382014-09-15 07:01:59 -070036
joshualitt79f8fae2014-10-28 17:59:26 -070037 memcpy(descInfo.fFixedFunctionVertexAttribIndices,
egdaniel89af44a2014-09-26 06:15:04 -070038 drawState.getFixedFunctionVertexAttribIndices(),
joshualitt79f8fae2014-10-28 17:59:26 -070039 sizeof(descInfo.fFixedFunctionVertexAttribIndices));
egdaniel3658f382014-09-15 07:01:59 -070040
joshualitt79f8fae2014-10-28 17:59:26 -070041 descInfo.fInputColorIsUsed = true;
42 descInfo.fInputCoverageIsUsed = true;
egdaniel3658f382014-09-15 07:01:59 -070043
egdaniel9cf45bf2014-10-08 06:49:10 -070044 int firstColorStageIdx = 0;
45 int firstCoverageStageIdx = 0;
46 bool separateCoverageFromColor;
47
48 uint8_t fixedFunctionVAToRemove = 0;
49
joshualitt79f8fae2014-10-28 17:59:26 -070050 this->computeEffectiveColorStages(drawState, &descInfo, &firstColorStageIdx,
51 &fixedFunctionVAToRemove);
52 this->computeEffectiveCoverageStages(drawState, &descInfo, &firstCoverageStageIdx);
53 this->adjustFromBlendOpts(drawState, &descInfo, &firstColorStageIdx, &firstCoverageStageIdx,
egdaniel9cf45bf2014-10-08 06:49:10 -070054 &fixedFunctionVAToRemove);
55 // Should not be setting any more FFVA to be removed at this point
egdanielc0651c12014-10-21 07:47:10 -070056 if (0 != fixedFunctionVAToRemove) {
joshualitt79f8fae2014-10-28 17:59:26 -070057 this->removeFixedFunctionVertexAttribs(fixedFunctionVAToRemove, &descInfo);
egdanielc0651c12014-10-21 07:47:10 -070058 }
joshualitt79f8fae2014-10-28 17:59:26 -070059 this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx, &descInfo);
60 this->setOutputStateInfo(drawState, *gpu->caps(), firstCoverageStageIdx, &descInfo,
61 &separateCoverageFromColor);
egdaniel9cf45bf2014-10-08 06:49:10 -070062
63 // Copy GeometryProcesssor from DS or ODS
egdaniel3658f382014-09-15 07:01:59 -070064 if (drawState.hasGeometryProcessor()) {
joshualitta5305a12014-10-10 17:47:00 -070065 fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
egdaniel3658f382014-09-15 07:01:59 -070066 } else {
67 fGeometryProcessor.reset(NULL);
68 }
69
egdaniel9cf45bf2014-10-08 06:49:10 -070070 // Copy Color Stages from DS to ODS
71 if (firstColorStageIdx < drawState.numColorStages()) {
egdanield9aa2182014-10-09 13:47:05 -070072 fFragmentStages.reset(&drawState.getColorStage(firstColorStageIdx),
73 drawState.numColorStages() - firstColorStageIdx);
egdaniel9cf45bf2014-10-08 06:49:10 -070074 } else {
egdanield9aa2182014-10-09 13:47:05 -070075 fFragmentStages.reset();
egdaniel9cf45bf2014-10-08 06:49:10 -070076 }
77
egdanield9aa2182014-10-09 13:47:05 -070078 fNumColorStages = fFragmentStages.count();
79
egdaniel9cf45bf2014-10-08 06:49:10 -070080 // Copy Coverage Stages from DS to ODS
egdanield9aa2182014-10-09 13:47:05 -070081 if (firstCoverageStageIdx < drawState.numCoverageStages()) {
82 fFragmentStages.push_back_n(drawState.numCoverageStages() - firstCoverageStageIdx,
83 &drawState.getCoverageStage(firstCoverageStageIdx));
84 if (!separateCoverageFromColor) {
85 fNumColorStages = fFragmentStages.count();
egdaniel9cf45bf2014-10-08 06:49:10 -070086 }
87 }
joshualitt79f8fae2014-10-28 17:59:26 -070088
89 // now create a key
90 gpu->buildProgramDesc(*this, descInfo, drawType, dstCopy, &fDesc);
egdaniel3658f382014-09-15 07:01:59 -070091};
92
joshualitt79f8fae2014-10-28 17:59:26 -070093GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState,
94 GrGpu* gpu,
95 const GrDeviceCoordTexture* dstCopy,
egdanielb109ac22014-10-07 06:45:44 -070096 GrGpu::DrawType drawType) {
joshualitt79f8fae2014-10-28 17:59:26 -070097 const GrDrawTargetCaps& caps = *gpu->caps();
egdanielb109ac22014-10-07 06:45:44 -070098 if (NULL == drawState.fCachedOptState || caps.getUniqueID() != drawState.fCachedCapsID) {
99 GrBlendCoeff srcCoeff;
100 GrBlendCoeff dstCoeff;
101 BlendOptFlags blendFlags = (BlendOptFlags) drawState.getBlendOpts(false,
102 &srcCoeff,
103 &dstCoeff);
104
105 // If our blend coeffs are set to 0,1 we know we will not end up drawing unless we are
106 // stenciling. When path rendering the stencil settings are not always set on the draw state
107 // so we must check the draw type. In cases where we will skip drawing we simply return a
108 // null GrOptDrawState.
109 if (kZero_GrBlendCoeff == srcCoeff && kOne_GrBlendCoeff == dstCoeff &&
110 !drawState.getStencil().doesWrite() && GrGpu::kStencilPath_DrawType != drawType) {
111 return NULL;
112 }
113
114 drawState.fCachedOptState = SkNEW_ARGS(GrOptDrawState, (drawState, blendFlags, srcCoeff,
joshualitt79f8fae2014-10-28 17:59:26 -0700115 dstCoeff, gpu, dstCopy, drawType));
egdanielb109ac22014-10-07 06:45:44 -0700116 drawState.fCachedCapsID = caps.getUniqueID();
117 } else {
118#ifdef SK_DEBUG
119 GrBlendCoeff srcCoeff;
120 GrBlendCoeff dstCoeff;
121 BlendOptFlags blendFlags = (BlendOptFlags) drawState.getBlendOpts(false,
122 &srcCoeff,
123 &dstCoeff);
joshualitt79f8fae2014-10-28 17:59:26 -0700124 SkASSERT(GrOptDrawState(drawState, blendFlags, srcCoeff, dstCoeff, gpu, dstCopy,
125 drawType) == *drawState.fCachedOptState);
egdanielb109ac22014-10-07 06:45:44 -0700126#endif
127 }
128 drawState.fCachedOptState->ref();
129 return drawState.fCachedOptState;
130}
131
egdaniel9cf45bf2014-10-08 06:49:10 -0700132void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds,
133 const GrDrawTargetCaps& caps,
134 int firstCoverageStageIdx,
joshualitt79f8fae2014-10-28 17:59:26 -0700135 GrProgramDesc::DescInfo* descInfo,
egdaniel9cf45bf2014-10-08 06:49:10 -0700136 bool* separateCoverageFromColor) {
egdanielc0648242014-09-22 13:17:02 -0700137 // Set this default and then possibly change our mind if there is coverage.
joshualitt79f8fae2014-10-28 17:59:26 -0700138 descInfo->fPrimaryOutputType = GrProgramDesc::kModulate_PrimaryOutputType;
139 descInfo->fSecondaryOutputType = GrProgramDesc::kNone_SecondaryOutputType;
egdanielc0648242014-09-22 13:17:02 -0700140
141 // If we do have coverage determine whether it matters.
egdaniel9cf45bf2014-10-08 06:49:10 -0700142 *separateCoverageFromColor = this->hasGeometryProcessor();
egdanielc0648242014-09-22 13:17:02 -0700143 if (!this->isCoverageDrawing() &&
egdaniel9cf45bf2014-10-08 06:49:10 -0700144 (ds.numCoverageStages() - firstCoverageStageIdx > 0 ||
145 ds.hasGeometryProcessor() ||
joshualitt79f8fae2014-10-28 17:59:26 -0700146 descInfo->hasCoverageVertexAttribute())) {
egdanielc0648242014-09-22 13:17:02 -0700147
148 if (caps.dualSourceBlendingSupport()) {
149 if (kZero_GrBlendCoeff == fDstBlend) {
150 // write the coverage value to second color
joshualitt79f8fae2014-10-28 17:59:26 -0700151 descInfo->fSecondaryOutputType = GrProgramDesc::kCoverage_SecondaryOutputType;
egdaniel9cf45bf2014-10-08 06:49:10 -0700152 *separateCoverageFromColor = true;
egdanielc0648242014-09-22 13:17:02 -0700153 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
154 } else if (kSA_GrBlendCoeff == fDstBlend) {
155 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
joshualitt79f8fae2014-10-28 17:59:26 -0700156 descInfo->fSecondaryOutputType = GrProgramDesc::kCoverageISA_SecondaryOutputType;
egdaniel9cf45bf2014-10-08 06:49:10 -0700157 *separateCoverageFromColor = true;
egdanielc0648242014-09-22 13:17:02 -0700158 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
159 } else if (kSC_GrBlendCoeff == fDstBlend) {
160 // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
joshualitt79f8fae2014-10-28 17:59:26 -0700161 descInfo->fSecondaryOutputType = GrProgramDesc::kCoverageISC_SecondaryOutputType;
egdaniel9cf45bf2014-10-08 06:49:10 -0700162 *separateCoverageFromColor = true;
egdanielc0648242014-09-22 13:17:02 -0700163 fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
164 }
joshualitt79f8fae2014-10-28 17:59:26 -0700165 } else if (descInfo->fReadsDst &&
egdanielc0648242014-09-22 13:17:02 -0700166 kOne_GrBlendCoeff == fSrcBlend &&
167 kZero_GrBlendCoeff == fDstBlend) {
joshualitt79f8fae2014-10-28 17:59:26 -0700168 descInfo->fPrimaryOutputType = GrProgramDesc::kCombineWithDst_PrimaryOutputType;
egdaniel9cf45bf2014-10-08 06:49:10 -0700169 *separateCoverageFromColor = true;
egdanielc0648242014-09-22 13:17:02 -0700170 }
171 }
egdanielc0648242014-09-22 13:17:02 -0700172}
173
egdaniel9cf45bf2014-10-08 06:49:10 -0700174void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds,
joshualitt79f8fae2014-10-28 17:59:26 -0700175 GrProgramDesc::DescInfo* descInfo,
egdaniel9cf45bf2014-10-08 06:49:10 -0700176 int* firstColorStageIdx,
177 int* firstCoverageStageIdx,
178 uint8_t* fixedFunctionVAToRemove) {
egdaniel170f90b2014-09-16 12:54:40 -0700179 switch (fBlendOptFlags) {
180 case kNone_BlendOpt:
181 case kSkipDraw_BlendOptFlag:
182 break;
183 case kCoverageAsAlpha_BlendOptFlag:
184 fFlagBits |= kCoverageDrawing_StateBit;
185 break;
186 case kEmitCoverage_BlendOptFlag:
187 fColor = 0xffffffff;
joshualitt79f8fae2014-10-28 17:59:26 -0700188 descInfo->fInputColorIsUsed = true;
egdaniel9cf45bf2014-10-08 06:49:10 -0700189 *firstColorStageIdx = ds.numColorStages();
190 *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
egdaniel170f90b2014-09-16 12:54:40 -0700191 break;
192 case kEmitTransBlack_BlendOptFlag:
193 fColor = 0;
194 fCoverage = 0xff;
joshualitt79f8fae2014-10-28 17:59:26 -0700195 descInfo->fInputColorIsUsed = true;
196 descInfo->fInputCoverageIsUsed = true;
egdaniel9cf45bf2014-10-08 06:49:10 -0700197 *firstColorStageIdx = ds.numColorStages();
198 *firstCoverageStageIdx = ds.numCoverageStages();
199 *fixedFunctionVAToRemove |= (0x1 << kColor_GrVertexAttribBinding |
200 0x1 << kCoverage_GrVertexAttribBinding);
egdaniel170f90b2014-09-16 12:54:40 -0700201 break;
202 default:
203 SkFAIL("Unknown BlendOptFlag");
egdaniel170f90b2014-09-16 12:54:40 -0700204 }
205}
206
joshualitt79f8fae2014-10-28 17:59:26 -0700207void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag,
208 GrProgramDesc::DescInfo* descInfo) {
egdaniel3658f382014-09-15 07:01:59 -0700209 int numToRemove = 0;
210 uint8_t maskCheck = 0x1;
211 // Count the number of vertex attributes that we will actually remove
212 for (int i = 0; i < kGrFixedFunctionVertexAttribBindingCnt; ++i) {
joshualitt79f8fae2014-10-28 17:59:26 -0700213 if ((maskCheck & removeVAFlag) && -1 != descInfo->fFixedFunctionVertexAttribIndices[i]) {
egdaniel3658f382014-09-15 07:01:59 -0700214 ++numToRemove;
215 }
216 maskCheck <<= 1;
217 }
egdaniel170f90b2014-09-16 12:54:40 -0700218
egdaniel3658f382014-09-15 07:01:59 -0700219 fOptVA.reset(fVACount - numToRemove);
220
221 GrVertexAttrib* dst = fOptVA.get();
222 const GrVertexAttrib* src = fVAPtr;
223
224 for (int i = 0, newIdx = 0; i < fVACount; ++i, ++src) {
225 const GrVertexAttrib& currAttrib = *src;
226 if (currAttrib.fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
227 uint8_t maskCheck = 0x1 << currAttrib.fBinding;
228 if (maskCheck & removeVAFlag) {
joshualitt79f8fae2014-10-28 17:59:26 -0700229 SkASSERT(-1 != descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding]);
230 descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
egdaniel3658f382014-09-15 07:01:59 -0700231 continue;
232 }
joshualitt79f8fae2014-10-28 17:59:26 -0700233 descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
egdaniel3658f382014-09-15 07:01:59 -0700234 }
235 memcpy(dst, src, sizeof(GrVertexAttrib));
egdaniel3658f382014-09-15 07:01:59 -0700236 ++newIdx;
237 ++dst;
238 }
239 fVACount -= numToRemove;
240 fVAPtr = fOptVA.get();
241}
242
joshualitt79f8fae2014-10-28 17:59:26 -0700243void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds,
244 GrProgramDesc::DescInfo* descInfo,
245 int* firstColorStageIdx,
egdaniel9cf45bf2014-10-08 06:49:10 -0700246 uint8_t* fixedFunctionVAToRemove) {
egdaniel3658f382014-09-15 07:01:59 -0700247 // Set up color and flags for ConstantColorComponent checks
egdaniel1a8ecdf2014-10-03 06:24:12 -0700248 GrProcessor::InvariantOutput inout;
249 inout.fIsSingleComponent = false;
joshualitt79f8fae2014-10-28 17:59:26 -0700250 if (!descInfo->hasColorVertexAttribute()) {
egdaniel1a8ecdf2014-10-03 06:24:12 -0700251 inout.fColor = ds.getColor();
252 inout.fValidFlags = kRGBA_GrColorComponentFlags;
egdaniel3658f382014-09-15 07:01:59 -0700253 } else {
254 if (ds.vertexColorsAreOpaque()) {
egdaniel1a8ecdf2014-10-03 06:24:12 -0700255 inout.fColor = 0xFF << GrColor_SHIFT_A;
256 inout.fValidFlags = kA_GrColorComponentFlag;
egdaniel3658f382014-09-15 07:01:59 -0700257 } else {
egdaniel1a8ecdf2014-10-03 06:24:12 -0700258 inout.fValidFlags = 0;
259 // not strictly necessary but we get false alarms from tools about uninit.
260 inout.fColor = 0;
egdaniel3658f382014-09-15 07:01:59 -0700261 }
262 }
263
264 for (int i = 0; i < ds.numColorStages(); ++i) {
joshualitt47bb3822014-10-07 16:43:25 -0700265 const GrFragmentProcessor* fp = ds.getColorStage(i).getProcessor();
egdaniel9e4d6d12014-10-15 13:49:02 -0700266 fp->computeInvariantOutput(&inout);
267 if (!inout.fWillUseInputColor) {
egdaniel9cf45bf2014-10-08 06:49:10 -0700268 *firstColorStageIdx = i;
joshualitt79f8fae2014-10-28 17:59:26 -0700269 descInfo->fInputColorIsUsed = false;
egdaniel3658f382014-09-15 07:01:59 -0700270 }
egdaniel1a8ecdf2014-10-03 06:24:12 -0700271 if (kRGBA_GrColorComponentFlags == inout.fValidFlags) {
egdaniel9cf45bf2014-10-08 06:49:10 -0700272 *firstColorStageIdx = i + 1;
egdaniel1a8ecdf2014-10-03 06:24:12 -0700273 fColor = inout.fColor;
joshualitt79f8fae2014-10-28 17:59:26 -0700274 descInfo->fInputColorIsUsed = true;
egdaniel9cf45bf2014-10-08 06:49:10 -0700275 *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
egdaniel9e4d6d12014-10-15 13:49:02 -0700276 // Since we are clearing all previous color stages we are in a state where we have found
277 // zero stages that don't multiply the inputColor.
278 inout.fNonMulStageFound = false;
egdaniel3658f382014-09-15 07:01:59 -0700279 }
280 }
egdaniel3658f382014-09-15 07:01:59 -0700281}
282
egdaniel9cf45bf2014-10-08 06:49:10 -0700283void GrOptDrawState::computeEffectiveCoverageStages(const GrDrawState& ds,
joshualitt79f8fae2014-10-28 17:59:26 -0700284 GrProgramDesc::DescInfo* descInfo,
egdaniel9cf45bf2014-10-08 06:49:10 -0700285 int* firstCoverageStageIdx) {
egdaniel3658f382014-09-15 07:01:59 -0700286 // We do not try to optimize out constantColor coverage effects here. It is extremely rare
287 // to have a coverage effect that returns a constant value for all four channels. Thus we
288 // save having to make extra virtual calls by not checking for it.
289
290 // Don't do any optimizations on coverage stages. It should not be the case where we do not use
291 // input coverage in an effect
292#ifdef OptCoverageStages
egdaniel9e4d6d12014-10-15 13:49:02 -0700293 GrProcessor::InvariantOutput inout;
egdaniel3658f382014-09-15 07:01:59 -0700294 for (int i = 0; i < ds.numCoverageStages(); ++i) {
egdaniel9e4d6d12014-10-15 13:49:02 -0700295 const GrFragmentProcessor* fp = ds.getCoverageStage(i).getProcessor();
296 fp->computeInvariantOutput(&inout);
297 if (!inout.fWillUseInputColor) {
egdaniel9cf45bf2014-10-08 06:49:10 -0700298 *firstCoverageStageIdx = i;
joshualitt79f8fae2014-10-28 17:59:26 -0700299 descInfo->fInputCoverageIsUsed = false;
egdaniel3658f382014-09-15 07:01:59 -0700300 }
301 }
302#endif
egdaniel3658f382014-09-15 07:01:59 -0700303}
304
joshualittb0a8a372014-09-23 09:50:21 -0700305static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool* readsFragPosition) {
joshualitt47bb3822014-10-07 16:43:25 -0700306 if (stage.getProcessor()->willReadDstColor()) {
egdaniela7dc0a82014-09-17 08:25:05 -0700307 *readsDst = true;
308 }
joshualitt47bb3822014-10-07 16:43:25 -0700309 if (stage.getProcessor()->willReadFragmentPosition()) {
egdaniela7dc0a82014-09-17 08:25:05 -0700310 *readsFragPosition = true;
311 }
312}
joshualittb0a8a372014-09-23 09:50:21 -0700313
egdaniel9cf45bf2014-10-08 06:49:10 -0700314void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx,
joshualitt79f8fae2014-10-28 17:59:26 -0700315 int firstCoverageStageIdx, GrProgramDesc::DescInfo* descInfo) {
egdaniela7dc0a82014-09-17 08:25:05 -0700316 // We will need a local coord attrib if there is one currently set on the optState and we are
317 // actually generating some effect code
joshualitt79f8fae2014-10-28 17:59:26 -0700318 descInfo->fRequiresLocalCoordAttrib = descInfo->hasLocalCoordAttribute() &&
egdaniel9cf45bf2014-10-08 06:49:10 -0700319 ds.numTotalStages() - firstColorStageIdx - firstCoverageStageIdx > 0;
egdaniela7dc0a82014-09-17 08:25:05 -0700320
joshualitt79f8fae2014-10-28 17:59:26 -0700321 descInfo->fReadsDst = false;
322 descInfo->fReadsFragPosition = false;
egdaniela7dc0a82014-09-17 08:25:05 -0700323
egdaniel9cf45bf2014-10-08 06:49:10 -0700324 for (int s = firstColorStageIdx; s < ds.numColorStages(); ++s) {
325 const GrFragmentStage& stage = ds.getColorStage(s);
joshualitt79f8fae2014-10-28 17:59:26 -0700326 get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPosition);
egdaniela7dc0a82014-09-17 08:25:05 -0700327 }
egdaniel9cf45bf2014-10-08 06:49:10 -0700328 for (int s = firstCoverageStageIdx; s < ds.numCoverageStages(); ++s) {
329 const GrFragmentStage& stage = ds.getCoverageStage(s);
joshualitt79f8fae2014-10-28 17:59:26 -0700330 get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPosition);
egdaniela7dc0a82014-09-17 08:25:05 -0700331 }
egdaniel9cf45bf2014-10-08 06:49:10 -0700332 if (ds.hasGeometryProcessor()) {
joshualitta5305a12014-10-10 17:47:00 -0700333 const GrGeometryProcessor& gp = *ds.getGeometryProcessor();
joshualitt79f8fae2014-10-28 17:59:26 -0700334 descInfo->fReadsFragPosition = descInfo->fReadsFragPosition || gp.willReadFragmentPosition();
egdaniela7dc0a82014-09-17 08:25:05 -0700335 }
336}
337
egdaniel89af44a2014-09-26 06:15:04 -0700338////////////////////////////////////////////////////////////////////////////////
339
egdaniel3658f382014-09-15 07:01:59 -0700340bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
341 return this->isEqual(that);
342}
343
egdaniel89af44a2014-09-26 06:15:04 -0700344bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
joshualitt79f8fae2014-10-28 17:59:26 -0700345 if (this->fDesc != that.fDesc) {
346 return false;
347 }
348 bool usingVertexColors = that.fDesc.header().fColorAttributeIndex != -1;
egdaniel89af44a2014-09-26 06:15:04 -0700349 if (!usingVertexColors && this->fColor != that.fColor) {
350 return false;
351 }
352
353 if (this->getRenderTarget() != that.getRenderTarget() ||
egdaniel89af44a2014-09-26 06:15:04 -0700354 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
355 this->fSrcBlend != that.fSrcBlend ||
356 this->fDstBlend != that.fDstBlend ||
357 this->fBlendConstant != that.fBlendConstant ||
358 this->fFlagBits != that.fFlagBits ||
359 this->fVACount != that.fVACount ||
360 this->fVAStride != that.fVAStride ||
361 memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib)) ||
362 this->fStencilSettings != that.fStencilSettings ||
joshualitt79f8fae2014-10-28 17:59:26 -0700363 this->fDrawFace != that.fDrawFace) {
egdaniel89af44a2014-09-26 06:15:04 -0700364 return false;
365 }
366
joshualitt79f8fae2014-10-28 17:59:26 -0700367 bool usingVertexCoverage = this->fDesc.header().fCoverageAttributeIndex != -1;
egdaniel89af44a2014-09-26 06:15:04 -0700368 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
369 return false;
370 }
371
egdaniel89af44a2014-09-26 06:15:04 -0700372 if (this->hasGeometryProcessor()) {
373 if (!that.hasGeometryProcessor()) {
374 return false;
joshualitta5305a12014-10-10 17:47:00 -0700375 } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
egdaniel89af44a2014-09-26 06:15:04 -0700376 return false;
377 }
378 } else if (that.hasGeometryProcessor()) {
379 return false;
380 }
381
joshualitt79f8fae2014-10-28 17:59:26 -0700382 bool explicitLocalCoords = this->fDesc.header().fLocalCoordAttributeIndex != -1;
egdanield9aa2182014-10-09 13:47:05 -0700383 for (int i = 0; i < this->numFragmentStages(); i++) {
joshualitta5305a12014-10-10 17:47:00 -0700384 if (!GrFragmentStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
385 explicitLocalCoords)) {
egdaniel89af44a2014-09-26 06:15:04 -0700386 return false;
387 }
388 }
egdaniel89af44a2014-09-26 06:15:04 -0700389 return true;
390}
391