Remove memcpy/memcmp from GrDrawState. Hopefully, this fixes Issue 912 without regressing performance.

Review URL: https://codereview.appspot.com/6571059

git-svn-id: http://skia.googlecode.com/svn/trunk@5697 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2012-09-26 17:28:25 +00:00
parent 71f0f8e1ca
commit 861b3a28c3

View File

@ -74,36 +74,22 @@ public:
void reset() { void reset() {
this->disableStages(); this->disableStages();
GrSafeSetNull(fRenderTarget);
// make sure any pad is zero for memcmp
// all GrDrawState members should default to something valid by the
// the memset except those initialized individually below. There should
// be no padding between the individually initialized members.
memset(this->podStart(), 0, this->memsetSize());
// pedantic assertion that our ptrs will
// be NULL (0 ptr is mem addr 0)
GrAssert((intptr_t)(void*)NULL == 0LL);
GR_STATIC_ASSERT(0 == kBoth_DrawFace);
GrAssert(fStencilSettings.isDisabled());
// memset exceptions
fColor = 0xffffffff; fColor = 0xffffffff;
fCoverage = 0xffffffff; fViewMatrix.reset();
fFirstCoverageStage = kNumStages; GrSafeSetNull(fRenderTarget);
fColorFilterMode = SkXfermode::kDst_Mode;
fSrcBlend = kOne_GrBlendCoeff; fSrcBlend = kOne_GrBlendCoeff;
fDstBlend = kZero_GrBlendCoeff; fDstBlend = kZero_GrBlendCoeff;
fViewMatrix.reset(); fBlendConstant = 0x0;
fFlagBits = 0x0;
// ensure values that will be memcmp'ed in == but not memset in reset() fVertexEdgeType = kHairLine_EdgeType;
// are tightly packed fStencilSettings.setDisabled();
GrAssert(this->memsetSize() + sizeof(fColor) + sizeof(fCoverage) + fFirstCoverageStage = kNumStages;
sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) + fCoverage = 0xffffffff;
sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(fRenderTarget) == fColorFilterMode = SkXfermode::kDst_Mode;
this->podSize()); fColorFilterColor = 0x0;
} fDrawFace = kBoth_DrawFace;
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
/// @name Color /// @name Color
@ -765,11 +751,20 @@ public:
// Most stages are usually not used, so conditionals here // Most stages are usually not used, so conditionals here
// reduce the expected number of bytes touched by 50%. // reduce the expected number of bytes touched by 50%.
bool operator ==(const GrDrawState& s) const { bool operator ==(const GrDrawState& s) const {
if (memcmp(this->podStart(), s.podStart(), this->podSize())) { if (fColor != s.fColor ||
return false; !s.fViewMatrix.cheapEqualTo(fViewMatrix) ||
} fRenderTarget != s.fRenderTarget ||
fSrcBlend != s.fSrcBlend ||
if (!s.fViewMatrix.cheapEqualTo(fViewMatrix)) { fDstBlend != s.fDstBlend ||
fBlendConstant != s.fBlendConstant ||
fFlagBits != s.fFlagBits ||
fVertexEdgeType != s.fVertexEdgeType ||
fStencilSettings != s.fStencilSettings ||
fFirstCoverageStage != s.fFirstCoverageStage ||
fCoverage != s.fCoverage ||
fColorFilterMode != s.fColorFilterMode ||
fColorFilterColor != s.fColorFilterColor ||
fDrawFace != s.fDrawFace) {
return false; return false;
} }
@ -797,9 +792,20 @@ public:
// Most stages are usually not used, so conditionals here // Most stages are usually not used, so conditionals here
// reduce the expected number of bytes touched by 50%. // reduce the expected number of bytes touched by 50%.
GrDrawState& operator =(const GrDrawState& s) { GrDrawState& operator =(const GrDrawState& s) {
memcpy(this->podStart(), s.podStart(), this->podSize()); fColor = s.fColor;
fViewMatrix = s.fViewMatrix; fViewMatrix = s.fViewMatrix;
SkRefCnt_SafeAssign(fRenderTarget, s.fRenderTarget);
fSrcBlend = s.fSrcBlend;
fDstBlend = s.fDstBlend;
fBlendConstant = s.fBlendConstant;
fFlagBits = s.fFlagBits;
fVertexEdgeType = s.fVertexEdgeType;
fStencilSettings = s.fStencilSettings;
fFirstCoverageStage = s.fFirstCoverageStage;
fCoverage = s.fCoverage;
fColorFilterMode = s.fColorFilterMode;
fColorFilterColor = s.fColorFilterColor;
fDrawFace = s.fDrawFace;
for (int i = 0; i < kNumStages; i++) { for (int i = 0; i < kNumStages; i++) {
if (s.isStageEnabled(i)) { if (s.isStageEnabled(i)) {
@ -807,8 +813,6 @@ public:
} }
} }
SkSafeRef(fRenderTarget); // already copied by memcpy
if (kColorMatrix_StateBit & s.fFlagBits) { if (kColorMatrix_StateBit & s.fFlagBits) {
memcpy(this->fColorMatrix, s.fColorMatrix, sizeof(fColorMatrix)); memcpy(this->fColorMatrix, s.fColorMatrix, sizeof(fColorMatrix));
} }
@ -818,56 +822,21 @@ public:
private: private:
const void* podStart() const { // These fields are roughly sorted by decreasing liklihood of being different in op==
return reinterpret_cast<const void*>(&fPodStartMarker); GrColor fColor;
} GrMatrix fViewMatrix;
void* podStart() { GrRenderTarget* fRenderTarget;
return reinterpret_cast<void*>(&fPodStartMarker); GrBlendCoeff fSrcBlend;
} GrBlendCoeff fDstBlend;
size_t memsetSize() const { GrColor fBlendConstant;
return reinterpret_cast<size_t>(&fMemsetEndMarker) - uint32_t fFlagBits;
reinterpret_cast<size_t>(&fPodStartMarker) +
sizeof(fMemsetEndMarker);
}
size_t podSize() const {
// Can't use offsetof() with non-POD types, so stuck with pointer math.
return reinterpret_cast<size_t>(&fPodEndMarker) -
reinterpret_cast<size_t>(&fPodStartMarker) +
sizeof(fPodEndMarker);
}
// @{ these fields can be initialized with memset to 0
union {
GrColor fBlendConstant;
GrColor fPodStartMarker;
};
GrColor fColorFilterColor;
DrawFace fDrawFace;
VertexEdgeType fVertexEdgeType; VertexEdgeType fVertexEdgeType;
GrStencilSettings fStencilSettings; GrStencilSettings fStencilSettings;
union {
uint32_t fFlagBits;
uint32_t fMemsetEndMarker;
};
// @}
// @{ Initialized to values other than zero, but memcmp'ed in operator==
// and memcpy'ed in operator=.
GrRenderTarget* fRenderTarget;
int fFirstCoverageStage; int fFirstCoverageStage;
GrColor fColor;
GrColor fCoverage; GrColor fCoverage;
SkXfermode::Mode fColorFilterMode; SkXfermode::Mode fColorFilterMode;
GrBlendCoeff fSrcBlend; GrColor fColorFilterColor;
union { DrawFace fDrawFace;
GrBlendCoeff fDstBlend;
GrBlendCoeff fPodEndMarker;
};
// @}
GrMatrix fViewMatrix;
// This field must be last; it will not be copied or compared // This field must be last; it will not be copied or compared
// if the corresponding fTexture[] is NULL. // if the corresponding fTexture[] is NULL.