| 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 |