Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Unified Diff: src/gpu/gl/GrGLProgramDesc.h

Issue 15252004: Make GrGLProgramDesc's key variable length by compacting the effect key array (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: address comments, fix unit test Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/gl/GrGLProgram.cpp ('k') | src/gpu/gl/GrGLProgramDesc.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/GrGLProgramDesc.h
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index b49cb722c017f0f5b67bcbcb5e3c69bf9ce755db..f83275dd464122f8fa12c67e1372c0695b15b882 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -25,26 +25,37 @@ class GrGpuGL;
to be API-neutral then so could this class. */
class GrGLProgramDesc {
public:
- GrGLProgramDesc() {
- // since we use this as part of a key we can't have any uninitialized padding
- memset(this, 0, sizeof(GrGLProgramDesc));
- }
+ GrGLProgramDesc() : fInitialized(false) {}
+ GrGLProgramDesc(const GrGLProgramDesc& desc) { *this = desc; }
- // Returns this as a uint32_t array to be used as a key in the program cache
+ // Returns this as a uint32_t array to be used as a key in the program cache.
const uint32_t* asKey() const {
- return reinterpret_cast<const uint32_t*>(this);
+ GrAssert(fInitialized);
+ return reinterpret_cast<const uint32_t*>(fKey.get());
}
+ // Gets the number of bytes in asKey(). It will be a 4-byte aligned value. When comparing two
+ // keys the size of either key can be used with memcmp() since the lengths themselves begin the
+ // keys and thus the memcmp will exit early if the keys are of different lengths.
+ uint32_t keyLength() const { return *this->atOffset<uint32_t, kLengthOffset>(); }
+
+ // Gets the a checksum of the key. Can be used as a hash value for a fast lookup in a cache.
+ uint32_t getChecksum() const { return *this->atOffset<uint32_t, kChecksumOffset>(); }
+
// For unit testing.
void setRandom(SkMWCRandom*,
const GrGpuGL* gpu,
- const GrTexture* dummyDstTexture,
- const GrEffectStage* stages[GrDrawState::kNumStages],
+ const GrRenderTarget* dummyDstRenderTarget,
+ const GrTexture* dummyDstCopyTexture,
+ const GrEffectStage* stages[],
+ int numColorStages,
+ int numCoverageStages,
int currAttribIndex);
/**
* Builds a program descriptor from a GrDrawState. Whether the primitive type is points, the
- * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs.
+ * output of GrDrawState::getBlendOpts, and the caps of the GrGpuGL are also inputs. It also
+ * writes a tightly packed array of GrEffectStage* from the drawState.
*/
static void Build(const GrDrawState&,
bool isPoints,
@@ -53,8 +64,37 @@ public:
GrBlendCoeff dstCoeff,
const GrGpuGL* gpu,
const GrDeviceCoordTexture* dstCopy,
+ const GrEffectStage* outStages[GrDrawState::kNumStages],
GrGLProgramDesc* outDesc);
+ int numColorEffects() const {
+ GrAssert(fInitialized);
+ return this->getHeader().fColorEffectCnt;
+ }
+
+ int numCoverageEffects() const {
+ GrAssert(fInitialized);
+ return this->getHeader().fCoverageEffectCnt;
+ }
+
+ int numTotalEffects() const { return this->numColorEffects() + this->numCoverageEffects(); }
+
+ GrGLProgramDesc& operator= (const GrGLProgramDesc& other);
+
+ bool operator== (const GrGLProgramDesc& other) const {
+ GrAssert(fInitialized && other.fInitialized);
+ // The length is masked as a hint to the compiler that the address will be 4 byte aligned.
+ return 0 == memcmp(this->asKey(), other.asKey(), this->keyLength() & ~0x3);
+ }
+
+ bool operator!= (const GrGLProgramDesc& other) const {
+ return !(*this == other);
+ }
+
+ static bool Less(const GrGLProgramDesc& a, const GrGLProgramDesc& b) {
+ return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0;
+ }
+
private:
// Specifies where the initial color comes from before the stages are applied.
enum ColorInput {
@@ -96,37 +136,78 @@ private:
}
}
- /** Non-zero if this stage has an effect */
- GrGLEffect::EffectKey fEffectKeys[GrDrawState::kNumStages];
-
- // To enable experimental geometry shader code (not for use in
- // production)
-#if GR_GL_EXPERIMENTAL_GS
- bool fExperimentalGS;
-#endif
-
- GrGLShaderBuilder::DstReadKey fDstReadKey; // set by GrGLShaderBuilder if there
+ struct KeyHeader {
+ GrGLShaderBuilder::DstReadKey fDstReadKey; // set by GrGLShaderBuilder if there
// are effects that must read the dst.
// Otherwise, 0.
- GrGLShaderBuilder::FragPosKey fFragPosKey; // set by GrGLShaderBuilder if there are
+ GrGLShaderBuilder::FragPosKey fFragPosKey; // set by GrGLShaderBuilder if there are
// effects that read the fragment position.
// Otherwise, 0.
- // should the FS discard if the coverage is zero (to avoid stencil manipulation)
- SkBool8 fDiscardIfZeroCoverage;
+ // should the FS discard if the coverage is zero (to avoid stencil manipulation)
+ SkBool8 fDiscardIfZeroCoverage;
- uint8_t fColorInput; // casts to enum ColorInput
- uint8_t fCoverageInput; // casts to enum ColorInput
- uint8_t fCoverageOutput; // casts to enum CoverageOutput
+ uint8_t fColorInput; // casts to enum ColorInput
+ uint8_t fCoverageInput; // casts to enum ColorInput
+ uint8_t fCoverageOutput; // casts to enum CoverageOutput
- int8_t fFirstCoverageStage;
- SkBool8 fEmitsPointSize;
- uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
+ SkBool8 fEmitsPointSize;
+ uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
+
+ // To enable experimental geometry shader code (not for use in
+ // production)
+#if GR_GL_EXPERIMENTAL_GS
+ SkBool8 fExperimentalGS;
+#endif
+
+ int8_t fPositionAttributeIndex;
+ int8_t fLocalCoordAttributeIndex;
+ int8_t fColorAttributeIndex;
+ int8_t fCoverageAttributeIndex;
+
+ int8_t fColorEffectCnt;
+ int8_t fCoverageEffectCnt;
+ };
+
+ // The key is 1 uint32_t for the length, followed another for the checksum, the header, and then
+ // the effect keys. Everything is fixed length except the effect key array.
+ enum {
+ kLengthOffset = 0,
+ kChecksumOffset = kLengthOffset + sizeof(uint32_t),
+ kHeaderOffset = kChecksumOffset + sizeof(uint32_t),
+ kHeaderSize = SkAlign4(sizeof(KeyHeader)),
+ kEffectKeyOffset = kHeaderOffset + kHeaderSize,
+ };
+
+ template<typename T, size_t OFFSET> T* atOffset() {
+ return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET);
+ }
+
+ template<typename T, size_t OFFSET> const T* atOffset() const {
+ return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.get()) + OFFSET);
+ }
+
+ typedef GrGLEffect::EffectKey EffectKey;
+
+ uint32_t* checksum() { return this->atOffset<uint32_t, kChecksumOffset>(); }
+ KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); }
+ EffectKey* effectKeys() { return this->atOffset<EffectKey, kEffectKeyOffset>(); }
+
+ const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
+ const EffectKey* getEffectKeys() const { return this->atOffset<EffectKey, kEffectKeyOffset>(); }
+
+ static size_t KeyLength(int effectCnt) {
+ GR_STATIC_ASSERT(!(sizeof(EffectKey) & 0x3));
+ return kEffectKeyOffset + effectCnt * sizeof(EffectKey);
+ }
+
+ enum {
+ kMaxPreallocEffects = 16,
+ kPreAllocSize = kEffectKeyOffset + kMaxPreallocEffects * sizeof(EffectKey),
+ };
- int8_t fPositionAttributeIndex;
- int8_t fLocalCoordAttributeIndex;
- int8_t fColorAttributeIndex;
- int8_t fCoverageAttributeIndex;
+ SkAutoSMalloc<kPreAllocSize> fKey;
+ bool fInitialized;
// GrGLProgram and GrGLShaderBuilder read the private fields to generate code. TODO: Move all
// code generation to GrGLShaderBuilder (and maybe add getters rather than friending).
« no previous file with comments | « src/gpu/gl/GrGLProgram.cpp ('k') | src/gpu/gl/GrGLProgramDesc.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698