diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 92ee2cbaad..dd63d6efa6 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -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(&fColor) - - reinterpret_cast(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(&fViewMatrix) - - reinterpret_cast(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(&fPodStartMarker); + } + void* podStart() { + return reinterpret_cast(&fPodStartMarker); + } + size_t memsetSize() const { + return reinterpret_cast(&fMemsetEndMarker) - + reinterpret_cast(&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(&fPodEndMarker) - + reinterpret_cast(&fPodStartMarker) + + sizeof(fPodEndMarker); + } + static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1); // @{ these fields can be initialized with memset to 0 - GrColor fBlendConstant; + union { + GrColor fBlendConstant; + GrColor fPodStartMarker; + }; GrTexture* fTextures[kNumStages]; GrColor fColorFilterColor; uint32_t fFlagBits; DrawFace fDrawFace; VertexEdgeType fVertexEdgeType; GrStencilSettings fStencilSettings; - GrRenderTarget* fRenderTarget; + 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; - GrBlendCoeff fDstBlend; + 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