WebGLFormats.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "WebGLFormats.h"
  6. //cjh #include "gfxPrefs.h"
  7. //#include "GLContext.h"
  8. //#include "GLDefs.h"
  9. //#include "mozilla/gfx/Logging.h"
  10. //#include "mozilla/StaticMutex.h"
  11. #include "GLConsts.h"
  12. #ifdef FOO
  13. #error FOO is already defined! We use FOO() macros to keep things succinct in this file.
  14. #endif
  15. namespace mozilla {
  16. namespace webgl {
  17. template<typename K, typename V, typename K2, typename V2>
  18. static inline void
  19. AlwaysInsert(std::map<K,V>& dest, const K2& key, const V2& val)
  20. {
  21. auto res = dest.insert({ key, val });
  22. bool didInsert = res.second;
  23. MOZ_ALWAYS_TRUE(didInsert);
  24. }
  25. template<typename K, typename V, typename K2>
  26. static inline V*
  27. FindOrNull(const std::map<K,V*>& dest, const K2& key)
  28. {
  29. auto itr = dest.find(key);
  30. if (itr == dest.end())
  31. return nullptr;
  32. return itr->second;
  33. }
  34. // Returns a pointer to the in-place value for `key`.
  35. template<typename K, typename V, typename K2>
  36. static inline V*
  37. FindPtrOrNull(std::map<K,V>& dest, const K2& key)
  38. {
  39. auto itr = dest.find(key);
  40. if (itr == dest.end())
  41. return nullptr;
  42. return &(itr->second);
  43. }
  44. //////////////////////////////////////////////////////////////////////////////////////////
  45. std::map<EffectiveFormat, const CompressedFormatInfo> gCompressedFormatInfoMap;
  46. std::map<EffectiveFormat, FormatInfo> gFormatInfoMap;
  47. static inline const CompressedFormatInfo*
  48. GetCompressedFormatInfo(EffectiveFormat format)
  49. {
  50. MOZ_ASSERT(!gCompressedFormatInfoMap.empty());
  51. return FindPtrOrNull(gCompressedFormatInfoMap, format);
  52. }
  53. static inline FormatInfo*
  54. GetFormatInfo_NoLock(EffectiveFormat format)
  55. {
  56. MOZ_ASSERT(!gFormatInfoMap.empty());
  57. return FindPtrOrNull(gFormatInfoMap, format);
  58. }
  59. //////////////////////////////////////////////////////////////////////////////////////////
  60. static void
  61. AddCompressedFormatInfo(EffectiveFormat format, uint16_t bitsPerBlock, uint8_t blockWidth,
  62. uint8_t blockHeight, CompressionFamily family)
  63. {
  64. MOZ_ASSERT(bitsPerBlock % 8 == 0);
  65. uint16_t bytesPerBlock = bitsPerBlock / 8; // The specs always state these in bits,
  66. // but it's only ever useful to us as
  67. // bytes.
  68. MOZ_ASSERT(bytesPerBlock <= 255);
  69. const CompressedFormatInfo info = { format, uint8_t(bytesPerBlock), blockWidth,
  70. blockHeight, family };
  71. AlwaysInsert(gCompressedFormatInfoMap, format, info);
  72. }
  73. static void
  74. InitCompressedFormatInfo()
  75. {
  76. // GLES 3.0.4, p147, table 3.19
  77. // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
  78. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_ETC2 , 64, 4, 4, CompressionFamily::ES3);
  79. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ETC2 , 64, 4, 4, CompressionFamily::ES3);
  80. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA8_ETC2_EAC , 128, 4, 4, CompressionFamily::ES3);
  81. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC , 128, 4, 4, CompressionFamily::ES3);
  82. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_R11_EAC , 64, 4, 4, CompressionFamily::ES3);
  83. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG11_EAC , 128, 4, 4, CompressionFamily::ES3);
  84. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_R11_EAC , 64, 4, 4, CompressionFamily::ES3);
  85. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC , 128, 4, 4, CompressionFamily::ES3);
  86. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 , 64, 4, 4, CompressionFamily::ES3);
  87. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, 64, 4, 4, CompressionFamily::ES3);
  88. // AMD_compressed_ATC_texture
  89. AddCompressedFormatInfo(EffectiveFormat::ATC_RGB_AMD , 64, 4, 4, CompressionFamily::ATC);
  90. AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_EXPLICIT_ALPHA_AMD , 128, 4, 4, CompressionFamily::ATC);
  91. AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_INTERPOLATED_ALPHA_AMD, 128, 4, 4, CompressionFamily::ATC);
  92. // EXT_texture_compression_s3tc
  93. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1_EXT , 64, 4, 4, CompressionFamily::S3TC);
  94. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1_EXT, 64, 4, 4, CompressionFamily::S3TC);
  95. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3_EXT, 128, 4, 4, CompressionFamily::S3TC);
  96. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5_EXT, 128, 4, 4, CompressionFamily::S3TC);
  97. // EXT_texture_compression_s3tc_srgb
  98. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_S3TC_DXT1_EXT , 64, 4, 4, CompressionFamily::S3TC);
  99. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 64, 4, 4, CompressionFamily::S3TC);
  100. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 128, 4, 4, CompressionFamily::S3TC);
  101. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 128, 4, 4, CompressionFamily::S3TC);
  102. // KHR_texture_compression_astc_ldr
  103. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_4x4_KHR , 128, 4, 4, CompressionFamily::ASTC);
  104. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_5x4_KHR , 128, 5, 4, CompressionFamily::ASTC);
  105. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_5x5_KHR , 128, 5, 5, CompressionFamily::ASTC);
  106. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_6x5_KHR , 128, 6, 5, CompressionFamily::ASTC);
  107. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_6x6_KHR , 128, 6, 6, CompressionFamily::ASTC);
  108. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x5_KHR , 128, 8, 5, CompressionFamily::ASTC);
  109. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x6_KHR , 128, 8, 6, CompressionFamily::ASTC);
  110. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x8_KHR , 128, 8, 8, CompressionFamily::ASTC);
  111. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x5_KHR , 128, 10, 5, CompressionFamily::ASTC);
  112. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x6_KHR , 128, 10, 6, CompressionFamily::ASTC);
  113. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x8_KHR , 128, 10, 8, CompressionFamily::ASTC);
  114. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x10_KHR , 128, 10, 10, CompressionFamily::ASTC);
  115. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_12x10_KHR , 128, 12, 10, CompressionFamily::ASTC);
  116. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_12x12_KHR , 128, 12, 12, CompressionFamily::ASTC);
  117. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR , 128, 4, 4, CompressionFamily::ASTC);
  118. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR , 128, 5, 4, CompressionFamily::ASTC);
  119. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR , 128, 5, 5, CompressionFamily::ASTC);
  120. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR , 128, 6, 5, CompressionFamily::ASTC);
  121. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR , 128, 6, 6, CompressionFamily::ASTC);
  122. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR , 128, 8, 5, CompressionFamily::ASTC);
  123. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR , 128, 8, 6, CompressionFamily::ASTC);
  124. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR , 128, 8, 8, CompressionFamily::ASTC);
  125. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR , 128, 10, 5, CompressionFamily::ASTC);
  126. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR , 128, 10, 6, CompressionFamily::ASTC);
  127. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR , 128, 10, 8, CompressionFamily::ASTC);
  128. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 128, 10, 10, CompressionFamily::ASTC);
  129. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 128, 12, 10, CompressionFamily::ASTC);
  130. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 128, 12, 12, CompressionFamily::ASTC);
  131. // IMG_texture_compression_pvrtc
  132. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_4BPPV1 , 256, 8, 8, CompressionFamily::PVRTC);
  133. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_4BPPV1, 256, 8, 8, CompressionFamily::PVRTC);
  134. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_2BPPV1 , 256, 16, 8, CompressionFamily::PVRTC);
  135. AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_2BPPV1, 256, 16, 8, CompressionFamily::PVRTC);
  136. // OES_compressed_ETC1_RGB8_texture
  137. AddCompressedFormatInfo(EffectiveFormat::ETC1_RGB8_OES, 64, 4, 4, CompressionFamily::ETC1);
  138. }
  139. //////////////////////////////////////////////////////////////////////////////////////////
  140. static void
  141. AddFormatInfo(EffectiveFormat format, const char* name, GLenum sizedFormat,
  142. uint8_t bytesPerPixel, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
  143. uint8_t d, uint8_t s, UnsizedFormat unsizedFormat, bool isSRGB,
  144. ComponentType componentType)
  145. {
  146. switch (unsizedFormat) {
  147. case UnsizedFormat::R:
  148. MOZ_ASSERT(r && !g && !b && !a && !d && !s);
  149. break;
  150. case UnsizedFormat::RG:
  151. MOZ_ASSERT(r && g && !b && !a && !d && !s);
  152. break;
  153. case UnsizedFormat::RGB:
  154. MOZ_ASSERT(r && g && b && !a && !d && !s);
  155. break;
  156. case UnsizedFormat::RGBA:
  157. MOZ_ASSERT(r && g && b && a && !d && !s);
  158. break;
  159. case UnsizedFormat::L:
  160. MOZ_ASSERT(r && !g && !b && !a && !d && !s);
  161. break;
  162. case UnsizedFormat::A:
  163. MOZ_ASSERT(!r && !g && !b && a && !d && !s);
  164. break;
  165. case UnsizedFormat::LA:
  166. MOZ_ASSERT(r && !g && !b && a && !d && !s);
  167. break;
  168. case UnsizedFormat::D:
  169. MOZ_ASSERT(!r && !g && !b && !a && d && !s);
  170. break;
  171. case UnsizedFormat::S:
  172. MOZ_ASSERT(!r && !g && !b && !a && !d && s);
  173. break;
  174. case UnsizedFormat::DEPTH_STENCIL:
  175. MOZ_ASSERT(!r && !g && !b && !a && d && s);
  176. break;
  177. }
  178. const CompressedFormatInfo* compressedFormatInfo = GetCompressedFormatInfo(format);
  179. MOZ_ASSERT(!bytesPerPixel == bool(compressedFormatInfo));
  180. #ifdef DEBUG
  181. uint8_t totalBits = r + g + b + a + d + s;
  182. if (format == EffectiveFormat::RGB9_E5) {
  183. totalBits = 9 + 9 + 9 + 5;
  184. }
  185. if (compressedFormatInfo) {
  186. MOZ_ASSERT(totalBits);
  187. MOZ_ASSERT(!bytesPerPixel);
  188. } else {
  189. MOZ_ASSERT(totalBits == bytesPerPixel*8);
  190. }
  191. #endif
  192. const FormatInfo info = { format, name, sizedFormat, unsizedFormat, componentType,
  193. isSRGB, compressedFormatInfo, bytesPerPixel, r,g,b,a,d,s };
  194. AlwaysInsert(gFormatInfoMap, format, info);
  195. }
  196. static void
  197. InitFormatInfo()
  198. {
  199. #define FOO(x) EffectiveFormat::x, #x, LOCAL_GL_ ## x
  200. // GLES 3.0.4, p130-132, table 3.13
  201. AddFormatInfo(FOO(R8 ), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::NormUInt);
  202. AddFormatInfo(FOO(R8_SNORM ), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::NormInt );
  203. AddFormatInfo(FOO(RG8 ), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::NormUInt);
  204. AddFormatInfo(FOO(RG8_SNORM ), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::NormInt );
  205. AddFormatInfo(FOO(RGB8 ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
  206. AddFormatInfo(FOO(RGB8_SNORM ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormInt );
  207. AddFormatInfo(FOO(RGB565 ), 2, 5, 6, 5, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
  208. AddFormatInfo(FOO(RGBA4 ), 2, 4, 4, 4, 4, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  209. AddFormatInfo(FOO(RGB5_A1 ), 2, 5, 5, 5, 1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  210. AddFormatInfo(FOO(RGBA8 ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  211. AddFormatInfo(FOO(RGBA8_SNORM ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormInt );
  212. AddFormatInfo(FOO(RGB10_A2 ), 4, 10,10,10, 2, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  213. AddFormatInfo(FOO(RGB10_A2UI ), 4, 10,10,10, 2, 0,0, UnsizedFormat::RGBA, false, ComponentType::UInt );
  214. AddFormatInfo(FOO(SRGB8 ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , true , ComponentType::NormUInt);
  215. AddFormatInfo(FOO(SRGB8_ALPHA8 ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  216. AddFormatInfo(FOO(R16F ), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Float );
  217. AddFormatInfo(FOO(RG16F ), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Float );
  218. AddFormatInfo(FOO(RGB16F ), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float );
  219. AddFormatInfo(FOO(RGBA16F ), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA, false, ComponentType::Float );
  220. AddFormatInfo(FOO(R32F ), 4, 32, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Float );
  221. AddFormatInfo(FOO(RG32F ), 8, 32,32, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Float );
  222. AddFormatInfo(FOO(RGB32F ), 12, 32,32,32, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float );
  223. AddFormatInfo(FOO(RGBA32F ), 16, 32,32,32,32, 0,0, UnsizedFormat::RGBA, false, ComponentType::Float );
  224. AddFormatInfo(FOO(R11F_G11F_B10F), 4, 11,11,10, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float );
  225. AddFormatInfo(FOO(RGB9_E5 ), 4, 14,14,14, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Float );
  226. AddFormatInfo(FOO(R8I ), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Int );
  227. AddFormatInfo(FOO(R8UI ), 1, 8, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::UInt );
  228. AddFormatInfo(FOO(R16I ), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Int );
  229. AddFormatInfo(FOO(R16UI ), 2, 16, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::UInt );
  230. AddFormatInfo(FOO(R32I ), 4, 32, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::Int );
  231. AddFormatInfo(FOO(R32UI ), 4, 32, 0, 0, 0, 0,0, UnsizedFormat::R , false, ComponentType::UInt );
  232. AddFormatInfo(FOO(RG8I ), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Int );
  233. AddFormatInfo(FOO(RG8UI ), 2, 8, 8, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::UInt );
  234. AddFormatInfo(FOO(RG16I ), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Int );
  235. AddFormatInfo(FOO(RG16UI ), 4, 16,16, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::UInt );
  236. AddFormatInfo(FOO(RG32I ), 8, 32,32, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::Int );
  237. AddFormatInfo(FOO(RG32UI ), 8, 32,32, 0, 0, 0,0, UnsizedFormat::RG , false, ComponentType::UInt );
  238. AddFormatInfo(FOO(RGB8I ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Int );
  239. AddFormatInfo(FOO(RGB8UI ), 3, 8, 8, 8, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::UInt );
  240. AddFormatInfo(FOO(RGB16I ), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Int );
  241. AddFormatInfo(FOO(RGB16UI ), 6, 16,16,16, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::UInt );
  242. AddFormatInfo(FOO(RGB32I ), 12, 32,32,32, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::Int );
  243. AddFormatInfo(FOO(RGB32UI ), 12, 32,32,32, 0, 0,0, UnsizedFormat::RGB , false, ComponentType::UInt );
  244. AddFormatInfo(FOO(RGBA8I ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, false, ComponentType::Int );
  245. AddFormatInfo(FOO(RGBA8UI ), 4, 8, 8, 8, 8, 0,0, UnsizedFormat::RGBA, false, ComponentType::UInt );
  246. AddFormatInfo(FOO(RGBA16I ), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA, false, ComponentType::Int );
  247. AddFormatInfo(FOO(RGBA16UI ), 8, 16,16,16,16, 0,0, UnsizedFormat::RGBA, false, ComponentType::UInt );
  248. AddFormatInfo(FOO(RGBA32I ), 16, 32,32,32,32, 0,0, UnsizedFormat::RGBA, false, ComponentType::Int );
  249. AddFormatInfo(FOO(RGBA32UI ), 16, 32,32,32,32, 0,0, UnsizedFormat::RGBA, false, ComponentType::UInt );
  250. // GLES 3.0.4, p133, table 3.14
  251. AddFormatInfo(FOO(DEPTH_COMPONENT16 ), 2, 0,0,0,0, 16,0, UnsizedFormat::D , false, ComponentType::NormUInt);
  252. AddFormatInfo(FOO(DEPTH_COMPONENT24 ), 3, 0,0,0,0, 24,0, UnsizedFormat::D , false, ComponentType::NormUInt);
  253. AddFormatInfo(FOO(DEPTH_COMPONENT32F), 4, 0,0,0,0, 32,0, UnsizedFormat::D , false, ComponentType::Float);
  254. AddFormatInfo(FOO(DEPTH24_STENCIL8 ), 4, 0,0,0,0, 24,8, UnsizedFormat::DEPTH_STENCIL, false, ComponentType::Special);
  255. AddFormatInfo(FOO(DEPTH32F_STENCIL8 ), 5, 0,0,0,0, 32,8, UnsizedFormat::DEPTH_STENCIL, false, ComponentType::Special);
  256. // GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
  257. AddFormatInfo(FOO(STENCIL_INDEX8), 1, 0,0,0,0, 0,8, UnsizedFormat::S, false, ComponentType::UInt);
  258. // GLES 3.0.4, p147, table 3.19
  259. // GLES 3.0.4 p286+ $C.1 "ETC Compressed Texture Image Formats"
  260. //cjh AddFormatInfo(FOO(COMPRESSED_RGB8_ETC2 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
  261. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ETC2 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , true , ComponentType::NormUInt);
  262. // AddFormatInfo(FOO(COMPRESSED_RGBA8_ETC2_EAC ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  263. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  264. // AddFormatInfo(FOO(COMPRESSED_R11_EAC ), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormUInt);
  265. // AddFormatInfo(FOO(COMPRESSED_RG11_EAC ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG , false, ComponentType::NormUInt);
  266. // AddFormatInfo(FOO(COMPRESSED_SIGNED_R11_EAC ), 0, 1,0,0,0, 0,0, UnsizedFormat::R , false, ComponentType::NormInt );
  267. // AddFormatInfo(FOO(COMPRESSED_SIGNED_RG11_EAC ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG , false, ComponentType::NormInt );
  268. // AddFormatInfo(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  269. // AddFormatInfo(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  270. // AMD_compressed_ATC_texture
  271. //cjh AddFormatInfo(FOO(ATC_RGB_AMD ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
  272. // AddFormatInfo(FOO(ATC_RGBA_EXPLICIT_ALPHA_AMD ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  273. // AddFormatInfo(FOO(ATC_RGBA_INTERPOLATED_ALPHA_AMD), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  274. // EXT_texture_compression_s3tc
  275. AddFormatInfo(FOO(COMPRESSED_RGB_S3TC_DXT1_EXT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
  276. AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT1_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  277. AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT3_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  278. AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT5_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  279. // EXT_texture_compression_s3tc_srgb
  280. AddFormatInfo(FOO(COMPRESSED_SRGB_S3TC_DXT1_EXT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , true, ComponentType::NormUInt);
  281. AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true, ComponentType::NormUInt);
  282. AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true, ComponentType::NormUInt);
  283. AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true, ComponentType::NormUInt);
  284. // KHR_texture_compression_astc_ldr
  285. //cjh AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_4x4_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  286. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_5x4_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  287. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_5x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  288. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_6x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  289. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_6x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  290. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  291. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  292. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x8_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  293. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  294. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  295. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x8_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  296. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x10_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  297. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_12x10_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  298. // AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_12x12_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  299. //
  300. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  301. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  302. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  303. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  304. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  305. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  306. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  307. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  308. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  309. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  310. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  311. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  312. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  313. // AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
  314. //
  315. // // IMG_texture_compression_pvrtc
  316. // AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_4BPPV1 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
  317. // AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_4BPPV1), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  318. // AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_2BPPV1 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
  319. // AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_2BPPV1), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
  320. //
  321. // // OES_compressed_ETC1_RGB8_texture
  322. // AddFormatInfo(FOO(ETC1_RGB8_OES), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB, false, ComponentType::NormUInt);
  323. #undef FOO
  324. // 'Virtual' effective formats have no sizedFormat.
  325. #define FOO(x) EffectiveFormat::x, #x, 0
  326. // GLES 3.0.4, p128, table 3.12.
  327. AddFormatInfo(FOO(Luminance8Alpha8), 2, 8,0,0,8, 0,0, UnsizedFormat::LA, false, ComponentType::NormUInt);
  328. AddFormatInfo(FOO(Luminance8 ), 1, 8,0,0,0, 0,0, UnsizedFormat::L , false, ComponentType::NormUInt);
  329. AddFormatInfo(FOO(Alpha8 ), 1, 0,0,0,8, 0,0, UnsizedFormat::A , false, ComponentType::NormUInt);
  330. // OES_texture_float
  331. AddFormatInfo(FOO(Luminance32FAlpha32F), 8, 32,0,0,32, 0,0, UnsizedFormat::LA, false, ComponentType::Float);
  332. AddFormatInfo(FOO(Luminance32F ), 4, 32,0,0, 0, 0,0, UnsizedFormat::L , false, ComponentType::Float);
  333. AddFormatInfo(FOO(Alpha32F ), 4, 0,0,0,32, 0,0, UnsizedFormat::A , false, ComponentType::Float);
  334. // OES_texture_half_float
  335. AddFormatInfo(FOO(Luminance16FAlpha16F), 4, 16,0,0,16, 0,0, UnsizedFormat::LA, false, ComponentType::Float);
  336. AddFormatInfo(FOO(Luminance16F ), 2, 16,0,0, 0, 0,0, UnsizedFormat::L , false, ComponentType::Float);
  337. AddFormatInfo(FOO(Alpha16F ), 2, 0,0,0,16, 0,0, UnsizedFormat::A , false, ComponentType::Float);
  338. #undef FOO
  339. ////////////////////////////////////////////////////////////////////////////
  340. const auto fnSetCopyDecay = [](EffectiveFormat src, EffectiveFormat asR,
  341. EffectiveFormat asRG, EffectiveFormat asRGB,
  342. EffectiveFormat asRGBA, EffectiveFormat asL,
  343. EffectiveFormat asA, EffectiveFormat asLA)
  344. {
  345. auto& map = GetFormatInfo_NoLock(src)->copyDecayFormats;
  346. const auto fnSet = [&map](UnsizedFormat uf, EffectiveFormat ef) {
  347. if (ef == EffectiveFormat::MAX)
  348. return;
  349. const auto* format = GetFormatInfo_NoLock(ef);
  350. MOZ_ASSERT(format->unsizedFormat == uf);
  351. AlwaysInsert(map, uf, format);
  352. };
  353. fnSet(UnsizedFormat::R , asR);
  354. fnSet(UnsizedFormat::RG , asRG);
  355. fnSet(UnsizedFormat::RGB , asRGB);
  356. fnSet(UnsizedFormat::RGBA, asRGBA);
  357. fnSet(UnsizedFormat::L , asL);
  358. fnSet(UnsizedFormat::A , asA);
  359. fnSet(UnsizedFormat::LA , asLA);
  360. };
  361. #define SET_COPY_DECAY(src,asR,asRG,asRGB,asRGBA,asL,asA,asLA) \
  362. fnSetCopyDecay(EffectiveFormat::src, EffectiveFormat::asR, EffectiveFormat::asRG, \
  363. EffectiveFormat::asRGB, EffectiveFormat::asRGBA, EffectiveFormat::asL, \
  364. EffectiveFormat::asA, EffectiveFormat::asLA);
  365. //////
  366. #define SET_BY_SUFFIX(X) \
  367. SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, Luminance##X, MAX, MAX) \
  368. SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, Luminance##X, MAX, MAX) \
  369. SET_COPY_DECAY( RGB##X, R##X, RG##X, RGB##X, MAX, Luminance##X, MAX, MAX) \
  370. SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, Luminance##X, Alpha##X, Luminance##X##Alpha##X)
  371. SET_BY_SUFFIX(8) // WebGL decided that RGB8 should be guaranteed renderable.
  372. SET_BY_SUFFIX(16F) // RGB16F is renderable in EXT_color_buffer_half_float, though not
  373. // EXT_color_buffer_float.
  374. SET_BY_SUFFIX(32F) // Technically RGB32F is never renderable, but no harm here.
  375. #undef SET_BY_SUFFIX
  376. //////
  377. #define SET_BY_SUFFIX(X) \
  378. SET_COPY_DECAY( R##X, R##X, MAX, MAX, MAX, MAX, MAX, MAX) \
  379. SET_COPY_DECAY( RG##X, R##X, RG##X, MAX, MAX, MAX, MAX, MAX) \
  380. SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, MAX, MAX, MAX)
  381. SET_BY_SUFFIX(8I)
  382. SET_BY_SUFFIX(8UI)
  383. SET_BY_SUFFIX(16I)
  384. SET_BY_SUFFIX(16UI)
  385. SET_BY_SUFFIX(32I)
  386. SET_BY_SUFFIX(32UI)
  387. #undef SET_BY_SUFFIX
  388. //////
  389. SET_COPY_DECAY( RGB565, R8, RG8, RGB565, MAX, Luminance8, MAX, MAX)
  390. SET_COPY_DECAY( RGBA4, R8, RG8, RGB565, RGBA4, Luminance8, Alpha8, Luminance8Alpha8)
  391. SET_COPY_DECAY( RGB5_A1, R8, RG8, RGB565, RGB5_A1, Luminance8, Alpha8, Luminance8Alpha8)
  392. SET_COPY_DECAY( RGB10_A2, R8, RG8, RGB8, RGB10_A2, Luminance8, Alpha8, MAX)
  393. SET_COPY_DECAY(RGB10_A2UI, R8UI, RG8UI, RGB8UI, RGB10_A2UI, MAX, MAX, MAX)
  394. SET_COPY_DECAY(SRGB8_ALPHA8, MAX, MAX, MAX, SRGB8_ALPHA8, MAX, Alpha8, MAX)
  395. SET_COPY_DECAY(R11F_G11F_B10F, R16F, RG16F, R11F_G11F_B10F, MAX, Luminance16F, MAX, MAX)
  396. #undef SET_COPY_DECAY
  397. }
  398. //////////////////////////////////////////////////////////////////////////////////////////
  399. bool gAreFormatTablesInitialized = false;
  400. static void
  401. EnsureInitFormatTables(/* cjh const StaticMutexAutoLock&*/) // Prove that you locked it!
  402. {
  403. if (MOZ_LIKELY(gAreFormatTablesInitialized))
  404. return;
  405. gAreFormatTablesInitialized = true;
  406. InitCompressedFormatInfo();
  407. InitFormatInfo();
  408. }
  409. //////////////////////////////////////////////////////////////////////////////////////////
  410. // Public funcs
  411. //cjh StaticMutex gFormatMapMutex;
  412. const FormatInfo*
  413. GetFormat(EffectiveFormat format)
  414. {
  415. //cjh StaticMutexAutoLock lock(gFormatMapMutex);
  416. // EnsureInitFormatTables(lock);
  417. EnsureInitFormatTables();
  418. return GetFormatInfo_NoLock(format);
  419. }
  420. //////////////////////////////////////////////////////////////////////////////////////////
  421. const FormatInfo*
  422. FormatInfo::GetCopyDecayFormat(UnsizedFormat uf) const
  423. {
  424. return FindOrNull(this->copyDecayFormats, uf);
  425. }
  426. bool
  427. GetBytesPerPixel(const PackingInfo& packing, uint8_t* const out_bytes)
  428. {
  429. uint8_t bytesPerChannel;
  430. switch (packing.type) {
  431. case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
  432. case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
  433. case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
  434. *out_bytes = 2;
  435. return true;
  436. case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV:
  437. case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV:
  438. case LOCAL_GL_UNSIGNED_INT_24_8:
  439. case LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV:
  440. *out_bytes = 4;
  441. return true;
  442. case LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
  443. *out_bytes = 8;
  444. return true;
  445. // Alright, that's all the fixed-size unpackTypes.
  446. case LOCAL_GL_BYTE:
  447. case LOCAL_GL_UNSIGNED_BYTE:
  448. bytesPerChannel = 1;
  449. break;
  450. case LOCAL_GL_SHORT:
  451. case LOCAL_GL_UNSIGNED_SHORT:
  452. case LOCAL_GL_HALF_FLOAT:
  453. case LOCAL_GL_HALF_FLOAT_OES:
  454. bytesPerChannel = 2;
  455. break;
  456. case LOCAL_GL_INT:
  457. case LOCAL_GL_UNSIGNED_INT:
  458. case LOCAL_GL_FLOAT:
  459. bytesPerChannel = 4;
  460. break;
  461. default:
  462. return false;
  463. }
  464. uint8_t channels;
  465. switch (packing.format) {
  466. case LOCAL_GL_RED:
  467. case LOCAL_GL_RED_INTEGER:
  468. case LOCAL_GL_LUMINANCE:
  469. case LOCAL_GL_ALPHA:
  470. case LOCAL_GL_DEPTH_COMPONENT:
  471. channels = 1;
  472. break;
  473. case LOCAL_GL_RG:
  474. case LOCAL_GL_RG_INTEGER:
  475. case LOCAL_GL_LUMINANCE_ALPHA:
  476. case LOCAL_GL_DEPTH_COMPONENT16:
  477. channels = 2;
  478. break;
  479. case LOCAL_GL_RGB:
  480. case LOCAL_GL_RGB_INTEGER:
  481. case LOCAL_GL_SRGB:
  482. case LOCAL_GL_DEPTH_COMPONENT24:
  483. channels = 3;
  484. break;
  485. case LOCAL_GL_BGRA:
  486. case LOCAL_GL_RGBA:
  487. case LOCAL_GL_RGBA_INTEGER:
  488. case LOCAL_GL_SRGB_ALPHA:
  489. case LOCAL_GL_DEPTH_COMPONENT32F:
  490. channels = 4;
  491. break;
  492. default:
  493. return false;
  494. }
  495. *out_bytes = bytesPerChannel * channels;
  496. return true;
  497. }
  498. uint8_t
  499. BytesPerPixel(const PackingInfo& packing)
  500. {
  501. uint8_t ret;
  502. if (MOZ_LIKELY(GetBytesPerPixel(packing, &ret)))
  503. return ret;
  504. //cjh gfxCriticalError() << "Bad `packing`: " << gfx::hexa(packing.format) << ", "
  505. // << gfx::hexa(packing.type);
  506. MOZ_CRASH("Bad `packing`.");
  507. }
  508. //////////////////////////////////////////////////////////////////////////////////////////
  509. //////////////////////////////////////////////////////////////////////////////////////////
  510. //////////////////////////////////////////////////////////////////////////////////////////
  511. //////////////////////////////////////////////////////////////////////////////////////////
  512. //////////////////////////////////////////////////////////////////////////////////////////
  513. //////////////////////////////////////////////////////////////////////////////////////////
  514. //////////////////////////////////////////////////////////////////////////////////////////
  515. //////////////////////////////////////////////////////////////////////////////////////////
  516. // FormatUsageAuthority
  517. bool
  518. FormatUsageInfo::IsUnpackValid(const PackingInfo& key,
  519. const DriverUnpackInfo** const out_value) const
  520. {
  521. auto itr = validUnpacks.find(key);
  522. if (itr == validUnpacks.end())
  523. return false;
  524. *out_value = &(itr->second);
  525. return true;
  526. }
  527. void
  528. FormatUsageInfo::ResolveMaxSamples(gl::GLContext* gl)
  529. {
  530. //cjh MOZ_ASSERT(!this->maxSamplesKnown);
  531. // MOZ_ASSERT(this->maxSamples == 0);
  532. // MOZ_ASSERT(gl->IsCurrent());
  533. //
  534. // this->maxSamplesKnown = true;
  535. //
  536. // const GLenum internalFormat = this->format->sizedFormat;
  537. // if (!internalFormat)
  538. // return;
  539. //
  540. // if (!gl->IsSupported(gl::GLFeature::internalformat_query))
  541. // return; // Leave it at 0.
  542. //
  543. // GLint maxSamplesGL = 0;
  544. // gl->fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalFormat, LOCAL_GL_SAMPLES, 1,
  545. // &maxSamplesGL);
  546. //
  547. // this->maxSamples = maxSamplesGL;
  548. }
  549. ////////////////////////////////////////
  550. static void
  551. AddSimpleUnsized(FormatUsageAuthority* fua, GLenum unpackFormat, GLenum unpackType,
  552. EffectiveFormat effFormat)
  553. {
  554. auto usage = fua->EditUsage(effFormat);
  555. usage->isFilterable = true;
  556. const PackingInfo pi = {unpackFormat, unpackType};
  557. const DriverUnpackInfo dui = {unpackFormat, unpackFormat, unpackType};
  558. fua->AddTexUnpack(usage, pi, dui);
  559. fua->AllowUnsizedTexFormat(pi, usage);
  560. };
  561. /*static*/ const GLint FormatUsageInfo::kLuminanceSwizzleRGBA[4] = { LOCAL_GL_RED,
  562. LOCAL_GL_RED,
  563. LOCAL_GL_RED,
  564. LOCAL_GL_ONE };
  565. /*static*/ const GLint FormatUsageInfo::kAlphaSwizzleRGBA[4] = { LOCAL_GL_ZERO,
  566. LOCAL_GL_ZERO,
  567. LOCAL_GL_ZERO,
  568. LOCAL_GL_RED };
  569. /*static*/ const GLint FormatUsageInfo::kLumAlphaSwizzleRGBA[4] = { LOCAL_GL_RED,
  570. LOCAL_GL_RED,
  571. LOCAL_GL_RED,
  572. LOCAL_GL_GREEN };
  573. static bool
  574. AddLegacyFormats_LA8(FormatUsageAuthority* fua, gl::GLContext* gl)
  575. {
  576. //cjh if (gl->IsCoreProfile()) {
  577. // if (!gl->IsSupported(gl::GLFeature::texture_swizzle))
  578. // return false;
  579. //
  580. // PackingInfo pi;
  581. // DriverUnpackInfo dui;
  582. //
  583. // const auto fnAdd = [fua, &pi, &dui](EffectiveFormat effFormat,
  584. // const GLint* swizzle)
  585. // {
  586. // auto usage = fua->EditUsage(effFormat);
  587. // usage->isFilterable = true;
  588. // usage->textureSwizzleRGBA = swizzle;
  589. //
  590. // fua->AddTexUnpack(usage, pi, dui);
  591. //
  592. // fua->AllowUnsizedTexFormat(pi, usage);
  593. // };
  594. //
  595. // pi = {LOCAL_GL_LUMINANCE, LOCAL_GL_UNSIGNED_BYTE};
  596. // dui = {LOCAL_GL_R8, LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE};
  597. // fnAdd(EffectiveFormat::Luminance8, FormatUsageInfo::kLuminanceSwizzleRGBA);
  598. //
  599. // pi = {LOCAL_GL_ALPHA, LOCAL_GL_UNSIGNED_BYTE};
  600. // dui = {LOCAL_GL_R8, LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE};
  601. // fnAdd(EffectiveFormat::Alpha8, FormatUsageInfo::kAlphaSwizzleRGBA);
  602. //
  603. // pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE};
  604. // dui = {LOCAL_GL_RG8, LOCAL_GL_RG, LOCAL_GL_UNSIGNED_BYTE};
  605. // fnAdd(EffectiveFormat::Luminance8Alpha8, FormatUsageInfo::kLumAlphaSwizzleRGBA);
  606. // } else
  607. {
  608. AddSimpleUnsized(fua, LOCAL_GL_LUMINANCE , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8 );
  609. AddSimpleUnsized(fua, LOCAL_GL_ALPHA , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Alpha8 );
  610. AddSimpleUnsized(fua, LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8Alpha8);
  611. }
  612. return true;
  613. }
  614. static bool
  615. AddUnsizedFormats(FormatUsageAuthority* fua, gl::GLContext* gl)
  616. {
  617. // GLES 2.0.25, p63, Table 3.4
  618. AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGBA8 );
  619. AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4, EffectiveFormat::RGBA4 );
  620. AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1, EffectiveFormat::RGB5_A1);
  621. AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_BYTE , EffectiveFormat::RGB8 );
  622. AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_SHORT_5_6_5 , EffectiveFormat::RGB565 );
  623. // L, A, LA
  624. return AddLegacyFormats_LA8(fua, gl);
  625. }
  626. void
  627. FormatUsageInfo::SetRenderable()
  628. {
  629. this->isRenderable = true;
  630. #ifdef DEBUG
  631. const auto format = this->format;
  632. if (format->IsColorFormat()) {
  633. const auto& map = format->copyDecayFormats;
  634. const auto itr = map.find(format->unsizedFormat);
  635. MOZ_ASSERT(itr != map.end(), "Renderable formats must be in copyDecayFormats.");
  636. MOZ_ASSERT(itr->second == format);
  637. }
  638. #endif
  639. }
  640. UniquePtr<FormatUsageAuthority>
  641. FormatUsageAuthority::CreateForWebGL1(gl::GLContext* gl)
  642. {
  643. UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
  644. const auto ptr = ret.get();
  645. ////////////////////////////////////////////////////////////////////////////
  646. // Usages
  647. const auto fnSet = [ptr](EffectiveFormat effFormat, bool isRenderable,
  648. bool isFilterable)
  649. {
  650. MOZ_ASSERT(!ptr->GetUsage(effFormat));
  651. auto usage = ptr->EditUsage(effFormat);
  652. usage->isFilterable = isFilterable;
  653. if (isRenderable) {
  654. usage->SetRenderable();
  655. }
  656. };
  657. // GLES 2.0.25, p117, Table 4.5
  658. // RGBA8 is made renderable in WebGL 1.0, "Framebuffer Object Attachments"
  659. // render filter
  660. // able able
  661. fnSet(EffectiveFormat::RGBA8 , true, true);
  662. fnSet(EffectiveFormat::RGBA4 , true, true);
  663. fnSet(EffectiveFormat::RGB5_A1, true, true);
  664. fnSet(EffectiveFormat::RGB565 , true, true);
  665. // RGB8 is not guaranteed to be renderable, but we should allow it for web-compat.
  666. // Min-capability mode should mark this as non-renderable.
  667. fnSet(EffectiveFormat::RGB8, true, true);
  668. fnSet(EffectiveFormat::Luminance8Alpha8, false, true);
  669. fnSet(EffectiveFormat::Luminance8 , false, true);
  670. fnSet(EffectiveFormat::Alpha8 , false, true);
  671. fnSet(EffectiveFormat::DEPTH_COMPONENT16, true, false);
  672. fnSet(EffectiveFormat::STENCIL_INDEX8 , true, false);
  673. // Added in WebGL 1.0 spec:
  674. fnSet(EffectiveFormat::DEPTH24_STENCIL8, true, false);
  675. ////////////////////////////////////
  676. // RB formats
  677. #define FOO(x) ptr->AllowRBFormat(LOCAL_GL_ ## x, ptr->GetUsage(EffectiveFormat::x))
  678. FOO(RGBA4 );
  679. FOO(RGB5_A1 );
  680. FOO(RGB565 );
  681. FOO(DEPTH_COMPONENT16);
  682. FOO(STENCIL_INDEX8 );
  683. //FOO(DEPTH24_STENCIL8 ); // WebGL 1 uses DEPTH_STENCIL instead of DEPTH24_STENCIL8.
  684. #undef FOO
  685. ptr->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL,
  686. ptr->GetUsage(EffectiveFormat::DEPTH24_STENCIL8));
  687. ////////////////////////////////////////////////////////////////////////////
  688. if (!AddUnsizedFormats(ptr, gl))
  689. return nullptr;
  690. return Move(ret);
  691. }
  692. UniquePtr<FormatUsageAuthority>
  693. FormatUsageAuthority::CreateForWebGL2(gl::GLContext* gl)
  694. {
  695. UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
  696. const auto ptr = ret.get();
  697. ////////////////////////////////////////////////////////////////////////////
  698. // GLES 3.0.4 p111-113
  699. const auto fnAddSizedUnpack = [ptr](EffectiveFormat effFormat, GLenum internalFormat,
  700. GLenum unpackFormat, GLenum unpackType)
  701. {
  702. auto usage = ptr->EditUsage(effFormat);
  703. const PackingInfo pi = {unpackFormat, unpackType};
  704. const DriverUnpackInfo dui = {internalFormat, unpackFormat, unpackType};
  705. ptr->AddTexUnpack(usage, pi, dui);
  706. };
  707. #define FOO(x) EffectiveFormat::x, LOCAL_GL_ ## x
  708. // RGBA
  709. fnAddSizedUnpack(FOO(RGBA8 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE );
  710. fnAddSizedUnpack(FOO(RGBA4 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 );
  711. fnAddSizedUnpack(FOO(RGBA4 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE );
  712. fnAddSizedUnpack(FOO(RGB5_A1 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 );
  713. fnAddSizedUnpack(FOO(RGB5_A1 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE );
  714. fnAddSizedUnpack(FOO(RGB5_A1 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV);
  715. fnAddSizedUnpack(FOO(SRGB8_ALPHA8), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE );
  716. fnAddSizedUnpack(FOO(RGBA8_SNORM ), LOCAL_GL_RGBA, LOCAL_GL_BYTE );
  717. fnAddSizedUnpack(FOO(RGB10_A2 ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV);
  718. fnAddSizedUnpack(FOO(RGBA16F ), LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT );
  719. fnAddSizedUnpack(FOO(RGBA16F ), LOCAL_GL_RGBA, LOCAL_GL_FLOAT );
  720. fnAddSizedUnpack(FOO(RGBA32F ), LOCAL_GL_RGBA, LOCAL_GL_FLOAT );
  721. // RGBA_INTEGER
  722. fnAddSizedUnpack(FOO(RGBA8UI ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_BYTE );
  723. fnAddSizedUnpack(FOO(RGBA8I ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_BYTE );
  724. fnAddSizedUnpack(FOO(RGBA16UI ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_SHORT );
  725. fnAddSizedUnpack(FOO(RGBA16I ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_SHORT );
  726. fnAddSizedUnpack(FOO(RGBA32UI ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_INT );
  727. fnAddSizedUnpack(FOO(RGBA32I ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_INT );
  728. fnAddSizedUnpack(FOO(RGB10_A2UI), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV);
  729. // RGB
  730. fnAddSizedUnpack(FOO(RGB8 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE );
  731. fnAddSizedUnpack(FOO(SRGB8 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE );
  732. fnAddSizedUnpack(FOO(RGB565 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_SHORT_5_6_5 );
  733. fnAddSizedUnpack(FOO(RGB565 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE );
  734. fnAddSizedUnpack(FOO(RGB8_SNORM ), LOCAL_GL_RGB, LOCAL_GL_BYTE );
  735. fnAddSizedUnpack(FOO(R11F_G11F_B10F), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV);
  736. fnAddSizedUnpack(FOO(R11F_G11F_B10F), LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT );
  737. fnAddSizedUnpack(FOO(R11F_G11F_B10F), LOCAL_GL_RGB, LOCAL_GL_FLOAT );
  738. fnAddSizedUnpack(FOO(RGB16F ), LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT );
  739. fnAddSizedUnpack(FOO(RGB16F ), LOCAL_GL_RGB, LOCAL_GL_FLOAT );
  740. fnAddSizedUnpack(FOO(RGB9_E5 ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV );
  741. fnAddSizedUnpack(FOO(RGB9_E5 ), LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT );
  742. fnAddSizedUnpack(FOO(RGB9_E5 ), LOCAL_GL_RGB, LOCAL_GL_FLOAT );
  743. fnAddSizedUnpack(FOO(RGB32F ), LOCAL_GL_RGB, LOCAL_GL_FLOAT );
  744. // RGB_INTEGER
  745. fnAddSizedUnpack(FOO(RGB8UI ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_BYTE );
  746. fnAddSizedUnpack(FOO(RGB8I ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_BYTE );
  747. fnAddSizedUnpack(FOO(RGB16UI), LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_SHORT);
  748. fnAddSizedUnpack(FOO(RGB16I ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_SHORT );
  749. fnAddSizedUnpack(FOO(RGB32UI), LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_INT );
  750. fnAddSizedUnpack(FOO(RGB32I ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_INT );
  751. // RG
  752. fnAddSizedUnpack(FOO(RG8 ), LOCAL_GL_RG, LOCAL_GL_UNSIGNED_BYTE);
  753. fnAddSizedUnpack(FOO(RG8_SNORM), LOCAL_GL_RG, LOCAL_GL_BYTE );
  754. fnAddSizedUnpack(FOO(RG16F ), LOCAL_GL_RG, LOCAL_GL_HALF_FLOAT );
  755. fnAddSizedUnpack(FOO(RG16F ), LOCAL_GL_RG, LOCAL_GL_FLOAT );
  756. fnAddSizedUnpack(FOO(RG32F ), LOCAL_GL_RG, LOCAL_GL_FLOAT );
  757. // RG_INTEGER
  758. fnAddSizedUnpack(FOO(RG8UI ), LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_BYTE );
  759. fnAddSizedUnpack(FOO(RG8I ), LOCAL_GL_RG_INTEGER, LOCAL_GL_BYTE );
  760. fnAddSizedUnpack(FOO(RG16UI), LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_SHORT);
  761. fnAddSizedUnpack(FOO(RG16I ), LOCAL_GL_RG_INTEGER, LOCAL_GL_SHORT );
  762. fnAddSizedUnpack(FOO(RG32UI), LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_INT );
  763. fnAddSizedUnpack(FOO(RG32I ), LOCAL_GL_RG_INTEGER, LOCAL_GL_INT );
  764. // RED
  765. fnAddSizedUnpack(FOO(R8 ), LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE);
  766. fnAddSizedUnpack(FOO(R8_SNORM), LOCAL_GL_RED, LOCAL_GL_BYTE );
  767. fnAddSizedUnpack(FOO(R16F ), LOCAL_GL_RED, LOCAL_GL_HALF_FLOAT );
  768. fnAddSizedUnpack(FOO(R16F ), LOCAL_GL_RED, LOCAL_GL_FLOAT );
  769. fnAddSizedUnpack(FOO(R32F ), LOCAL_GL_RED, LOCAL_GL_FLOAT );
  770. // RED_INTEGER
  771. fnAddSizedUnpack(FOO(R8UI ), LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_BYTE );
  772. fnAddSizedUnpack(FOO(R8I ), LOCAL_GL_RED_INTEGER, LOCAL_GL_BYTE );
  773. fnAddSizedUnpack(FOO(R16UI), LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_SHORT);
  774. fnAddSizedUnpack(FOO(R16I ), LOCAL_GL_RED_INTEGER, LOCAL_GL_SHORT );
  775. fnAddSizedUnpack(FOO(R32UI), LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_INT );
  776. fnAddSizedUnpack(FOO(R32I ), LOCAL_GL_RED_INTEGER, LOCAL_GL_INT );
  777. // DEPTH_COMPONENT
  778. fnAddSizedUnpack(FOO(DEPTH_COMPONENT16 ), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_SHORT);
  779. fnAddSizedUnpack(FOO(DEPTH_COMPONENT16 ), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_INT );
  780. fnAddSizedUnpack(FOO(DEPTH_COMPONENT24 ), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_INT );
  781. fnAddSizedUnpack(FOO(DEPTH_COMPONENT32F), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_FLOAT );
  782. // DEPTH_STENCIL
  783. fnAddSizedUnpack(FOO(DEPTH24_STENCIL8 ), LOCAL_GL_DEPTH_STENCIL, LOCAL_GL_UNSIGNED_INT_24_8 );
  784. fnAddSizedUnpack(FOO(DEPTH32F_STENCIL8), LOCAL_GL_DEPTH_STENCIL, LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
  785. #undef FOO
  786. ////////////////////////////////////////////////////////////////////////////
  787. // For renderable, see GLES 3.0.4, p212 "Framebuffer Completeness"
  788. // For filterable, see GLES 3.0.4, p161 "...a texture is complete unless..."
  789. const auto fnAllowES3TexFormat = [ptr](GLenum sizedFormat, EffectiveFormat effFormat,
  790. bool isRenderable, bool isFilterable)
  791. {
  792. auto usage = ptr->EditUsage(effFormat);
  793. usage->isFilterable = isFilterable;
  794. if (isRenderable) {
  795. usage->SetRenderable();
  796. }
  797. ptr->AllowSizedTexFormat(sizedFormat, usage);
  798. if (isRenderable) {
  799. ptr->AllowRBFormat(sizedFormat, usage);
  800. }
  801. };
  802. #define FOO(x) LOCAL_GL_ ## x, EffectiveFormat::x
  803. // GLES 3.0.4, p128-129 "Required Texture Formats"
  804. // GLES 3.0.4, p130-132, table 3.13
  805. // render filter
  806. // able able
  807. fnAllowES3TexFormat(FOO(R8 ), true , true );
  808. fnAllowES3TexFormat(FOO(R8_SNORM ), false, true );
  809. fnAllowES3TexFormat(FOO(RG8 ), true , true );
  810. fnAllowES3TexFormat(FOO(RG8_SNORM ), false, true );
  811. fnAllowES3TexFormat(FOO(RGB8 ), true , true );
  812. fnAllowES3TexFormat(FOO(RGB8_SNORM ), false, true );
  813. fnAllowES3TexFormat(FOO(RGB565 ), true , true );
  814. fnAllowES3TexFormat(FOO(RGBA4 ), true , true );
  815. fnAllowES3TexFormat(FOO(RGB5_A1 ), true , true );
  816. fnAllowES3TexFormat(FOO(RGBA8 ), true , true );
  817. fnAllowES3TexFormat(FOO(RGBA8_SNORM), false, true );
  818. fnAllowES3TexFormat(FOO(RGB10_A2 ), true , true );
  819. fnAllowES3TexFormat(FOO(RGB10_A2UI ), true , false);
  820. fnAllowES3TexFormat(FOO(SRGB8 ), false, true);
  821. fnAllowES3TexFormat(FOO(SRGB8_ALPHA8), true , true);
  822. fnAllowES3TexFormat(FOO(R16F ), false, true);
  823. fnAllowES3TexFormat(FOO(RG16F ), false, true);
  824. fnAllowES3TexFormat(FOO(RGB16F ), false, true);
  825. fnAllowES3TexFormat(FOO(RGBA16F), false, true);
  826. fnAllowES3TexFormat(FOO(R32F ), false, false);
  827. fnAllowES3TexFormat(FOO(RG32F ), false, false);
  828. fnAllowES3TexFormat(FOO(RGB32F ), false, false);
  829. fnAllowES3TexFormat(FOO(RGBA32F), false, false);
  830. fnAllowES3TexFormat(FOO(R11F_G11F_B10F), false, true);
  831. fnAllowES3TexFormat(FOO(RGB9_E5 ), false, true);
  832. fnAllowES3TexFormat(FOO(R8I ), true, false);
  833. fnAllowES3TexFormat(FOO(R8UI ), true, false);
  834. fnAllowES3TexFormat(FOO(R16I ), true, false);
  835. fnAllowES3TexFormat(FOO(R16UI), true, false);
  836. fnAllowES3TexFormat(FOO(R32I ), true, false);
  837. fnAllowES3TexFormat(FOO(R32UI), true, false);
  838. fnAllowES3TexFormat(FOO(RG8I ), true, false);
  839. fnAllowES3TexFormat(FOO(RG8UI ), true, false);
  840. fnAllowES3TexFormat(FOO(RG16I ), true, false);
  841. fnAllowES3TexFormat(FOO(RG16UI), true, false);
  842. fnAllowES3TexFormat(FOO(RG32I ), true, false);
  843. fnAllowES3TexFormat(FOO(RG32UI), true, false);
  844. fnAllowES3TexFormat(FOO(RGB8I ), false, false);
  845. fnAllowES3TexFormat(FOO(RGB8UI ), false, false);
  846. fnAllowES3TexFormat(FOO(RGB16I ), false, false);
  847. fnAllowES3TexFormat(FOO(RGB16UI), false, false);
  848. fnAllowES3TexFormat(FOO(RGB32I ), false, false);
  849. fnAllowES3TexFormat(FOO(RGB32UI), false, false);
  850. fnAllowES3TexFormat(FOO(RGBA8I ), true, false);
  851. fnAllowES3TexFormat(FOO(RGBA8UI ), true, false);
  852. fnAllowES3TexFormat(FOO(RGBA16I ), true, false);
  853. fnAllowES3TexFormat(FOO(RGBA16UI), true, false);
  854. fnAllowES3TexFormat(FOO(RGBA32I ), true, false);
  855. fnAllowES3TexFormat(FOO(RGBA32UI), true, false);
  856. // GLES 3.0.4, p133, table 3.14
  857. fnAllowES3TexFormat(FOO(DEPTH_COMPONENT16 ), true, false);
  858. fnAllowES3TexFormat(FOO(DEPTH_COMPONENT24 ), true, false);
  859. fnAllowES3TexFormat(FOO(DEPTH_COMPONENT32F), true, false);
  860. fnAllowES3TexFormat(FOO(DEPTH24_STENCIL8 ), true, false);
  861. fnAllowES3TexFormat(FOO(DEPTH32F_STENCIL8 ), true, false);
  862. #undef FOO
  863. // GLES 3.0.4, p206, "Required Renderbuffer Formats":
  864. // "Implementations are also required to support STENCIL_INDEX8. Requesting this
  865. // internal format for a renderbuffer will allocate at least 8 stencil bit planes."
  866. auto usage = ptr->EditUsage(EffectiveFormat::STENCIL_INDEX8);
  867. usage->SetRenderable();
  868. ptr->AllowRBFormat(LOCAL_GL_STENCIL_INDEX8, usage);
  869. ////////////////
  870. // Legacy formats
  871. if (!AddUnsizedFormats(ptr, gl))
  872. return nullptr;
  873. ptr->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL,
  874. ptr->GetUsage(EffectiveFormat::DEPTH24_STENCIL8));
  875. //cjh if (gfxPrefs::WebGL2CompatMode()) {
  876. // AddSimpleUnsized(ptr, LOCAL_GL_RGBA, LOCAL_GL_FLOAT, EffectiveFormat::RGBA32F);
  877. // AddSimpleUnsized(ptr, LOCAL_GL_RGB , LOCAL_GL_FLOAT, EffectiveFormat::RGB32F );
  878. //
  879. // AddSimpleUnsized(ptr, LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGBA16F);
  880. // AddSimpleUnsized(ptr, LOCAL_GL_RGB , LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGB16F );
  881. // }
  882. ////////////////////////////////////
  883. return Move(ret);
  884. }
  885. //////////////////////////////////////////////////////////////////////////////////////////
  886. void
  887. FormatUsageAuthority::AddTexUnpack(FormatUsageInfo* usage, const PackingInfo& pi,
  888. const DriverUnpackInfo& dui)
  889. {
  890. // Don't AlwaysInsert here, since we'll see duplicates from sized and unsized formats.
  891. auto res = usage->validUnpacks.insert({ pi, dui });
  892. auto itr = res.first;
  893. if (!usage->idealUnpack) {
  894. // First one!
  895. usage->idealUnpack = &(itr->second);
  896. }
  897. mValidTexUnpackFormats.insert(pi.format);
  898. mValidTexUnpackTypes.insert(pi.type);
  899. }
  900. static bool
  901. Contains(const std::set<GLenum>& set, GLenum key)
  902. {
  903. return set.find(key) != set.end();
  904. }
  905. bool
  906. FormatUsageAuthority::IsInternalFormatEnumValid(GLenum internalFormat) const
  907. {
  908. return Contains(mValidTexInternalFormats, internalFormat);
  909. }
  910. bool
  911. FormatUsageAuthority::AreUnpackEnumsValid(GLenum unpackFormat, GLenum unpackType) const
  912. {
  913. return (Contains(mValidTexUnpackFormats, unpackFormat) &&
  914. Contains(mValidTexUnpackTypes, unpackType));
  915. }
  916. ////////////////////
  917. void
  918. FormatUsageAuthority::AllowRBFormat(GLenum sizedFormat, const FormatUsageInfo* usage)
  919. {
  920. MOZ_ASSERT(!usage->format->compression);
  921. MOZ_ASSERT(usage->format->sizedFormat);
  922. MOZ_ASSERT(usage->IsRenderable());
  923. AlwaysInsert(mRBFormatMap, sizedFormat, usage);
  924. }
  925. void
  926. FormatUsageAuthority::AllowSizedTexFormat(GLenum sizedFormat,
  927. const FormatUsageInfo* usage)
  928. {
  929. if (usage->format->compression) {
  930. MOZ_ASSERT(usage->isFilterable, "Compressed formats should be filterable.");
  931. } else {
  932. MOZ_ASSERT(usage->validUnpacks.size() && usage->idealUnpack,
  933. "AddTexUnpack() first.");
  934. }
  935. AlwaysInsert(mSizedTexFormatMap, sizedFormat, usage);
  936. mValidTexInternalFormats.insert(sizedFormat);
  937. }
  938. void
  939. FormatUsageAuthority::AllowUnsizedTexFormat(const PackingInfo& pi,
  940. const FormatUsageInfo* usage)
  941. {
  942. MOZ_ASSERT(!usage->format->compression);
  943. MOZ_ASSERT(usage->validUnpacks.size() && usage->idealUnpack, "AddTexUnpack() first.");
  944. AlwaysInsert(mUnsizedTexFormatMap, pi, usage);
  945. mValidTexInternalFormats.insert(pi.format);
  946. mValidTexUnpackFormats.insert(pi.format);
  947. mValidTexUnpackTypes.insert(pi.type);
  948. }
  949. const FormatUsageInfo*
  950. FormatUsageAuthority::GetRBUsage(GLenum sizedFormat) const
  951. {
  952. return FindOrNull(mRBFormatMap, sizedFormat);
  953. }
  954. const FormatUsageInfo*
  955. FormatUsageAuthority::GetSizedTexUsage(GLenum sizedFormat) const
  956. {
  957. return FindOrNull(mSizedTexFormatMap, sizedFormat);
  958. }
  959. const FormatUsageInfo*
  960. FormatUsageAuthority::GetUnsizedTexUsage(const PackingInfo& pi) const
  961. {
  962. return FindOrNull(mUnsizedTexFormatMap, pi);
  963. }
  964. FormatUsageInfo*
  965. FormatUsageAuthority::EditUsage(EffectiveFormat format)
  966. {
  967. auto itr = mUsageMap.find(format);
  968. if (itr == mUsageMap.end()) {
  969. const FormatInfo* formatInfo = GetFormat(format);
  970. MOZ_RELEASE_ASSERT(formatInfo, "GFX: no format info set.");
  971. FormatUsageInfo usage(formatInfo);
  972. auto res = mUsageMap.insert({ format, usage });
  973. //cjh DebugOnly<bool> didInsert = res.second;
  974. // MOZ_ASSERT(didInsert);
  975. itr = res.first;
  976. }
  977. return &(itr->second);
  978. }
  979. const FormatUsageInfo*
  980. FormatUsageAuthority::GetUsage(EffectiveFormat format) const
  981. {
  982. auto itr = mUsageMap.find(format);
  983. if (itr == mUsageMap.end())
  984. return nullptr;
  985. return &(itr->second);
  986. }
  987. ////////////////////////////////////////////////////////////////////////////////
  988. } // namespace webgl
  989. } // namespace mozilla