Index: src/gpu/GrProgramDesc.h |
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/GrProgramDesc.h |
similarity index 65% |
copy from src/gpu/gl/GrGLProgramDesc.h |
copy to src/gpu/GrProgramDesc.h |
index 4e1be5b2f9c0d1127b62c134bfdc2471a17bb55d..0c9e8a21479e23e5e63babb67d515ad09fb5eadb 100644 |
--- a/src/gpu/gl/GrGLProgramDesc.h |
+++ b/src/gpu/GrProgramDesc.h |
@@ -1,26 +1,25 @@ |
/* |
- * Copyright 2013 Google Inc. |
+ * Copyright 2014 Google Inc. |
* |
* Use of this source code is governed by a BSD-style license that can be |
* found in the LICENSE file. |
*/ |
-#ifndef GrGLProgramDesc_DEFINED |
-#define GrGLProgramDesc_DEFINED |
+#ifndef GrProgramDesc_DEFINED |
+#define GrProgramDesc_DEFINED |
-#include "GrGLProcessor.h" |
-#include "GrDrawState.h" |
+#include "GrColor.h" |
#include "GrGpu.h" |
-#include "GrOptDrawState.h" |
+#include "GrTypesPriv.h" |
class GrGpuGL; |
/** This class describes a program to generate. It also serves as a program cache key. Very little |
of this is GL-specific. The GL-specific parts could be factored out into a subclass. */ |
-class GrGLProgramDesc { |
+class GrProgramDesc { |
public: |
- GrGLProgramDesc() {} |
- GrGLProgramDesc(const GrGLProgramDesc& desc) { *this = desc; } |
+ // Dummy constructor creates a zombie descriptor |
bsalomon
2014/10/23 18:10:30
This seems like an unhelpful comment. Can you eith
|
+ GrProgramDesc() {} |
// Returns this as a uint32_t array to be used as a key in the program cache. |
const uint32_t* asKey() const { |
@@ -35,48 +34,57 @@ public: |
// 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>(); } |
- /** |
- * Builds a program descriptor from a GrOptDrawState. Whether the primitive type is points, and |
- * the caps of the GrGpuGL are also inputs. It also outputs the color and coverage stages |
- * referenced by the generated descriptor. Coverage stages from the drawState may be treated as |
- * color stages in the output. |
- */ |
- static bool Build(const GrOptDrawState&, |
- GrGpu::DrawType, |
- GrGpuGL*, |
- const GrDeviceCoordTexture*, |
- GrGLProgramDesc*); |
- |
- bool hasGeometryProcessor() const { |
- return SkToBool(this->getHeader().fHasGeometryProcessor); |
- } |
- |
- int numColorEffects() const { |
- return this->getHeader().fColorEffectCnt; |
+ GrProgramDesc& operator= (const GrProgramDesc& other) { |
+ size_t keyLength = other.keyLength(); |
+ fKey.reset(keyLength); |
+ memcpy(fKey.begin(), other.fKey.begin(), keyLength); |
+ return *this; |
} |
- int numCoverageEffects() const { |
- return this->getHeader().fCoverageEffectCnt; |
- } |
- |
- int numTotalEffects() const { return this->numColorEffects() + this->numCoverageEffects(); } |
- |
- GrGLProgramDesc& operator= (const GrGLProgramDesc& other); |
- |
- bool operator== (const GrGLProgramDesc& other) const { |
+ bool operator== (const GrProgramDesc& other) const { |
// 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 { |
+ bool operator!= (const GrProgramDesc& other) const { |
return !(*this == other); |
} |
- static bool Less(const GrGLProgramDesc& a, const GrGLProgramDesc& b) { |
+ static bool Less(const GrProgramDesc& a, const GrProgramDesc& b) { |
return memcmp(a.asKey(), b.asKey(), a.keyLength() & ~0x3) < 0; |
} |
-private: |
+ |
+ /////////////////////////////////////////////////////////////////////////// |
+ /// @name Stage Output Types |
+ //// |
+ |
+ enum PrimaryOutputType { |
+ // Modulate color and coverage, write result as the color output. |
+ kModulate_PrimaryOutputType, |
+ // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This |
+ // can only be set if fDstReadKey is non-zero. |
+ kCombineWithDst_PrimaryOutputType, |
+ |
+ kPrimaryOutputTypeCnt, |
+ }; |
+ |
+ enum SecondaryOutputType { |
+ // There is no secondary output |
+ kNone_SecondaryOutputType, |
+ // Writes coverage as the secondary output. Only set if dual source blending is supported |
+ // and primary output is kModulate. |
+ kCoverage_SecondaryOutputType, |
+ // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending |
+ // is supported and primary output is kModulate. |
+ kCoverageISA_SecondaryOutputType, |
+ // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source |
+ // blending is supported and primary output is kModulate. |
+ kCoverageISC_SecondaryOutputType, |
+ |
+ kSecondaryOutputTypeCnt, |
+ }; |
+ |
// Specifies where the initial color comes from before the stages are applied. |
enum ColorInput { |
kAllOnes_ColorInput, |
@@ -94,14 +102,13 @@ private: |
// effects that read the fragment position. |
// Otherwise, 0. |
- SkBool8 fUseFragShaderOnly; |
SkBool8 fEmitsPointSize; |
ColorInput fColorInput : 8; |
ColorInput fCoverageInput : 8; |
- GrOptDrawState::PrimaryOutputType fPrimaryOutputType : 8; |
- GrOptDrawState::SecondaryOutputType fSecondaryOutputType : 8; |
+ PrimaryOutputType fPrimaryOutputType : 8; |
+ SecondaryOutputType fSecondaryOutputType : 8; |
int8_t fPositionAttributeIndex; |
int8_t fLocalCoordAttributeIndex; |
@@ -113,46 +120,23 @@ private: |
int8_t fCoverageEffectCnt; |
}; |
- // The key, stored in fKey, is composed of five parts: |
- // 1. uint32_t for total key length. |
- // 2. uint32_t for a checksum. |
- // 3. Header struct defined above. |
- // 4. An array of offsets to effect keys and their sizes (see 5). uint16_t for each |
- // offset and size. |
- // 5. per-effect keys. Each effect's key is a variable length array of uint32_t. |
- enum { |
- // Part 1. |
- kLengthOffset = 0, |
- // Part 2. |
- kChecksumOffset = kLengthOffset + sizeof(uint32_t), |
- // Part 3. |
- kHeaderOffset = kChecksumOffset + sizeof(uint32_t), |
- kHeaderSize = SkAlign4(sizeof(KeyHeader)), |
- // Part 4. |
- // This is the offset in the overall key to the array of per-effect offset,length pairs. |
- kEffectKeyOffsetsAndLengthOffset = kHeaderOffset + kHeaderSize, |
- }; |
- template<typename T, size_t OFFSET> T* atOffset() { |
- return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET); |
+ bool hasGeometryProcessor() const { |
+ return SkToBool(this->header().fHasGeometryProcessor); |
} |
- template<typename T, size_t OFFSET> const T* atOffset() const { |
- return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET); |
+ int numColorEffects() const { |
+ return this->header().fColorEffectCnt; |
} |
- KeyHeader* header() { return this->atOffset<KeyHeader, kHeaderOffset>(); } |
+ int numCoverageEffects() const { |
+ return this->header().fCoverageEffectCnt; |
+ } |
- // a helper class to handle getting an individual processor's key |
- template <class ProcessorKeyBuilder> |
- static bool BuildStagedProcessorKey(const typename ProcessorKeyBuilder::StagedProcessor& stage, |
- const GrGLCaps& caps, |
- bool requiresLocalCoordAttrib, |
- GrGLProgramDesc* desc, |
- int* offsetAndSizeIndex); |
- void finalize(); |
+ int numTotalEffects() const { return this->numColorEffects() + this->numCoverageEffects(); } |
- const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); } |
+ // This should really only be used internally, base classes should return their own headers |
+ const KeyHeader& header() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); } |
/** Used to provide effects' keys to their emitCode() function. */ |
class ProcKeyProvider { |
@@ -162,8 +146,8 @@ private: |
kFragment_ProcessorType, |
}; |
- ProcKeyProvider(const GrGLProgramDesc* desc, ProcessorType type) |
- : fDesc(desc), fBaseIndex(0) { |
+ ProcKeyProvider(const GrProgramDesc* desc, ProcessorType type, int effectOffset) |
+ : fDesc(desc), fBaseIndex(0), fEffectOffset(effectOffset) { |
switch (type) { |
case kGeometry_ProcessorType: |
// there can be only one |
@@ -177,7 +161,7 @@ private: |
GrProcessorKey get(int index) const { |
const uint16_t* offsetsAndLengths = reinterpret_cast<const uint16_t*>( |
- fDesc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset); |
+ fDesc->fKey.begin() + fEffectOffset); |
// We store two uint16_ts per effect, one for the offset to the effect's key and one for |
// its length. Here we just need the offset. |
uint16_t offset = offsetsAndLengths[2 * (fBaseIndex + index) + 0]; |
@@ -188,8 +172,38 @@ private: |
length / sizeof(uint32_t)); |
} |
private: |
- const GrGLProgramDesc* fDesc; |
- int fBaseIndex; |
+ const GrProgramDesc* fDesc; |
+ int fBaseIndex; |
+ int fEffectOffset; |
+ }; |
+ |
+protected: |
+ |
+ template<typename T, size_t OFFSET> T* atOffset() { |
+ return reinterpret_cast<T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET); |
+ } |
+ |
+ template<typename T, size_t OFFSET> const T* atOffset() const { |
+ return reinterpret_cast<const T*>(reinterpret_cast<intptr_t>(fKey.begin()) + OFFSET); |
+ } |
+ // The key, stored in fKey, is composed of five parts: |
+ // 1. uint32_t for total key length. |
+ // 2. uint32_t for a checksum. |
+ // 3. Header struct defined above., also room for derived class headers. |
+ // 4. An array of offsets to effect keys and their sizes (see 5). uint16_t for each |
+ // offset and size. |
+ // 5. per-effect keys. Each effect's key is a variable length array of uint32_t. |
+ enum KeyOffsets { |
+ // Part 1. |
+ kLengthOffset = 0, |
+ // Part 2. |
+ kChecksumOffset = kLengthOffset + sizeof(uint32_t), |
+ // Part 3. |
+ kHeaderOffset = kChecksumOffset + sizeof(uint32_t), |
+ kHeaderSize = SkAlign4(2 * sizeof(KeyHeader)), |
+ // Part 4. |
+ // This is the offset in the overall key to the array of per-effect offset,length pairs. |
+ kEffectKeyOffsetsAndLengthOffset = kHeaderOffset + kHeaderSize, |
}; |
enum { |
@@ -201,15 +215,7 @@ private: |
SkSTArray<kPreAllocSize, uint8_t, true> fKey; |
- // GrGLProgram and GrGLShaderBuilder read the private fields to generate code. TODO: Split out |
- // part of GrGLShaderBuilder that is used by effects so that this header doesn't need to be |
- // visible to GrGLProcessors. Then make public accessors as necessary and remove friends. |
- friend class GrGLProgram; |
- friend class GrGLProgramBuilder; |
- friend class GrGLLegacyNvprProgramBuilder; |
- friend class GrGLVertexBuilder; |
- friend class GrGLFragmentShaderBuilder; |
- friend class GrGLGeometryBuilder; |
+ friend class GrGLProgramDesc; |
}; |
#endif |