GrDefaultGeoProcFactory.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. * Copyright 2014 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. #include "src/gpu/GrDefaultGeoProcFactory.h"
  8. #include "include/core/SkRefCnt.h"
  9. #include "src/gpu/GrCaps.h"
  10. #include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
  11. #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
  12. #include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
  13. #include "src/gpu/glsl/GrGLSLUniformHandler.h"
  14. #include "src/gpu/glsl/GrGLSLUtil.h"
  15. #include "src/gpu/glsl/GrGLSLVarying.h"
  16. #include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
  17. /*
  18. * The default Geometry Processor simply takes position and multiplies it by the uniform view
  19. * matrix. It also leaves coverage untouched. Behind the scenes, we may add per vertex color or
  20. * local coords.
  21. */
  22. enum GPFlag {
  23. kColorAttribute_GPFlag = 0x1,
  24. kColorAttributeIsSkColor_GPFlag = 0x2,
  25. kColorAttributeIsWide_GPFlag = 0x4,
  26. kLocalCoordAttribute_GPFlag = 0x8,
  27. kCoverageAttribute_GPFlag = 0x10,
  28. kCoverageAttributeTweak_GPFlag = 0x20,
  29. };
  30. class DefaultGeoProc : public GrGeometryProcessor {
  31. public:
  32. static sk_sp<GrGeometryProcessor> Make(const GrShaderCaps* shaderCaps,
  33. uint32_t gpTypeFlags,
  34. const SkPMColor4f& color,
  35. sk_sp<GrColorSpaceXform> colorSpaceXform,
  36. const SkMatrix& viewMatrix,
  37. const SkMatrix& localMatrix,
  38. bool localCoordsWillBeRead,
  39. uint8_t coverage) {
  40. return sk_sp<GrGeometryProcessor>(new DefaultGeoProc(
  41. shaderCaps, gpTypeFlags, color, std::move(colorSpaceXform), viewMatrix, localMatrix,
  42. coverage, localCoordsWillBeRead));
  43. }
  44. const char* name() const override { return "DefaultGeometryProcessor"; }
  45. const SkPMColor4f& color() const { return fColor; }
  46. bool hasVertexColor() const { return fInColor.isInitialized(); }
  47. const SkMatrix& viewMatrix() const { return fViewMatrix; }
  48. const SkMatrix& localMatrix() const { return fLocalMatrix; }
  49. bool localCoordsWillBeRead() const { return fLocalCoordsWillBeRead; }
  50. uint8_t coverage() const { return fCoverage; }
  51. bool hasVertexCoverage() const { return fInCoverage.isInitialized(); }
  52. class GLSLProcessor : public GrGLSLGeometryProcessor {
  53. public:
  54. GLSLProcessor()
  55. : fViewMatrix(SkMatrix::InvalidMatrix())
  56. , fColor(SK_PMColor4fILLEGAL)
  57. , fCoverage(0xff) {}
  58. void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
  59. const DefaultGeoProc& gp = args.fGP.cast<DefaultGeoProc>();
  60. GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
  61. GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
  62. GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
  63. GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
  64. // emit attributes
  65. varyingHandler->emitAttributes(gp);
  66. bool tweakAlpha = SkToBool(gp.fFlags & kCoverageAttributeTweak_GPFlag);
  67. SkASSERT(!tweakAlpha || gp.hasVertexCoverage());
  68. // Setup pass through color
  69. if (gp.hasVertexColor() || tweakAlpha) {
  70. GrGLSLVarying varying(kHalf4_GrSLType);
  71. varyingHandler->addVarying("color", &varying);
  72. // There are several optional steps to process the color. Start with the attribute,
  73. // or with uniform color (in the case of folding coverage into a uniform color):
  74. if (gp.hasVertexColor()) {
  75. vertBuilder->codeAppendf("half4 color = %s;", gp.fInColor.name());
  76. } else {
  77. const char* colorUniformName;
  78. fColorUniform = uniformHandler->addUniform(kVertex_GrShaderFlag,
  79. kHalf4_GrSLType,
  80. "Color",
  81. &colorUniformName);
  82. vertBuilder->codeAppendf("half4 color = %s;", colorUniformName);
  83. }
  84. // For SkColor, do a red/blue swap, possible color space conversion, and premul
  85. if (gp.fFlags & kColorAttributeIsSkColor_GPFlag) {
  86. vertBuilder->codeAppend("color = color.bgra;");
  87. if (gp.fColorSpaceXform) {
  88. fColorSpaceHelper.emitCode(uniformHandler, gp.fColorSpaceXform.get(),
  89. kVertex_GrShaderFlag);
  90. SkString xformedColor;
  91. vertBuilder->appendColorGamutXform(&xformedColor, "color",
  92. &fColorSpaceHelper);
  93. vertBuilder->codeAppendf("color = %s;", xformedColor.c_str());
  94. }
  95. vertBuilder->codeAppend("color = half4(color.rgb * color.a, color.a);");
  96. }
  97. // Optionally fold coverage into alpha (color).
  98. if (tweakAlpha) {
  99. vertBuilder->codeAppendf("color = color * %s;", gp.fInCoverage.name());
  100. }
  101. vertBuilder->codeAppendf("%s = color;\n", varying.vsOut());
  102. fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn());
  103. } else {
  104. this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
  105. &fColorUniform);
  106. }
  107. // Setup position
  108. this->writeOutputPosition(vertBuilder,
  109. uniformHandler,
  110. gpArgs,
  111. gp.fInPosition.name(),
  112. gp.viewMatrix(),
  113. &fViewMatrixUniform);
  114. if (gp.fInLocalCoords.isInitialized()) {
  115. // emit transforms with explicit local coords
  116. this->emitTransforms(vertBuilder,
  117. varyingHandler,
  118. uniformHandler,
  119. gp.fInLocalCoords.asShaderVar(),
  120. gp.localMatrix(),
  121. args.fFPCoordTransformHandler);
  122. } else {
  123. // emit transforms with position
  124. this->emitTransforms(vertBuilder,
  125. varyingHandler,
  126. uniformHandler,
  127. gp.fInPosition.asShaderVar(),
  128. gp.localMatrix(),
  129. args.fFPCoordTransformHandler);
  130. }
  131. // Setup coverage as pass through
  132. if (gp.hasVertexCoverage() && !tweakAlpha) {
  133. fragBuilder->codeAppendf("half alpha = 1.0;");
  134. varyingHandler->addPassThroughAttribute(gp.fInCoverage, "alpha");
  135. fragBuilder->codeAppendf("%s = half4(alpha);", args.fOutputCoverage);
  136. } else if (gp.coverage() == 0xff) {
  137. fragBuilder->codeAppendf("%s = half4(1);", args.fOutputCoverage);
  138. } else {
  139. const char* fragCoverage;
  140. fCoverageUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
  141. kHalf_GrSLType,
  142. "Coverage",
  143. &fragCoverage);
  144. fragBuilder->codeAppendf("%s = half4(%s);", args.fOutputCoverage, fragCoverage);
  145. }
  146. }
  147. static inline void GenKey(const GrGeometryProcessor& gp,
  148. const GrShaderCaps&,
  149. GrProcessorKeyBuilder* b) {
  150. const DefaultGeoProc& def = gp.cast<DefaultGeoProc>();
  151. uint32_t key = def.fFlags;
  152. key |= (def.coverage() == 0xff) ? 0x80 : 0;
  153. key |= (def.localCoordsWillBeRead() && def.localMatrix().hasPerspective()) ? 0x100 : 0;
  154. key |= ComputePosKey(def.viewMatrix()) << 20;
  155. b->add32(key);
  156. b->add32(GrColorSpaceXform::XformKey(def.fColorSpaceXform.get()));
  157. }
  158. void setData(const GrGLSLProgramDataManager& pdman,
  159. const GrPrimitiveProcessor& gp,
  160. FPCoordTransformIter&& transformIter) override {
  161. const DefaultGeoProc& dgp = gp.cast<DefaultGeoProc>();
  162. if (!dgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dgp.viewMatrix())) {
  163. fViewMatrix = dgp.viewMatrix();
  164. float viewMatrix[3 * 3];
  165. GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix);
  166. pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
  167. }
  168. if (!dgp.hasVertexColor() && dgp.color() != fColor) {
  169. pdman.set4fv(fColorUniform, 1, dgp.color().vec());
  170. fColor = dgp.color();
  171. }
  172. if (dgp.coverage() != fCoverage && !dgp.hasVertexCoverage()) {
  173. pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(dgp.coverage()));
  174. fCoverage = dgp.coverage();
  175. }
  176. this->setTransformDataHelper(dgp.fLocalMatrix, pdman, &transformIter);
  177. fColorSpaceHelper.setData(pdman, dgp.fColorSpaceXform.get());
  178. }
  179. private:
  180. SkMatrix fViewMatrix;
  181. SkPMColor4f fColor;
  182. uint8_t fCoverage;
  183. UniformHandle fViewMatrixUniform;
  184. UniformHandle fColorUniform;
  185. UniformHandle fCoverageUniform;
  186. GrGLSLColorSpaceXformHelper fColorSpaceHelper;
  187. typedef GrGLSLGeometryProcessor INHERITED;
  188. };
  189. void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
  190. GLSLProcessor::GenKey(*this, caps, b);
  191. }
  192. GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override {
  193. return new GLSLProcessor();
  194. }
  195. private:
  196. DefaultGeoProc(const GrShaderCaps* shaderCaps,
  197. uint32_t gpTypeFlags,
  198. const SkPMColor4f& color,
  199. sk_sp<GrColorSpaceXform> colorSpaceXform,
  200. const SkMatrix& viewMatrix,
  201. const SkMatrix& localMatrix,
  202. uint8_t coverage,
  203. bool localCoordsWillBeRead)
  204. : INHERITED(kDefaultGeoProc_ClassID)
  205. , fColor(color)
  206. , fViewMatrix(viewMatrix)
  207. , fLocalMatrix(localMatrix)
  208. , fCoverage(coverage)
  209. , fFlags(gpTypeFlags)
  210. , fLocalCoordsWillBeRead(localCoordsWillBeRead)
  211. , fColorSpaceXform(std::move(colorSpaceXform)) {
  212. fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
  213. if (fFlags & kColorAttribute_GPFlag) {
  214. fInColor = MakeColorAttribute("inColor",
  215. SkToBool(fFlags & kColorAttributeIsWide_GPFlag));
  216. }
  217. if (fFlags & kLocalCoordAttribute_GPFlag) {
  218. fInLocalCoords = {"inLocalCoord", kFloat2_GrVertexAttribType,
  219. kFloat2_GrSLType};
  220. }
  221. if (fFlags & kCoverageAttribute_GPFlag) {
  222. fInCoverage = {"inCoverage", kFloat_GrVertexAttribType, kHalf_GrSLType};
  223. }
  224. this->setVertexAttributes(&fInPosition, 4);
  225. }
  226. Attribute fInPosition;
  227. Attribute fInColor;
  228. Attribute fInLocalCoords;
  229. Attribute fInCoverage;
  230. SkPMColor4f fColor;
  231. SkMatrix fViewMatrix;
  232. SkMatrix fLocalMatrix;
  233. uint8_t fCoverage;
  234. uint32_t fFlags;
  235. bool fLocalCoordsWillBeRead;
  236. sk_sp<GrColorSpaceXform> fColorSpaceXform;
  237. GR_DECLARE_GEOMETRY_PROCESSOR_TEST
  238. typedef GrGeometryProcessor INHERITED;
  239. };
  240. GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
  241. #if GR_TEST_UTILS
  242. sk_sp<GrGeometryProcessor> DefaultGeoProc::TestCreate(GrProcessorTestData* d) {
  243. uint32_t flags = 0;
  244. if (d->fRandom->nextBool()) {
  245. flags |= kColorAttribute_GPFlag;
  246. }
  247. if (d->fRandom->nextBool()) {
  248. flags |= kColorAttributeIsSkColor_GPFlag;
  249. }
  250. if (d->fRandom->nextBool()) {
  251. flags |= kColorAttributeIsWide_GPFlag;
  252. }
  253. if (d->fRandom->nextBool()) {
  254. flags |= kCoverageAttribute_GPFlag;
  255. if (d->fRandom->nextBool()) {
  256. flags |= kCoverageAttributeTweak_GPFlag;
  257. }
  258. }
  259. if (d->fRandom->nextBool()) {
  260. flags |= kLocalCoordAttribute_GPFlag;
  261. }
  262. return DefaultGeoProc::Make(d->caps()->shaderCaps(),
  263. flags,
  264. SkPMColor4f::FromBytes_RGBA(GrRandomColor(d->fRandom)),
  265. GrTest::TestColorXform(d->fRandom),
  266. GrTest::TestMatrix(d->fRandom),
  267. GrTest::TestMatrix(d->fRandom),
  268. d->fRandom->nextBool(),
  269. GrRandomCoverage(d->fRandom));
  270. }
  271. #endif
  272. sk_sp<GrGeometryProcessor> GrDefaultGeoProcFactory::Make(const GrShaderCaps* shaderCaps,
  273. const Color& color,
  274. const Coverage& coverage,
  275. const LocalCoords& localCoords,
  276. const SkMatrix& viewMatrix) {
  277. uint32_t flags = 0;
  278. if (Color::kPremulGrColorAttribute_Type == color.fType) {
  279. flags |= kColorAttribute_GPFlag;
  280. } else if (Color::kUnpremulSkColorAttribute_Type == color.fType) {
  281. flags |= kColorAttribute_GPFlag | kColorAttributeIsSkColor_GPFlag;
  282. } else if (Color::kPremulWideColorAttribute_Type == color.fType) {
  283. flags |= kColorAttribute_GPFlag | kColorAttributeIsWide_GPFlag;
  284. }
  285. if (Coverage::kAttribute_Type == coverage.fType) {
  286. flags |= kCoverageAttribute_GPFlag;
  287. } else if (Coverage::kAttributeTweakAlpha_Type == coverage.fType) {
  288. flags |= kCoverageAttribute_GPFlag | kCoverageAttributeTweak_GPFlag;
  289. }
  290. flags |= localCoords.fType == LocalCoords::kHasExplicit_Type ? kLocalCoordAttribute_GPFlag : 0;
  291. uint8_t inCoverage = coverage.fCoverage;
  292. bool localCoordsWillBeRead = localCoords.fType != LocalCoords::kUnused_Type;
  293. return DefaultGeoProc::Make(shaderCaps,
  294. flags,
  295. color.fColor,
  296. color.fColorSpaceXform,
  297. viewMatrix,
  298. localCoords.fMatrix ? *localCoords.fMatrix : SkMatrix::I(),
  299. localCoordsWillBeRead,
  300. inCoverage);
  301. }
  302. sk_sp<GrGeometryProcessor> GrDefaultGeoProcFactory::MakeForDeviceSpace(
  303. const GrShaderCaps* shaderCaps,
  304. const Color& color,
  305. const Coverage& coverage,
  306. const LocalCoords& localCoords,
  307. const SkMatrix& viewMatrix) {
  308. SkMatrix invert = SkMatrix::I();
  309. if (LocalCoords::kUnused_Type != localCoords.fType) {
  310. SkASSERT(LocalCoords::kUsePosition_Type == localCoords.fType);
  311. if (!viewMatrix.isIdentity() && !viewMatrix.invert(&invert)) {
  312. return nullptr;
  313. }
  314. if (localCoords.hasLocalMatrix()) {
  315. invert.postConcat(*localCoords.fMatrix);
  316. }
  317. }
  318. LocalCoords inverted(LocalCoords::kUsePosition_Type, &invert);
  319. return Make(shaderCaps, color, coverage, inverted, SkMatrix::I());
  320. }