Make GrDrawState ref counted. (Small step towards a perf improvement.)

Review URL: http://codereview.appspot.com/5905069/




git-svn-id: http://skia.googlecode.com/svn/trunk@3498 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2012-03-26 20:33:54 +00:00
parent 4db4adc0e1
commit 2e3d144dfd

View File

@ -11,6 +11,7 @@
#include "GrColor.h"
#include "GrMatrix.h"
#include "GrNoncopyable.h"
#include "GrRefCnt.h"
#include "GrSamplerState.h"
#include "GrStencil.h"
@ -19,8 +20,9 @@
class GrRenderTarget;
class GrTexture;
struct GrDrawState {
class GrDrawState : public GrRefCnt {
public:
/**
* Number of texture stages. Each stage takes as input a color and
* 2D texture coordinates. The color input to the first enabled stage is the
@ -62,10 +64,8 @@ struct GrDrawState {
// 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.
static const size_t kMemsetSize =
reinterpret_cast<intptr_t>(&fColor) -
reinterpret_cast<intptr_t>(this);
memset(this, 0, kMemsetSize);
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);
@ -83,11 +83,10 @@ struct GrDrawState {
// ensure values that will be memcmp'ed in == but not memset in reset()
// are tightly packed
GrAssert(kMemsetSize + sizeof(fColor) + sizeof(fCoverage) +
GrAssert(this->memsetSize() + sizeof(fColor) + sizeof(fCoverage) +
sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) +
sizeof(fSrcBlend) + sizeof(fDstBlend) ==
reinterpret_cast<uintptr_t>(&fViewMatrix) -
reinterpret_cast<uintptr_t>(this));
this->podSize());
fEdgeAANumEdges = 0;
}
@ -740,7 +739,7 @@ struct GrDrawState {
// Most stages are usually not used, so conditionals here
// reduce the expected number of bytes touched by 50%.
bool operator ==(const GrDrawState& s) const {
if (memcmp(this, &s, this->leadingBytes())) {
if (memcmp(this->podStart(), s.podStart(), this->podSize())) {
return false;
}
@ -770,7 +769,7 @@ struct GrDrawState {
// Most stages are usually not used, so conditionals here
// reduce the expected number of bytes touched by 50%.
GrDrawState& operator =(const GrDrawState& s) {
memcpy(this, &s, this->leadingBytes());
memcpy(this->podStart(), s.podStart(), this->podSize());
fViewMatrix = s.fViewMatrix;
@ -788,25 +787,57 @@ struct GrDrawState {
}
private:
const void* podStart() const {
return reinterpret_cast<const void*>(&fPodStartMarker);
}
void* podStart() {
return reinterpret_cast<void*>(&fPodStartMarker);
}
size_t memsetSize() const {
return reinterpret_cast<size_t>(&fMemsetEndMarker) -
reinterpret_cast<size_t>(&fPodStartMarker) +
sizeof(fMemsetEndMarker);
}
size_t podSize() const {
// Can't use offsetof() with non-POD types, so stuck with pointer math.
// TODO: ignores GrTesselatedPathRenderer data structures. We don't
// have a compile-time flag that lets us know if it's being used, and
// checking at runtime seems to cost 5% performance.
return reinterpret_cast<size_t>(&fPodEndMarker) -
reinterpret_cast<size_t>(&fPodStartMarker) +
sizeof(fPodEndMarker);
}
static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
// @{ these fields can be initialized with memset to 0
union {
GrColor fBlendConstant;
GrColor fPodStartMarker;
};
GrTexture* fTextures[kNumStages];
GrColor fColorFilterColor;
uint32_t fFlagBits;
DrawFace fDrawFace;
VertexEdgeType fVertexEdgeType;
GrStencilSettings fStencilSettings;
union {
GrRenderTarget* fRenderTarget;
GrRenderTarget* fMemsetEndMarker;
};
// @}
// @{ Initialized to values other than zero
// @{ Initialized to values other than zero, but memcmp'ed in operator==
// and memcpy'ed in operator=.
GrColor fColor;
GrColor fCoverage;
int fFirstCoverageStage;
SkXfermode::Mode fColorFilterMode;
GrBlendCoeff fSrcBlend;
union {
GrBlendCoeff fDstBlend;
GrBlendCoeff fPodEndMarker;
};
// @}
GrMatrix fViewMatrix;
@ -824,15 +855,6 @@ private:
// only compared if the color matrix enable flag is set
float fColorMatrix[20]; // 5 x 4 matrix
size_t leadingBytes() const {
// Can't use offsetof() with non-POD types, so stuck with pointer math.
// TODO: ignores GrTesselatedPathRenderer data structures. We don't
// have a compile-time flag that lets us know if it's being used, and
// checking at runtime seems to cost 5% performance.
return (size_t) ((unsigned char*)&fViewMatrix -
(unsigned char*)&fBlendConstant);
}
};
#endif