| Index: src/gpu/gl/GrGLProgramDesc.cpp
|
| diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
|
| index ecd48e014810eb4158a452a256418bad0aaba159..2c260cda52b16e3808fc03534b76e6d640ef49fc 100644
|
| --- a/src/gpu/gl/GrGLProgramDesc.cpp
|
| +++ b/src/gpu/gl/GrGLProgramDesc.cpp
|
| @@ -14,29 +14,28 @@
|
|
|
| #include "SkChecksum.h"
|
|
|
| -namespace {
|
| -inline GrGLEffect::EffectKey get_key_and_update_stats(const GrEffectStage& stage,
|
| - const GrGLCaps& caps,
|
| - bool useExplicitLocalCoords,
|
| - bool* setTrueIfReadsDst,
|
| - bool* setTrueIfReadsPos,
|
| - bool* setTrueIfHasVertexCode) {
|
| - const GrEffect* effect = stage.getEffect();
|
| - const GrBackendEffectFactory& factory = effect->getFactory();
|
| +static inline bool get_key_and_update_stats(const GrEffectStage& stage,
|
| + const GrGLCaps& caps,
|
| + bool useExplicitLocalCoords,
|
| + GrEffectKeyBuilder* b,
|
| + bool* setTrueIfReadsDst,
|
| + bool* setTrueIfReadsPos,
|
| + bool* setTrueIfHasVertexCode) {
|
| + const GrBackendEffectFactory& factory = stage.getEffect()->getFactory();
|
| GrDrawEffect drawEffect(stage, useExplicitLocalCoords);
|
| - if (effect->willReadDstColor()) {
|
| + if (stage.getEffect()->willReadDstColor()) {
|
| *setTrueIfReadsDst = true;
|
| }
|
| - if (effect->willReadFragmentPosition()) {
|
| + if (stage.getEffect()->willReadFragmentPosition()) {
|
| *setTrueIfReadsPos = true;
|
| }
|
| - if (effect->hasVertexCode()) {
|
| + if (stage.getEffect()->hasVertexCode()) {
|
| *setTrueIfHasVertexCode = true;
|
| }
|
| - return factory.glEffectKey(drawEffect, caps);
|
| + return factory.getGLEffectKey(drawEffect, caps, b);
|
| }
|
| -}
|
| -void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
| +
|
| +bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
| GrGpu::DrawType drawType,
|
| GrDrawState::BlendOptFlags blendOpts,
|
| GrBlendCoeff srcCoeff,
|
| @@ -94,45 +93,68 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
| (!requiresColorAttrib && 0xffffffff == drawState.getColor()) ||
|
| (!inputColorIsUsed);
|
|
|
| - int numEffects = (skipColor ? 0 : (drawState.numColorStages() - firstEffectiveColorStage)) +
|
| - (skipCoverage ? 0 : (drawState.numCoverageStages() - firstEffectiveCoverageStage));
|
| -
|
| - size_t newKeyLength = KeyLength(numEffects);
|
| - bool allocChanged;
|
| - desc->fKey.reset(newKeyLength, SkAutoMalloc::kAlloc_OnShrink, &allocChanged);
|
| - if (allocChanged || !desc->fInitialized) {
|
| - // make sure any padding in the header is zero if we we haven't used this allocation before.
|
| - memset(desc->header(), 0, kHeaderSize);
|
| - }
|
| - // write the key length
|
| - *desc->atOffset<uint32_t, kLengthOffset>() = SkToU32(newKeyLength);
|
| -
|
| - KeyHeader* header = desc->header();
|
| - EffectKey* effectKeys = desc->effectKeys();
|
| -
|
| - int currEffectKey = 0;
|
| bool readsDst = false;
|
| bool readFragPosition = false;
|
| // We use vertexshader-less shader programs only when drawing paths.
|
| bool hasVertexCode = !(GrGpu::kDrawPath_DrawType == drawType ||
|
| GrGpu::kDrawPaths_DrawType == drawType);
|
| + int numStages = 0;
|
| + if (!skipColor) {
|
| + numStages += drawState.numColorStages() - firstEffectiveColorStage;
|
| + }
|
| + if (!skipCoverage) {
|
| + numStages += drawState.numCoverageStages() - firstEffectiveCoverageStage;
|
| + }
|
| + GR_STATIC_ASSERT(0 == kEffectKeyLengthsOffset % sizeof(uint32_t));
|
| + // Make room for everything up to and including the array of offsets to effect keys.
|
| + desc->fKey.reset();
|
| + desc->fKey.push_back_n(kEffectKeyLengthsOffset + sizeof(uint32_t) * numStages);
|
|
|
| + size_t offset = desc->fKey.count();
|
| + int offsetIndex = 0;
|
| +
|
| + bool effectKeySuccess = true;
|
| if (!skipColor) {
|
| for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
|
| - effectKeys[currEffectKey++] =
|
| - get_key_and_update_stats(drawState.getColorStage(s), gpu->glCaps(),
|
| - requiresLocalCoordAttrib, &readsDst, &readFragPosition,
|
| - &hasVertexCode);
|
| + uint32_t* offsetLocation = reinterpret_cast<uint32_t*>(desc->fKey.begin() +
|
| + kEffectKeyLengthsOffset +
|
| + offsetIndex * sizeof(uint32_t));
|
| + *offsetLocation = offset;
|
| + ++offsetIndex;
|
| +
|
| + GrEffectKeyBuilder b(&desc->fKey);
|
| + effectKeySuccess |= get_key_and_update_stats(drawState.getColorStage(s), gpu->glCaps(),
|
| + requiresLocalCoordAttrib, &b, &readsDst,
|
| + &readFragPosition, &hasVertexCode);
|
| + offset += b.size();
|
| }
|
| }
|
| if (!skipCoverage) {
|
| for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) {
|
| - effectKeys[currEffectKey++] =
|
| - get_key_and_update_stats(drawState.getCoverageStage(s), gpu->glCaps(),
|
| - requiresLocalCoordAttrib, &readsDst, &readFragPosition,
|
| - &hasVertexCode);
|
| + uint32_t* offsetLocation = reinterpret_cast<uint32_t*>(desc->fKey.begin() +
|
| + kEffectKeyLengthsOffset +
|
| + offsetIndex * sizeof(uint32_t));
|
| + *offsetLocation = offset;
|
| + ++offsetIndex;
|
| + GrEffectKeyBuilder b(&desc->fKey);
|
| + effectKeySuccess |= get_key_and_update_stats(drawState.getCoverageStage(s),
|
| + gpu->glCaps(), requiresLocalCoordAttrib,
|
| + &b, &readsDst, &readFragPosition,
|
| + &hasVertexCode);
|
| + offset += b.size();
|
| }
|
| }
|
| + if (!effectKeySuccess) {
|
| + desc->fKey.reset();
|
| + return false;
|
| + }
|
| +
|
| + KeyHeader* header = desc->header();
|
| + // make sure any padding in the header is zeroed.
|
| + memset(desc->header(), 0, kHeaderSize);
|
| +
|
| + // Because header is a pointer into the dynamic array, we can't push any new data into the key
|
| + // below here.
|
|
|
| header->fHasVertexCode = hasVertexCode || requiresLocalCoordAttrib;
|
| header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType;
|
| @@ -268,18 +290,23 @@ void GrGLProgramDesc::Build(const GrDrawState& drawState,
|
| header->fColorEffectCnt = colorStages->count();
|
| header->fCoverageEffectCnt = coverageStages->count();
|
|
|
| - *desc->checksum() = 0;
|
| - *desc->checksum() = SkChecksum::Compute(reinterpret_cast<uint32_t*>(desc->fKey.get()),
|
| - newKeyLength);
|
| - desc->fInitialized = true;
|
| + desc->finalize();
|
| + return true;
|
| +}
|
| +
|
| +void GrGLProgramDesc::finalize() {
|
| + int keyLength = fKey.count();
|
| + SkASSERT(0 == (keyLength % 4));
|
| + *this->atOffset<uint32_t, kLengthOffset>() = SkToU32(keyLength);
|
| +
|
| + uint32_t* checksum = this->atOffset<uint32_t, kChecksumOffset>();
|
| + *checksum = 0;
|
| + *checksum = SkChecksum::Compute(reinterpret_cast<uint32_t*>(fKey.begin()), keyLength);
|
| }
|
|
|
| GrGLProgramDesc& GrGLProgramDesc::operator= (const GrGLProgramDesc& other) {
|
| - fInitialized = other.fInitialized;
|
| - if (fInitialized) {
|
| - size_t keyLength = other.keyLength();
|
| - fKey.reset(keyLength);
|
| - memcpy(fKey.get(), other.fKey.get(), keyLength);
|
| - }
|
| + size_t keyLength = other.keyLength();
|
| + fKey.reset(keyLength);
|
| + memcpy(fKey.begin(), other.fKey.begin(), keyLength);
|
| return *this;
|
| }
|
|
|