OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrOptDrawState.h" | 8 #include "GrOptDrawState.h" |
9 | 9 |
10 #include "GrDefaultGeoProcFactory.h" | |
11 #include "GrDrawState.h" | 10 #include "GrDrawState.h" |
12 #include "GrDrawTargetCaps.h" | 11 #include "GrDrawTargetCaps.h" |
13 #include "GrGpu.h" | 12 #include "GrGpu.h" |
14 #include "GrProcOptInfo.h" | 13 #include "GrProcOptInfo.h" |
15 | 14 |
16 GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, | 15 GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, |
17 GrGpu* gpu, | 16 GrGpu* gpu, |
18 const ScissorState& scissorState, | 17 const ScissorState& scissorState, |
19 const GrDeviceCoordTexture* dstCopy, | 18 const GrDeviceCoordTexture* dstCopy, |
20 GrGpu::DrawType drawType) { | 19 GrGpu::DrawType drawType) { |
21 | 20 |
22 GrBlendCoeff optSrcCoeff; | 21 GrBlendCoeff optSrcCoeff; |
23 GrBlendCoeff optDstCoeff; | 22 GrBlendCoeff optDstCoeff; |
24 GrDrawState::BlendOpt blendOpt = drawState.getBlendOpt(false, &optSrcCoeff,
&optDstCoeff); | 23 GrDrawState::BlendOpt blendOpt = drawState.getBlendOpt(false, &optSrcCoeff,
&optDstCoeff); |
25 | 24 |
26 // When path rendering the stencil settings are not always set on the draw s
tate | 25 // When path rendering the stencil settings are not always set on the draw s
tate |
27 // so we must check the draw type. In cases where we will skip drawing we si
mply return a | 26 // so we must check the draw type. In cases where we will skip drawing we si
mply return a |
28 // null GrOptDrawState. | 27 // null GrOptDrawState. |
29 if (GrDrawState::kSkipDraw_BlendOpt == blendOpt && GrGpu::kStencilPath_DrawT
ype != drawType) { | 28 if (GrDrawState::kSkipDraw_BlendOpt == blendOpt && GrGpu::kStencilPath_DrawT
ype != drawType) { |
30 // Set the fields that don't default init and return. The lack of a rend
er target will | 29 // Set the fields that don't default init and return. The lack of a rend
er target will |
31 // indicate that this can be skipped. | 30 // indicate that this can be skipped. |
32 fFlags = 0; | 31 fFlags = 0; |
33 fVAPtr = NULL; | |
34 fVACount = 0; | |
35 fVAStride = 0; | |
36 fDrawFace = GrDrawState::kInvalid_DrawFace; | 32 fDrawFace = GrDrawState::kInvalid_DrawFace; |
37 fSrcBlend = kZero_GrBlendCoeff; | 33 fSrcBlend = kZero_GrBlendCoeff; |
38 fDstBlend = kZero_GrBlendCoeff; | 34 fDstBlend = kZero_GrBlendCoeff; |
39 fBlendConstant = 0x0; | 35 fBlendConstant = 0x0; |
40 fViewMatrix.reset(); | 36 fViewMatrix.reset(); |
41 return; | 37 return; |
42 } | 38 } |
43 | 39 |
44 fRenderTarget.reset(drawState.fRenderTarget.get()); | 40 fRenderTarget.reset(drawState.fRenderTarget.get()); |
45 SkASSERT(fRenderTarget); | 41 SkASSERT(fRenderTarget); |
46 fScissorState = scissorState; | 42 fScissorState = scissorState; |
47 fViewMatrix = drawState.getViewMatrix(); | 43 fViewMatrix = drawState.getViewMatrix(); |
48 fBlendConstant = drawState.getBlendConstant(); | 44 fBlendConstant = drawState.getBlendConstant(); |
49 fVAPtr = drawState.getVertexAttribs(); | |
50 fVACount = drawState.getVertexAttribCount(); | |
51 fVAStride = drawState.getVertexStride(); | |
52 fStencilSettings = drawState.getStencil(); | 45 fStencilSettings = drawState.getStencil(); |
53 fDrawFace = drawState.getDrawFace(); | 46 fDrawFace = drawState.getDrawFace(); |
54 fSrcBlend = optSrcCoeff; | 47 fSrcBlend = optSrcCoeff; |
55 fDstBlend = optDstCoeff; | 48 fDstBlend = optDstCoeff; |
56 | 49 |
57 // TODO move this out of optDrawState | 50 // TODO move this out of optDrawState |
58 if (dstCopy) { | 51 if (dstCopy) { |
59 fDstCopy = *dstCopy; | 52 fDstCopy = *dstCopy; |
60 } | 53 } |
61 | 54 |
62 GrProgramDesc::DescInfo descInfo; | 55 GrProgramDesc::DescInfo descInfo; |
63 | 56 |
64 fFlags = 0; | 57 fFlags = 0; |
65 if (drawState.isHWAntialias()) { | 58 if (drawState.isHWAntialias()) { |
66 fFlags |= kHWAA_Flag; | 59 fFlags |= kHWAA_Flag; |
67 } | 60 } |
68 if (drawState.isColorWriteDisabled()) { | 61 if (drawState.isColorWriteDisabled()) { |
69 fFlags |= kDisableColorWrite_Flag; | 62 fFlags |= kDisableColorWrite_Flag; |
70 } | 63 } |
71 if (drawState.isDither()) { | 64 if (drawState.isDither()) { |
72 fFlags |= kDither_Flag; | 65 fFlags |= kDither_Flag; |
73 } | 66 } |
74 | 67 |
75 memcpy(descInfo.fFixedFunctionVertexAttribIndices, | 68 descInfo.fHasVertexColor = drawState.hasGeometryProcessor() && |
76 drawState.getFixedFunctionVertexAttribIndices(), | 69 drawState.getGeometryProcessor()->hasVertexColor(
); |
77 sizeof(descInfo.fFixedFunctionVertexAttribIndices)); | |
78 | 70 |
79 uint8_t fixedFunctionVAToRemove = 0; | 71 descInfo.fHasVertexCoverage = drawState.hasGeometryProcessor() && |
| 72 drawState.getGeometryProcessor()->hasVertexCove
rage(); |
| 73 |
| 74 bool hasLocalCoords = drawState.hasGeometryProcessor() && |
| 75 drawState.getGeometryProcessor()->hasLocalCoords(); |
80 | 76 |
81 const GrProcOptInfo& colorPOI = drawState.colorProcInfo(); | 77 const GrProcOptInfo& colorPOI = drawState.colorProcInfo(); |
82 int firstColorStageIdx = colorPOI.firstEffectiveStageIndex(); | 78 int firstColorStageIdx = colorPOI.firstEffectiveStageIndex(); |
83 descInfo.fInputColorIsUsed = colorPOI.inputColorIsUsed(); | 79 descInfo.fInputColorIsUsed = colorPOI.inputColorIsUsed(); |
84 fColor = colorPOI.inputColorToEffectiveStage(); | 80 fColor = colorPOI.inputColorToEffectiveStage(); |
85 if (colorPOI.removeVertexAttrib()) { | 81 if (colorPOI.removeVertexAttrib()) { |
86 fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding; | 82 descInfo.fHasVertexColor = false; |
87 } | 83 } |
88 | 84 |
89 // TODO: Once we can handle single or four channel input into coverage stage
s then we can use | 85 // TODO: Once we can handle single or four channel input into coverage stage
s then we can use |
90 // drawState's coverageProcInfo (like color above) to set this initial infor
mation. | 86 // drawState's coverageProcInfo (like color above) to set this initial infor
mation. |
91 int firstCoverageStageIdx = 0; | 87 int firstCoverageStageIdx = 0; |
92 descInfo.fInputCoverageIsUsed = true; | 88 descInfo.fInputCoverageIsUsed = true; |
93 fCoverage = drawState.getCoverage(); | 89 fCoverage = drawState.getCoverage(); |
94 | 90 |
95 this->adjustProgramForBlendOpt(drawState, blendOpt, &descInfo, &firstColorSt
ageIdx, | 91 this->adjustProgramForBlendOpt(drawState, blendOpt, &descInfo, &firstColorSt
ageIdx, |
96 &firstCoverageStageIdx, &fixedFunctionVAToRem
ove); | 92 &firstCoverageStageIdx); |
97 // Should not be setting any more FFVA to be removed at this point | 93 |
98 if (0 != fixedFunctionVAToRemove) { | 94 this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx, ha
sLocalCoords, |
99 this->removeFixedFunctionVertexAttribs(fixedFunctionVAToRemove, &descInf
o); | 95 &descInfo); |
100 } | |
101 this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx, &d
escInfo); | |
102 | 96 |
103 // Copy GeometryProcesssor from DS or ODS | 97 // Copy GeometryProcesssor from DS or ODS |
104 SkASSERT(GrGpu::IsPathRenderingDrawType(drawType) || | 98 SkASSERT(GrGpu::IsPathRenderingDrawType(drawType) || |
105 GrGpu::kStencilPath_DrawType || | 99 GrGpu::kStencilPath_DrawType || |
106 drawState.hasGeometryProcessor()); | 100 drawState.hasGeometryProcessor()); |
107 fGeometryProcessor.reset(drawState.getGeometryProcessor()); | 101 fGeometryProcessor.reset(drawState.getGeometryProcessor()); |
108 | 102 |
109 // Copy Stages from DS to ODS | 103 // Copy Stages from DS to ODS |
110 bool explicitLocalCoords = descInfo.hasLocalCoordAttribute(); | |
111 | |
112 for (int i = firstColorStageIdx; i < drawState.numColorStages(); ++i) { | 104 for (int i = firstColorStageIdx; i < drawState.numColorStages(); ++i) { |
113 SkNEW_APPEND_TO_TARRAY(&fFragmentStages, | 105 SkNEW_APPEND_TO_TARRAY(&fFragmentStages, |
114 GrPendingFragmentStage, | 106 GrPendingFragmentStage, |
115 (drawState.fColorStages[i], explicitLocalCoords))
; | 107 (drawState.fColorStages[i], hasLocalCoords)); |
116 } | 108 } |
117 fNumColorStages = fFragmentStages.count(); | 109 fNumColorStages = fFragmentStages.count(); |
118 for (int i = firstCoverageStageIdx; i < drawState.numCoverageStages(); ++i)
{ | 110 for (int i = firstCoverageStageIdx; i < drawState.numCoverageStages(); ++i)
{ |
119 SkNEW_APPEND_TO_TARRAY(&fFragmentStages, | 111 SkNEW_APPEND_TO_TARRAY(&fFragmentStages, |
120 GrPendingFragmentStage, | 112 GrPendingFragmentStage, |
121 (drawState.fCoverageStages[i], explicitLocalCoord
s)); | 113 (drawState.fCoverageStages[i], hasLocalCoords)); |
122 } | 114 } |
123 | 115 |
124 this->setOutputStateInfo(drawState, blendOpt, *gpu->caps(), &descInfo); | 116 this->setOutputStateInfo(drawState, blendOpt, *gpu->caps(), &descInfo); |
125 | 117 |
126 // now create a key | 118 // now create a key |
127 gpu->buildProgramDesc(*this, descInfo, drawType, &fDesc); | 119 gpu->buildProgramDesc(*this, descInfo, drawType, &fDesc); |
128 }; | 120 }; |
129 | 121 |
130 void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds, | 122 void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds, |
131 GrDrawState::BlendOpt blendOpt, | 123 GrDrawState::BlendOpt blendOpt, |
(...skipping 27 matching lines...) Expand all Loading... |
159 kZero_GrBlendCoeff == fDstBlend) { | 151 kZero_GrBlendCoeff == fDstBlend) { |
160 descInfo->fPrimaryOutputType = GrProgramDesc::kCombineWithDst_Primar
yOutputType; | 152 descInfo->fPrimaryOutputType = GrProgramDesc::kCombineWithDst_Primar
yOutputType; |
161 } | 153 } |
162 } | 154 } |
163 } | 155 } |
164 | 156 |
165 void GrOptDrawState::adjustProgramForBlendOpt(const GrDrawState& ds, | 157 void GrOptDrawState::adjustProgramForBlendOpt(const GrDrawState& ds, |
166 GrDrawState::BlendOpt blendOpt, | 158 GrDrawState::BlendOpt blendOpt, |
167 GrProgramDesc::DescInfo* descInfo, | 159 GrProgramDesc::DescInfo* descInfo, |
168 int* firstColorStageIdx, | 160 int* firstColorStageIdx, |
169 int* firstCoverageStageIdx, | 161 int* firstCoverageStageIdx) { |
170 uint8_t* fixedFunctionVAToRemove)
{ | |
171 switch (blendOpt) { | 162 switch (blendOpt) { |
172 case GrDrawState::kNone_BlendOpt: | 163 case GrDrawState::kNone_BlendOpt: |
173 case GrDrawState::kSkipDraw_BlendOpt: | 164 case GrDrawState::kSkipDraw_BlendOpt: |
174 case GrDrawState::kCoverageAsAlpha_BlendOpt: | 165 case GrDrawState::kCoverageAsAlpha_BlendOpt: |
175 break; | 166 break; |
176 case GrDrawState::kEmitCoverage_BlendOpt: | 167 case GrDrawState::kEmitCoverage_BlendOpt: |
177 fColor = 0xffffffff; | 168 fColor = 0xffffffff; |
178 descInfo->fInputColorIsUsed = true; | 169 descInfo->fInputColorIsUsed = true; |
179 *firstColorStageIdx = ds.numColorStages(); | 170 *firstColorStageIdx = ds.numColorStages(); |
180 *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding; | 171 descInfo->fHasVertexColor = false; |
181 break; | 172 break; |
182 case GrDrawState::kEmitTransBlack_BlendOpt: | 173 case GrDrawState::kEmitTransBlack_BlendOpt: |
183 fColor = 0; | 174 fColor = 0; |
184 fCoverage = 0xff; | 175 fCoverage = 0xff; |
185 descInfo->fInputColorIsUsed = true; | 176 descInfo->fInputColorIsUsed = true; |
186 descInfo->fInputCoverageIsUsed = true; | 177 descInfo->fInputCoverageIsUsed = true; |
187 *firstColorStageIdx = ds.numColorStages(); | 178 *firstColorStageIdx = ds.numColorStages(); |
188 *firstCoverageStageIdx = ds.numCoverageStages(); | 179 *firstCoverageStageIdx = ds.numCoverageStages(); |
189 *fixedFunctionVAToRemove |= (0x1 << kColor_GrVertexAttribBinding | | 180 descInfo->fHasVertexColor = false; |
190 0x1 << kCoverage_GrVertexAttribBinding)
; | 181 descInfo->fHasVertexCoverage = false; |
191 break; | 182 break; |
192 } | 183 } |
193 } | 184 } |
194 | 185 |
195 void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag, | |
196 GrProgramDesc::DescInfo* d
escInfo) { | |
197 int numToRemove = 0; | |
198 uint8_t maskCheck = 0x1; | |
199 // Count the number of vertex attributes that we will actually remove | |
200 for (int i = 0; i < kGrFixedFunctionVertexAttribBindingCnt; ++i) { | |
201 if ((maskCheck & removeVAFlag) && -1 != descInfo->fFixedFunctionVertexAt
tribIndices[i]) { | |
202 ++numToRemove; | |
203 } | |
204 maskCheck <<= 1; | |
205 } | |
206 | |
207 fOptVA.reset(fVACount - numToRemove); | |
208 | |
209 GrVertexAttrib* dst = fOptVA.get(); | |
210 const GrVertexAttrib* src = fVAPtr; | |
211 | |
212 for (int i = 0, newIdx = 0; i < fVACount; ++i, ++src) { | |
213 const GrVertexAttrib& currAttrib = *src; | |
214 if (currAttrib.fBinding < kGrFixedFunctionVertexAttribBindingCnt) { | |
215 uint8_t maskCheck = 0x1 << currAttrib.fBinding; | |
216 if (maskCheck & removeVAFlag) { | |
217 SkASSERT(-1 != descInfo->fFixedFunctionVertexAttribIndices[currA
ttrib.fBinding]); | |
218 descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding]
= -1; | |
219 continue; | |
220 } | |
221 descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = n
ewIdx; | |
222 } | |
223 memcpy(dst, src, sizeof(GrVertexAttrib)); | |
224 ++newIdx; | |
225 ++dst; | |
226 } | |
227 fVACount -= numToRemove; | |
228 fVAPtr = fOptVA.get(); | |
229 } | |
230 | |
231 static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool*
readsFragPosition) { | 186 static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool*
readsFragPosition) { |
232 if (stage.getProcessor()->willReadDstColor()) { | 187 if (stage.getProcessor()->willReadDstColor()) { |
233 *readsDst = true; | 188 *readsDst = true; |
234 } | 189 } |
235 if (stage.getProcessor()->willReadFragmentPosition()) { | 190 if (stage.getProcessor()->willReadFragmentPosition()) { |
236 *readsFragPosition = true; | 191 *readsFragPosition = true; |
237 } | 192 } |
238 } | 193 } |
239 | 194 |
240 void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx
, | 195 void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx
, |
241 int firstCoverageStageIdx, GrProgramDesc::Des
cInfo* descInfo) { | 196 int firstCoverageStageIdx, bool hasLocalCoord
s, |
| 197 GrProgramDesc::DescInfo* descInfo) { |
242 // We will need a local coord attrib if there is one currently set on the op
tState and we are | 198 // We will need a local coord attrib if there is one currently set on the op
tState and we are |
243 // actually generating some effect code | 199 // actually generating some effect code |
244 descInfo->fRequiresLocalCoordAttrib = descInfo->hasLocalCoordAttribute() && | 200 descInfo->fRequiresLocalCoordAttrib = hasLocalCoords && |
245 ds.numTotalStages() - firstColorStageIdx - firstCoverageStageIdx > 0; | 201 ds.numTotalStages() - firstColorStageIdx - firstCoverageStageIdx > 0; |
246 | 202 |
247 descInfo->fReadsDst = false; | 203 descInfo->fReadsDst = false; |
248 descInfo->fReadsFragPosition = false; | 204 descInfo->fReadsFragPosition = false; |
249 | 205 |
250 for (int s = firstColorStageIdx; s < ds.numColorStages(); ++s) { | 206 for (int s = firstColorStageIdx; s < ds.numColorStages(); ++s) { |
251 const GrFragmentStage& stage = ds.getColorStage(s); | 207 const GrFragmentStage& stage = ds.getColorStage(s); |
252 get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPositi
on); | 208 get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPositi
on); |
253 } | 209 } |
254 for (int s = firstCoverageStageIdx; s < ds.numCoverageStages(); ++s) { | 210 for (int s = firstCoverageStageIdx; s < ds.numCoverageStages(); ++s) { |
255 const GrFragmentStage& stage = ds.getCoverageStage(s); | 211 const GrFragmentStage& stage = ds.getCoverageStage(s); |
256 get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPositi
on); | 212 get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPositi
on); |
257 } | 213 } |
258 if (ds.hasGeometryProcessor()) { | 214 if (ds.hasGeometryProcessor()) { |
259 const GrGeometryProcessor& gp = *ds.getGeometryProcessor(); | 215 const GrGeometryProcessor& gp = *ds.getGeometryProcessor(); |
260 descInfo->fReadsFragPosition = descInfo->fReadsFragPosition || gp.willRe
adFragmentPosition(); | 216 descInfo->fReadsFragPosition = descInfo->fReadsFragPosition || gp.willRe
adFragmentPosition(); |
261 } | 217 } |
262 } | 218 } |
263 | 219 |
264 //////////////////////////////////////////////////////////////////////////////// | 220 //////////////////////////////////////////////////////////////////////////////// |
265 | 221 |
266 bool GrOptDrawState::operator== (const GrOptDrawState& that) const { | 222 bool GrOptDrawState::operator== (const GrOptDrawState& that) const { |
267 if (this->fDesc != that.fDesc) { | 223 if (this->fDesc != that.fDesc) { |
268 return false; | 224 return false; |
269 } | 225 } |
270 bool usingVertexColors = that.fDesc.header().fColorAttributeIndex != -1; | 226 bool hasVertexColors = this->fDesc.header().fColorInput == GrProgramDesc::kA
ttribute_ColorInput; |
271 if (!usingVertexColors && this->fColor != that.fColor) { | 227 if (!hasVertexColors && this->fColor != that.fColor) { |
272 return false; | 228 return false; |
273 } | 229 } |
274 | 230 |
275 if (this->getRenderTarget() != that.getRenderTarget() || | 231 if (this->getRenderTarget() != that.getRenderTarget() || |
276 this->fScissorState != that.fScissorState || | 232 this->fScissorState != that.fScissorState || |
277 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) || | 233 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) || |
278 this->fSrcBlend != that.fSrcBlend || | 234 this->fSrcBlend != that.fSrcBlend || |
279 this->fDstBlend != that.fDstBlend || | 235 this->fDstBlend != that.fDstBlend || |
280 this->fBlendConstant != that.fBlendConstant || | 236 this->fBlendConstant != that.fBlendConstant || |
281 this->fFlags != that.fFlags || | 237 this->fFlags != that.fFlags || |
282 this->fVACount != that.fVACount || | |
283 this->fVAStride != that.fVAStride || | |
284 memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib
)) || | |
285 this->fStencilSettings != that.fStencilSettings || | 238 this->fStencilSettings != that.fStencilSettings || |
286 this->fDrawFace != that.fDrawFace || | 239 this->fDrawFace != that.fDrawFace || |
287 this->fDstCopy.texture() != that.fDstCopy.texture()) { | 240 this->fDstCopy.texture() != that.fDstCopy.texture()) { |
288 return false; | 241 return false; |
289 } | 242 } |
290 | 243 |
291 bool usingVertexCoverage = this->fDesc.header().fCoverageAttributeIndex != -
1; | 244 bool hasVertexCoverage = |
292 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) { | 245 this->fDesc.header().fCoverageInput == GrProgramDesc::kAttribute_Col
orInput; |
| 246 if (!hasVertexCoverage && this->fCoverage != that.fCoverage) { |
293 return false; | 247 return false; |
294 } | 248 } |
295 | 249 |
296 if (this->hasGeometryProcessor()) { | 250 if (this->hasGeometryProcessor()) { |
297 if (!that.hasGeometryProcessor()) { | 251 if (!that.hasGeometryProcessor()) { |
298 return false; | 252 return false; |
299 } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProce
ssor())) { | 253 } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProce
ssor())) { |
300 return false; | 254 return false; |
301 } | 255 } |
302 } else if (that.hasGeometryProcessor()) { | 256 } else if (that.hasGeometryProcessor()) { |
303 return false; | 257 return false; |
304 } | 258 } |
305 | 259 |
306 // The program desc comparison should have already assured that the stage co
unts match. | 260 // The program desc comparison should have already assured that the stage co
unts match. |
307 SkASSERT(this->numFragmentStages() == that.numFragmentStages()); | 261 SkASSERT(this->numFragmentStages() == that.numFragmentStages()); |
308 for (int i = 0; i < this->numFragmentStages(); i++) { | 262 for (int i = 0; i < this->numFragmentStages(); i++) { |
309 | 263 |
310 if (this->getFragmentStage(i) != that.getFragmentStage(i)) { | 264 if (this->getFragmentStage(i) != that.getFragmentStage(i)) { |
311 return false; | 265 return false; |
312 } | 266 } |
313 } | 267 } |
314 return true; | 268 return true; |
315 } | 269 } |
316 | 270 |
OLD | NEW |