GrGLProgramDataManager.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*
  2. * Copyright 2012 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/core/SkMatrix.h"
  8. #include "src/gpu/gl/GrGLGpu.h"
  9. #include "src/gpu/gl/GrGLProgramDataManager.h"
  10. #include "src/gpu/glsl/GrGLSLUniformHandler.h"
  11. #define ASSERT_ARRAY_UPLOAD_IN_BOUNDS(UNI, COUNT) \
  12. SkASSERT((COUNT) <= (UNI).fArrayCount || \
  13. (1 == (COUNT) && GrShaderVar::kNonArray == (UNI).fArrayCount))
  14. GrGLProgramDataManager::GrGLProgramDataManager(GrGLGpu* gpu, GrGLuint programID,
  15. const UniformInfoArray& uniforms,
  16. const VaryingInfoArray& pathProcVaryings)
  17. : fGpu(gpu)
  18. , fProgramID(programID) {
  19. int count = uniforms.count();
  20. fUniforms.push_back_n(count);
  21. for (int i = 0; i < count; i++) {
  22. Uniform& uniform = fUniforms[i];
  23. const UniformInfo& builderUniform = uniforms[i];
  24. SkASSERT(GrShaderVar::kNonArray == builderUniform.fVariable.getArrayCount() ||
  25. builderUniform.fVariable.getArrayCount() > 0);
  26. SkDEBUGCODE(
  27. uniform.fArrayCount = builderUniform.fVariable.getArrayCount();
  28. uniform.fType = builderUniform.fVariable.getType();
  29. )
  30. uniform.fLocation = builderUniform.fLocation;
  31. }
  32. // NVPR programs have separable varyings
  33. count = pathProcVaryings.count();
  34. fPathProcVaryings.push_back_n(count);
  35. for (int i = 0; i < count; i++) {
  36. SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
  37. PathProcVarying& pathProcVarying = fPathProcVaryings[i];
  38. const VaryingInfo& builderPathProcVarying = pathProcVaryings[i];
  39. SkASSERT(GrShaderVar::kNonArray == builderPathProcVarying.fVariable.getArrayCount() ||
  40. builderPathProcVarying.fVariable.getArrayCount() > 0);
  41. SkDEBUGCODE(
  42. pathProcVarying.fArrayCount = builderPathProcVarying.fVariable.getArrayCount();
  43. pathProcVarying.fType = builderPathProcVarying.fVariable.getType();
  44. )
  45. pathProcVarying.fLocation = builderPathProcVarying.fLocation;
  46. }
  47. }
  48. void GrGLProgramDataManager::setSamplerUniforms(const UniformInfoArray& samplers,
  49. int startUnit) const {
  50. for (int i = 0; i < samplers.count(); ++i) {
  51. const UniformInfo& sampler = samplers[i];
  52. SkASSERT(sampler.fVisibility);
  53. if (kUnusedUniform != sampler.fLocation) {
  54. GR_GL_CALL(fGpu->glInterface(), Uniform1i(sampler.fLocation, i + startUnit));
  55. }
  56. }
  57. }
  58. void GrGLProgramDataManager::set1i(UniformHandle u, int32_t i) const {
  59. const Uniform& uni = fUniforms[u.toIndex()];
  60. SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
  61. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  62. if (kUnusedUniform != uni.fLocation) {
  63. GR_GL_CALL(fGpu->glInterface(), Uniform1i(uni.fLocation, i));
  64. }
  65. }
  66. void GrGLProgramDataManager::set1iv(UniformHandle u,
  67. int arrayCount,
  68. const int32_t v[]) const {
  69. const Uniform& uni = fUniforms[u.toIndex()];
  70. SkASSERT(uni.fType == kInt_GrSLType || uni.fType == kShort_GrSLType);
  71. SkASSERT(arrayCount > 0);
  72. ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
  73. if (kUnusedUniform != uni.fLocation) {
  74. GR_GL_CALL(fGpu->glInterface(), Uniform1iv(uni.fLocation, arrayCount, v));
  75. }
  76. }
  77. void GrGLProgramDataManager::set1f(UniformHandle u, float v0) const {
  78. const Uniform& uni = fUniforms[u.toIndex()];
  79. SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
  80. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  81. if (kUnusedUniform != uni.fLocation) {
  82. GR_GL_CALL(fGpu->glInterface(), Uniform1f(uni.fLocation, v0));
  83. }
  84. }
  85. void GrGLProgramDataManager::set1fv(UniformHandle u,
  86. int arrayCount,
  87. const float v[]) const {
  88. const Uniform& uni = fUniforms[u.toIndex()];
  89. SkASSERT(uni.fType == kFloat_GrSLType || uni.fType == kHalf_GrSLType);
  90. SkASSERT(arrayCount > 0);
  91. ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
  92. // This assert fires in some instances of the two-pt gradient for its VSParams.
  93. // Once the uniform manager is responsible for inserting the duplicate uniform
  94. // arrays in VS and FS driver bug workaround, this can be enabled.
  95. // this->printUni(uni);
  96. if (kUnusedUniform != uni.fLocation) {
  97. GR_GL_CALL(fGpu->glInterface(), Uniform1fv(uni.fLocation, arrayCount, v));
  98. }
  99. }
  100. void GrGLProgramDataManager::set2i(UniformHandle u, int32_t i0, int32_t i1) const {
  101. const Uniform& uni = fUniforms[u.toIndex()];
  102. SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
  103. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  104. if (kUnusedUniform != uni.fLocation) {
  105. GR_GL_CALL(fGpu->glInterface(), Uniform2i(uni.fLocation, i0, i1));
  106. }
  107. }
  108. void GrGLProgramDataManager::set2iv(UniformHandle u,
  109. int arrayCount,
  110. const int32_t v[]) const {
  111. const Uniform& uni = fUniforms[u.toIndex()];
  112. SkASSERT(uni.fType == kInt2_GrSLType || uni.fType == kShort2_GrSLType);
  113. SkASSERT(arrayCount > 0);
  114. ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
  115. if (kUnusedUniform != uni.fLocation) {
  116. GR_GL_CALL(fGpu->glInterface(), Uniform2iv(uni.fLocation, arrayCount, v));
  117. }
  118. }
  119. void GrGLProgramDataManager::set2f(UniformHandle u, float v0, float v1) const {
  120. const Uniform& uni = fUniforms[u.toIndex()];
  121. SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
  122. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  123. if (kUnusedUniform != uni.fLocation) {
  124. GR_GL_CALL(fGpu->glInterface(), Uniform2f(uni.fLocation, v0, v1));
  125. }
  126. }
  127. void GrGLProgramDataManager::set2fv(UniformHandle u,
  128. int arrayCount,
  129. const float v[]) const {
  130. const Uniform& uni = fUniforms[u.toIndex()];
  131. SkASSERT(uni.fType == kFloat2_GrSLType || uni.fType == kHalf2_GrSLType);
  132. SkASSERT(arrayCount > 0);
  133. ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
  134. if (kUnusedUniform != uni.fLocation) {
  135. GR_GL_CALL(fGpu->glInterface(), Uniform2fv(uni.fLocation, arrayCount, v));
  136. }
  137. }
  138. void GrGLProgramDataManager::set3i(UniformHandle u, int32_t i0, int32_t i1, int32_t i2) const {
  139. const Uniform& uni = fUniforms[u.toIndex()];
  140. SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
  141. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  142. if (kUnusedUniform != uni.fLocation) {
  143. GR_GL_CALL(fGpu->glInterface(), Uniform3i(uni.fLocation, i0, i1, i2));
  144. }
  145. }
  146. void GrGLProgramDataManager::set3iv(UniformHandle u,
  147. int arrayCount,
  148. const int32_t v[]) const {
  149. const Uniform& uni = fUniforms[u.toIndex()];
  150. SkASSERT(uni.fType == kInt3_GrSLType || uni.fType == kShort3_GrSLType);
  151. SkASSERT(arrayCount > 0);
  152. ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
  153. if (kUnusedUniform != uni.fLocation) {
  154. GR_GL_CALL(fGpu->glInterface(), Uniform3iv(uni.fLocation, arrayCount, v));
  155. }
  156. }
  157. void GrGLProgramDataManager::set3f(UniformHandle u, float v0, float v1, float v2) const {
  158. const Uniform& uni = fUniforms[u.toIndex()];
  159. SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
  160. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  161. if (kUnusedUniform != uni.fLocation) {
  162. GR_GL_CALL(fGpu->glInterface(), Uniform3f(uni.fLocation, v0, v1, v2));
  163. }
  164. }
  165. void GrGLProgramDataManager::set3fv(UniformHandle u,
  166. int arrayCount,
  167. const float v[]) const {
  168. const Uniform& uni = fUniforms[u.toIndex()];
  169. SkASSERT(uni.fType == kFloat3_GrSLType || uni.fType == kHalf3_GrSLType);
  170. SkASSERT(arrayCount > 0);
  171. ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
  172. if (kUnusedUniform != uni.fLocation) {
  173. GR_GL_CALL(fGpu->glInterface(), Uniform3fv(uni.fLocation, arrayCount, v));
  174. }
  175. }
  176. void GrGLProgramDataManager::set4i(UniformHandle u,
  177. int32_t i0,
  178. int32_t i1,
  179. int32_t i2,
  180. int32_t i3) const {
  181. const Uniform& uni = fUniforms[u.toIndex()];
  182. SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
  183. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  184. if (kUnusedUniform != uni.fLocation) {
  185. GR_GL_CALL(fGpu->glInterface(), Uniform4i(uni.fLocation, i0, i1, i2, i3));
  186. }
  187. }
  188. void GrGLProgramDataManager::set4iv(UniformHandle u,
  189. int arrayCount,
  190. const int32_t v[]) const {
  191. const Uniform& uni = fUniforms[u.toIndex()];
  192. SkASSERT(uni.fType == kInt4_GrSLType || uni.fType == kShort4_GrSLType);
  193. SkASSERT(arrayCount > 0);
  194. ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
  195. if (kUnusedUniform != uni.fLocation) {
  196. GR_GL_CALL(fGpu->glInterface(), Uniform4iv(uni.fLocation, arrayCount, v));
  197. }
  198. }
  199. void GrGLProgramDataManager::set4f(UniformHandle u,
  200. float v0,
  201. float v1,
  202. float v2,
  203. float v3) const {
  204. const Uniform& uni = fUniforms[u.toIndex()];
  205. SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
  206. SkASSERT(GrShaderVar::kNonArray == uni.fArrayCount);
  207. if (kUnusedUniform != uni.fLocation) {
  208. GR_GL_CALL(fGpu->glInterface(), Uniform4f(uni.fLocation, v0, v1, v2, v3));
  209. }
  210. }
  211. void GrGLProgramDataManager::set4fv(UniformHandle u,
  212. int arrayCount,
  213. const float v[]) const {
  214. const Uniform& uni = fUniforms[u.toIndex()];
  215. SkASSERT(uni.fType == kFloat4_GrSLType || uni.fType == kHalf4_GrSLType);
  216. SkASSERT(arrayCount > 0);
  217. ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
  218. if (kUnusedUniform != uni.fLocation) {
  219. GR_GL_CALL(fGpu->glInterface(), Uniform4fv(uni.fLocation, arrayCount, v));
  220. }
  221. }
  222. void GrGLProgramDataManager::setMatrix2f(UniformHandle u, const float matrix[]) const {
  223. this->setMatrices<2>(u, 1, matrix);
  224. }
  225. void GrGLProgramDataManager::setMatrix3f(UniformHandle u, const float matrix[]) const {
  226. this->setMatrices<3>(u, 1, matrix);
  227. }
  228. void GrGLProgramDataManager::setMatrix4f(UniformHandle u, const float matrix[]) const {
  229. this->setMatrices<4>(u, 1, matrix);
  230. }
  231. void GrGLProgramDataManager::setMatrix2fv(UniformHandle u, int arrayCount, const float m[]) const {
  232. this->setMatrices<2>(u, arrayCount, m);
  233. }
  234. void GrGLProgramDataManager::setMatrix3fv(UniformHandle u, int arrayCount, const float m[]) const {
  235. this->setMatrices<3>(u, arrayCount, m);
  236. }
  237. void GrGLProgramDataManager::setMatrix4fv(UniformHandle u, int arrayCount, const float m[]) const {
  238. this->setMatrices<4>(u, arrayCount, m);
  239. }
  240. template<int N> struct set_uniform_matrix;
  241. template<int N> inline void GrGLProgramDataManager::setMatrices(UniformHandle u,
  242. int arrayCount,
  243. const float matrices[]) const {
  244. const Uniform& uni = fUniforms[u.toIndex()];
  245. SkASSERT(uni.fType == kFloat2x2_GrSLType + (N - 2) ||
  246. uni.fType == kHalf2x2_GrSLType + (N - 2));
  247. SkASSERT(arrayCount > 0);
  248. ASSERT_ARRAY_UPLOAD_IN_BOUNDS(uni, arrayCount);
  249. if (kUnusedUniform != uni.fLocation) {
  250. set_uniform_matrix<N>::set(fGpu->glInterface(), uni.fLocation, arrayCount, matrices);
  251. }
  252. }
  253. template<> struct set_uniform_matrix<2> {
  254. inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) {
  255. GR_GL_CALL(gli, UniformMatrix2fv(loc, cnt, false, m));
  256. }
  257. };
  258. template<> struct set_uniform_matrix<3> {
  259. inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) {
  260. GR_GL_CALL(gli, UniformMatrix3fv(loc, cnt, false, m));
  261. }
  262. };
  263. template<> struct set_uniform_matrix<4> {
  264. inline static void set(const GrGLInterface* gli, const GrGLint loc, int cnt, const float m[]) {
  265. GR_GL_CALL(gli, UniformMatrix4fv(loc, cnt, false, m));
  266. }
  267. };
  268. void GrGLProgramDataManager::setPathFragmentInputTransform(VaryingHandle u,
  269. int components,
  270. const SkMatrix& matrix) const {
  271. SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
  272. const PathProcVarying& fragmentInput = fPathProcVaryings[u.toIndex()];
  273. SkASSERT((components == 2 && (fragmentInput.fType == kFloat2_GrSLType ||
  274. fragmentInput.fType == kHalf2_GrSLType)) ||
  275. (components == 3 && (fragmentInput.fType == kFloat3_GrSLType ||
  276. fragmentInput.fType == kHalf3_GrSLType)));
  277. fGpu->glPathRendering()->setProgramPathFragmentInputTransform(fProgramID,
  278. fragmentInput.fLocation,
  279. GR_GL_OBJECT_LINEAR,
  280. components,
  281. matrix);
  282. }