aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrPrimitiveProcessor.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/GrPrimitiveProcessor.h')
-rw-r--r--src/gpu/GrPrimitiveProcessor.h149
1 files changed, 96 insertions, 53 deletions
diff --git a/src/gpu/GrPrimitiveProcessor.h b/src/gpu/GrPrimitiveProcessor.h
index c75f13c496..6563ad9a7d 100644
--- a/src/gpu/GrPrimitiveProcessor.h
+++ b/src/gpu/GrPrimitiveProcessor.h
@@ -40,23 +40,22 @@ class GrGLSLPrimitiveProcessor;
*/
class GrPrimitiveProcessor : public GrResourceIOProcessor, public GrProgramElement {
public:
+ /** Describes a vertex or instance attribute. */
class Attribute {
public:
- enum class InputRate : bool {
- kPerVertex,
- kPerInstance
- };
-
constexpr Attribute() = default;
- constexpr Attribute(const char* name, GrVertexAttribType type, int offset, InputRate rate)
- : fName(name), fType(type), fOffsetInRecord(offset), fInputRate(rate) {}
+ constexpr Attribute(const char* name, GrVertexAttribType type) : fName(name), fType(type) {}
+ constexpr Attribute(const Attribute&) = default;
+
+ Attribute& operator=(const Attribute&) = default;
+
+ constexpr bool isInitialized() const { return SkToBool(fName); }
- bool isInitialized() const { return SkToBool(fName); }
+ constexpr const char* name() const { return fName; }
+ constexpr GrVertexAttribType type() const { return fType; }
- const char* name() const { return fName; }
- GrVertexAttribType type() const { return fType; }
- int offsetInRecord() const { return fOffsetInRecord; }
- InputRate inputRate() const { return fInputRate; }
+ inline constexpr size_t size() const;
+ constexpr size_t sizeAlign4() const { return SkAlign4(this->size()); }
GrShaderVar asShaderVar() const {
return {fName, GrVertexAttribTypeToSLType(fType), GrShaderVar::kIn_TypeModifier};
@@ -65,35 +64,34 @@ public:
private:
const char* fName = nullptr;
GrVertexAttribType fType = kFloat_GrVertexAttribType;
- int fOffsetInRecord = 0;
- InputRate fInputRate = InputRate::kPerVertex;
};
- GrPrimitiveProcessor(ClassID classID)
- : GrResourceIOProcessor(classID) {}
+ GrPrimitiveProcessor(ClassID);
- int numAttribs() const { return fAttribs.count(); }
- const Attribute& getAttrib(int index) const { return fAttribs[index]; }
+ int numVertexAttributes() const { return fVertexAttributeCnt; }
+ const Attribute& vertexAttribute(int i) const;
+ int numInstanceAttributes() const { return fInstanceAttributeCnt; }
+ const Attribute& instanceAttribute(int i) const;
- bool hasVertexAttribs() const { return SkToBool(fVertexStride); }
- bool hasInstanceAttribs() const { return SkToBool(fInstanceStride); }
+ bool hasVertexAttributes() const { return SkToBool(fVertexAttributeCnt); }
+ bool hasInstanceAttributes() const { return SkToBool(fInstanceAttributeCnt); }
+#ifdef SK_DEBUG
/**
- * These return the strides of the vertex and instance buffers. Attributes are expected to be
- * laid out interleaved in their corresponding buffer (vertex or instance). fOffsetInRecord
- * indicates an attribute's location in bytes relative to the first attribute. (These are padded
- * to the nearest 4 bytes for performance reasons.)
- *
- * A common practice is to populate the buffer's memory using an implicit array of structs. In
- * this case, it is best to assert:
- *
- * stride == sizeof(struct) and
- * offsetof(struct, field[i]) == attrib[i].fOffsetInRecord
- *
- * NOTE: for instanced draws the vertex buffer has a single record that each instance reuses.
+ * A common practice is to populate the the vertex/instance's memory using an implicit array of
+ * structs. In this case, it is best to assert that:
+ * debugOnly_stride == sizeof(struct) and
+ * offsetof(struct, field[i]) == debugOnly_AttributeOffset(i)
+ * In general having Op subclasses assert that attribute offsets and strides agree with their
+ * tessellation code's expectations is good practice.
+ * However, these functions walk the attributes to compute offsets and call virtual functions
+ * to access the attributes. Thus, they are only available in debug builds.
*/
- int getVertexStride() const { return fVertexStride; }
- int getInstanceStride() const { return fInstanceStride; }
+ size_t debugOnly_vertexStride() const;
+ size_t debugOnly_instanceStride() const;
+ size_t debugOnly_vertexAttributeOffset(int) const;
+ size_t debugOnly_instanceAttributeOffset(int) const;
+#endif
// Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
// we put these calls on the base class to prevent having to cast
@@ -129,24 +127,11 @@ public:
*/
virtual const char* getDestColorOverride() const { return nullptr; }
- virtual float getSampleShading() const {
- return 0.0;
- }
+ virtual float getSampleShading() const { return 0.0; }
protected:
- /**
- * Subclasses call these from their constructor to register vertex and instance attributes.
- */
- const Attribute& addVertexAttrib(const char* name, GrVertexAttribType type) {
- fAttribs.push_back() = {name, type, fVertexStride, Attribute::InputRate::kPerVertex};
- fVertexStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
- return fAttribs.back();
- }
- const Attribute& addInstanceAttrib(const char* name, GrVertexAttribType type) {
- fAttribs.push_back() = {name, type, fInstanceStride, Attribute::InputRate::kPerInstance};
- fInstanceStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
- return fAttribs.back();
- }
+ void setVertexAttributeCnt(int cnt) { fVertexAttributeCnt = cnt; }
+ void setInstanceAttributeCnt(int cnt) { fInstanceAttributeCnt = cnt; }
private:
void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
@@ -154,11 +139,69 @@ private:
void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); }
void notifyRefCntIsZero() const final {}
- SkSTArray<8, Attribute> fAttribs;
- int fVertexStride = 0;
- int fInstanceStride = 0;
+ virtual const Attribute& onVertexAttribute(int) const = 0;
+ virtual const Attribute& onInstanceAttribute(int) const = 0;
+ int fVertexAttributeCnt = 0;
+ int fInstanceAttributeCnt = 0;
typedef GrProcessor INHERITED;
};
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Returns the size of the attrib type in bytes.
+ * This was moved from include/private/GrTypesPriv.h in service of Skia dependents that build
+ * with C++11.
+ */
+static constexpr inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
+ switch (type) {
+ case kFloat_GrVertexAttribType:
+ return sizeof(float);
+ case kFloat2_GrVertexAttribType:
+ return 2 * sizeof(float);
+ case kFloat3_GrVertexAttribType:
+ return 3 * sizeof(float);
+ case kFloat4_GrVertexAttribType:
+ return 4 * sizeof(float);
+ case kHalf_GrVertexAttribType:
+ return sizeof(float);
+ case kHalf2_GrVertexAttribType:
+ return 2 * sizeof(float);
+ case kHalf3_GrVertexAttribType:
+ return 3 * sizeof(float);
+ case kHalf4_GrVertexAttribType:
+ return 4 * sizeof(float);
+ case kInt2_GrVertexAttribType:
+ return 2 * sizeof(int32_t);
+ case kInt3_GrVertexAttribType:
+ return 3 * sizeof(int32_t);
+ case kInt4_GrVertexAttribType:
+ return 4 * sizeof(int32_t);
+ case kUByte_norm_GrVertexAttribType:
+ return 1 * sizeof(char);
+ case kUByte4_norm_GrVertexAttribType:
+ return 4 * sizeof(char);
+ case kShort2_GrVertexAttribType:
+ return 2 * sizeof(int16_t);
+ case kUShort2_GrVertexAttribType: // fall through
+ case kUShort2_norm_GrVertexAttribType:
+ return 2 * sizeof(uint16_t);
+ case kInt_GrVertexAttribType:
+ return sizeof(int32_t);
+ case kUint_GrVertexAttribType:
+ return sizeof(uint32_t);
+ }
+ // GCC fails because SK_ABORT evaluates to non constexpr. clang and cl.exe think this is
+ // unreachable and don't complain.
+#if defined(__clang__) || !defined(__GNUC__)
+ SK_ABORT("Unsupported type conversion");
+#endif
+ return 0;
+}
+
+constexpr size_t GrPrimitiveProcessor::Attribute::size() const {
+ return GrVertexAttribTypeSize(fType);
+}
+
#endif