| Index: src/gpu/GrOptDrawState.cpp
|
| diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
|
| index 77a9fc8dc454a25672d849f9ec8d5fb1f10c2081..529e9ed75e9bbe5bc773de378474da442afe91d2 100644
|
| --- a/src/gpu/GrOptDrawState.cpp
|
| +++ b/src/gpu/GrOptDrawState.cpp
|
| @@ -9,12 +9,15 @@
|
|
|
| #include "GrDrawState.h"
|
| #include "GrDrawTargetCaps.h"
|
| +#include "gl/GrGpuGL.h"
|
|
|
| GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
| BlendOptFlags blendOptFlags,
|
| GrBlendCoeff optSrcCoeff,
|
| GrBlendCoeff optDstCoeff,
|
| - const GrDrawTargetCaps& caps) {
|
| + GrGpu* gpu,
|
| + const GrDeviceCoordTexture* dstCopy,
|
| + GrGpu::DrawType drawType) {
|
| fRenderTarget.set(SkSafeRef(drawState.getRenderTarget()), kWrite_GrIOType);
|
| fColor = drawState.getColor();
|
| fCoverage = drawState.getCoverage();
|
| @@ -29,13 +32,14 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
| fBlendOptFlags = blendOptFlags;
|
| fSrcBlend = optSrcCoeff;
|
| fDstBlend = optDstCoeff;
|
| + GrProgramDesc::DescInfo descInfo;
|
|
|
| - memcpy(fFixedFunctionVertexAttribIndices,
|
| + memcpy(descInfo.fFixedFunctionVertexAttribIndices,
|
| drawState.getFixedFunctionVertexAttribIndices(),
|
| - sizeof(fFixedFunctionVertexAttribIndices));
|
| + sizeof(descInfo.fFixedFunctionVertexAttribIndices));
|
|
|
| - fInputColorIsUsed = true;
|
| - fInputCoverageIsUsed = true;
|
| + descInfo.fInputColorIsUsed = true;
|
| + descInfo.fInputCoverageIsUsed = true;
|
|
|
| int firstColorStageIdx = 0;
|
| int firstCoverageStageIdx = 0;
|
| @@ -43,16 +47,18 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
|
|
| uint8_t fixedFunctionVAToRemove = 0;
|
|
|
| - this->computeEffectiveColorStages(drawState, &firstColorStageIdx, &fixedFunctionVAToRemove);
|
| - this->computeEffectiveCoverageStages(drawState, &firstCoverageStageIdx);
|
| - this->adjustFromBlendOpts(drawState, &firstColorStageIdx, &firstCoverageStageIdx,
|
| + this->computeEffectiveColorStages(drawState, &descInfo, &firstColorStageIdx,
|
| + &fixedFunctionVAToRemove);
|
| + this->computeEffectiveCoverageStages(drawState, &descInfo, &firstCoverageStageIdx);
|
| + this->adjustFromBlendOpts(drawState, &descInfo, &firstColorStageIdx, &firstCoverageStageIdx,
|
| &fixedFunctionVAToRemove);
|
| // Should not be setting any more FFVA to be removed at this point
|
| if (0 != fixedFunctionVAToRemove) {
|
| - this->removeFixedFunctionVertexAttribs(fixedFunctionVAToRemove);
|
| + this->removeFixedFunctionVertexAttribs(fixedFunctionVAToRemove, &descInfo);
|
| }
|
| - this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx);
|
| - this->setOutputStateInfo(drawState, caps, firstCoverageStageIdx, &separateCoverageFromColor);
|
| + this->getStageStats(drawState, firstColorStageIdx, firstCoverageStageIdx, &descInfo);
|
| + this->setOutputStateInfo(drawState, *gpu->caps(), firstCoverageStageIdx, &descInfo,
|
| + &separateCoverageFromColor);
|
|
|
| // Copy GeometryProcesssor from DS or ODS
|
| if (drawState.hasGeometryProcessor()) {
|
| @@ -79,10 +85,16 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
| fNumColorStages = fFragmentStages.count();
|
| }
|
| }
|
| +
|
| + // now create a key
|
| + gpu->buildProgramDesc(*this, descInfo, drawType, dstCopy, &fDesc);
|
| };
|
|
|
| -GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDrawTargetCaps& caps,
|
| +GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState,
|
| + GrGpu* gpu,
|
| + const GrDeviceCoordTexture* dstCopy,
|
| GrGpu::DrawType drawType) {
|
| + const GrDrawTargetCaps& caps = *gpu->caps();
|
| if (NULL == drawState.fCachedOptState || caps.getUniqueID() != drawState.fCachedCapsID) {
|
| GrBlendCoeff srcCoeff;
|
| GrBlendCoeff dstCoeff;
|
| @@ -100,7 +112,7 @@ GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDra
|
| }
|
|
|
| drawState.fCachedOptState = SkNEW_ARGS(GrOptDrawState, (drawState, blendFlags, srcCoeff,
|
| - dstCoeff, caps));
|
| + dstCoeff, gpu, dstCopy, drawType));
|
| drawState.fCachedCapsID = caps.getUniqueID();
|
| } else {
|
| #ifdef SK_DEBUG
|
| @@ -109,8 +121,8 @@ GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDra
|
| BlendOptFlags blendFlags = (BlendOptFlags) drawState.getBlendOpts(false,
|
| &srcCoeff,
|
| &dstCoeff);
|
| - SkASSERT(GrOptDrawState(drawState, blendFlags, srcCoeff, dstCoeff, caps) ==
|
| - *drawState.fCachedOptState);
|
| + SkASSERT(GrOptDrawState(drawState, blendFlags, srcCoeff, dstCoeff, gpu, dstCopy,
|
| + drawType) == *drawState.fCachedOptState);
|
| #endif
|
| }
|
| drawState.fCachedOptState->ref();
|
| @@ -120,45 +132,47 @@ GrOptDrawState* GrOptDrawState::Create(const GrDrawState& drawState, const GrDra
|
| void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds,
|
| const GrDrawTargetCaps& caps,
|
| int firstCoverageStageIdx,
|
| + GrProgramDesc::DescInfo* descInfo,
|
| bool* separateCoverageFromColor) {
|
| // Set this default and then possibly change our mind if there is coverage.
|
| - fPrimaryOutputType = kModulate_PrimaryOutputType;
|
| - fSecondaryOutputType = kNone_SecondaryOutputType;
|
| + descInfo->fPrimaryOutputType = GrProgramDesc::kModulate_PrimaryOutputType;
|
| + descInfo->fSecondaryOutputType = GrProgramDesc::kNone_SecondaryOutputType;
|
|
|
| // If we do have coverage determine whether it matters.
|
| *separateCoverageFromColor = this->hasGeometryProcessor();
|
| if (!this->isCoverageDrawing() &&
|
| (ds.numCoverageStages() - firstCoverageStageIdx > 0 ||
|
| ds.hasGeometryProcessor() ||
|
| - this->hasCoverageVertexAttribute())) {
|
| + descInfo->hasCoverageVertexAttribute())) {
|
|
|
| if (caps.dualSourceBlendingSupport()) {
|
| if (kZero_GrBlendCoeff == fDstBlend) {
|
| // write the coverage value to second color
|
| - fSecondaryOutputType = kCoverage_SecondaryOutputType;
|
| + descInfo->fSecondaryOutputType = GrProgramDesc::kCoverage_SecondaryOutputType;
|
| *separateCoverageFromColor = true;
|
| fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
|
| } else if (kSA_GrBlendCoeff == fDstBlend) {
|
| // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
|
| - fSecondaryOutputType = kCoverageISA_SecondaryOutputType;
|
| + descInfo->fSecondaryOutputType = GrProgramDesc::kCoverageISA_SecondaryOutputType;
|
| *separateCoverageFromColor = true;
|
| fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
|
| } else if (kSC_GrBlendCoeff == fDstBlend) {
|
| // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered.
|
| - fSecondaryOutputType = kCoverageISC_SecondaryOutputType;
|
| + descInfo->fSecondaryOutputType = GrProgramDesc::kCoverageISC_SecondaryOutputType;
|
| *separateCoverageFromColor = true;
|
| fDstBlend = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff;
|
| }
|
| - } else if (fReadsDst &&
|
| + } else if (descInfo->fReadsDst &&
|
| kOne_GrBlendCoeff == fSrcBlend &&
|
| kZero_GrBlendCoeff == fDstBlend) {
|
| - fPrimaryOutputType = kCombineWithDst_PrimaryOutputType;
|
| + descInfo->fPrimaryOutputType = GrProgramDesc::kCombineWithDst_PrimaryOutputType;
|
| *separateCoverageFromColor = true;
|
| }
|
| }
|
| }
|
|
|
| void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds,
|
| + GrProgramDesc::DescInfo* descInfo,
|
| int* firstColorStageIdx,
|
| int* firstCoverageStageIdx,
|
| uint8_t* fixedFunctionVAToRemove) {
|
| @@ -171,15 +185,15 @@ void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds,
|
| break;
|
| case kEmitCoverage_BlendOptFlag:
|
| fColor = 0xffffffff;
|
| - fInputColorIsUsed = true;
|
| + descInfo->fInputColorIsUsed = true;
|
| *firstColorStageIdx = ds.numColorStages();
|
| *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
|
| break;
|
| case kEmitTransBlack_BlendOptFlag:
|
| fColor = 0;
|
| fCoverage = 0xff;
|
| - fInputColorIsUsed = true;
|
| - fInputCoverageIsUsed = true;
|
| + descInfo->fInputColorIsUsed = true;
|
| + descInfo->fInputCoverageIsUsed = true;
|
| *firstColorStageIdx = ds.numColorStages();
|
| *firstCoverageStageIdx = ds.numCoverageStages();
|
| *fixedFunctionVAToRemove |= (0x1 << kColor_GrVertexAttribBinding |
|
| @@ -190,12 +204,13 @@ void GrOptDrawState::adjustFromBlendOpts(const GrDrawState& ds,
|
| }
|
| }
|
|
|
| -void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
|
| +void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag,
|
| + GrProgramDesc::DescInfo* descInfo) {
|
| int numToRemove = 0;
|
| uint8_t maskCheck = 0x1;
|
| // Count the number of vertex attributes that we will actually remove
|
| for (int i = 0; i < kGrFixedFunctionVertexAttribBindingCnt; ++i) {
|
| - if ((maskCheck & removeVAFlag) && -1 != fFixedFunctionVertexAttribIndices[i]) {
|
| + if ((maskCheck & removeVAFlag) && -1 != descInfo->fFixedFunctionVertexAttribIndices[i]) {
|
| ++numToRemove;
|
| }
|
| maskCheck <<= 1;
|
| @@ -211,11 +226,11 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
|
| if (currAttrib.fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
|
| uint8_t maskCheck = 0x1 << currAttrib.fBinding;
|
| if (maskCheck & removeVAFlag) {
|
| - SkASSERT(-1 != fFixedFunctionVertexAttribIndices[currAttrib.fBinding]);
|
| - fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
|
| + SkASSERT(-1 != descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding]);
|
| + descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
|
| continue;
|
| }
|
| - fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
|
| + descInfo->fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
|
| }
|
| memcpy(dst, src, sizeof(GrVertexAttrib));
|
| ++newIdx;
|
| @@ -225,12 +240,14 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
|
| fVAPtr = fOptVA.get();
|
| }
|
|
|
| -void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds, int* firstColorStageIdx,
|
| +void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds,
|
| + GrProgramDesc::DescInfo* descInfo,
|
| + int* firstColorStageIdx,
|
| uint8_t* fixedFunctionVAToRemove) {
|
| // Set up color and flags for ConstantColorComponent checks
|
| GrProcessor::InvariantOutput inout;
|
| inout.fIsSingleComponent = false;
|
| - if (!this->hasColorVertexAttribute()) {
|
| + if (!descInfo->hasColorVertexAttribute()) {
|
| inout.fColor = ds.getColor();
|
| inout.fValidFlags = kRGBA_GrColorComponentFlags;
|
| } else {
|
| @@ -249,12 +266,12 @@ void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds, int* fir
|
| fp->computeInvariantOutput(&inout);
|
| if (!inout.fWillUseInputColor) {
|
| *firstColorStageIdx = i;
|
| - fInputColorIsUsed = false;
|
| + descInfo->fInputColorIsUsed = false;
|
| }
|
| if (kRGBA_GrColorComponentFlags == inout.fValidFlags) {
|
| *firstColorStageIdx = i + 1;
|
| fColor = inout.fColor;
|
| - fInputColorIsUsed = true;
|
| + descInfo->fInputColorIsUsed = true;
|
| *fixedFunctionVAToRemove |= 0x1 << kColor_GrVertexAttribBinding;
|
| // Since we are clearing all previous color stages we are in a state where we have found
|
| // zero stages that don't multiply the inputColor.
|
| @@ -264,6 +281,7 @@ void GrOptDrawState::computeEffectiveColorStages(const GrDrawState& ds, int* fir
|
| }
|
|
|
| void GrOptDrawState::computeEffectiveCoverageStages(const GrDrawState& ds,
|
| + GrProgramDesc::DescInfo* descInfo,
|
| int* firstCoverageStageIdx) {
|
| // We do not try to optimize out constantColor coverage effects here. It is extremely rare
|
| // to have a coverage effect that returns a constant value for all four channels. Thus we
|
| @@ -278,7 +296,7 @@ void GrOptDrawState::computeEffectiveCoverageStages(const GrDrawState& ds,
|
| fp->computeInvariantOutput(&inout);
|
| if (!inout.fWillUseInputColor) {
|
| *firstCoverageStageIdx = i;
|
| - fInputCoverageIsUsed = false;
|
| + descInfo->fInputCoverageIsUsed = false;
|
| }
|
| }
|
| #endif
|
| @@ -294,26 +312,26 @@ static void get_stage_stats(const GrFragmentStage& stage, bool* readsDst, bool*
|
| }
|
|
|
| void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx,
|
| - int firstCoverageStageIdx) {
|
| + int firstCoverageStageIdx, GrProgramDesc::DescInfo* descInfo) {
|
| // We will need a local coord attrib if there is one currently set on the optState and we are
|
| // actually generating some effect code
|
| - fRequiresLocalCoordAttrib = this->hasLocalCoordAttribute() &&
|
| + descInfo->fRequiresLocalCoordAttrib = descInfo->hasLocalCoordAttribute() &&
|
| ds.numTotalStages() - firstColorStageIdx - firstCoverageStageIdx > 0;
|
|
|
| - fReadsDst = false;
|
| - fReadsFragPosition = false;
|
| + descInfo->fReadsDst = false;
|
| + descInfo->fReadsFragPosition = false;
|
|
|
| for (int s = firstColorStageIdx; s < ds.numColorStages(); ++s) {
|
| const GrFragmentStage& stage = ds.getColorStage(s);
|
| - get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
|
| + get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPosition);
|
| }
|
| for (int s = firstCoverageStageIdx; s < ds.numCoverageStages(); ++s) {
|
| const GrFragmentStage& stage = ds.getCoverageStage(s);
|
| - get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
|
| + get_stage_stats(stage, &descInfo->fReadsDst, &descInfo->fReadsFragPosition);
|
| }
|
| if (ds.hasGeometryProcessor()) {
|
| const GrGeometryProcessor& gp = *ds.getGeometryProcessor();
|
| - fReadsFragPosition = fReadsFragPosition || gp.willReadFragmentPosition();
|
| + descInfo->fReadsFragPosition = descInfo->fReadsFragPosition || gp.willReadFragmentPosition();
|
| }
|
| }
|
|
|
| @@ -324,14 +342,15 @@ bool GrOptDrawState::operator== (const GrOptDrawState& that) const {
|
| }
|
|
|
| bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
|
| - bool usingVertexColors = this->hasColorVertexAttribute();
|
| + if (this->fDesc != that.fDesc) {
|
| + return false;
|
| + }
|
| + bool usingVertexColors = that.fDesc.header().fColorAttributeIndex != -1;
|
| if (!usingVertexColors && this->fColor != that.fColor) {
|
| return false;
|
| }
|
|
|
| if (this->getRenderTarget() != that.getRenderTarget() ||
|
| - this->fFragmentStages.count() != that.fFragmentStages.count() ||
|
| - this->fNumColorStages != that.fNumColorStages ||
|
| !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) ||
|
| this->fSrcBlend != that.fSrcBlend ||
|
| this->fDstBlend != that.fDstBlend ||
|
| @@ -341,23 +360,15 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
|
| this->fVAStride != that.fVAStride ||
|
| memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib)) ||
|
| this->fStencilSettings != that.fStencilSettings ||
|
| - this->fDrawFace != that.fDrawFace ||
|
| - this->fInputColorIsUsed != that.fInputColorIsUsed ||
|
| - this->fInputCoverageIsUsed != that.fInputCoverageIsUsed ||
|
| - this->fReadsDst != that.fReadsDst ||
|
| - this->fReadsFragPosition != that.fReadsFragPosition ||
|
| - this->fRequiresLocalCoordAttrib != that.fRequiresLocalCoordAttrib ||
|
| - this->fPrimaryOutputType != that.fPrimaryOutputType ||
|
| - this->fSecondaryOutputType != that.fSecondaryOutputType) {
|
| + this->fDrawFace != that.fDrawFace) {
|
| return false;
|
| }
|
|
|
| - bool usingVertexCoverage = this->hasCoverageVertexAttribute();
|
| + bool usingVertexCoverage = this->fDesc.header().fCoverageAttributeIndex != -1;
|
| if (!usingVertexCoverage && this->fCoverage != that.fCoverage) {
|
| return false;
|
| }
|
|
|
| - bool explicitLocalCoords = this->hasLocalCoordAttribute();
|
| if (this->hasGeometryProcessor()) {
|
| if (!that.hasGeometryProcessor()) {
|
| return false;
|
| @@ -368,17 +379,13 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
|
| return false;
|
| }
|
|
|
| + bool explicitLocalCoords = this->fDesc.header().fLocalCoordAttributeIndex != -1;
|
| for (int i = 0; i < this->numFragmentStages(); i++) {
|
| if (!GrFragmentStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
|
| explicitLocalCoords)) {
|
| return false;
|
| }
|
| }
|
| -
|
| - SkASSERT(0 == memcmp(this->fFixedFunctionVertexAttribIndices,
|
| - that.fFixedFunctionVertexAttribIndices,
|
| - sizeof(this->fFixedFunctionVertexAttribIndices)));
|
| -
|
| return true;
|
| }
|
|
|
|
|