GrGLSLFragmentShaderBuilder.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  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 "include/gpu/GrRenderTarget.h"
  8. #include "src/gpu/GrRenderTargetPriv.h"
  9. #include "src/gpu/GrShaderCaps.h"
  10. #include "src/gpu/gl/GrGLGpu.h"
  11. #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
  12. #include "src/gpu/glsl/GrGLSLProgramBuilder.h"
  13. #include "src/gpu/glsl/GrGLSLUniformHandler.h"
  14. #include "src/gpu/glsl/GrGLSLVarying.h"
  15. const char* GrGLSLFragmentShaderBuilder::kDstColorName = "_dstColor";
  16. static const char* specific_layout_qualifier_name(GrBlendEquation equation) {
  17. SkASSERT(GrBlendEquationIsAdvanced(equation));
  18. static const char* kLayoutQualifierNames[] = {
  19. "blend_support_screen",
  20. "blend_support_overlay",
  21. "blend_support_darken",
  22. "blend_support_lighten",
  23. "blend_support_colordodge",
  24. "blend_support_colorburn",
  25. "blend_support_hardlight",
  26. "blend_support_softlight",
  27. "blend_support_difference",
  28. "blend_support_exclusion",
  29. "blend_support_multiply",
  30. "blend_support_hsl_hue",
  31. "blend_support_hsl_saturation",
  32. "blend_support_hsl_color",
  33. "blend_support_hsl_luminosity"
  34. };
  35. return kLayoutQualifierNames[equation - kFirstAdvancedGrBlendEquation];
  36. GR_STATIC_ASSERT(0 == kScreen_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  37. GR_STATIC_ASSERT(1 == kOverlay_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  38. GR_STATIC_ASSERT(2 == kDarken_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  39. GR_STATIC_ASSERT(3 == kLighten_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  40. GR_STATIC_ASSERT(4 == kColorDodge_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  41. GR_STATIC_ASSERT(5 == kColorBurn_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  42. GR_STATIC_ASSERT(6 == kHardLight_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  43. GR_STATIC_ASSERT(7 == kSoftLight_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  44. GR_STATIC_ASSERT(8 == kDifference_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  45. GR_STATIC_ASSERT(9 == kExclusion_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  46. GR_STATIC_ASSERT(10 == kMultiply_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  47. GR_STATIC_ASSERT(11 == kHSLHue_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  48. GR_STATIC_ASSERT(12 == kHSLSaturation_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  49. GR_STATIC_ASSERT(13 == kHSLColor_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  50. GR_STATIC_ASSERT(14 == kHSLLuminosity_GrBlendEquation - kFirstAdvancedGrBlendEquation);
  51. // There's an illegal GrBlendEquation at the end there, hence the -1.
  52. GR_STATIC_ASSERT(SK_ARRAY_COUNT(kLayoutQualifierNames) ==
  53. kGrBlendEquationCnt - kFirstAdvancedGrBlendEquation - 1);
  54. }
  55. uint8_t GrGLSLFragmentShaderBuilder::KeyForSurfaceOrigin(GrSurfaceOrigin origin) {
  56. SkASSERT(kTopLeft_GrSurfaceOrigin == origin || kBottomLeft_GrSurfaceOrigin == origin);
  57. return origin + 1;
  58. GR_STATIC_ASSERT(0 == kTopLeft_GrSurfaceOrigin);
  59. GR_STATIC_ASSERT(1 == kBottomLeft_GrSurfaceOrigin);
  60. }
  61. GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program)
  62. : GrGLSLFragmentBuilder(program) {
  63. fSubstageIndices.push_back(0);
  64. }
  65. SkString GrGLSLFragmentShaderBuilder::ensureCoords2D(const GrShaderVar& coords) {
  66. if (kFloat3_GrSLType != coords.getType() && kHalf3_GrSLType != coords.getType()) {
  67. SkASSERT(kFloat2_GrSLType == coords.getType() || kHalf2_GrSLType == coords.getType());
  68. return coords.getName();
  69. }
  70. SkString coords2D;
  71. coords2D.printf("%s_ensure2D", coords.c_str());
  72. this->codeAppendf("\tfloat2 %s = %s.xy / %s.z;", coords2D.c_str(), coords.c_str(),
  73. coords.c_str());
  74. return coords2D;
  75. }
  76. const char* GrGLSLFragmentShaderBuilder::sampleOffsets() {
  77. SkASSERT(CustomFeatures::kSampleLocations & fProgramBuilder->header().processorFeatures());
  78. SkDEBUGCODE(fUsedProcessorFeaturesThisStage_DebugOnly |= CustomFeatures::kSampleLocations);
  79. SkDEBUGCODE(fUsedProcessorFeaturesAllStages_DebugOnly |= CustomFeatures::kSampleLocations);
  80. return "_sampleOffsets";
  81. }
  82. void GrGLSLFragmentShaderBuilder::maskOffMultisampleCoverage(
  83. const char* mask, ScopeFlags scopeFlags) {
  84. const GrShaderCaps& shaderCaps = *fProgramBuilder->shaderCaps();
  85. if (!shaderCaps.sampleVariablesSupport() && !shaderCaps.sampleVariablesStencilSupport()) {
  86. SkDEBUGFAIL("Attempted to mask sample coverage without support.");
  87. return;
  88. }
  89. if (const char* extension = shaderCaps.sampleVariablesExtensionString()) {
  90. this->addFeature(1 << kSampleVariables_GLSLPrivateFeature, extension);
  91. }
  92. if (!fHasModifiedSampleMask) {
  93. fHasModifiedSampleMask = true;
  94. if (ScopeFlags::kTopLevel != scopeFlags) {
  95. this->codePrependf("gl_SampleMask[0] = ~0;");
  96. }
  97. if (!(ScopeFlags::kInsideLoop & scopeFlags)) {
  98. this->codeAppendf("gl_SampleMask[0] = (%s);", mask);
  99. return;
  100. }
  101. }
  102. this->codeAppendf("gl_SampleMask[0] &= (%s);", mask);
  103. }
  104. void GrGLSLFragmentShaderBuilder::applyFnToMultisampleMask(
  105. const char* fn, const char* grad, ScopeFlags scopeFlags) {
  106. SkASSERT(CustomFeatures::kSampleLocations & fProgramBuilder->header().processorFeatures());
  107. SkDEBUGCODE(fUsedProcessorFeaturesThisStage_DebugOnly |= CustomFeatures::kSampleLocations);
  108. SkDEBUGCODE(fUsedProcessorFeaturesAllStages_DebugOnly |= CustomFeatures::kSampleLocations);
  109. int sampleCnt = fProgramBuilder->effectiveSampleCnt();
  110. SkASSERT(sampleCnt > 1);
  111. this->codeAppendf("{");
  112. if (!grad) {
  113. SkASSERT(fProgramBuilder->shaderCaps()->shaderDerivativeSupport());
  114. // In order to use HW derivatives, our neighbors within the same primitive must also be
  115. // executing the same code. A per-pixel branch makes this pre-condition impossible to
  116. // fulfill.
  117. SkASSERT(!(ScopeFlags::kInsidePerPixelBranch & scopeFlags));
  118. this->codeAppendf("float2 grad = float2(dFdx(%s), dFdy(%s));", fn, fn);
  119. this->codeAppendf("float fnwidth = fwidth(%s);", fn);
  120. grad = "grad";
  121. } else {
  122. this->codeAppendf("float fnwidth = abs(%s.x) + abs(%s.y);", grad, grad);
  123. }
  124. this->codeAppendf("int mask = 0;");
  125. this->codeAppendf("if (%s*2 < fnwidth) {", fn); // Are ANY samples inside the implicit fn?
  126. this->codeAppendf( "if (%s*-2 >= fnwidth) {", fn); // Are ALL samples inside the implicit?
  127. this->codeAppendf( "mask = ~0;");
  128. this->codeAppendf( "} else for (int i = 0; i < %i; ++i) {", sampleCnt);
  129. this->codeAppendf( "float fnsample = dot(%s, _sampleOffsets[i]) + %s;", grad, fn);
  130. this->codeAppendf( "if (fnsample < 0) {");
  131. this->codeAppendf( "mask |= (1 << i);");
  132. this->codeAppendf( "}");
  133. this->codeAppendf( "}");
  134. this->codeAppendf("}");
  135. this->maskOffMultisampleCoverage("mask", scopeFlags);
  136. this->codeAppendf("}");
  137. }
  138. const char* GrGLSLFragmentShaderBuilder::dstColor() {
  139. SkDEBUGCODE(fHasReadDstColorThisStage_DebugOnly = true;)
  140. const GrShaderCaps* shaderCaps = fProgramBuilder->shaderCaps();
  141. if (shaderCaps->fbFetchSupport()) {
  142. this->addFeature(1 << kFramebufferFetch_GLSLPrivateFeature,
  143. shaderCaps->fbFetchExtensionString());
  144. // Some versions of this extension string require declaring custom color output on ES 3.0+
  145. const char* fbFetchColorName = "sk_LastFragColor";
  146. if (shaderCaps->fbFetchNeedsCustomOutput()) {
  147. this->enableCustomOutput();
  148. fOutputs[fCustomColorOutputIndex].setTypeModifier(GrShaderVar::kInOut_TypeModifier);
  149. fbFetchColorName = DeclaredColorOutputName();
  150. // Set the dstColor to an intermediate variable so we don't override it with the output
  151. this->codeAppendf("half4 %s = %s;", kDstColorName, fbFetchColorName);
  152. } else {
  153. return fbFetchColorName;
  154. }
  155. }
  156. return kDstColorName;
  157. }
  158. void GrGLSLFragmentShaderBuilder::enableAdvancedBlendEquationIfNeeded(GrBlendEquation equation) {
  159. SkASSERT(GrBlendEquationIsAdvanced(equation));
  160. const GrShaderCaps& caps = *fProgramBuilder->shaderCaps();
  161. if (!caps.mustEnableAdvBlendEqs()) {
  162. return;
  163. }
  164. this->addFeature(1 << kBlendEquationAdvanced_GLSLPrivateFeature,
  165. "GL_KHR_blend_equation_advanced");
  166. if (caps.mustEnableSpecificAdvBlendEqs()) {
  167. this->addLayoutQualifier(specific_layout_qualifier_name(equation), kOut_InterfaceQualifier);
  168. } else {
  169. this->addLayoutQualifier("blend_support_all_equations", kOut_InterfaceQualifier);
  170. }
  171. }
  172. void GrGLSLFragmentShaderBuilder::enableCustomOutput() {
  173. if (!fHasCustomColorOutput) {
  174. fHasCustomColorOutput = true;
  175. fCustomColorOutputIndex = fOutputs.count();
  176. fOutputs.push_back().set(kHalf4_GrSLType, DeclaredColorOutputName(),
  177. GrShaderVar::kOut_TypeModifier);
  178. fProgramBuilder->finalizeFragmentOutputColor(fOutputs.back());
  179. }
  180. }
  181. void GrGLSLFragmentShaderBuilder::enableSecondaryOutput() {
  182. SkASSERT(!fHasSecondaryOutput);
  183. fHasSecondaryOutput = true;
  184. const GrShaderCaps& caps = *fProgramBuilder->shaderCaps();
  185. if (const char* extension = caps.secondaryOutputExtensionString()) {
  186. this->addFeature(1 << kBlendFuncExtended_GLSLPrivateFeature, extension);
  187. }
  188. // If the primary output is declared, we must declare also the secondary output
  189. // and vice versa, since it is not allowed to use a built-in gl_FragColor and a custom
  190. // output. The condition also co-incides with the condition in whici GLES SL 2.0
  191. // requires the built-in gl_SecondaryFragColorEXT, where as 3.0 requires a custom output.
  192. if (caps.mustDeclareFragmentShaderOutput()) {
  193. fOutputs.push_back().set(kHalf4_GrSLType, DeclaredSecondaryColorOutputName(),
  194. GrShaderVar::kOut_TypeModifier);
  195. fProgramBuilder->finalizeFragmentSecondaryColor(fOutputs.back());
  196. }
  197. }
  198. const char* GrGLSLFragmentShaderBuilder::getPrimaryColorOutputName() const {
  199. return fHasCustomColorOutput ? DeclaredColorOutputName() : "sk_FragColor";
  200. }
  201. bool GrGLSLFragmentShaderBuilder::primaryColorOutputIsInOut() const {
  202. return fHasCustomColorOutput &&
  203. fOutputs[fCustomColorOutputIndex].getTypeModifier() == GrShaderVar::kInOut_TypeModifier;
  204. }
  205. void GrGLSLFragmentBuilder::declAppendf(const char* fmt, ...) {
  206. va_list argp;
  207. va_start(argp, fmt);
  208. inputs().appendVAList(fmt, argp);
  209. va_end(argp);
  210. }
  211. const char* GrGLSLFragmentShaderBuilder::getSecondaryColorOutputName() const {
  212. if (this->hasSecondaryOutput()) {
  213. return (fProgramBuilder->shaderCaps()->mustDeclareFragmentShaderOutput())
  214. ? DeclaredSecondaryColorOutputName()
  215. : "gl_SecondaryFragColorEXT";
  216. }
  217. return nullptr;
  218. }
  219. GrSurfaceOrigin GrGLSLFragmentShaderBuilder::getSurfaceOrigin() const {
  220. SkASSERT(fProgramBuilder->header().hasSurfaceOriginKey());
  221. return static_cast<GrSurfaceOrigin>(fProgramBuilder->header().fSurfaceOriginKey-1);
  222. GR_STATIC_ASSERT(0 == kTopLeft_GrSurfaceOrigin);
  223. GR_STATIC_ASSERT(1 == kBottomLeft_GrSurfaceOrigin);
  224. }
  225. void GrGLSLFragmentShaderBuilder::onFinalize() {
  226. SkASSERT(fProgramBuilder->header().processorFeatures()
  227. == fUsedProcessorFeaturesAllStages_DebugOnly);
  228. if (CustomFeatures::kSampleLocations & fProgramBuilder->header().processorFeatures()) {
  229. const SkTArray<SkPoint>& sampleLocations =
  230. fProgramBuilder->renderTarget()->renderTargetPriv().getSampleLocations();
  231. this->definitions().append("const float2 _sampleOffsets[] = float2[](");
  232. for (int i = 0; i < sampleLocations.count(); ++i) {
  233. SkPoint offset = sampleLocations[i] - SkPoint::Make(.5f, .5f);
  234. if (kBottomLeft_GrSurfaceOrigin == this->getSurfaceOrigin()) {
  235. offset.fY = -offset.fY;
  236. }
  237. this->definitions().appendf("float2(%f, %f)", offset.x(), offset.y());
  238. this->definitions().append((i + 1 != sampleLocations.count()) ? ", " : ");");
  239. }
  240. }
  241. fProgramBuilder->varyingHandler()->getFragDecls(&this->inputs(), &this->outputs());
  242. }
  243. void GrGLSLFragmentShaderBuilder::onBeforeChildProcEmitCode() {
  244. SkASSERT(fSubstageIndices.count() >= 1);
  245. fSubstageIndices.push_back(0);
  246. // second-to-last value in the fSubstageIndices stack is the index of the child proc
  247. // at that level which is currently emitting code.
  248. fMangleString.appendf("_c%d", fSubstageIndices[fSubstageIndices.count() - 2]);
  249. }
  250. void GrGLSLFragmentShaderBuilder::onAfterChildProcEmitCode() {
  251. SkASSERT(fSubstageIndices.count() >= 2);
  252. fSubstageIndices.pop_back();
  253. fSubstageIndices.back()++;
  254. int removeAt = fMangleString.findLastOf('_');
  255. fMangleString.remove(removeAt, fMangleString.size() - removeAt);
  256. }