blob: c75f13c4963426420de0751ec51de0b82bb3f676 [file] [log] [blame]
joshualitt8072caa2015-02-12 14:20:52 -08001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrPrimitiveProcessor_DEFINED
9#define GrPrimitiveProcessor_DEFINED
10
11#include "GrColor.h"
12#include "GrProcessor.h"
13#include "GrShaderVar.h"
14
15/*
16 * The GrPrimitiveProcessor represents some kind of geometric primitive. This includes the shape
17 * of the primitive and the inherent color of the primitive. The GrPrimitiveProcessor is
18 * responsible for providing a color and coverage input into the Ganesh rendering pipeline. Through
19 * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
20 * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this
Brian Salomon09d994e2016-12-21 11:14:46 -050021 * functionality.
joshualitt8072caa2015-02-12 14:20:52 -080022 *
23 * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
Brian Salomoncb30bb22017-02-12 09:28:54 -050024 * GrPrimitiveProcessor. These loops run on the CPU and to determine known properties of the final
25 * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve
26 * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its
Brian Salomona811b122017-03-30 08:21:32 -040027 * getProcessorAnalysisInputs implementation. These seed values are processed by the
Brian Salomon5298dc82017-02-22 11:52:03 -050028 * subsequent
Brian Salomon92aee3d2016-12-21 09:20:25 -050029 * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in
30 * the applyPipelineOptimizations call, where the op can use the information to inform decisions
31 * about GrPrimitiveProcessor creation.
joshualitt8072caa2015-02-12 14:20:52 -080032 */
33
egdaniele659a582015-11-13 09:55:43 -080034class GrGLSLPrimitiveProcessor;
joshualitt8072caa2015-02-12 14:20:52 -080035
joshualitt8072caa2015-02-12 14:20:52 -080036/*
joshualitt8072caa2015-02-12 14:20:52 -080037 * GrPrimitiveProcessor defines an interface which all subclasses must implement. All
38 * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
39 * pipelines, and they must provide some notion of equality
40 */
Brian Salomond61c9d92017-04-10 10:54:25 -040041class GrPrimitiveProcessor : public GrResourceIOProcessor, public GrProgramElement {
joshualitt8072caa2015-02-12 14:20:52 -080042public:
Brian Salomon70132d02018-05-29 15:33:06 -040043 class Attribute {
44 public:
Mike Klein5045e502018-06-19 01:40:57 +000045 enum class InputRate : bool {
46 kPerVertex,
47 kPerInstance
48 };
49
Brian Salomon70132d02018-05-29 15:33:06 -040050 constexpr Attribute() = default;
Mike Klein5045e502018-06-19 01:40:57 +000051 constexpr Attribute(const char* name, GrVertexAttribType type, int offset, InputRate rate)
52 : fName(name), fType(type), fOffsetInRecord(offset), fInputRate(rate) {}
Brian Salomon70132d02018-05-29 15:33:06 -040053
Mike Klein5045e502018-06-19 01:40:57 +000054 bool isInitialized() const { return SkToBool(fName); }
Brian Salomon70132d02018-05-29 15:33:06 -040055
Mike Klein5045e502018-06-19 01:40:57 +000056 const char* name() const { return fName; }
57 GrVertexAttribType type() const { return fType; }
58 int offsetInRecord() const { return fOffsetInRecord; }
59 InputRate inputRate() const { return fInputRate; }
Brian Salomon70132d02018-05-29 15:33:06 -040060
61 GrShaderVar asShaderVar() const {
62 return {fName, GrVertexAttribTypeToSLType(fType), GrShaderVar::kIn_TypeModifier};
63 }
64
65 private:
66 const char* fName = nullptr;
67 GrVertexAttribType fType = kFloat_GrVertexAttribType;
Mike Klein5045e502018-06-19 01:40:57 +000068 int fOffsetInRecord = 0;
69 InputRate fInputRate = InputRate::kPerVertex;
joshualitt8072caa2015-02-12 14:20:52 -080070 };
71
Mike Klein5045e502018-06-19 01:40:57 +000072 GrPrimitiveProcessor(ClassID classID)
73 : GrResourceIOProcessor(classID) {}
Ethan Nicholasabff9562017-10-09 10:54:08 -040074
Mike Klein5045e502018-06-19 01:40:57 +000075 int numAttribs() const { return fAttribs.count(); }
76 const Attribute& getAttrib(int index) const { return fAttribs[index]; }
joshualitt8072caa2015-02-12 14:20:52 -080077
Mike Klein5045e502018-06-19 01:40:57 +000078 bool hasVertexAttribs() const { return SkToBool(fVertexStride); }
79 bool hasInstanceAttribs() const { return SkToBool(fInstanceStride); }
Chris Dalton1d616352017-05-31 12:51:23 -060080
81 /**
Mike Klein5045e502018-06-19 01:40:57 +000082 * These return the strides of the vertex and instance buffers. Attributes are expected to be
83 * laid out interleaved in their corresponding buffer (vertex or instance). fOffsetInRecord
84 * indicates an attribute's location in bytes relative to the first attribute. (These are padded
85 * to the nearest 4 bytes for performance reasons.)
86 *
87 * A common practice is to populate the buffer's memory using an implicit array of structs. In
88 * this case, it is best to assert:
89 *
90 * stride == sizeof(struct) and
91 * offsetof(struct, field[i]) == attrib[i].fOffsetInRecord
92 *
93 * NOTE: for instanced draws the vertex buffer has a single record that each instance reuses.
Chris Dalton1d616352017-05-31 12:51:23 -060094 */
Mike Klein5045e502018-06-19 01:40:57 +000095 int getVertexStride() const { return fVertexStride; }
96 int getInstanceStride() const { return fInstanceStride; }
Chris Dalton1d616352017-05-31 12:51:23 -060097
98 // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
99 // we put these calls on the base class to prevent having to cast
100 virtual bool willUseGeoShader() const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800101
102 /**
wangyixa7f4c432015-08-20 07:25:02 -0700103 * Computes a transformKey from an array of coord transforms. Will only look at the first
104 * <numCoords> transforms in the array.
105 *
106 * TODO: A better name for this function would be "compute" instead of "get".
joshualitt8072caa2015-02-12 14:20:52 -0800107 */
wangyixa7f4c432015-08-20 07:25:02 -0700108 uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
109 int numCoords) const;
joshualitt8072caa2015-02-12 14:20:52 -0800110
111 /**
112 * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
113 * processor's GL backend implementation.
wangyixa7f4c432015-08-20 07:25:02 -0700114 *
115 * TODO: A better name for this function would be "compute" instead of "get".
joshualitt8072caa2015-02-12 14:20:52 -0800116 */
Brian Salomon94efbf52016-11-29 13:43:05 -0500117 virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800118
119
120 /** Returns a new instance of the appropriate *GL* implementation class
121 for the given GrProcessor; caller is responsible for deleting
122 the object. */
Brian Salomon94efbf52016-11-29 13:43:05 -0500123 virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0;
joshualitt8072caa2015-02-12 14:20:52 -0800124
ethannicholas22793252016-01-30 09:59:10 -0800125 virtual bool isPathRendering() const { return false; }
joshualitt8072caa2015-02-12 14:20:52 -0800126
ethannicholas22793252016-01-30 09:59:10 -0800127 /**
128 * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
129 */
130 virtual const char* getDestColorOverride() const { return nullptr; }
halcanary9d524f22016-03-29 09:03:52 -0700131
Mike Klein5045e502018-06-19 01:40:57 +0000132 virtual float getSampleShading() const {
133 return 0.0;
134 }
ethannicholas28ef4452016-03-25 09:26:03 -0700135
joshualitt8072caa2015-02-12 14:20:52 -0800136protected:
Mike Klein5045e502018-06-19 01:40:57 +0000137 /**
138 * Subclasses call these from their constructor to register vertex and instance attributes.
139 */
140 const Attribute& addVertexAttrib(const char* name, GrVertexAttribType type) {
141 fAttribs.push_back() = {name, type, fVertexStride, Attribute::InputRate::kPerVertex};
142 fVertexStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
143 return fAttribs.back();
144 }
145 const Attribute& addInstanceAttrib(const char* name, GrVertexAttribType type) {
146 fAttribs.push_back() = {name, type, fInstanceStride, Attribute::InputRate::kPerInstance};
147 fInstanceStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type)));
148 return fAttribs.back();
149 }
joshualitt8072caa2015-02-12 14:20:52 -0800150
151private:
Brian Salomond61c9d92017-04-10 10:54:25 -0400152 void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); }
153 void removeRefs() const override { GrResourceIOProcessor::removeRefs(); }
154 void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); }
Mike Kleinfc6c37b2016-09-27 09:34:10 -0400155 void notifyRefCntIsZero() const final {}
joshualitt8072caa2015-02-12 14:20:52 -0800156
Mike Klein5045e502018-06-19 01:40:57 +0000157 SkSTArray<8, Attribute> fAttribs;
158 int fVertexStride = 0;
159 int fInstanceStride = 0;
Chris Dalton1d616352017-05-31 12:51:23 -0600160
joshualitt8072caa2015-02-12 14:20:52 -0800161 typedef GrProcessor INHERITED;
162};
163
164#endif