GrPrimitiveProcessor.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  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. #ifndef GrPrimitiveProcessor_DEFINED
  8. #define GrPrimitiveProcessor_DEFINED
  9. #include "src/gpu/GrColor.h"
  10. #include "src/gpu/GrNonAtomicRef.h"
  11. #include "src/gpu/GrProcessor.h"
  12. #include "src/gpu/GrShaderVar.h"
  13. class GrCoordTransform;
  14. /*
  15. * The GrPrimitiveProcessor represents some kind of geometric primitive. This includes the shape
  16. * of the primitive and the inherent color of the primitive. The GrPrimitiveProcessor is
  17. * responsible for providing a color and coverage input into the Ganesh rendering pipeline. Through
  18. * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
  19. * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this
  20. * functionality.
  21. *
  22. * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
  23. * GrPrimitiveProcessor. These loops run on the CPU and to determine known properties of the final
  24. * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve
  25. * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its
  26. * getProcessorAnalysisInputs implementation. These seed values are processed by the
  27. * subsequent
  28. * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in
  29. * the applyPipelineOptimizations call, where the op can use the information to inform decisions
  30. * about GrPrimitiveProcessor creation.
  31. */
  32. class GrGLSLPrimitiveProcessor;
  33. /**
  34. * GrPrimitiveProcessor defines an interface which all subclasses must implement. All
  35. * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
  36. * pipelines, and they must provide some notion of equality
  37. *
  38. * TODO: This class does not really need to be ref counted. Instances should be allocated using
  39. * GrOpFlushState's arena and destroyed when the arena is torn down.
  40. */
  41. class GrPrimitiveProcessor : public GrProcessor, public GrNonAtomicRef<GrPrimitiveProcessor> {
  42. public:
  43. class TextureSampler;
  44. /** Describes a vertex or instance attribute. */
  45. class Attribute {
  46. public:
  47. constexpr Attribute() = default;
  48. constexpr Attribute(const char* name,
  49. GrVertexAttribType cpuType,
  50. GrSLType gpuType)
  51. : fName(name), fCPUType(cpuType), fGPUType(gpuType) {}
  52. constexpr Attribute(const Attribute&) = default;
  53. Attribute& operator=(const Attribute&) = default;
  54. constexpr bool isInitialized() const { return SkToBool(fName); }
  55. constexpr const char* name() const { return fName; }
  56. constexpr GrVertexAttribType cpuType() const { return fCPUType; }
  57. constexpr GrSLType gpuType() const { return fGPUType; }
  58. inline constexpr size_t size() const;
  59. constexpr size_t sizeAlign4() const { return SkAlign4(this->size()); }
  60. GrShaderVar asShaderVar() const {
  61. return {fName, fGPUType, GrShaderVar::kIn_TypeModifier};
  62. }
  63. private:
  64. const char* fName = nullptr;
  65. GrVertexAttribType fCPUType = kFloat_GrVertexAttribType;
  66. GrSLType fGPUType = kFloat_GrSLType;
  67. };
  68. class Iter {
  69. public:
  70. Iter() : fCurr(nullptr), fRemaining(0) {}
  71. Iter(const Iter& iter) : fCurr(iter.fCurr), fRemaining(iter.fRemaining) {}
  72. Iter& operator= (const Iter& iter) {
  73. fCurr = iter.fCurr;
  74. fRemaining = iter.fRemaining;
  75. return *this;
  76. }
  77. Iter(const Attribute* attrs, int count) : fCurr(attrs), fRemaining(count) {
  78. this->skipUninitialized();
  79. }
  80. bool operator!=(const Iter& that) const { return fCurr != that.fCurr; }
  81. const Attribute& operator*() const { return *fCurr; }
  82. void operator++() {
  83. if (fRemaining) {
  84. fRemaining--;
  85. fCurr++;
  86. this->skipUninitialized();
  87. }
  88. }
  89. private:
  90. void skipUninitialized() {
  91. if (!fRemaining) {
  92. fCurr = nullptr;
  93. } else {
  94. while (!fCurr->isInitialized()) {
  95. ++fCurr;
  96. }
  97. }
  98. }
  99. const Attribute* fCurr;
  100. int fRemaining;
  101. };
  102. class AttributeSet {
  103. public:
  104. Iter begin() const { return Iter(fAttributes, fCount); }
  105. Iter end() const { return Iter(); }
  106. private:
  107. friend class GrPrimitiveProcessor;
  108. void init(const Attribute* attrs, int count) {
  109. fAttributes = attrs;
  110. fRawCount = count;
  111. fCount = 0;
  112. fStride = 0;
  113. for (int i = 0; i < count; ++i) {
  114. if (attrs[i].isInitialized()) {
  115. fCount++;
  116. fStride += attrs[i].sizeAlign4();
  117. }
  118. }
  119. }
  120. const Attribute* fAttributes = nullptr;
  121. int fRawCount = 0;
  122. int fCount = 0;
  123. size_t fStride = 0;
  124. };
  125. GrPrimitiveProcessor(ClassID);
  126. int numTextureSamplers() const { return fTextureSamplerCnt; }
  127. const TextureSampler& textureSampler(int index) const;
  128. int numVertexAttributes() const { return fVertexAttributes.fCount; }
  129. const AttributeSet& vertexAttributes() const { return fVertexAttributes; }
  130. int numInstanceAttributes() const { return fInstanceAttributes.fCount; }
  131. const AttributeSet& instanceAttributes() const { return fInstanceAttributes; }
  132. bool hasVertexAttributes() const { return SkToBool(fVertexAttributes.fCount); }
  133. bool hasInstanceAttributes() const { return SkToBool(fInstanceAttributes.fCount); }
  134. /**
  135. * A common practice is to populate the the vertex/instance's memory using an implicit array of
  136. * structs. In this case, it is best to assert that:
  137. * stride == sizeof(struct)
  138. */
  139. size_t vertexStride() const { return fVertexAttributes.fStride; }
  140. size_t instanceStride() const { return fInstanceAttributes.fStride; }
  141. // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
  142. // we put these calls on the base class to prevent having to cast
  143. virtual bool willUseGeoShader() const = 0;
  144. /**
  145. * Computes a transformKey from an array of coord transforms. Will only look at the first
  146. * <numCoords> transforms in the array.
  147. *
  148. * TODO: A better name for this function would be "compute" instead of "get".
  149. */
  150. uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
  151. int numCoords) const;
  152. /**
  153. * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
  154. * processor's GL backend implementation.
  155. *
  156. * TODO: A better name for this function would be "compute" instead of "get".
  157. */
  158. virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
  159. void getAttributeKey(GrProcessorKeyBuilder* b) const {
  160. // Ensure that our CPU and GPU type fields fit together in a 32-bit value, and we never
  161. // collide with the "uninitialized" value.
  162. static_assert(kGrVertexAttribTypeCount < (1 << 8), "");
  163. static_assert(kGrSLTypeCount < (1 << 8), "");
  164. auto add_attributes = [=](const Attribute* attrs, int attrCount) {
  165. for (int i = 0; i < attrCount; ++i) {
  166. b->add32(attrs[i].isInitialized() ? (attrs[i].cpuType() << 16) | attrs[i].gpuType()
  167. : ~0);
  168. }
  169. };
  170. add_attributes(fVertexAttributes.fAttributes, fVertexAttributes.fRawCount);
  171. add_attributes(fInstanceAttributes.fAttributes, fInstanceAttributes.fRawCount);
  172. }
  173. /** Returns a new instance of the appropriate *GL* implementation class
  174. for the given GrProcessor; caller is responsible for deleting
  175. the object. */
  176. virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0;
  177. virtual bool isPathRendering() const { return false; }
  178. protected:
  179. void setVertexAttributes(const Attribute* attrs, int attrCount) {
  180. fVertexAttributes.init(attrs, attrCount);
  181. }
  182. void setInstanceAttributes(const Attribute* attrs, int attrCount) {
  183. SkASSERT(attrCount >= 0);
  184. fInstanceAttributes.init(attrs, attrCount);
  185. }
  186. void setTextureSamplerCnt(int cnt) {
  187. SkASSERT(cnt >= 0);
  188. fTextureSamplerCnt = cnt;
  189. }
  190. /**
  191. * Helper for implementing onTextureSampler(). E.g.:
  192. * return IthTexureSampler(i, fMyFirstSampler, fMySecondSampler, fMyThirdSampler);
  193. */
  194. template <typename... Args>
  195. static const TextureSampler& IthTextureSampler(int i, const TextureSampler& samp0,
  196. const Args&... samps) {
  197. return (0 == i) ? samp0 : IthTextureSampler(i - 1, samps...);
  198. }
  199. inline static const TextureSampler& IthTextureSampler(int i);
  200. private:
  201. virtual const TextureSampler& onTextureSampler(int) const { return IthTextureSampler(0); }
  202. AttributeSet fVertexAttributes;
  203. AttributeSet fInstanceAttributes;
  204. int fTextureSamplerCnt = 0;
  205. typedef GrProcessor INHERITED;
  206. };
  207. //////////////////////////////////////////////////////////////////////////////
  208. /**
  209. * Used to represent a texture that is required by a GrPrimitiveProcessor. It holds a GrTextureProxy
  210. * along with an associated GrSamplerState. TextureSamplers don't perform any coord manipulation to
  211. * account for texture origin.
  212. */
  213. class GrPrimitiveProcessor::TextureSampler {
  214. public:
  215. TextureSampler() = default;
  216. TextureSampler(GrTextureType, GrPixelConfig, const GrSamplerState&, const GrSwizzle&,
  217. uint32_t extraSamplerKey);
  218. explicit TextureSampler(GrTextureType, GrPixelConfig, GrSamplerState::Filter,
  219. GrSamplerState::WrapMode wrapXAndY, const GrSwizzle&);
  220. TextureSampler(const TextureSampler&) = delete;
  221. TextureSampler& operator=(const TextureSampler&) = delete;
  222. void reset(GrTextureType, GrPixelConfig, const GrSamplerState&, const GrSwizzle&,
  223. uint32_t extraSamplerKey = 0);
  224. void reset(GrTextureType, GrPixelConfig,
  225. GrSamplerState::Filter,
  226. GrSamplerState::WrapMode wrapXAndY,
  227. const GrSwizzle& swizzle);
  228. GrTextureType textureType() const { return fTextureType; }
  229. GrPixelConfig config() const { return fConfig; }
  230. const GrSamplerState& samplerState() const { return fSamplerState; }
  231. const GrSwizzle& swizzle() const { return fSwizzle; }
  232. uint32_t extraSamplerKey() const { return fExtraSamplerKey; }
  233. bool isInitialized() const { return fConfig != kUnknown_GrPixelConfig; }
  234. private:
  235. GrSamplerState fSamplerState;
  236. GrSwizzle fSwizzle;
  237. GrTextureType fTextureType = GrTextureType::k2D;
  238. GrPixelConfig fConfig = kUnknown_GrPixelConfig;
  239. uint32_t fExtraSamplerKey = 0;
  240. };
  241. const GrPrimitiveProcessor::TextureSampler& GrPrimitiveProcessor::IthTextureSampler(int i) {
  242. SK_ABORT("Illegal texture sampler index");
  243. static const TextureSampler kBogus;
  244. return kBogus;
  245. }
  246. //////////////////////////////////////////////////////////////////////////////
  247. /**
  248. * Returns the size of the attrib type in bytes.
  249. * This was moved from include/private/GrTypesPriv.h in service of Skia dependents that build
  250. * with C++11.
  251. */
  252. static constexpr inline size_t GrVertexAttribTypeSize(GrVertexAttribType type) {
  253. switch (type) {
  254. case kFloat_GrVertexAttribType:
  255. return sizeof(float);
  256. case kFloat2_GrVertexAttribType:
  257. return 2 * sizeof(float);
  258. case kFloat3_GrVertexAttribType:
  259. return 3 * sizeof(float);
  260. case kFloat4_GrVertexAttribType:
  261. return 4 * sizeof(float);
  262. case kHalf_GrVertexAttribType:
  263. return sizeof(uint16_t);
  264. case kHalf2_GrVertexAttribType:
  265. return 2 * sizeof(uint16_t);
  266. case kHalf3_GrVertexAttribType:
  267. return 3 * sizeof(uint16_t);
  268. case kHalf4_GrVertexAttribType:
  269. return 4 * sizeof(uint16_t);
  270. case kInt2_GrVertexAttribType:
  271. return 2 * sizeof(int32_t);
  272. case kInt3_GrVertexAttribType:
  273. return 3 * sizeof(int32_t);
  274. case kInt4_GrVertexAttribType:
  275. return 4 * sizeof(int32_t);
  276. case kByte_GrVertexAttribType:
  277. return 1 * sizeof(char);
  278. case kByte2_GrVertexAttribType:
  279. return 2 * sizeof(char);
  280. case kByte3_GrVertexAttribType:
  281. return 3 * sizeof(char);
  282. case kByte4_GrVertexAttribType:
  283. return 4 * sizeof(char);
  284. case kUByte_GrVertexAttribType:
  285. return 1 * sizeof(char);
  286. case kUByte2_GrVertexAttribType:
  287. return 2 * sizeof(char);
  288. case kUByte3_GrVertexAttribType:
  289. return 3 * sizeof(char);
  290. case kUByte4_GrVertexAttribType:
  291. return 4 * sizeof(char);
  292. case kUByte_norm_GrVertexAttribType:
  293. return 1 * sizeof(char);
  294. case kUByte4_norm_GrVertexAttribType:
  295. return 4 * sizeof(char);
  296. case kShort2_GrVertexAttribType:
  297. return 2 * sizeof(int16_t);
  298. case kShort4_GrVertexAttribType:
  299. return 4 * sizeof(int16_t);
  300. case kUShort2_GrVertexAttribType: // fall through
  301. case kUShort2_norm_GrVertexAttribType:
  302. return 2 * sizeof(uint16_t);
  303. case kInt_GrVertexAttribType:
  304. return sizeof(int32_t);
  305. case kUint_GrVertexAttribType:
  306. return sizeof(uint32_t);
  307. case kUShort_norm_GrVertexAttribType:
  308. return sizeof(uint16_t);
  309. // Experimental (for Y416)
  310. case kUShort4_norm_GrVertexAttribType:
  311. return 4 * sizeof(uint16_t);
  312. }
  313. // GCC fails because SK_ABORT evaluates to non constexpr. clang and cl.exe think this is
  314. // unreachable and don't complain.
  315. #if defined(__clang__) || !defined(__GNUC__)
  316. SK_ABORT("Unsupported type conversion");
  317. #endif
  318. return 0;
  319. }
  320. constexpr size_t GrPrimitiveProcessor::Attribute::size() const {
  321. return GrVertexAttribTypeSize(fCPUType);
  322. }
  323. #endif