OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "GrGLProgramDesc.h" | 8 #include "GrGLProgramDesc.h" |
9 #include "GrBackendEffectFactory.h" | 9 #include "GrBackendEffectFactory.h" |
10 #include "GrDrawEffect.h" | 10 #include "GrDrawEffect.h" |
11 #include "GrEffect.h" | 11 #include "GrEffect.h" |
12 #include "GrGLShaderBuilder.h" | 12 #include "GrGLShaderBuilder.h" |
13 #include "GrGpuGL.h" | 13 #include "GrGpuGL.h" |
14 | 14 |
15 #include "SkChecksum.h" | 15 #include "SkChecksum.h" |
16 | 16 |
| 17 namespace { |
| 18 inline GrGLEffect::EffectKey get_key_and_update_stats(const GrEffectStage& stage
, |
| 19 const GrGLCaps& caps, |
| 20 bool useExplicitLocalCoord
s, |
| 21 bool* setTrueIfReadsDst, |
| 22 bool* setTrueIfReadsPos) { |
| 23 const GrEffectRef& effect = *stage.getEffect(); |
| 24 const GrBackendEffectFactory& factory = effect->getFactory(); |
| 25 GrDrawEffect drawEffect(stage, useExplicitLocalCoords); |
| 26 if (effect->willReadDstColor()) { |
| 27 *setTrueIfReadsDst = true; |
| 28 } |
| 29 if (effect->willReadFragmentPosition()) { |
| 30 *setTrueIfReadsPos = true; |
| 31 } |
| 32 return factory.glEffectKey(drawEffect, caps); |
| 33 } |
| 34 } |
17 void GrGLProgramDesc::Build(const GrDrawState& drawState, | 35 void GrGLProgramDesc::Build(const GrDrawState& drawState, |
18 bool isPoints, | 36 bool isPoints, |
19 GrDrawState::BlendOptFlags blendOpts, | 37 GrDrawState::BlendOptFlags blendOpts, |
20 GrBlendCoeff srcCoeff, | 38 GrBlendCoeff srcCoeff, |
21 GrBlendCoeff dstCoeff, | 39 GrBlendCoeff dstCoeff, |
22 const GrGpuGL* gpu, | 40 const GrGpuGL* gpu, |
23 const GrDeviceCoordTexture* dstCopy, | 41 const GrDeviceCoordTexture* dstCopy, |
24 SkTArray<const GrEffectStage*, true>* colorStages, | 42 SkTArray<const GrEffectStage*, true>* colorStages, |
25 SkTArray<const GrEffectStage*, true>* coverageStages
, | 43 SkTArray<const GrEffectStage*, true>* coverageStages
, |
26 GrGLProgramDesc* desc) { | 44 GrGLProgramDesc* desc) { |
(...skipping 16 matching lines...) Expand all Loading... |
43 bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute()
; | 61 bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute()
; |
44 bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAt
tribute(); | 62 bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAt
tribute(); |
45 // we only need the local coords if we're actually going to generate effect
code | 63 // we only need the local coords if we're actually going to generate effect
code |
46 bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) && | 64 bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) && |
47 drawState.hasLocalCoordAttribute(); | 65 drawState.hasLocalCoordAttribute(); |
48 | 66 |
49 bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_B
lendOptFlag); | 67 bool colorIsTransBlack = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_B
lendOptFlag); |
50 bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFla
g) || | 68 bool colorIsSolidWhite = (blendOpts & GrDrawState::kEmitCoverage_BlendOptFla
g) || |
51 (!requiresColorAttrib && 0xffffffff == drawState.ge
tColor()); | 69 (!requiresColorAttrib && 0xffffffff == drawState.ge
tColor()); |
52 | 70 |
53 // Do an initial loop over the stages to count them. We count the color and
coverage effects | 71 int numEffects = (skipColor ? 0 : drawState.numColorStages()) + |
54 // separately here. Later we may decide the distinction doesn't matter and w
ill count all | 72 (skipCoverage ? 0 : drawState.numCoverageStages()); |
55 // effects as color in desc. Two things will allow simplication of this mess
: GrDrawState will | |
56 // have tight lists of color and coverage stages rather than a fixed size ar
ray with NULLS and | |
57 // the xfermode-color filter will be removed. | |
58 if (!skipColor) { | |
59 for (int s = 0; s < drawState.getFirstCoverageStage(); ++s) { | |
60 if (drawState.isStageEnabled(s)) { | |
61 colorStages->push_back(&drawState.getStage(s)); | |
62 } | |
63 } | |
64 } | |
65 if (!skipCoverage) { | |
66 for (int s = drawState.getFirstCoverageStage(); s < GrDrawState::kNumSta
ges; ++s) { | |
67 if (drawState.isStageEnabled(s)) { | |
68 coverageStages->push_back(&drawState.getStage(s)); | |
69 } | |
70 } | |
71 } | |
72 | 73 |
73 size_t newKeyLength = KeyLength(colorStages->count() + coverageStages->count
()); | 74 size_t newKeyLength = KeyLength(numEffects); |
74 bool allocChanged; | 75 bool allocChanged; |
75 desc->fKey.reset(newKeyLength, SkAutoMalloc::kAlloc_OnShrink, &allocChanged)
; | 76 desc->fKey.reset(newKeyLength, SkAutoMalloc::kAlloc_OnShrink, &allocChanged)
; |
76 if (allocChanged || !desc->fInitialized) { | 77 if (allocChanged || !desc->fInitialized) { |
77 // make sure any padding in the header is zero if we we haven't used thi
s allocation before. | 78 // make sure any padding in the header is zero if we we haven't used thi
s allocation before. |
78 memset(desc->header(), 0, kHeaderSize); | 79 memset(desc->header(), 0, kHeaderSize); |
79 } | 80 } |
80 // write the key length | 81 // write the key length |
81 *desc->atOffset<uint32_t, kLengthOffset>() = newKeyLength; | 82 *desc->atOffset<uint32_t, kLengthOffset>() = newKeyLength; |
82 | 83 |
83 KeyHeader* header = desc->header(); | 84 KeyHeader* header = desc->header(); |
84 EffectKey* effectKeys = desc->effectKeys(); | 85 EffectKey* effectKeys = desc->effectKeys(); |
85 | 86 |
86 int currEffectKey = 0; | 87 int currEffectKey = 0; |
87 bool readsDst = false; | 88 bool readsDst = false; |
88 bool readFragPosition = false; | 89 bool readFragPosition = false; |
89 for (int s = 0; s < GrDrawState::kNumStages; ++s) { | 90 if (!skipColor) { |
90 bool skip = s < drawState.getFirstCoverageStage() ? skipColor : skipCove
rage; | 91 for (int s = 0; s < drawState.numColorStages(); ++s) { |
91 if (!skip && drawState.isStageEnabled(s)) { | 92 effectKeys[currEffectKey++] = |
92 const GrEffectRef& effect = *drawState.getStage(s).getEffect(); | 93 get_key_and_update_stats(drawState.getColorStage(s), gpu->glCaps
(), |
93 const GrBackendEffectFactory& factory = effect->getFactory(); | 94 requiresLocalCoordAttrib, &readsDst, &r
eadFragPosition); |
94 GrDrawEffect drawEffect(drawState.getStage(s), requiresLocalCoordAtt
rib); | 95 } |
95 effectKeys[currEffectKey] = factory.glEffectKey(drawEffect, gpu->glC
aps()); | 96 } |
96 ++currEffectKey; | 97 if (!skipCoverage) { |
97 if (effect->willReadDstColor()) { | 98 for (int s = 0; s < drawState.numCoverageStages(); ++s) { |
98 readsDst = true; | 99 effectKeys[currEffectKey++] = |
99 } | 100 get_key_and_update_stats(drawState.getCoverageStage(s), gpu->glC
aps(), |
100 if (effect->willReadFragmentPosition()) { | 101 requiresLocalCoordAttrib, &readsDst, &r
eadFragPosition); |
101 readFragPosition = true; | |
102 } | |
103 } | 102 } |
104 } | 103 } |
105 | 104 |
106 header->fEmitsPointSize = isPoints; | 105 header->fEmitsPointSize = isPoints; |
107 header->fColorFilterXfermode = skipColor ? SkXfermode::kDst_Mode : drawState
.getColorFilterMode(); | 106 header->fColorFilterXfermode = skipColor ? SkXfermode::kDst_Mode : drawState
.getColorFilterMode(); |
108 | 107 |
109 // Currently the experimental GS will only work with triangle prims (and it
doesn't do anything | 108 // Currently the experimental GS will only work with triangle prims (and it
doesn't do anything |
110 // other than pass through values from the VS to the FS anyway). | 109 // other than pass through values from the VS to the FS anyway). |
111 #if GR_GL_EXPERIMENTAL_GS | 110 #if GR_GL_EXPERIMENTAL_GS |
112 #if 0 | 111 #if 0 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 } | 181 } |
183 | 182 |
184 // Here we deal with whether/how we handle color and coverage separately. | 183 // Here we deal with whether/how we handle color and coverage separately. |
185 | 184 |
186 // Set these defaults and then possibly change our mind if there is coverage
. | 185 // Set these defaults and then possibly change our mind if there is coverage
. |
187 header->fDiscardIfZeroCoverage = false; | 186 header->fDiscardIfZeroCoverage = false; |
188 header->fCoverageOutput = kModulate_CoverageOutput; | 187 header->fCoverageOutput = kModulate_CoverageOutput; |
189 | 188 |
190 // If we do have coverage determine whether it matters. | 189 // If we do have coverage determine whether it matters. |
191 bool separateCoverageFromColor = false; | 190 bool separateCoverageFromColor = false; |
192 if (!drawState.isCoverageDrawing() && (coverageStages->count() > 0 || requir
esCoverageAttrib)) { | 191 if (!drawState.isCoverageDrawing() && !skipCoverage && |
| 192 (drawState.numCoverageStages() > 0 || requiresCoverageAttrib)) { |
193 // color filter is applied between color/coverage computation | 193 // color filter is applied between color/coverage computation |
194 if (SkXfermode::kDst_Mode != header->fColorFilterXfermode) { | 194 if (SkXfermode::kDst_Mode != header->fColorFilterXfermode) { |
195 separateCoverageFromColor = true; | 195 separateCoverageFromColor = true; |
196 } | 196 } |
197 | 197 |
198 // If we're stenciling then we want to discard samples that have zero co
verage | 198 // If we're stenciling then we want to discard samples that have zero co
verage |
199 if (drawState.getStencil().doesWrite()) { | 199 if (drawState.getStencil().doesWrite()) { |
200 header->fDiscardIfZeroCoverage = true; | 200 header->fDiscardIfZeroCoverage = true; |
201 separateCoverageFromColor = true; | 201 separateCoverageFromColor = true; |
202 } | 202 } |
(...skipping 14 matching lines...) Expand all Loading... |
217 header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput; | 217 header->fCoverageOutput = kSecondaryCoverageISC_CoverageOutput; |
218 separateCoverageFromColor = true; | 218 separateCoverageFromColor = true; |
219 } | 219 } |
220 } else if (readsDst && | 220 } else if (readsDst && |
221 kOne_GrBlendCoeff == srcCoeff && | 221 kOne_GrBlendCoeff == srcCoeff && |
222 kZero_GrBlendCoeff == dstCoeff) { | 222 kZero_GrBlendCoeff == dstCoeff) { |
223 header->fCoverageOutput = kCombineWithDst_CoverageOutput; | 223 header->fCoverageOutput = kCombineWithDst_CoverageOutput; |
224 separateCoverageFromColor = true; | 224 separateCoverageFromColor = true; |
225 } | 225 } |
226 } | 226 } |
227 if (separateCoverageFromColor) { | 227 if (!skipColor) { |
228 header->fColorEffectCnt = colorStages->count(); | 228 for (int s = 0; s < drawState.numColorStages(); ++s) { |
229 header->fCoverageEffectCnt = coverageStages->count(); | 229 colorStages->push_back(&drawState.getColorStage(s)); |
230 } else { | 230 } |
231 header->fColorEffectCnt = colorStages->count() + coverageStages->count()
; | 231 header->fColorEffectCnt = drawState.numColorStages(); |
232 header->fCoverageEffectCnt = 0; | 232 } |
233 colorStages->push_back_n(coverageStages->count(), coverageStages->begin(
)); | 233 if (!skipCoverage) { |
234 coverageStages->reset(); | 234 SkTArray<const GrEffectStage*, true>* array; |
| 235 if (separateCoverageFromColor) { |
| 236 array = coverageStages; |
| 237 header->fCoverageEffectCnt = drawState.numCoverageStages(); |
| 238 } else { |
| 239 array = colorStages; |
| 240 header->fColorEffectCnt += drawState.numCoverageStages(); |
| 241 } |
| 242 for (int s = 0; s < drawState.numCoverageStages(); ++s) { |
| 243 array->push_back(&drawState.getCoverageStage(s)); |
| 244 } |
235 } | 245 } |
236 | 246 |
237 *desc->checksum() = 0; | 247 *desc->checksum() = 0; |
238 *desc->checksum() = SkChecksum::Compute(reinterpret_cast<uint32_t*>(desc->fK
ey.get()), | 248 *desc->checksum() = SkChecksum::Compute(reinterpret_cast<uint32_t*>(desc->fK
ey.get()), |
239 newKeyLength); | 249 newKeyLength); |
240 desc->fInitialized = true; | 250 desc->fInitialized = true; |
241 } | 251 } |
242 | 252 |
243 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { | 253 GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) { |
244 fInitialized = other.fInitialized; | 254 fInitialized = other.fInitialized; |
245 if (fInitialized) { | 255 if (fInitialized) { |
246 size_t keyLength = other.keyLength(); | 256 size_t keyLength = other.keyLength(); |
247 fKey.reset(keyLength); | 257 fKey.reset(keyLength); |
248 memcpy(fKey.get(), other.fKey.get(), keyLength); | 258 memcpy(fKey.get(), other.fKey.get(), keyLength); |
249 } | 259 } |
250 return *this; | 260 return *this; |
251 } | 261 } |
OLD | NEW |