Attach GrOptDrawState into shader building pipeline
The OptDrawState is now used for creating the actual gl shader. Current optimizations dones in GrOptDrawState include: All blend optimizations Constant color/coverage stage optimizations BUG=skia: Committed: https://skia.googlesource.com/skia/+/ee6206572b42fec11f83ad0c1e6d435903640518 R=bsalomon@google.com, joshualitt@google.com Author: egdaniel@google.com Review URL: https://codereview.chromium.org/504203004
This commit is contained in:
parent
3375c8047e
commit
170f90b457
@ -15,9 +15,17 @@
|
|||||||
|
|
||||||
GrOptDrawState* GrDrawState::createOptState() const {
|
GrOptDrawState* GrDrawState::createOptState() const {
|
||||||
if (NULL == fCachedOptState) {
|
if (NULL == fCachedOptState) {
|
||||||
fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this));
|
GrBlendCoeff srcCoeff;
|
||||||
|
GrBlendCoeff dstCoeff;
|
||||||
|
BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
|
||||||
|
fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this, blendFlags, srcCoeff, dstCoeff));
|
||||||
} else {
|
} else {
|
||||||
SkASSERT(GrOptDrawState(*this) == *fCachedOptState);
|
#ifdef SK_DEBUG
|
||||||
|
GrBlendCoeff srcCoeff;
|
||||||
|
GrBlendCoeff dstCoeff;
|
||||||
|
BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
|
||||||
|
SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff) == *fCachedOptState);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
fCachedOptState->ref();
|
fCachedOptState->ref();
|
||||||
return fCachedOptState;
|
return fCachedOptState;
|
||||||
@ -106,9 +114,6 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
|
|||||||
}
|
}
|
||||||
fColorStages = that.fColorStages;
|
fColorStages = that.fColorStages;
|
||||||
fCoverageStages = that.fCoverageStages;
|
fCoverageStages = that.fCoverageStages;
|
||||||
fOptSrcBlend = that.fOptSrcBlend;
|
|
||||||
fOptDstBlend = that.fOptDstBlend;
|
|
||||||
fBlendOptFlags = that.fBlendOptFlags;
|
|
||||||
|
|
||||||
fHints = that.fHints;
|
fHints = that.fHints;
|
||||||
|
|
||||||
@ -299,7 +304,7 @@ bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
|
|||||||
// or c) the src, dst blend coeffs are 1,0 and we will read Dst Color
|
// or c) the src, dst blend coeffs are 1,0 and we will read Dst Color
|
||||||
GrBlendCoeff srcCoeff;
|
GrBlendCoeff srcCoeff;
|
||||||
GrBlendCoeff dstCoeff;
|
GrBlendCoeff dstCoeff;
|
||||||
GrRODrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff);
|
BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff);
|
||||||
return GrRODrawState::kNone_BlendOpt != flag ||
|
return GrRODrawState::kNone_BlendOpt != flag ||
|
||||||
(this->willEffectReadDstColor() &&
|
(this->willEffectReadDstColor() &&
|
||||||
kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
|
kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
|
||||||
@ -455,3 +460,16 @@ void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void GrDrawState::invalidateOptState() const {
|
||||||
|
SkSafeSetNull(fCachedOptState);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
GrDrawState::~GrDrawState() {
|
||||||
|
SkSafeUnref(fCachedOptState);
|
||||||
|
SkASSERT(0 == fBlockEffectRemovalCnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -9,11 +9,12 @@
|
|||||||
#define GrDrawState_DEFINED
|
#define GrDrawState_DEFINED
|
||||||
|
|
||||||
#include "GrBlend.h"
|
#include "GrBlend.h"
|
||||||
#include "GrOptDrawState.h"
|
|
||||||
#include "GrProgramResource.h"
|
#include "GrProgramResource.h"
|
||||||
#include "GrRODrawState.h"
|
#include "GrRODrawState.h"
|
||||||
#include "effects/GrSimpleTextureEffect.h"
|
#include "effects/GrSimpleTextureEffect.h"
|
||||||
|
|
||||||
|
class GrOptDrawState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modifiable subclass derived from GrRODrawState. The majority of the data that represents a draw
|
* Modifiable subclass derived from GrRODrawState. The majority of the data that represents a draw
|
||||||
* state is stored in the parent class. GrDrawState contains methods for setting, adding to, etc.
|
* state is stored in the parent class. GrDrawState contains methods for setting, adding to, etc.
|
||||||
@ -47,10 +48,7 @@ public:
|
|||||||
**/
|
**/
|
||||||
GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
|
GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
|
||||||
|
|
||||||
virtual ~GrDrawState() {
|
virtual ~GrDrawState();
|
||||||
SkSafeUnref(fCachedOptState);
|
|
||||||
SkASSERT(0 == fBlockEffectRemovalCnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets to the default state. GrEffects will be removed from all stages.
|
* Resets to the default state. GrEffects will be removed from all stages.
|
||||||
@ -552,17 +550,10 @@ public:
|
|||||||
GrOptDrawState* createOptState() const;
|
GrOptDrawState* createOptState() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void invalidateOptState() const {
|
void invalidateOptState() const;
|
||||||
SkSafeSetNull(fCachedOptState);
|
|
||||||
fBlendOptFlags = kInvalid_BlendOptFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
void onReset(const SkMatrix* initialViewMatrix);
|
void onReset(const SkMatrix* initialViewMatrix);
|
||||||
|
|
||||||
void invalidateBlendOptFlags() {
|
|
||||||
fBlendOptFlags = kInvalid_BlendOptFlag;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some of the auto restore objects assume that no effects are removed during their lifetime.
|
// Some of the auto restore objects assume that no effects are removed during their lifetime.
|
||||||
// This is used to assert that this condition holds.
|
// This is used to assert that this condition holds.
|
||||||
SkDEBUGCODE(int fBlockEffectRemovalCnt;)
|
SkDEBUGCODE(int fBlockEffectRemovalCnt;)
|
||||||
|
@ -9,7 +9,10 @@
|
|||||||
|
|
||||||
#include "GrDrawState.h"
|
#include "GrDrawState.h"
|
||||||
|
|
||||||
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState) : INHERITED(drawState) {
|
GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
|
||||||
|
BlendOptFlags blendOptFlags,
|
||||||
|
GrBlendCoeff optSrcCoeff,
|
||||||
|
GrBlendCoeff optDstCoeff) : INHERITED(drawState) {
|
||||||
fColor = drawState.getColor();
|
fColor = drawState.getColor();
|
||||||
fCoverage = drawState.getCoverage();
|
fCoverage = drawState.getCoverage();
|
||||||
fViewMatrix = drawState.getViewMatrix();
|
fViewMatrix = drawState.getViewMatrix();
|
||||||
@ -20,13 +23,15 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState) : INHERITED(drawSta
|
|||||||
fVAStride = drawState.getVertexStride();
|
fVAStride = drawState.getVertexStride();
|
||||||
fStencilSettings = drawState.getStencil();
|
fStencilSettings = drawState.getStencil();
|
||||||
fDrawFace = drawState.getDrawFace();
|
fDrawFace = drawState.getDrawFace();
|
||||||
|
fBlendOptFlags = blendOptFlags;
|
||||||
fBlendOptFlags = drawState.getBlendOpts(false, &fSrcBlend, &fDstBlend);
|
fSrcBlend = optSrcCoeff;
|
||||||
|
fDstBlend = optDstCoeff;
|
||||||
|
|
||||||
memcpy(fFixedFunctionVertexAttribIndices,
|
memcpy(fFixedFunctionVertexAttribIndices,
|
||||||
drawState.getFixedFunctionVertexAttribIndices(),
|
drawState.getFixedFunctionVertexAttribIndices(),
|
||||||
sizeof(fFixedFunctionVertexAttribIndices));
|
sizeof(fFixedFunctionVertexAttribIndices));
|
||||||
|
|
||||||
|
|
||||||
fInputColorIsUsed = true;
|
fInputColorIsUsed = true;
|
||||||
fInputCoverageIsUsed = true;
|
fInputCoverageIsUsed = true;
|
||||||
|
|
||||||
@ -38,8 +43,40 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState) : INHERITED(drawSta
|
|||||||
|
|
||||||
this->copyEffectiveColorStages(drawState);
|
this->copyEffectiveColorStages(drawState);
|
||||||
this->copyEffectiveCoverageStages(drawState);
|
this->copyEffectiveCoverageStages(drawState);
|
||||||
|
this->adjustFromBlendOpts();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void GrOptDrawState::adjustFromBlendOpts() {
|
||||||
|
|
||||||
|
switch (fBlendOptFlags) {
|
||||||
|
case kNone_BlendOpt:
|
||||||
|
case kSkipDraw_BlendOptFlag:
|
||||||
|
break;
|
||||||
|
case kCoverageAsAlpha_BlendOptFlag:
|
||||||
|
fFlagBits |= kCoverageDrawing_StateBit;
|
||||||
|
break;
|
||||||
|
case kEmitCoverage_BlendOptFlag:
|
||||||
|
fColor = 0xffffffff;
|
||||||
|
fInputColorIsUsed = true;
|
||||||
|
fColorStages.reset();
|
||||||
|
this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding);
|
||||||
|
break;
|
||||||
|
case kEmitTransBlack_BlendOptFlag:
|
||||||
|
fColor = 0;
|
||||||
|
fCoverage = 0xff;
|
||||||
|
fInputColorIsUsed = true;
|
||||||
|
fInputCoverageIsUsed = true;
|
||||||
|
fColorStages.reset();
|
||||||
|
fCoverageStages.reset();
|
||||||
|
this->removeFixedFunctionVertexAttribs(0x1 << kColor_GrVertexAttribBinding |
|
||||||
|
0x1 << kCoverage_GrVertexAttribBinding);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SkFAIL("Unknown BlendOptFlag");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
|
void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
|
||||||
int numToRemove = 0;
|
int numToRemove = 0;
|
||||||
uint8_t maskCheck = 0x1;
|
uint8_t maskCheck = 0x1;
|
||||||
@ -50,6 +87,7 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
|
|||||||
}
|
}
|
||||||
maskCheck <<= 1;
|
maskCheck <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fOptVA.reset(fVACount - numToRemove);
|
fOptVA.reset(fVACount - numToRemove);
|
||||||
|
|
||||||
GrVertexAttrib* dst = fOptVA.get();
|
GrVertexAttrib* dst = fOptVA.get();
|
||||||
@ -64,9 +102,9 @@ void GrOptDrawState::removeFixedFunctionVertexAttribs(uint8_t removeVAFlag) {
|
|||||||
fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
|
fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = -1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
|
||||||
}
|
}
|
||||||
memcpy(dst, src, sizeof(GrVertexAttrib));
|
memcpy(dst, src, sizeof(GrVertexAttrib));
|
||||||
fFixedFunctionVertexAttribIndices[currAttrib.fBinding] = newIdx;
|
|
||||||
++newIdx;
|
++newIdx;
|
||||||
++dst;
|
++dst;
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,9 @@
|
|||||||
#ifndef GrOptDrawState_DEFINED
|
#ifndef GrOptDrawState_DEFINED
|
||||||
#define GrOptDrawState_DEFINED
|
#define GrOptDrawState_DEFINED
|
||||||
|
|
||||||
|
#include "GrDrawState.h"
|
||||||
#include "GrRODrawState.h"
|
#include "GrRODrawState.h"
|
||||||
|
|
||||||
class GrDrawState;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclass of GrRODrawState that holds an optimized version of a GrDrawState. Like it's parent
|
* Subclass of GrRODrawState that holds an optimized version of a GrDrawState. Like it's parent
|
||||||
* it is meant to be an immutable class, and simply adds a few helpful data members not in the
|
* it is meant to be an immutable class, and simply adds a few helpful data members not in the
|
||||||
@ -19,15 +18,19 @@ class GrDrawState;
|
|||||||
*/
|
*/
|
||||||
class GrOptDrawState : public GrRODrawState {
|
class GrOptDrawState : public GrRODrawState {
|
||||||
public:
|
public:
|
||||||
|
bool operator== (const GrOptDrawState& that) const;
|
||||||
|
|
||||||
|
bool inputColorIsUsed() const { return fInputColorIsUsed; }
|
||||||
|
bool inputCoverageIsUsed() const { return fInputCoverageIsUsed; }
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
* Constructs and optimized drawState out of a GrRODrawState.
|
* Constructs and optimized drawState out of a GrRODrawState.
|
||||||
*/
|
*/
|
||||||
explicit GrOptDrawState(const GrDrawState& drawState);
|
GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags,
|
||||||
|
GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff);
|
||||||
|
|
||||||
bool operator== (const GrOptDrawState& that) const;
|
/**
|
||||||
|
|
||||||
private:
|
|
||||||
/*
|
|
||||||
* Loops through all the color stage effects to check if the stage will ignore color input or
|
* Loops through all the color stage effects to check if the stage will ignore color input or
|
||||||
* always output a constant color. In the ignore color input case we can ignore all previous
|
* always output a constant color. In the ignore color input case we can ignore all previous
|
||||||
* stages. In the constant color case, we can ignore all previous stages and
|
* stages. In the constant color case, we can ignore all previous stages and
|
||||||
@ -37,7 +40,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
void copyEffectiveColorStages(const GrDrawState& ds);
|
void copyEffectiveColorStages(const GrDrawState& ds);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Loops through all the coverage stage effects to check if the stage will ignore color input.
|
* Loops through all the coverage stage effects to check if the stage will ignore color input.
|
||||||
* If a coverage stage will ignore input, then we can ignore all coverage stages before it. We
|
* If a coverage stage will ignore input, then we can ignore all coverage stages before it. We
|
||||||
* loop to determine the first effective coverage stage, and then copy all of our effective
|
* loop to determine the first effective coverage stage, and then copy all of our effective
|
||||||
@ -45,14 +48,18 @@ private:
|
|||||||
*/
|
*/
|
||||||
void copyEffectiveCoverageStages(const GrDrawState& ds);
|
void copyEffectiveCoverageStages(const GrDrawState& ds);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* This function takes in a flag and removes the corresponding fixed function vertex attributes.
|
* This function takes in a flag and removes the corresponding fixed function vertex attributes.
|
||||||
* The flags are in the same order as GrVertexAttribBinding array. If bit i of removeVAFlags is
|
* The flags are in the same order as GrVertexAttribBinding array. If bit i of removeVAFlags is
|
||||||
* set, then vertex attributes with binding (GrVertexAttribute)i will be removed.
|
* set, then vertex attributes with binding (GrVertexAttribute)i will be removed.
|
||||||
*/
|
*/
|
||||||
void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags);
|
void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags);
|
||||||
|
|
||||||
void removeColorVertexAttrib();
|
/**
|
||||||
|
* Alter the OptDrawState (adjusting stages, vertex attribs, flags, etc.) based on the
|
||||||
|
* BlendOptFlags.
|
||||||
|
*/
|
||||||
|
void adjustFromBlendOpts();
|
||||||
|
|
||||||
// These flags are needed to protect the code from creating an unused uniform color/coverage
|
// These flags are needed to protect the code from creating an unused uniform color/coverage
|
||||||
// which will cause shader compiler errors.
|
// which will cause shader compiler errors.
|
||||||
@ -61,6 +68,9 @@ private:
|
|||||||
|
|
||||||
SkAutoSTArray<4, GrVertexAttrib> fOptVA;
|
SkAutoSTArray<4, GrVertexAttrib> fOptVA;
|
||||||
|
|
||||||
|
BlendOptFlags fBlendOptFlags;
|
||||||
|
|
||||||
|
friend GrOptDrawState* GrDrawState::createOptState() const;
|
||||||
typedef GrRODrawState INHERITED;
|
typedef GrRODrawState INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -184,26 +184,6 @@ GrRODrawState::BlendOptFlags GrRODrawState::getBlendOpts(bool forceCoverage,
|
|||||||
dstCoeff = &bogusDstCoeff;
|
dstCoeff = &bogusDstCoeff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forceCoverage) {
|
|
||||||
return this->calcBlendOpts(true, srcCoeff, dstCoeff);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) {
|
|
||||||
*srcCoeff = fOptSrcBlend;
|
|
||||||
*dstCoeff = fOptDstBlend;
|
|
||||||
return fBlendOptFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff);
|
|
||||||
fOptSrcBlend = *srcCoeff;
|
|
||||||
fOptDstBlend = *dstCoeff;
|
|
||||||
|
|
||||||
return fBlendOptFlags;
|
|
||||||
}
|
|
||||||
|
|
||||||
GrRODrawState::BlendOptFlags GrRODrawState::calcBlendOpts(bool forceCoverage,
|
|
||||||
GrBlendCoeff* srcCoeff,
|
|
||||||
GrBlendCoeff* dstCoeff) const {
|
|
||||||
*srcCoeff = this->getSrcBlendCoeff();
|
*srcCoeff = this->getSrcBlendCoeff();
|
||||||
*dstCoeff = this->getDstBlendCoeff();
|
*dstCoeff = this->getDstBlendCoeff();
|
||||||
|
|
||||||
@ -225,6 +205,7 @@ GrRODrawState::BlendOptFlags GrRODrawState::calcBlendOpts(bool forceCoverage,
|
|||||||
if (this->getStencil().doesWrite()) {
|
if (this->getStencil().doesWrite()) {
|
||||||
return kEmitCoverage_BlendOptFlag;
|
return kEmitCoverage_BlendOptFlag;
|
||||||
} else {
|
} else {
|
||||||
|
*dstCoeff = kOne_GrBlendCoeff;
|
||||||
return kSkipDraw_BlendOptFlag;
|
return kSkipDraw_BlendOptFlag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -372,13 +353,3 @@ bool GrRODrawState::srcAlphaWillBeOne() const {
|
|||||||
return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnpackA(color);
|
return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnpackA(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
bool GrRODrawState::canIgnoreColorAttribute() const {
|
|
||||||
if (fBlendOptFlags & kInvalid_BlendOptFlag) {
|
|
||||||
this->getBlendOpts();
|
|
||||||
}
|
|
||||||
return SkToBool(fBlendOptFlags & (GrRODrawState::kEmitTransBlack_BlendOptFlag |
|
|
||||||
GrRODrawState::kEmitCoverage_BlendOptFlag));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -166,12 +166,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
GrColor getBlendConstant() const { return fBlendConstant; }
|
GrColor getBlendConstant() const { return fBlendConstant; }
|
||||||
|
|
||||||
/**
|
|
||||||
* We don't use supplied vertex color attributes if our blend mode is EmitCoverage or
|
|
||||||
* EmitTransBlack
|
|
||||||
*/
|
|
||||||
bool canIgnoreColorAttribute() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether multiplying the computed per-pixel color by the pixel's fractional
|
* Determines whether multiplying the computed per-pixel color by the pixel's fractional
|
||||||
* coverage before the blend will give the correct final destination color. In general it
|
* coverage before the blend will give the correct final destination color. In general it
|
||||||
@ -179,56 +173,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool canTweakAlphaForCoverage() const;
|
bool canTweakAlphaForCoverage() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Optimizations for blending / coverage to that can be applied based on the current state.
|
|
||||||
*/
|
|
||||||
enum BlendOptFlags {
|
|
||||||
/**
|
|
||||||
* No optimization
|
|
||||||
*/
|
|
||||||
kNone_BlendOpt = 0,
|
|
||||||
/**
|
|
||||||
* Don't draw at all
|
|
||||||
*/
|
|
||||||
kSkipDraw_BlendOptFlag = 0x1,
|
|
||||||
/**
|
|
||||||
* The coverage value does not have to be computed separately from alpha, the output
|
|
||||||
* color can be the modulation of the two.
|
|
||||||
*/
|
|
||||||
kCoverageAsAlpha_BlendOptFlag = 0x2,
|
|
||||||
/**
|
|
||||||
* Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
|
|
||||||
* "don't cares".
|
|
||||||
*/
|
|
||||||
kEmitCoverage_BlendOptFlag = 0x4,
|
|
||||||
/**
|
|
||||||
* Emit transparent black instead of the src color, no need to compute coverage.
|
|
||||||
*/
|
|
||||||
kEmitTransBlack_BlendOptFlag = 0x8,
|
|
||||||
/**
|
|
||||||
* Flag used to invalidate the cached BlendOptFlags, OptSrcCoeff, and OptDstCoeff cached by
|
|
||||||
* the get BlendOpts function.
|
|
||||||
*/
|
|
||||||
kInvalid_BlendOptFlag = 1 << 31,
|
|
||||||
};
|
|
||||||
GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines what optimizations can be applied based on the blend. The coefficients may have
|
|
||||||
* to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
|
|
||||||
* params that receive the tweaked coefficients. Normally the function looks at the current
|
|
||||||
* state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
|
|
||||||
* determine the blend optimizations that would be used if there was partial pixel coverage.
|
|
||||||
*
|
|
||||||
* Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
|
|
||||||
* playback) must call this function and respect the flags that replace the output color.
|
|
||||||
*
|
|
||||||
* If the cached BlendOptFlags does not have the invalidate bit set, then getBlendOpts will
|
|
||||||
* simply returned the cached flags and coefficients. Otherwise it will calculate the values.
|
|
||||||
*/
|
|
||||||
BlendOptFlags getBlendOpts(bool forceCoverage = false,
|
|
||||||
GrBlendCoeff* srcCoeff = NULL,
|
|
||||||
GrBlendCoeff* dstCoeff = NULL) const;
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@ -407,6 +351,52 @@ protected:
|
|||||||
|
|
||||||
bool isEqual(const GrRODrawState& that) const;
|
bool isEqual(const GrRODrawState& that) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optimizations for blending / coverage to that can be applied based on the current state.
|
||||||
|
*/
|
||||||
|
enum BlendOptFlags {
|
||||||
|
/**
|
||||||
|
* No optimization
|
||||||
|
*/
|
||||||
|
kNone_BlendOpt = 0,
|
||||||
|
/**
|
||||||
|
* Don't draw at all
|
||||||
|
*/
|
||||||
|
kSkipDraw_BlendOptFlag = 0x1,
|
||||||
|
/**
|
||||||
|
* The coverage value does not have to be computed separately from alpha, the the output
|
||||||
|
* color can be the modulation of the two.
|
||||||
|
*/
|
||||||
|
kCoverageAsAlpha_BlendOptFlag = 0x2,
|
||||||
|
/**
|
||||||
|
* Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
|
||||||
|
* "don't cares".
|
||||||
|
*/
|
||||||
|
kEmitCoverage_BlendOptFlag = 0x4,
|
||||||
|
/**
|
||||||
|
* Emit transparent black instead of the src color, no need to compute coverage.
|
||||||
|
*/
|
||||||
|
kEmitTransBlack_BlendOptFlag = 0x8,
|
||||||
|
};
|
||||||
|
GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines what optimizations can be applied based on the blend. The coefficients may have
|
||||||
|
* to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
|
||||||
|
* params that receive the tweaked coefficients. Normally the function looks at the current
|
||||||
|
* state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
|
||||||
|
* determine the blend optimizations that would be used if there was partial pixel coverage.
|
||||||
|
*
|
||||||
|
* Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
|
||||||
|
* playback) must call this function and respect the flags that replace the output color.
|
||||||
|
*
|
||||||
|
* If the cached BlendOptFlags does not have the invalidate bit set, then getBlendOpts will
|
||||||
|
* simply returned the cached flags and coefficients. Otherwise it will calculate the values.
|
||||||
|
*/
|
||||||
|
BlendOptFlags getBlendOpts(bool forceCoverage = false,
|
||||||
|
GrBlendCoeff* srcCoeff = NULL,
|
||||||
|
GrBlendCoeff* dstCoeff = NULL) const;
|
||||||
|
|
||||||
// These fields are roughly sorted by decreasing likelihood of being different in op==
|
// These fields are roughly sorted by decreasing likelihood of being different in op==
|
||||||
GrProgramResource fRenderTarget;
|
GrProgramResource fRenderTarget;
|
||||||
GrColor fColor;
|
GrColor fColor;
|
||||||
@ -429,10 +419,6 @@ protected:
|
|||||||
|
|
||||||
uint32_t fHints;
|
uint32_t fHints;
|
||||||
|
|
||||||
mutable GrBlendCoeff fOptSrcBlend;
|
|
||||||
mutable GrBlendCoeff fOptDstBlend;
|
|
||||||
mutable BlendOptFlags fBlendOptFlags;
|
|
||||||
|
|
||||||
// This is simply a different representation of info in fVertexAttribs and thus does
|
// This is simply a different representation of info in fVertexAttribs and thus does
|
||||||
// not need to be compared in op==.
|
// not need to be compared in op==.
|
||||||
int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
|
int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
|
||||||
@ -443,13 +429,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool srcAlphaWillBeOne() const;
|
bool srcAlphaWillBeOne() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function for getBlendOpts.
|
|
||||||
*/
|
|
||||||
BlendOptFlags calcBlendOpts(bool forceCoverage = false,
|
|
||||||
GrBlendCoeff* srcCoeff = NULL,
|
|
||||||
GrBlendCoeff* dstCoeff = NULL) const;
|
|
||||||
|
|
||||||
typedef SkRefCnt INHERITED;
|
typedef SkRefCnt INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
* Use of this source code is governed by a BSD-style license that can be
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "GrGLProgram.h"
|
#include "GrGLProgram.h"
|
||||||
|
|
||||||
#include "GrAllocator.h"
|
#include "GrAllocator.h"
|
||||||
@ -15,6 +14,7 @@
|
|||||||
#include "GrGLPathRendering.h"
|
#include "GrGLPathRendering.h"
|
||||||
#include "GrGLShaderVar.h"
|
#include "GrGLShaderVar.h"
|
||||||
#include "GrGLSL.h"
|
#include "GrGLSL.h"
|
||||||
|
#include "GrOptDrawState.h"
|
||||||
#include "SkXfermode.h"
|
#include "SkXfermode.h"
|
||||||
|
|
||||||
#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
|
#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
|
||||||
@ -108,31 +108,19 @@ void GrGLProgram::initSamplerUniforms() {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void GrGLProgram::setData(GrGpu::DrawType drawType,
|
void GrGLProgram::setData(const GrOptDrawState& optState,
|
||||||
GrDrawState::BlendOptFlags blendOpts,
|
GrGpu::DrawType drawType,
|
||||||
const GrEffectStage* geometryProcessor,
|
const GrEffectStage* geometryProcessor,
|
||||||
const GrEffectStage* colorStages[],
|
const GrEffectStage* colorStages[],
|
||||||
const GrEffectStage* coverageStages[],
|
const GrEffectStage* coverageStages[],
|
||||||
const GrDeviceCoordTexture* dstCopy,
|
const GrDeviceCoordTexture* dstCopy,
|
||||||
SharedGLState* sharedState) {
|
SharedGLState* sharedState) {
|
||||||
const GrDrawState& drawState = fGpu->getDrawState();
|
GrColor color = optState.getColor();
|
||||||
|
GrColor coverage = optState.getCoverageColor();
|
||||||
|
|
||||||
GrColor color;
|
this->setColor(optState, color, sharedState);
|
||||||
GrColor coverage;
|
this->setCoverage(optState, coverage, sharedState);
|
||||||
if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) {
|
this->setMatrixAndRenderTargetHeight(drawType, optState);
|
||||||
color = 0;
|
|
||||||
coverage = 0;
|
|
||||||
} else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
|
|
||||||
color = 0xffffffff;
|
|
||||||
coverage = drawState.getCoverageColor();
|
|
||||||
} else {
|
|
||||||
color = drawState.getColor();
|
|
||||||
coverage = drawState.getCoverageColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
this->setColor(drawState, color, sharedState);
|
|
||||||
this->setCoverage(drawState, coverage, sharedState);
|
|
||||||
this->setMatrixAndRenderTargetHeight(drawType, drawState);
|
|
||||||
|
|
||||||
if (dstCopy) {
|
if (dstCopy) {
|
||||||
if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) {
|
if (fBuiltinUniformHandles.fDstCopyTopLeftUni.isValid()) {
|
||||||
@ -170,11 +158,11 @@ void GrGLProgram::setData(GrGpu::DrawType drawType,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLProgram::setColor(const GrDrawState& drawState,
|
void GrGLProgram::setColor(const GrOptDrawState& optState,
|
||||||
GrColor color,
|
GrColor color,
|
||||||
SharedGLState* sharedState) {
|
SharedGLState* sharedState) {
|
||||||
const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
|
const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
|
||||||
if (!drawState.hasColorVertexAttribute() || drawState.canIgnoreColorAttribute()) {
|
if (!optState.hasColorVertexAttribute()) {
|
||||||
switch (header.fColorInput) {
|
switch (header.fColorInput) {
|
||||||
case GrGLProgramDesc::kAttribute_ColorInput:
|
case GrGLProgramDesc::kAttribute_ColorInput:
|
||||||
SkASSERT(-1 != header.fColorAttributeIndex);
|
SkASSERT(-1 != header.fColorAttributeIndex);
|
||||||
@ -209,11 +197,11 @@ void GrGLProgram::setColor(const GrDrawState& drawState,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLProgram::setCoverage(const GrDrawState& drawState,
|
void GrGLProgram::setCoverage(const GrOptDrawState& optState,
|
||||||
GrColor coverage,
|
GrColor coverage,
|
||||||
SharedGLState* sharedState) {
|
SharedGLState* sharedState) {
|
||||||
const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
|
const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader();
|
||||||
if (!drawState.hasCoverageVertexAttribute()) {
|
if (!optState.hasCoverageVertexAttribute()) {
|
||||||
switch (header.fCoverageInput) {
|
switch (header.fCoverageInput) {
|
||||||
case GrGLProgramDesc::kAttribute_ColorInput:
|
case GrGLProgramDesc::kAttribute_ColorInput:
|
||||||
if (sharedState->fConstAttribCoverage != coverage ||
|
if (sharedState->fConstAttribCoverage != coverage ||
|
||||||
@ -248,8 +236,8 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
|
void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
|
||||||
const GrDrawState& drawState) {
|
const GrOptDrawState& optState) {
|
||||||
const GrRenderTarget* rt = drawState.getRenderTarget();
|
const GrRenderTarget* rt = optState.getRenderTarget();
|
||||||
SkISize size;
|
SkISize size;
|
||||||
size.set(rt->width(), rt->height());
|
size.set(rt->width(), rt->height());
|
||||||
|
|
||||||
@ -261,13 +249,13 @@ void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (GrGpu::IsPathRenderingDrawType(drawType)) {
|
if (GrGpu::IsPathRenderingDrawType(drawType)) {
|
||||||
fGpu->glPathRendering()->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
|
fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin());
|
||||||
} else if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
|
} else if (fMatrixState.fRenderTargetOrigin != rt->origin() ||
|
||||||
fMatrixState.fRenderTargetSize != size ||
|
fMatrixState.fRenderTargetSize != size ||
|
||||||
!fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix())) {
|
!fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) {
|
||||||
SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid());
|
SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid());
|
||||||
|
|
||||||
fMatrixState.fViewMatrix = drawState.getViewMatrix();
|
fMatrixState.fViewMatrix = optState.getViewMatrix();
|
||||||
fMatrixState.fRenderTargetSize = size;
|
fMatrixState.fRenderTargetSize = size;
|
||||||
fMatrixState.fRenderTargetOrigin = rt->origin();
|
fMatrixState.fRenderTargetOrigin = rt->origin();
|
||||||
|
|
||||||
|
@ -157,8 +157,8 @@ public:
|
|||||||
* GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage
|
* GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage
|
||||||
* stages come from GrGLProgramDesc::Build().
|
* stages come from GrGLProgramDesc::Build().
|
||||||
*/
|
*/
|
||||||
void setData(GrGpu::DrawType,
|
void setData(const GrOptDrawState&,
|
||||||
GrDrawState::BlendOptFlags,
|
GrGpu::DrawType,
|
||||||
const GrEffectStage* geometryProcessor,
|
const GrEffectStage* geometryProcessor,
|
||||||
const GrEffectStage* colorStages[],
|
const GrEffectStage* colorStages[],
|
||||||
const GrEffectStage* coverageStages[],
|
const GrEffectStage* coverageStages[],
|
||||||
@ -177,14 +177,14 @@ private:
|
|||||||
|
|
||||||
// Helper for setData(). Makes GL calls to specify the initial color when there is not
|
// Helper for setData(). Makes GL calls to specify the initial color when there is not
|
||||||
// per-vertex colors.
|
// per-vertex colors.
|
||||||
void setColor(const GrDrawState&, GrColor color, SharedGLState*);
|
void setColor(const GrOptDrawState&, GrColor color, SharedGLState*);
|
||||||
|
|
||||||
// Helper for setData(). Makes GL calls to specify the initial coverage when there is not
|
// Helper for setData(). Makes GL calls to specify the initial coverage when there is not
|
||||||
// per-vertex coverages.
|
// per-vertex coverages.
|
||||||
void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*);
|
void setCoverage(const GrOptDrawState&, GrColor coverage, SharedGLState*);
|
||||||
|
|
||||||
// Helper for setData() that sets the view matrix and loads the render target height uniform
|
// Helper for setData() that sets the view matrix and loads the render target height uniform
|
||||||
void setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrDrawState&);
|
void setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState&);
|
||||||
|
|
||||||
// these reflect the current values of uniforms (GL uniform values travel with program)
|
// these reflect the current values of uniforms (GL uniform values travel with program)
|
||||||
MatrixState fMatrixState;
|
MatrixState fMatrixState;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "GrBackendEffectFactory.h"
|
#include "GrBackendEffectFactory.h"
|
||||||
#include "GrEffect.h"
|
#include "GrEffect.h"
|
||||||
#include "GrGpuGL.h"
|
#include "GrGpuGL.h"
|
||||||
|
#include "GrOptDrawState.h"
|
||||||
|
|
||||||
#include "SkChecksum.h"
|
#include "SkChecksum.h"
|
||||||
|
|
||||||
@ -48,9 +49,8 @@ bool GrGLProgramDesc::GetEffectKeyAndUpdateStats(const GrEffectStage& stage,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
|
||||||
GrGpu::DrawType drawType,
|
GrGpu::DrawType drawType,
|
||||||
GrDrawState::BlendOptFlags blendOpts,
|
|
||||||
GrBlendCoeff srcCoeff,
|
GrBlendCoeff srcCoeff,
|
||||||
GrBlendCoeff dstCoeff,
|
GrBlendCoeff dstCoeff,
|
||||||
const GrGpuGL* gpu,
|
const GrGpuGL* gpu,
|
||||||
@ -62,47 +62,19 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
colorStages->reset();
|
colorStages->reset();
|
||||||
coverageStages->reset();
|
coverageStages->reset();
|
||||||
|
|
||||||
// This should already have been caught
|
bool inputColorIsUsed = optState.inputColorIsUsed();
|
||||||
SkASSERT(!(GrDrawState::kSkipDraw_BlendOptFlag & blendOpts));
|
bool inputCoverageIsUsed = optState.inputColorIsUsed();
|
||||||
|
|
||||||
bool skipCoverage = SkToBool(blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag);
|
|
||||||
|
|
||||||
bool skipColor = SkToBool(blendOpts & (GrDrawState::kEmitTransBlack_BlendOptFlag |
|
|
||||||
GrDrawState::kEmitCoverage_BlendOptFlag));
|
|
||||||
|
|
||||||
int firstEffectiveColorStage = 0;
|
|
||||||
bool inputColorIsUsed = true;
|
|
||||||
|
|
||||||
if (!skipColor) {
|
|
||||||
firstEffectiveColorStage = drawState.numColorStages();
|
|
||||||
while (firstEffectiveColorStage > 0 && inputColorIsUsed) {
|
|
||||||
--firstEffectiveColorStage;
|
|
||||||
const GrEffect* effect = drawState.getColorStage(firstEffectiveColorStage).getEffect();
|
|
||||||
inputColorIsUsed = effect->willUseInputColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int firstEffectiveCoverageStage = 0;
|
|
||||||
bool inputCoverageIsUsed = true;
|
|
||||||
if (!skipCoverage) {
|
|
||||||
firstEffectiveCoverageStage = drawState.numCoverageStages();
|
|
||||||
while (firstEffectiveCoverageStage > 0 && inputCoverageIsUsed) {
|
|
||||||
--firstEffectiveCoverageStage;
|
|
||||||
const GrEffect* effect = drawState.getCoverageStage(firstEffectiveCoverageStage).getEffect();
|
|
||||||
inputCoverageIsUsed = effect->willUseInputColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The descriptor is used as a cache key. Thus when a field of the
|
// The descriptor is used as a cache key. Thus when a field of the
|
||||||
// descriptor will not affect program generation (because of the attribute
|
// descriptor will not affect program generation (because of the attribute
|
||||||
// bindings in use or other descriptor field settings) it should be set
|
// bindings in use or other descriptor field settings) it should be set
|
||||||
// to a canonical value to avoid duplicate programs with different keys.
|
// to a canonical value to avoid duplicate programs with different keys.
|
||||||
|
|
||||||
bool requiresColorAttrib = !skipColor && drawState.hasColorVertexAttribute();
|
bool requiresColorAttrib = optState.hasColorVertexAttribute();
|
||||||
bool requiresCoverageAttrib = !skipCoverage && drawState.hasCoverageVertexAttribute();
|
bool requiresCoverageAttrib = optState.hasCoverageVertexAttribute();
|
||||||
// we only need the local coords if we're actually going to generate effect code
|
// we only need the local coords if we're actually going to generate effect code
|
||||||
bool requiresLocalCoordAttrib = !(skipCoverage && skipColor) &&
|
bool requiresLocalCoordAttrib = optState.numTotalStages() > 0 &&
|
||||||
drawState.hasLocalCoordAttribute();
|
optState.hasLocalCoordAttribute();
|
||||||
|
|
||||||
bool readsDst = false;
|
bool readsDst = false;
|
||||||
bool readFragPosition = false;
|
bool readFragPosition = false;
|
||||||
@ -110,16 +82,8 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
// Provide option for shader programs without vertex shader only when drawing paths.
|
// Provide option for shader programs without vertex shader only when drawing paths.
|
||||||
bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType);
|
bool requiresVertexShader = !GrGpu::IsPathRenderingDrawType(drawType);
|
||||||
|
|
||||||
int numStages = 0;
|
int numStages = optState.numTotalStages();
|
||||||
if (drawState.hasGeometryProcessor()) {
|
|
||||||
numStages++;
|
|
||||||
}
|
|
||||||
if (!skipColor) {
|
|
||||||
numStages += drawState.numColorStages() - firstEffectiveColorStage;
|
|
||||||
}
|
|
||||||
if (!skipCoverage) {
|
|
||||||
numStages += drawState.numCoverageStages() - firstEffectiveCoverageStage;
|
|
||||||
}
|
|
||||||
GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t));
|
GR_STATIC_ASSERT(0 == kEffectKeyOffsetsAndLengthOffset % sizeof(uint32_t));
|
||||||
// Make room for everything up to and including the array of offsets to effect keys.
|
// Make room for everything up to and including the array of offsets to effect keys.
|
||||||
desc->fKey.reset();
|
desc->fKey.reset();
|
||||||
@ -133,7 +97,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
memset(desc->header(), 0, kHeaderSize);
|
memset(desc->header(), 0, kHeaderSize);
|
||||||
|
|
||||||
// We can only have one effect which touches the vertex shader
|
// We can only have one effect which touches the vertex shader
|
||||||
if (drawState.hasGeometryProcessor()) {
|
if (optState.hasGeometryProcessor()) {
|
||||||
uint16_t* offsetAndSize =
|
uint16_t* offsetAndSize =
|
||||||
reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
|
reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
|
||||||
offsetAndSizeIndex * 2 * sizeof(uint16_t));
|
offsetAndSizeIndex * 2 * sizeof(uint16_t));
|
||||||
@ -142,7 +106,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
uint16_t effectKeySize;
|
uint16_t effectKeySize;
|
||||||
uint32_t effectOffset = desc->fKey.count();
|
uint32_t effectOffset = desc->fKey.count();
|
||||||
effectKeySuccess |= GetEffectKeyAndUpdateStats(
|
effectKeySuccess |= GetEffectKeyAndUpdateStats(
|
||||||
*drawState.getGeometryProcessor(), gpu->glCaps(),
|
*optState.getGeometryProcessor(), gpu->glCaps(),
|
||||||
requiresLocalCoordAttrib, &b,
|
requiresLocalCoordAttrib, &b,
|
||||||
&effectKeySize, &readsDst,
|
&effectKeySize, &readsDst,
|
||||||
&readFragPosition, &requiresVertexShader);
|
&readFragPosition, &requiresVertexShader);
|
||||||
@ -151,57 +115,55 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
offsetAndSize[0] = SkToU16(effectOffset);
|
offsetAndSize[0] = SkToU16(effectOffset);
|
||||||
offsetAndSize[1] = effectKeySize;
|
offsetAndSize[1] = effectKeySize;
|
||||||
++offsetAndSizeIndex;
|
++offsetAndSizeIndex;
|
||||||
*geometryProcessor = drawState.getGeometryProcessor();
|
*geometryProcessor = optState.getGeometryProcessor();
|
||||||
SkASSERT(requiresVertexShader);
|
SkASSERT(requiresVertexShader);
|
||||||
header->fHasGeometryProcessor = true;
|
header->fHasGeometryProcessor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skipColor) {
|
for (int s = 0; s < optState.numColorStages(); ++s) {
|
||||||
for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
|
uint16_t* offsetAndSize =
|
||||||
uint16_t* offsetAndSize =
|
reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
|
||||||
reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
|
offsetAndSizeIndex * 2 * sizeof(uint16_t));
|
||||||
offsetAndSizeIndex * 2 * sizeof(uint16_t));
|
|
||||||
|
|
||||||
bool effectRequiresVertexShader = false;
|
bool effectRequiresVertexShader = false;
|
||||||
GrEffectKeyBuilder b(&desc->fKey);
|
GrEffectKeyBuilder b(&desc->fKey);
|
||||||
uint16_t effectKeySize;
|
uint16_t effectKeySize;
|
||||||
uint32_t effectOffset = desc->fKey.count();
|
uint32_t effectOffset = desc->fKey.count();
|
||||||
effectKeySuccess |= GetEffectKeyAndUpdateStats(
|
effectKeySuccess |= GetEffectKeyAndUpdateStats(
|
||||||
drawState.getColorStage(s), gpu->glCaps(),
|
optState.getColorStage(s), gpu->glCaps(),
|
||||||
requiresLocalCoordAttrib, &b,
|
requiresLocalCoordAttrib, &b,
|
||||||
&effectKeySize, &readsDst,
|
&effectKeySize, &readsDst,
|
||||||
&readFragPosition, &effectRequiresVertexShader);
|
&readFragPosition, &effectRequiresVertexShader);
|
||||||
effectKeySuccess |= (effectOffset <= SK_MaxU16);
|
effectKeySuccess |= (effectOffset <= SK_MaxU16);
|
||||||
|
|
||||||
offsetAndSize[0] = SkToU16(effectOffset);
|
offsetAndSize[0] = SkToU16(effectOffset);
|
||||||
offsetAndSize[1] = effectKeySize;
|
offsetAndSize[1] = effectKeySize;
|
||||||
++offsetAndSizeIndex;
|
++offsetAndSizeIndex;
|
||||||
SkASSERT(!effectRequiresVertexShader);
|
SkASSERT(!effectRequiresVertexShader);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!skipCoverage) {
|
|
||||||
for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) {
|
|
||||||
uint16_t* offsetAndSize =
|
|
||||||
reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
|
|
||||||
offsetAndSizeIndex * 2 * sizeof(uint16_t));
|
|
||||||
|
|
||||||
bool effectRequiresVertexShader = false;
|
for (int s = 0; s < optState.numCoverageStages(); ++s) {
|
||||||
GrEffectKeyBuilder b(&desc->fKey);
|
uint16_t* offsetAndSize =
|
||||||
uint16_t effectKeySize;
|
reinterpret_cast<uint16_t*>(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset +
|
||||||
uint32_t effectOffset = desc->fKey.count();
|
offsetAndSizeIndex * 2 * sizeof(uint16_t));
|
||||||
effectKeySuccess |= GetEffectKeyAndUpdateStats(
|
|
||||||
drawState.getCoverageStage(s), gpu->glCaps(),
|
|
||||||
requiresLocalCoordAttrib, &b,
|
|
||||||
&effectKeySize, &readsDst,
|
|
||||||
&readFragPosition, &effectRequiresVertexShader);
|
|
||||||
effectKeySuccess |= (effectOffset <= SK_MaxU16);
|
|
||||||
|
|
||||||
offsetAndSize[0] = SkToU16(effectOffset);
|
bool effectRequiresVertexShader = false;
|
||||||
offsetAndSize[1] = effectKeySize;
|
GrEffectKeyBuilder b(&desc->fKey);
|
||||||
++offsetAndSizeIndex;
|
uint16_t effectKeySize;
|
||||||
SkASSERT(!effectRequiresVertexShader);
|
uint32_t effectOffset = desc->fKey.count();
|
||||||
}
|
effectKeySuccess |= GetEffectKeyAndUpdateStats(
|
||||||
|
optState.getCoverageStage(s), gpu->glCaps(),
|
||||||
|
requiresLocalCoordAttrib, &b,
|
||||||
|
&effectKeySize, &readsDst,
|
||||||
|
&readFragPosition, &effectRequiresVertexShader);
|
||||||
|
effectKeySuccess |= (effectOffset <= SK_MaxU16);
|
||||||
|
|
||||||
|
offsetAndSize[0] = SkToU16(effectOffset);
|
||||||
|
offsetAndSize[1] = effectKeySize;
|
||||||
|
++offsetAndSizeIndex;
|
||||||
|
SkASSERT(!effectRequiresVertexShader);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!effectKeySuccess) {
|
if (!effectKeySuccess) {
|
||||||
desc->fKey.reset();
|
desc->fKey.reset();
|
||||||
return false;
|
return false;
|
||||||
@ -224,20 +186,20 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
#endif
|
#endif
|
||||||
bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->pathRenderingSupport();
|
bool defaultToUniformInputs = GR_GL_NO_CONSTANT_ATTRIBUTES || gpu->caps()->pathRenderingSupport();
|
||||||
|
|
||||||
if (!inputColorIsUsed && !skipColor) {
|
if (!inputColorIsUsed) {
|
||||||
header->fColorInput = kAllOnes_ColorInput;
|
header->fColorInput = kAllOnes_ColorInput;
|
||||||
} else if (defaultToUniformInputs && !requiresColorAttrib && inputColorIsUsed) {
|
} else if (defaultToUniformInputs && !requiresColorAttrib) {
|
||||||
header->fColorInput = kUniform_ColorInput;
|
header->fColorInput = kUniform_ColorInput;
|
||||||
} else {
|
} else {
|
||||||
header->fColorInput = kAttribute_ColorInput;
|
header->fColorInput = kAttribute_ColorInput;
|
||||||
header->fRequiresVertexShader = true;
|
header->fRequiresVertexShader = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor();
|
bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == optState.getCoverageColor();
|
||||||
|
|
||||||
if ((covIsSolidWhite || !inputCoverageIsUsed) && !skipCoverage) {
|
if (covIsSolidWhite || !inputCoverageIsUsed) {
|
||||||
header->fCoverageInput = kAllOnes_ColorInput;
|
header->fCoverageInput = kAllOnes_ColorInput;
|
||||||
} else if (defaultToUniformInputs && !requiresCoverageAttrib && inputCoverageIsUsed) {
|
} else if (defaultToUniformInputs && !requiresCoverageAttrib) {
|
||||||
header->fCoverageInput = kUniform_ColorInput;
|
header->fCoverageInput = kUniform_ColorInput;
|
||||||
} else {
|
} else {
|
||||||
header->fCoverageInput = kAttribute_ColorInput;
|
header->fCoverageInput = kAttribute_ColorInput;
|
||||||
@ -259,19 +221,19 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
|
|
||||||
if (readFragPosition) {
|
if (readFragPosition) {
|
||||||
header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(
|
header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(
|
||||||
drawState.getRenderTarget(), gpu->glCaps());
|
optState.getRenderTarget(), gpu->glCaps());
|
||||||
} else {
|
} else {
|
||||||
header->fFragPosKey = 0;
|
header->fFragPosKey = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record attribute indices
|
// Record attribute indices
|
||||||
header->fPositionAttributeIndex = drawState.positionAttributeIndex();
|
header->fPositionAttributeIndex = optState.positionAttributeIndex();
|
||||||
header->fLocalCoordAttributeIndex = drawState.localCoordAttributeIndex();
|
header->fLocalCoordAttributeIndex = optState.localCoordAttributeIndex();
|
||||||
|
|
||||||
// For constant color and coverage we need an attribute with an index beyond those already set
|
// For constant color and coverage we need an attribute with an index beyond those already set
|
||||||
int availableAttributeIndex = drawState.getVertexAttribCount();
|
int availableAttributeIndex = optState.getVertexAttribCount();
|
||||||
if (requiresColorAttrib) {
|
if (requiresColorAttrib) {
|
||||||
header->fColorAttributeIndex = drawState.colorVertexAttributeIndex();
|
header->fColorAttributeIndex = optState.colorVertexAttributeIndex();
|
||||||
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) {
|
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) {
|
||||||
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
|
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
|
||||||
header->fColorAttributeIndex = availableAttributeIndex;
|
header->fColorAttributeIndex = availableAttributeIndex;
|
||||||
@ -281,7 +243,7 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (requiresCoverageAttrib) {
|
if (requiresCoverageAttrib) {
|
||||||
header->fCoverageAttributeIndex = drawState.coverageVertexAttributeIndex();
|
header->fCoverageAttributeIndex = optState.coverageVertexAttributeIndex();
|
||||||
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
|
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
|
||||||
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
|
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
|
||||||
header->fCoverageAttributeIndex = availableAttributeIndex;
|
header->fCoverageAttributeIndex = availableAttributeIndex;
|
||||||
@ -295,15 +257,13 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
header->fCoverageOutput = kModulate_CoverageOutput;
|
header->fCoverageOutput = kModulate_CoverageOutput;
|
||||||
|
|
||||||
// If we do have coverage determine whether it matters.
|
// If we do have coverage determine whether it matters.
|
||||||
bool separateCoverageFromColor = drawState.hasGeometryProcessor();
|
bool separateCoverageFromColor = optState.hasGeometryProcessor();
|
||||||
if (!drawState.isCoverageDrawing() && !skipCoverage &&
|
if (!optState.isCoverageDrawing() &&
|
||||||
(drawState.numCoverageStages() > 0 ||
|
(optState.numCoverageStages() > 0 ||
|
||||||
drawState.hasGeometryProcessor() ||
|
optState.hasGeometryProcessor() ||
|
||||||
requiresCoverageAttrib)) {
|
requiresCoverageAttrib)) {
|
||||||
|
|
||||||
if (gpu->caps()->dualSourceBlendingSupport() &&
|
if (gpu->caps()->dualSourceBlendingSupport()) {
|
||||||
!(blendOpts & (GrDrawState::kEmitCoverage_BlendOptFlag |
|
|
||||||
GrDrawState::kCoverageAsAlpha_BlendOptFlag))) {
|
|
||||||
if (kZero_GrBlendCoeff == dstCoeff) {
|
if (kZero_GrBlendCoeff == dstCoeff) {
|
||||||
// write the coverage value to second color
|
// write the coverage value to second color
|
||||||
header->fCoverageOutput = kSecondaryCoverage_CoverageOutput;
|
header->fCoverageOutput = kSecondaryCoverage_CoverageOutput;
|
||||||
@ -325,22 +285,19 @@ bool GrGLProgramDesc::Build(const GrDrawState& drawState,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skipColor) {
|
for (int s = 0; s < optState.numColorStages(); ++s) {
|
||||||
for (int s = firstEffectiveColorStage; s < drawState.numColorStages(); ++s) {
|
colorStages->push_back(&optState.getColorStage(s));
|
||||||
colorStages->push_back(&drawState.getColorStage(s));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!skipCoverage) {
|
SkTArray<const GrEffectStage*, true>* array;
|
||||||
SkTArray<const GrEffectStage*, true>* array;
|
if (separateCoverageFromColor) {
|
||||||
if (separateCoverageFromColor) {
|
array = coverageStages;
|
||||||
array = coverageStages;
|
} else {
|
||||||
} else {
|
array = colorStages;
|
||||||
array = colorStages;
|
|
||||||
}
|
|
||||||
for (int s = firstEffectiveCoverageStage; s < drawState.numCoverageStages(); ++s) {
|
|
||||||
array->push_back(&drawState.getCoverageStage(s));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
for (int s = 0; s < optState.numCoverageStages(); ++s) {
|
||||||
|
array->push_back(&optState.getCoverageStage(s));
|
||||||
|
}
|
||||||
|
|
||||||
header->fColorEffectCnt = colorStages->count();
|
header->fColorEffectCnt = colorStages->count();
|
||||||
header->fCoverageEffectCnt = coverageStages->count();
|
header->fCoverageEffectCnt = coverageStages->count();
|
||||||
|
|
||||||
|
@ -55,15 +55,13 @@ public:
|
|||||||
int currAttribIndex);
|
int currAttribIndex);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the
|
* Builds a program descriptor from a GrOptDrawState. Whether the primitive type is points, and
|
||||||
* output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs. It also
|
* the caps of the GrGpuGL are also inputs. It also outputs the color and coverage stages
|
||||||
* outputs the color and coverage stages referenced by the generated descriptor. This may
|
* referenced by the generated descriptor. Coverage stages from the drawState may be treated as
|
||||||
* not contain all stages from the draw state and coverage stages from the drawState may
|
* color stages in the output.
|
||||||
* be treated as color stages in the output.
|
|
||||||
*/
|
*/
|
||||||
static bool Build(const GrDrawState&,
|
static bool Build(const GrOptDrawState&,
|
||||||
GrGpu::DrawType drawType,
|
GrGpu::DrawType drawType,
|
||||||
GrDrawState::BlendOptFlags,
|
|
||||||
GrBlendCoeff srcCoeff,
|
GrBlendCoeff srcCoeff,
|
||||||
GrBlendCoeff dstCoeff,
|
GrBlendCoeff dstCoeff,
|
||||||
const GrGpuGL* gpu,
|
const GrGpuGL* gpu,
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "GrGpuGL.h"
|
#include "GrGpuGL.h"
|
||||||
#include "GrGLStencilBuffer.h"
|
#include "GrGLStencilBuffer.h"
|
||||||
|
#include "GrOptDrawState.h"
|
||||||
#include "GrTemplates.h"
|
#include "GrTemplates.h"
|
||||||
#include "GrTypes.h"
|
#include "GrTypes.h"
|
||||||
#include "SkStrokeRec.h"
|
#include "SkStrokeRec.h"
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
|
|
||||||
#include "GrEffect.h"
|
#include "GrEffect.h"
|
||||||
#include "GrGLEffect.h"
|
#include "GrGLEffect.h"
|
||||||
#include "SkRTConf.h"
|
|
||||||
#include "GrGLPathRendering.h"
|
#include "GrGLPathRendering.h"
|
||||||
|
#include "GrOptDrawState.h"
|
||||||
|
#include "SkRTConf.h"
|
||||||
#include "SkTSearch.h"
|
#include "SkTSearch.h"
|
||||||
|
|
||||||
#ifdef PROGRAM_CACHE_STATS
|
#ifdef PROGRAM_CACHE_STATS
|
||||||
@ -204,23 +205,25 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc,
|
|||||||
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
|
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
|
||||||
|
|
||||||
bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) {
|
bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) {
|
||||||
const GrDrawState& drawState = this->getDrawState();
|
SkAutoTUnref<GrOptDrawState> optState(this->getDrawState().createOptState());
|
||||||
|
|
||||||
// GrGpu::setupClipAndFlushState should have already checked this and bailed if not true.
|
// GrGpu::setupClipAndFlushState should have already checked this and bailed if not true.
|
||||||
SkASSERT(drawState.getRenderTarget());
|
SkASSERT(optState->getRenderTarget());
|
||||||
|
|
||||||
if (kStencilPath_DrawType == type) {
|
if (kStencilPath_DrawType == type) {
|
||||||
const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
|
const GrRenderTarget* rt = optState->getRenderTarget();
|
||||||
SkISize size;
|
SkISize size;
|
||||||
size.set(rt->width(), rt->height());
|
size.set(rt->width(), rt->height());
|
||||||
this->glPathRendering()->setProjectionMatrix(drawState.getViewMatrix(), size, rt->origin());
|
this->glPathRendering()->setProjectionMatrix(optState->getViewMatrix(), size, rt->origin());
|
||||||
} else {
|
} else {
|
||||||
this->flushMiscFixedFunctionState();
|
this->flushMiscFixedFunctionState();
|
||||||
|
|
||||||
GrBlendCoeff srcCoeff;
|
GrBlendCoeff srcCoeff = optState->getSrcBlendCoeff();
|
||||||
GrBlendCoeff dstCoeff;
|
GrBlendCoeff dstCoeff = optState->getDstBlendCoeff();
|
||||||
GrDrawState::BlendOptFlags blendOpts = drawState.getBlendOpts(false, &srcCoeff, &dstCoeff);
|
|
||||||
if (GrDrawState::kSkipDraw_BlendOptFlag & blendOpts) {
|
// In these blend coeff's we end up drawing nothing so we can skip draw all together
|
||||||
|
if (kZero_GrBlendCoeff == srcCoeff && kOne_GrBlendCoeff == dstCoeff &&
|
||||||
|
!optState->getStencil().doesWrite()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,9 +231,8 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
|
|||||||
SkSTArray<8, const GrEffectStage*, true> colorStages;
|
SkSTArray<8, const GrEffectStage*, true> colorStages;
|
||||||
SkSTArray<8, const GrEffectStage*, true> coverageStages;
|
SkSTArray<8, const GrEffectStage*, true> coverageStages;
|
||||||
GrGLProgramDesc desc;
|
GrGLProgramDesc desc;
|
||||||
if (!GrGLProgramDesc::Build(this->getDrawState(),
|
if (!GrGLProgramDesc::Build(*optState.get(),
|
||||||
type,
|
type,
|
||||||
blendOpts,
|
|
||||||
srcCoeff,
|
srcCoeff,
|
||||||
dstCoeff,
|
dstCoeff,
|
||||||
this,
|
this,
|
||||||
@ -263,8 +265,8 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
|
|||||||
fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff);
|
fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff);
|
||||||
this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
|
this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
|
||||||
|
|
||||||
fCurrentProgram->setData(type,
|
fCurrentProgram->setData(*optState.get(),
|
||||||
blendOpts,
|
type,
|
||||||
geometryProcessor,
|
geometryProcessor,
|
||||||
colorStages.begin(),
|
colorStages.begin(),
|
||||||
coverageStages.begin(),
|
coverageStages.begin(),
|
||||||
@ -272,15 +274,15 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
|
|||||||
&fSharedGLProgramState);
|
&fSharedGLProgramState);
|
||||||
}
|
}
|
||||||
|
|
||||||
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(drawState.getRenderTarget());
|
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState->getRenderTarget());
|
||||||
this->flushStencil(type);
|
this->flushStencil(type);
|
||||||
this->flushScissor(glRT->getViewport(), glRT->origin());
|
this->flushScissor(glRT->getViewport(), glRT->origin());
|
||||||
this->flushAAState(type);
|
this->flushAAState(type);
|
||||||
|
|
||||||
SkIRect* devRect = NULL;
|
SkIRect* devRect = NULL;
|
||||||
SkIRect devClipBounds;
|
SkIRect devClipBounds;
|
||||||
if (drawState.isClipState()) {
|
if (optState->isClipState()) {
|
||||||
this->getClip()->getConservativeBounds(drawState.getRenderTarget(), &devClipBounds);
|
this->getClip()->getConservativeBounds(optState->getRenderTarget(), &devClipBounds);
|
||||||
devRect = &devClipBounds;
|
devRect = &devClipBounds;
|
||||||
}
|
}
|
||||||
// This must come after textures are flushed because a texture may need
|
// This must come after textures are flushed because a texture may need
|
||||||
@ -291,8 +293,9 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
|
void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
|
||||||
|
SkAutoTUnref<GrOptDrawState> optState(this->getDrawState().createOptState());
|
||||||
|
|
||||||
GrGLsizei stride = static_cast<GrGLsizei>(this->getDrawState().getVertexStride());
|
GrGLsizei stride = static_cast<GrGLsizei>(optState->getVertexStride());
|
||||||
|
|
||||||
size_t vertexOffsetInBytes = stride * info.startVertex();
|
size_t vertexOffsetInBytes = stride * info.startVertex();
|
||||||
|
|
||||||
@ -346,16 +349,12 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
|
|||||||
fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf);
|
fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf);
|
||||||
|
|
||||||
if (fCurrentProgram->hasVertexShader()) {
|
if (fCurrentProgram->hasVertexShader()) {
|
||||||
int vertexAttribCount = this->getDrawState().getVertexAttribCount();
|
int vertexAttribCount = optState->getVertexAttribCount();
|
||||||
uint32_t usedAttribArraysMask = 0;
|
uint32_t usedAttribArraysMask = 0;
|
||||||
const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs();
|
const GrVertexAttrib* vertexAttrib = optState->getVertexAttribs();
|
||||||
|
|
||||||
bool canIgnoreColorAttrib = this->getDrawState().canIgnoreColorAttribute();
|
|
||||||
|
|
||||||
for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
|
for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
|
||||||
++vertexAttribIndex, ++vertexAttrib) {
|
++vertexAttribIndex, ++vertexAttrib) {
|
||||||
|
|
||||||
if (kColor_GrVertexAttribBinding != vertexAttrib->fBinding || !canIgnoreColorAttrib) {
|
|
||||||
usedAttribArraysMask |= (1 << vertexAttribIndex);
|
usedAttribArraysMask |= (1 << vertexAttribIndex);
|
||||||
GrVertexAttribType attribType = vertexAttrib->fType;
|
GrVertexAttribType attribType = vertexAttrib->fType;
|
||||||
attribState->set(this,
|
attribState->set(this,
|
||||||
@ -367,7 +366,6 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
|
|||||||
stride,
|
stride,
|
||||||
reinterpret_cast<GrGLvoid*>(
|
reinterpret_cast<GrGLvoid*>(
|
||||||
vertexOffsetInBytes + vertexAttrib->fOffset));
|
vertexOffsetInBytes + vertexAttrib->fOffset));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
attribState->disableUnusedArrays(this, usedAttribArraysMask);
|
attribState->disableUnusedArrays(this, usedAttribArraysMask);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "GrGLProgramBuilder.h"
|
#include "GrGLProgramBuilder.h"
|
||||||
#include "GrGLShaderStringBuilder.h"
|
#include "GrGLShaderStringBuilder.h"
|
||||||
#include "../GrGpuGL.h"
|
#include "../GrGpuGL.h"
|
||||||
|
#include "../../GrOptDrawState.h"
|
||||||
|
|
||||||
#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
|
#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X)
|
||||||
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
|
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X)
|
||||||
@ -83,10 +84,12 @@ void GrGLVertexShaderBuilder::bindProgramLocations(GrGLuint programId) {
|
|||||||
coverage_attribute_name()));
|
coverage_attribute_name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// We pull the current state of attributes off of drawstate and bind them in order
|
// We pull the current state of attributes off of drawstate's optimized state and bind them in
|
||||||
const GrRODrawState* ds = fProgramBuilder->gpu()->drawState();
|
// order. This assumes that the drawState has not changed since we called flushGraphicsState()
|
||||||
const GrVertexAttrib* vaPtr = ds->getVertexAttribs();
|
// higher up in the stack.
|
||||||
const int vaCount = ds->getVertexAttribCount();
|
SkAutoTUnref<GrOptDrawState> optState(fProgramBuilder->gpu()->drawState()->createOptState());
|
||||||
|
const GrVertexAttrib* vaPtr = optState->getVertexAttribs();
|
||||||
|
const int vaCount = optState->getVertexAttribCount();
|
||||||
|
|
||||||
int i = fEffectAttribOffset;
|
int i = fEffectAttribOffset;
|
||||||
for (int index = 0; index < vaCount; index++) {
|
for (int index = 0; index < vaCount; index++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user