WebGLTexelConversions.h 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346
  1. /*
  2. * Copyright (C) 2010 Apple Inc. All rights reserved.
  3. * Copyright (C) 2010 Google Inc. All rights reserved.
  4. * Copyright (C) 2010 Mozilla Corporation. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
  16. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  18. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
  19. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  20. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  21. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  22. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  23. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  25. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #ifndef WEBGLTEXELCONVERSIONS_H_
  28. #define WEBGLTEXELCONVERSIONS_H_
  29. #ifdef __SUNPRO_CC
  30. #define __restrict
  31. #endif
  32. #include "WebGLTypes.h"
  33. #include <stdint.h>
  34. #include "mozilla/Attributes.h"
  35. #include "mozilla/Casting.h"
  36. namespace mozilla {
  37. bool ConvertImage(size_t width, size_t height,
  38. const void* srcBegin, size_t srcStride, gl::OriginPos srcOrigin,
  39. WebGLTexelFormat srcFormat, bool srcPremultiplied,
  40. void* dstBegin, size_t dstStride, gl::OriginPos dstOrigin,
  41. WebGLTexelFormat dstFormat, bool dstPremultiplied,
  42. bool* out_wasTrivial);
  43. //////////////////////////////////////////////////////////////////////////////////////////
  44. // single precision float
  45. // seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
  46. // half precision float
  47. // seeeeemmmmmmmmmm
  48. // IEEE 16bits floating point:
  49. const uint16_t kFloat16Value_Zero = 0x0000; // = 0000000000000000b
  50. const uint16_t kFloat16Value_One = 0x3C00; // = 0011110000000000b
  51. const uint16_t kFloat16Value_Infinity = 0x7C00; // = 0111110000000000b
  52. const uint16_t kFloat16Value_NaN = 0x7FFF; // = 011111yyyyyyyyyyb (nonzero y)
  53. MOZ_ALWAYS_INLINE uint16_t
  54. packToFloat16(float v)
  55. {
  56. union {
  57. float f32Value;
  58. uint32_t f32Bits;
  59. };
  60. f32Value = v;
  61. // pull the sign from v into f16bits
  62. uint16_t f16Bits = uint16_t(f32Bits >> 16) & 0x8000;
  63. const uint32_t mantissa = f32Bits & 0x7FFFFF;
  64. const uint32_t exp = (f32Bits >> 23) & 0xFF;
  65. // Adapted from: OpenGL ES 2.0 Programming Guide Appx.
  66. // Converting Float to Half-Float
  67. // 143 = 255 - 127 + 15
  68. // = sp_max - sp_bias + hp_bias
  69. if (exp >= 143) {
  70. if (mantissa && exp == 0xFF) {
  71. // Single precision was NaN
  72. return f16Bits | kFloat16Value_NaN;
  73. } else {
  74. // Outside range, store as infinity
  75. return f16Bits | kFloat16Value_Infinity;
  76. }
  77. }
  78. // too small, try to make a denormalized number
  79. // 112 = 255 - 127 - (15 + 1)
  80. // = sp_max - sp_bias - (hp_bias + 1)
  81. if (exp <= 112) {
  82. return f16Bits | uint16_t(mantissa >> (14 + 112 - exp));
  83. }
  84. f16Bits |= uint16_t(exp - 112) << 10;
  85. f16Bits |= uint16_t(mantissa >> 13) & 0x03FF;
  86. return f16Bits;
  87. }
  88. MOZ_ALWAYS_INLINE float
  89. unpackFromFloat16(uint16_t v)
  90. {
  91. union {
  92. float f32Value;
  93. uint32_t f32Bits;
  94. };
  95. // grab sign bit
  96. f32Bits = uint32_t(v & 0x8000) << 16;
  97. uint16_t exp = (v >> 10) & 0x001F;
  98. uint16_t mantissa = v & 0x03FF;
  99. if (!exp) {
  100. // Handle denormalized numbers
  101. // Adapted from: OpenGL ES 2.0 Programming Guide Appx.
  102. // Converting Float to Half-Float
  103. if (mantissa) {
  104. exp = 112; // See packToFloat16
  105. mantissa <<= 1;
  106. // For every leading zero, decrement the exponent
  107. // and shift the mantissa to the left
  108. while ((mantissa & (1 << 10)) == 0) {
  109. mantissa <<= 1;
  110. --exp;
  111. }
  112. mantissa &= 0x03FF;
  113. f32Bits |= (exp << 23) | (mantissa << 13);
  114. // Denormalized number
  115. return f32Value;
  116. }
  117. // +/- zero
  118. return f32Value;
  119. }
  120. if (exp == 0x001F) {
  121. if (v & 0x03FF) {
  122. // this is a NaN
  123. f32Bits |= 0x7FFFFFFF;
  124. } else {
  125. // this is -inf or +inf
  126. f32Bits |= 0x7F800000;
  127. }
  128. return f32Value;
  129. }
  130. f32Bits |= uint32_t(exp + (-15 + 127)) << 23;
  131. f32Bits |= uint32_t(v & 0x03FF) << 13;
  132. return f32Value;
  133. }
  134. // These routines come from angle/common/mathutil.h
  135. // They are copied here to remove the dependency on ANGLE headers
  136. // included from mathutil.h
  137. MOZ_ALWAYS_INLINE uint16_t
  138. packToFloat11(float fp32)
  139. {
  140. const unsigned int float32MantissaMask = 0x7FFFFF;
  141. const unsigned int float32ExponentMask = 0x7F800000;
  142. const unsigned int float32SignMask = 0x80000000;
  143. const unsigned int float32ValueMask = ~float32SignMask;
  144. const unsigned int float32ExponentFirstBit = 23;
  145. const unsigned int float32ExponentBias = 127;
  146. const unsigned short float11Max = 0x7BF;
  147. const unsigned short float11MantissaMask = 0x3F;
  148. const unsigned short float11ExponentMask = 0x7C0;
  149. const unsigned short float11BitMask = 0x7FF;
  150. const unsigned int float11ExponentBias = 14;
  151. const unsigned int float32Maxfloat11 = 0x477E0000;
  152. const unsigned int float32Minfloat11 = 0x38800000;
  153. const unsigned int float32Bits = BitwiseCast<unsigned int>(fp32);
  154. const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
  155. unsigned int float32Val = float32Bits & float32ValueMask;
  156. if ((float32Val & float32ExponentMask) == float32ExponentMask)
  157. {
  158. // INF or NAN
  159. if ((float32Val & float32MantissaMask) != 0)
  160. {
  161. return float11ExponentMask | (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) & float11MantissaMask);
  162. }
  163. else if (float32Sign)
  164. {
  165. // -INF is clamped to 0 since float11 is positive only
  166. return 0;
  167. }
  168. else
  169. {
  170. return float11ExponentMask;
  171. }
  172. }
  173. else if (float32Sign)
  174. {
  175. // float11 is positive only, so clamp to zero
  176. return 0;
  177. }
  178. else if (float32Val > float32Maxfloat11)
  179. {
  180. // The number is too large to be represented as a float11, set to max
  181. return float11Max;
  182. }
  183. else
  184. {
  185. if (float32Val < float32Minfloat11)
  186. {
  187. // The number is too small to be represented as a normalized float11
  188. // Convert it to a denormalized value.
  189. const unsigned int shift = (float32ExponentBias - float11ExponentBias) - (float32Val >> float32ExponentFirstBit);
  190. float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
  191. }
  192. else
  193. {
  194. // Rebias the exponent to represent the value as a normalized float11
  195. float32Val += 0xC8000000;
  196. }
  197. return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask;
  198. }
  199. }
  200. MOZ_ALWAYS_INLINE uint16_t
  201. packToFloat10(float fp32)
  202. {
  203. const unsigned int float32MantissaMask = 0x7FFFFF;
  204. const unsigned int float32ExponentMask = 0x7F800000;
  205. const unsigned int float32SignMask = 0x80000000;
  206. const unsigned int float32ValueMask = ~float32SignMask;
  207. const unsigned int float32ExponentFirstBit = 23;
  208. const unsigned int float32ExponentBias = 127;
  209. const unsigned short float10Max = 0x3DF;
  210. const unsigned short float10MantissaMask = 0x1F;
  211. const unsigned short float10ExponentMask = 0x3E0;
  212. const unsigned short float10BitMask = 0x3FF;
  213. const unsigned int float10ExponentBias = 14;
  214. const unsigned int float32Maxfloat10 = 0x477C0000;
  215. const unsigned int float32Minfloat10 = 0x38800000;
  216. const unsigned int float32Bits = BitwiseCast<unsigned int>(fp32);
  217. const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
  218. unsigned int float32Val = float32Bits & float32ValueMask;
  219. if ((float32Val & float32ExponentMask) == float32ExponentMask)
  220. {
  221. // INF or NAN
  222. if ((float32Val & float32MantissaMask) != 0)
  223. {
  224. return float10ExponentMask | (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) & float10MantissaMask);
  225. }
  226. else if (float32Sign)
  227. {
  228. // -INF is clamped to 0 since float11 is positive only
  229. return 0;
  230. }
  231. else
  232. {
  233. return float10ExponentMask;
  234. }
  235. }
  236. else if (float32Sign)
  237. {
  238. // float10 is positive only, so clamp to zero
  239. return 0;
  240. }
  241. else if (float32Val > float32Maxfloat10)
  242. {
  243. // The number is too large to be represented as a float11, set to max
  244. return float10Max;
  245. }
  246. else
  247. {
  248. if (float32Val < float32Minfloat10)
  249. {
  250. // The number is too small to be represented as a normalized float11
  251. // Convert it to a denormalized value.
  252. const unsigned int shift = (float32ExponentBias - float10ExponentBias) - (float32Val >> float32ExponentFirstBit);
  253. float32Val = ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
  254. }
  255. else
  256. {
  257. // Rebias the exponent to represent the value as a normalized float11
  258. float32Val += 0xC8000000;
  259. }
  260. return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask;
  261. }
  262. }
  263. enum class WebGLTexelPremultiplicationOp : int {
  264. None,
  265. Premultiply,
  266. Unpremultiply
  267. };
  268. namespace WebGLTexelConversions {
  269. template<WebGLTexelFormat Format>
  270. struct IsFloatFormat
  271. {
  272. static const bool Value =
  273. Format == WebGLTexelFormat::A32F ||
  274. Format == WebGLTexelFormat::R32F ||
  275. Format == WebGLTexelFormat::RA32F ||
  276. Format == WebGLTexelFormat::RG32F ||
  277. Format == WebGLTexelFormat::RGB11F11F10F ||
  278. Format == WebGLTexelFormat::RGB32F ||
  279. Format == WebGLTexelFormat::RGBA32F;
  280. };
  281. template<WebGLTexelFormat Format>
  282. struct IsHalfFloatFormat
  283. {
  284. static const bool Value =
  285. Format == WebGLTexelFormat::A16F ||
  286. Format == WebGLTexelFormat::R16F ||
  287. Format == WebGLTexelFormat::RA16F ||
  288. Format == WebGLTexelFormat::RG16F ||
  289. Format == WebGLTexelFormat::RGB16F ||
  290. Format == WebGLTexelFormat::RGBA16F;
  291. };
  292. template<WebGLTexelFormat Format>
  293. struct Is16bppFormat
  294. {
  295. static const bool Value =
  296. Format == WebGLTexelFormat::RGB565 ||
  297. Format == WebGLTexelFormat::RGBA4444 ||
  298. Format == WebGLTexelFormat::RGBA5551;
  299. };
  300. template<WebGLTexelFormat Format,
  301. bool IsFloat = IsFloatFormat<Format>::Value,
  302. bool Is16bpp = Is16bppFormat<Format>::Value,
  303. bool IsHalfFloat = IsHalfFloatFormat<Format>::Value>
  304. struct DataTypeForFormat
  305. {
  306. typedef uint8_t Type;
  307. };
  308. template<WebGLTexelFormat Format>
  309. struct DataTypeForFormat<Format, true, false, false>
  310. {
  311. typedef float Type;
  312. };
  313. template<WebGLTexelFormat Format>
  314. struct DataTypeForFormat<Format, false, true, false>
  315. {
  316. typedef uint16_t Type;
  317. };
  318. template<WebGLTexelFormat Format>
  319. struct DataTypeForFormat<Format, false, false, true>
  320. {
  321. typedef uint16_t Type;
  322. };
  323. template<>
  324. struct DataTypeForFormat<WebGLTexelFormat::RGB11F11F10F, true, false, false>
  325. {
  326. typedef uint32_t Type;
  327. };
  328. template<WebGLTexelFormat Format>
  329. struct IntermediateFormat
  330. {
  331. static const WebGLTexelFormat Value
  332. = IsFloatFormat<Format>::Value
  333. ? WebGLTexelFormat::RGBA32F
  334. : IsHalfFloatFormat<Format>::Value ? WebGLTexelFormat::RGBA16F
  335. : WebGLTexelFormat::RGBA8;
  336. };
  337. inline size_t TexelBytesForFormat(WebGLTexelFormat format) {
  338. switch (format) {
  339. case WebGLTexelFormat::A8:
  340. case WebGLTexelFormat::R8:
  341. return 1;
  342. case WebGLTexelFormat::A16F:
  343. case WebGLTexelFormat::R16F:
  344. case WebGLTexelFormat::RA8:
  345. case WebGLTexelFormat::RG8:
  346. case WebGLTexelFormat::RGB565:
  347. case WebGLTexelFormat::RGBA4444:
  348. case WebGLTexelFormat::RGBA5551:
  349. return 2;
  350. case WebGLTexelFormat::RGB8:
  351. return 3;
  352. case WebGLTexelFormat::A32F:
  353. case WebGLTexelFormat::R32F:
  354. case WebGLTexelFormat::RA16F:
  355. case WebGLTexelFormat::RG16F:
  356. case WebGLTexelFormat::RGB11F11F10F:
  357. case WebGLTexelFormat::RGBA8:
  358. case WebGLTexelFormat::BGRX8:
  359. case WebGLTexelFormat::BGRA8:
  360. return 4;
  361. case WebGLTexelFormat::RGB16F:
  362. return 6;
  363. case WebGLTexelFormat::RA32F:
  364. case WebGLTexelFormat::RG32F:
  365. case WebGLTexelFormat::RGBA16F:
  366. return 8;
  367. case WebGLTexelFormat::RGB32F:
  368. return 12;
  369. case WebGLTexelFormat::RGBA32F:
  370. return 16;
  371. default:
  372. MOZ_ASSERT(false, "Unknown texel format. Coding mistake?");
  373. return 0;
  374. }
  375. }
  376. MOZ_ALWAYS_INLINE bool HasAlpha(WebGLTexelFormat format) {
  377. return (format == WebGLTexelFormat::A8 ||
  378. format == WebGLTexelFormat::A16F ||
  379. format == WebGLTexelFormat::A32F ||
  380. format == WebGLTexelFormat::RA8 ||
  381. format == WebGLTexelFormat::RA16F ||
  382. format == WebGLTexelFormat::RA32F ||
  383. format == WebGLTexelFormat::RGBA4444 ||
  384. format == WebGLTexelFormat::RGBA5551 ||
  385. format == WebGLTexelFormat::RGBA8 ||
  386. format == WebGLTexelFormat::RGBA16F ||
  387. format == WebGLTexelFormat::RGBA32F ||
  388. format == WebGLTexelFormat::BGRA8);
  389. }
  390. MOZ_ALWAYS_INLINE bool HasColor(WebGLTexelFormat format) {
  391. return (format == WebGLTexelFormat::R8 ||
  392. format == WebGLTexelFormat::R16F ||
  393. format == WebGLTexelFormat::R32F ||
  394. format == WebGLTexelFormat::RA8 ||
  395. format == WebGLTexelFormat::RA16F ||
  396. format == WebGLTexelFormat::RA32F ||
  397. format == WebGLTexelFormat::RG8 ||
  398. format == WebGLTexelFormat::RG16F ||
  399. format == WebGLTexelFormat::RG32F ||
  400. format == WebGLTexelFormat::RGB565 ||
  401. format == WebGLTexelFormat::RGB8 ||
  402. format == WebGLTexelFormat::RGB11F11F10F ||
  403. format == WebGLTexelFormat::RGB16F ||
  404. format == WebGLTexelFormat::RGB32F ||
  405. format == WebGLTexelFormat::RGBA4444 ||
  406. format == WebGLTexelFormat::RGBA5551 ||
  407. format == WebGLTexelFormat::RGBA8 ||
  408. format == WebGLTexelFormat::RGBA16F ||
  409. format == WebGLTexelFormat::RGBA32F ||
  410. format == WebGLTexelFormat::BGRX8 ||
  411. format == WebGLTexelFormat::BGRA8);
  412. }
  413. /****** BEGIN CODE SHARED WITH WEBKIT ******/
  414. // the pack/unpack functions here are originally from this file:
  415. // http://trac.webkit.org/browser/trunk/WebCore/platform/graphics/GraphicsContext3D.cpp
  416. //----------------------------------------------------------------------
  417. // Pixel unpacking routines.
  418. template<WebGLTexelFormat Format, typename SrcType, typename DstType>
  419. MOZ_ALWAYS_INLINE void
  420. unpack(const SrcType* __restrict src,
  421. DstType* __restrict dst)
  422. {
  423. MOZ_ASSERT(false, "Unimplemented texture format conversion");
  424. }
  425. ////////////////////////////////////////////////////////////////////////////////
  426. // 1-channel formats
  427. template<> MOZ_ALWAYS_INLINE void
  428. unpack<WebGLTexelFormat::A8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  429. {
  430. dst[0] = 0;
  431. dst[1] = 0;
  432. dst[2] = 0;
  433. dst[3] = src[0];
  434. }
  435. template<> MOZ_ALWAYS_INLINE void
  436. unpack<WebGLTexelFormat::A16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  437. {
  438. dst[0] = kFloat16Value_Zero;
  439. dst[1] = kFloat16Value_Zero;
  440. dst[2] = kFloat16Value_Zero;
  441. dst[3] = src[0];
  442. }
  443. template<> MOZ_ALWAYS_INLINE void
  444. unpack<WebGLTexelFormat::A32F, float, float>(const float* __restrict src, float* __restrict dst)
  445. {
  446. dst[0] = 0;
  447. dst[1] = 0;
  448. dst[2] = 0;
  449. dst[3] = src[0];
  450. }
  451. template<> MOZ_ALWAYS_INLINE void
  452. unpack<WebGLTexelFormat::R8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  453. {
  454. dst[0] = src[0];
  455. dst[1] = src[0];
  456. dst[2] = src[0];
  457. dst[3] = 0xFF;
  458. }
  459. template<> MOZ_ALWAYS_INLINE void
  460. unpack<WebGLTexelFormat::R16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  461. {
  462. dst[0] = src[0];
  463. dst[1] = src[0];
  464. dst[2] = src[0];
  465. dst[3] = kFloat16Value_One;
  466. }
  467. template<> MOZ_ALWAYS_INLINE void
  468. unpack<WebGLTexelFormat::R32F, float, float>(const float* __restrict src, float* __restrict dst)
  469. {
  470. dst[0] = src[0];
  471. dst[1] = src[0];
  472. dst[2] = src[0];
  473. dst[3] = 1.0f;
  474. }
  475. ////////////////////////////////////////////////////////////////////////////////
  476. // 2-channel formats
  477. template<> MOZ_ALWAYS_INLINE void
  478. unpack<WebGLTexelFormat::RA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  479. {
  480. dst[0] = src[0];
  481. dst[1] = src[0];
  482. dst[2] = src[0];
  483. dst[3] = src[1];
  484. }
  485. template<> MOZ_ALWAYS_INLINE void
  486. unpack<WebGLTexelFormat::RA16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  487. {
  488. dst[0] = src[0];
  489. dst[1] = src[0];
  490. dst[2] = src[0];
  491. dst[3] = src[1];
  492. }
  493. template<> MOZ_ALWAYS_INLINE void
  494. unpack<WebGLTexelFormat::RA32F, float, float>(const float* __restrict src, float* __restrict dst)
  495. {
  496. dst[0] = src[0];
  497. dst[1] = src[0];
  498. dst[2] = src[0];
  499. dst[3] = src[1];
  500. }
  501. ////////////////////////////////////////////////////////////////////////////////
  502. // 3-channel formats
  503. template<> MOZ_ALWAYS_INLINE void
  504. unpack<WebGLTexelFormat::RGB565, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst)
  505. {
  506. uint16_t packedValue = src[0];
  507. uint8_t r = (packedValue >> 11) & 0x1F;
  508. uint8_t g = (packedValue >> 5) & 0x3F;
  509. uint8_t b = packedValue & 0x1F;
  510. dst[0] = (r << 3) | (r & 0x7);
  511. dst[1] = (g << 2) | (g & 0x3);
  512. dst[2] = (b << 3) | (b & 0x7);
  513. dst[3] = 0xFF;
  514. }
  515. template<> MOZ_ALWAYS_INLINE void
  516. unpack<WebGLTexelFormat::RGB8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  517. {
  518. dst[0] = src[0];
  519. dst[1] = src[1];
  520. dst[2] = src[2];
  521. dst[3] = 0xFF;
  522. }
  523. template<> MOZ_ALWAYS_INLINE void
  524. unpack<WebGLTexelFormat::RGB16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  525. {
  526. dst[0] = src[0];
  527. dst[1] = src[1];
  528. dst[2] = src[2];
  529. dst[3] = kFloat16Value_One;
  530. }
  531. template<> MOZ_ALWAYS_INLINE void
  532. unpack<WebGLTexelFormat::RGB32F, float, float>(const float* __restrict src, float* __restrict dst)
  533. {
  534. dst[0] = src[0];
  535. dst[1] = src[1];
  536. dst[2] = src[2];
  537. dst[3] = 1.0f;
  538. }
  539. ////////////////////////////////////////////////////////////////////////////////
  540. // 4-channel formats
  541. template<> MOZ_ALWAYS_INLINE void
  542. unpack<WebGLTexelFormat::RGBA4444, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst)
  543. {
  544. uint16_t packedValue = src[0];
  545. uint8_t r = (packedValue >> 12) & 0x0F;
  546. uint8_t g = (packedValue >> 8) & 0x0F;
  547. uint8_t b = (packedValue >> 4) & 0x0F;
  548. uint8_t a = packedValue & 0x0F;
  549. dst[0] = (r << 4) | r;
  550. dst[1] = (g << 4) | g;
  551. dst[2] = (b << 4) | b;
  552. dst[3] = (a << 4) | a;
  553. }
  554. template<> MOZ_ALWAYS_INLINE void
  555. unpack<WebGLTexelFormat::RGBA5551, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst)
  556. {
  557. uint16_t packedValue = src[0];
  558. uint8_t r = (packedValue >> 11) & 0x1F;
  559. uint8_t g = (packedValue >> 6) & 0x1F;
  560. uint8_t b = (packedValue >> 1) & 0x1F;
  561. dst[0] = (r << 3) | (r & 0x7);
  562. dst[1] = (g << 3) | (g & 0x7);
  563. dst[2] = (b << 3) | (b & 0x7);
  564. dst[3] = (packedValue & 0x1) ? 0xFF : 0;
  565. }
  566. template<> MOZ_ALWAYS_INLINE void
  567. unpack<WebGLTexelFormat::RGBA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  568. {
  569. dst[0] = src[0];
  570. dst[1] = src[1];
  571. dst[2] = src[2];
  572. dst[3] = src[3];
  573. }
  574. template<> MOZ_ALWAYS_INLINE void
  575. unpack<WebGLTexelFormat::RGBA16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  576. {
  577. dst[0] = src[0];
  578. dst[1] = src[1];
  579. dst[2] = src[2];
  580. dst[3] = src[3];
  581. }
  582. template<> MOZ_ALWAYS_INLINE void
  583. unpack<WebGLTexelFormat::RGBA32F, float, float>(const float* __restrict src, float* __restrict dst)
  584. {
  585. dst[0] = src[0];
  586. dst[1] = src[1];
  587. dst[2] = src[2];
  588. dst[3] = src[3];
  589. }
  590. ////////////////////////////////////////////////////////////////////////////////
  591. // DOM element formats
  592. template<> MOZ_ALWAYS_INLINE void
  593. unpack<WebGLTexelFormat::BGRX8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  594. {
  595. dst[0] = src[2];
  596. dst[1] = src[1];
  597. dst[2] = src[0];
  598. dst[3] = 0xFF;
  599. }
  600. template<> MOZ_ALWAYS_INLINE void
  601. unpack<WebGLTexelFormat::BGRA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  602. {
  603. dst[0] = src[2];
  604. dst[1] = src[1];
  605. dst[2] = src[0];
  606. dst[3] = src[3];
  607. }
  608. //----------------------------------------------------------------------
  609. // Pixel packing routines.
  610. //
  611. template<WebGLTexelFormat Format,
  612. WebGLTexelPremultiplicationOp PremultiplicationOp,
  613. typename SrcType,
  614. typename DstType>
  615. MOZ_ALWAYS_INLINE void
  616. pack(const SrcType* __restrict src,
  617. DstType* __restrict dst)
  618. {
  619. MOZ_CRASH("GFX: Unimplemented texture format conversion");
  620. }
  621. ////////////////////////////////////////////////////////////////////////////////
  622. // 1-channel formats
  623. template<> MOZ_ALWAYS_INLINE void
  624. pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  625. {
  626. dst[0] = src[3];
  627. }
  628. template<> MOZ_ALWAYS_INLINE void
  629. pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  630. {
  631. dst[0] = src[3];
  632. }
  633. template<> MOZ_ALWAYS_INLINE void
  634. pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  635. {
  636. dst[0] = src[3];
  637. }
  638. template<> MOZ_ALWAYS_INLINE void
  639. pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  640. {
  641. dst[0] = src[3];
  642. }
  643. template<> MOZ_ALWAYS_INLINE void
  644. pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  645. {
  646. dst[0] = src[3];
  647. }
  648. template<> MOZ_ALWAYS_INLINE void
  649. pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  650. {
  651. dst[0] = src[3];
  652. }
  653. template<> MOZ_ALWAYS_INLINE void
  654. pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
  655. {
  656. dst[0] = src[3];
  657. }
  658. template<> MOZ_ALWAYS_INLINE void
  659. pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
  660. {
  661. dst[0] = src[3];
  662. }
  663. template<> MOZ_ALWAYS_INLINE void
  664. pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
  665. {
  666. dst[0] = src[3];
  667. }
  668. template<> MOZ_ALWAYS_INLINE void
  669. pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  670. {
  671. dst[0] = src[0];
  672. }
  673. template<> MOZ_ALWAYS_INLINE void
  674. pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  675. {
  676. float scaleFactor = src[3] / 255.0f;
  677. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  678. dst[0] = srcR;
  679. }
  680. template<> MOZ_ALWAYS_INLINE void
  681. pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  682. {
  683. float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
  684. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  685. dst[0] = srcR;
  686. }
  687. template<> MOZ_ALWAYS_INLINE void
  688. pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  689. {
  690. dst[0] = src[0];
  691. }
  692. template<> MOZ_ALWAYS_INLINE void
  693. pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  694. {
  695. float scaleFactor = unpackFromFloat16(src[3]);
  696. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  697. }
  698. template<> MOZ_ALWAYS_INLINE void
  699. pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  700. {
  701. float unpackedAlpha = unpackFromFloat16(src[3]);
  702. float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
  703. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  704. }
  705. template<> MOZ_ALWAYS_INLINE void
  706. pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
  707. {
  708. dst[0] = src[0];
  709. }
  710. template<> MOZ_ALWAYS_INLINE void
  711. pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
  712. {
  713. float scaleFactor = src[3];
  714. dst[0] = src[0] * scaleFactor;
  715. }
  716. template<> MOZ_ALWAYS_INLINE void
  717. pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
  718. {
  719. float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
  720. dst[0] = src[0] * scaleFactor;
  721. }
  722. ////////////////////////////////////////////////////////////////////////////////
  723. // 2-channel formats
  724. template<> MOZ_ALWAYS_INLINE void
  725. pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  726. {
  727. dst[0] = src[0];
  728. dst[1] = src[3];
  729. }
  730. template<> MOZ_ALWAYS_INLINE void
  731. pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  732. {
  733. float scaleFactor = src[3] / 255.0f;
  734. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  735. dst[0] = srcR;
  736. dst[1] = src[3];
  737. }
  738. // FIXME: this routine is lossy and must be removed.
  739. template<> MOZ_ALWAYS_INLINE void
  740. pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  741. {
  742. float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
  743. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  744. dst[0] = srcR;
  745. dst[1] = src[3];
  746. }
  747. template<> MOZ_ALWAYS_INLINE void
  748. pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  749. {
  750. dst[0] = src[0];
  751. dst[1] = src[3];
  752. }
  753. template<> MOZ_ALWAYS_INLINE void
  754. pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  755. {
  756. float scaleFactor = unpackFromFloat16(src[3]);
  757. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  758. dst[1] = src[3];
  759. }
  760. template<> MOZ_ALWAYS_INLINE void
  761. pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  762. {
  763. float unpackedAlpha = unpackFromFloat16(src[3]);
  764. float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
  765. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  766. dst[1] = src[3];
  767. }
  768. template<> MOZ_ALWAYS_INLINE void
  769. pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
  770. {
  771. dst[0] = src[0];
  772. dst[1] = src[3];
  773. }
  774. template<> MOZ_ALWAYS_INLINE void
  775. pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
  776. {
  777. float scaleFactor = src[3];
  778. dst[0] = src[0] * scaleFactor;
  779. dst[1] = src[3];
  780. }
  781. template<> MOZ_ALWAYS_INLINE void
  782. pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
  783. {
  784. float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
  785. dst[0] = src[0] * scaleFactor;
  786. dst[1] = src[3];
  787. }
  788. template<> MOZ_ALWAYS_INLINE void
  789. pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  790. {
  791. dst[0] = src[0];
  792. dst[1] = src[1];
  793. }
  794. template<> MOZ_ALWAYS_INLINE void
  795. pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  796. {
  797. float scaleFactor = src[3] / 255.0f;
  798. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  799. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  800. dst[0] = srcR;
  801. dst[1] = srcG;
  802. }
  803. // FIXME: this routine is lossy and must be removed.
  804. template<> MOZ_ALWAYS_INLINE void
  805. pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  806. {
  807. float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
  808. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  809. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  810. dst[0] = srcR;
  811. dst[1] = srcG;
  812. }
  813. template<> MOZ_ALWAYS_INLINE void
  814. pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  815. {
  816. dst[0] = src[0];
  817. dst[1] = src[1];
  818. }
  819. template<> MOZ_ALWAYS_INLINE void
  820. pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  821. {
  822. float scaleFactor = unpackFromFloat16(src[3]);
  823. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  824. dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
  825. }
  826. template<> MOZ_ALWAYS_INLINE void
  827. pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  828. {
  829. float unpackedAlpha = unpackFromFloat16(src[3]);
  830. float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
  831. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  832. dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
  833. }
  834. template<> MOZ_ALWAYS_INLINE void
  835. pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
  836. {
  837. dst[0] = src[0];
  838. dst[1] = src[1];
  839. }
  840. template<> MOZ_ALWAYS_INLINE void
  841. pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
  842. {
  843. float scaleFactor = src[3];
  844. dst[0] = src[0] * scaleFactor;
  845. dst[1] = src[1] * scaleFactor;
  846. }
  847. template<> MOZ_ALWAYS_INLINE void
  848. pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
  849. {
  850. float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
  851. dst[0] = src[0] * scaleFactor;
  852. dst[1] = src[1] * scaleFactor;
  853. }
  854. ////////////////////////////////////////////////////////////////////////////////
  855. // 3-channel formats
  856. template<> MOZ_ALWAYS_INLINE void
  857. pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  858. {
  859. *dst = ( ((src[0] & 0xF8) << 8)
  860. | ((src[1] & 0xFC) << 3)
  861. | ((src[2] & 0xF8) >> 3));
  862. }
  863. template<> MOZ_ALWAYS_INLINE void
  864. pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  865. {
  866. float scaleFactor = src[3] / 255.0f;
  867. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  868. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  869. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  870. *dst = ( ((srcR & 0xF8) << 8)
  871. | ((srcG & 0xFC) << 3)
  872. | ((srcB & 0xF8) >> 3));
  873. }
  874. // FIXME: this routine is lossy and must be removed.
  875. template<> MOZ_ALWAYS_INLINE void
  876. pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  877. {
  878. float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
  879. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  880. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  881. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  882. *dst = ( ((srcR & 0xF8) << 8)
  883. | ((srcG & 0xFC) << 3)
  884. | ((srcB & 0xF8) >> 3));
  885. }
  886. template<> MOZ_ALWAYS_INLINE void
  887. pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  888. {
  889. dst[0] = src[0];
  890. dst[1] = src[1];
  891. dst[2] = src[2];
  892. }
  893. template<> MOZ_ALWAYS_INLINE void
  894. pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  895. {
  896. float scaleFactor = src[3] / 255.0f;
  897. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  898. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  899. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  900. dst[0] = srcR;
  901. dst[1] = srcG;
  902. dst[2] = srcB;
  903. }
  904. template<> MOZ_ALWAYS_INLINE void
  905. pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  906. {
  907. float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
  908. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  909. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  910. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  911. dst[0] = srcR;
  912. dst[1] = srcG;
  913. dst[2] = srcB;
  914. }
  915. template<> MOZ_ALWAYS_INLINE void
  916. pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::None, float, uint32_t>(const float* __restrict src, uint32_t* __restrict dst)
  917. {
  918. dst[0] = ((packToFloat11(src[0]) << 0) |
  919. (packToFloat11(src[1]) << 11) |
  920. (packToFloat10(src[2]) << 22));
  921. }
  922. template<> MOZ_ALWAYS_INLINE void
  923. pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::Premultiply, float, uint32_t>(const float* __restrict src, uint32_t* __restrict dst)
  924. {
  925. float scaleFactor = src[3];
  926. dst[0] = ((packToFloat11(src[0] * scaleFactor) << 0) |
  927. (packToFloat11(src[1] * scaleFactor) << 11) |
  928. (packToFloat10(src[2] * scaleFactor) << 22));
  929. }
  930. template<> MOZ_ALWAYS_INLINE void
  931. pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::Unpremultiply, float, uint32_t>(const float* __restrict src, uint32_t* __restrict dst)
  932. {
  933. float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
  934. dst[0] = ((packToFloat11(src[0] * scaleFactor) << 0) |
  935. (packToFloat11(src[1] * scaleFactor) << 11) |
  936. (packToFloat10(src[2] * scaleFactor) << 22));
  937. }
  938. template<> MOZ_ALWAYS_INLINE void
  939. pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  940. {
  941. dst[0] = src[0];
  942. dst[1] = src[1];
  943. dst[2] = src[2];
  944. }
  945. template<> MOZ_ALWAYS_INLINE void
  946. pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  947. {
  948. float scaleFactor = unpackFromFloat16(src[3]);
  949. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  950. dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
  951. dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
  952. }
  953. template<> MOZ_ALWAYS_INLINE void
  954. pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  955. {
  956. float unpackedAlpha = unpackFromFloat16(src[3]);
  957. float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
  958. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  959. dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
  960. dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
  961. }
  962. template<> MOZ_ALWAYS_INLINE void
  963. pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
  964. {
  965. dst[0] = src[0];
  966. dst[1] = src[1];
  967. dst[2] = src[2];
  968. }
  969. template<> MOZ_ALWAYS_INLINE void
  970. pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
  971. {
  972. float scaleFactor = src[3];
  973. dst[0] = src[0] * scaleFactor;
  974. dst[1] = src[1] * scaleFactor;
  975. dst[2] = src[2] * scaleFactor;
  976. }
  977. template<> MOZ_ALWAYS_INLINE void
  978. pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
  979. {
  980. float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
  981. dst[0] = src[0] * scaleFactor;
  982. dst[1] = src[1] * scaleFactor;
  983. dst[2] = src[2] * scaleFactor;
  984. }
  985. ////////////////////////////////////////////////////////////////////////////////
  986. // 4-channel formats
  987. template<> MOZ_ALWAYS_INLINE void
  988. pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  989. {
  990. *dst = ( ((src[0] & 0xF0) << 8)
  991. | ((src[1] & 0xF0) << 4)
  992. | (src[2] & 0xF0)
  993. | (src[3] >> 4) );
  994. }
  995. template<> MOZ_ALWAYS_INLINE void
  996. pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  997. {
  998. float scaleFactor = src[3] / 255.0f;
  999. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  1000. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  1001. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  1002. *dst = ( ((srcR & 0xF0) << 8)
  1003. | ((srcG & 0xF0) << 4)
  1004. | (srcB & 0xF0)
  1005. | (src[3] >> 4));
  1006. }
  1007. // FIXME: this routine is lossy and must be removed.
  1008. template<> MOZ_ALWAYS_INLINE void
  1009. pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  1010. {
  1011. float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
  1012. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  1013. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  1014. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  1015. *dst = ( ((srcR & 0xF0) << 8)
  1016. | ((srcG & 0xF0) << 4)
  1017. | (srcB & 0xF0)
  1018. | (src[3] >> 4));
  1019. }
  1020. template<> MOZ_ALWAYS_INLINE void
  1021. pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  1022. {
  1023. *dst = ( ((src[0] & 0xF8) << 8)
  1024. | ((src[1] & 0xF8) << 3)
  1025. | ((src[2] & 0xF8) >> 2)
  1026. | (src[3] >> 7));
  1027. }
  1028. template<> MOZ_ALWAYS_INLINE void
  1029. pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  1030. {
  1031. float scaleFactor = src[3] / 255.0f;
  1032. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  1033. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  1034. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  1035. *dst = ( ((srcR & 0xF8) << 8)
  1036. | ((srcG & 0xF8) << 3)
  1037. | ((srcB & 0xF8) >> 2)
  1038. | (src[3] >> 7));
  1039. }
  1040. // FIXME: this routine is lossy and must be removed.
  1041. template<> MOZ_ALWAYS_INLINE void
  1042. pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  1043. {
  1044. float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
  1045. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  1046. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  1047. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  1048. *dst = ( ((srcR & 0xF8) << 8)
  1049. | ((srcG & 0xF8) << 3)
  1050. | ((srcB & 0xF8) >> 2)
  1051. | (src[3] >> 7));
  1052. }
  1053. template<> MOZ_ALWAYS_INLINE void
  1054. pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  1055. {
  1056. dst[0] = src[0];
  1057. dst[1] = src[1];
  1058. dst[2] = src[2];
  1059. dst[3] = src[3];
  1060. }
  1061. template<> MOZ_ALWAYS_INLINE void
  1062. pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  1063. {
  1064. float scaleFactor = src[3] / 255.0f;
  1065. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  1066. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  1067. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  1068. dst[0] = srcR;
  1069. dst[1] = srcG;
  1070. dst[2] = srcB;
  1071. dst[3] = src[3];
  1072. }
  1073. // FIXME: this routine is lossy and must be removed.
  1074. template<> MOZ_ALWAYS_INLINE void
  1075. pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  1076. {
  1077. float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
  1078. uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
  1079. uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
  1080. uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
  1081. dst[0] = srcR;
  1082. dst[1] = srcG;
  1083. dst[2] = srcB;
  1084. dst[3] = src[3];
  1085. }
  1086. template<> MOZ_ALWAYS_INLINE void
  1087. pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  1088. {
  1089. dst[0] = src[0];
  1090. dst[1] = src[1];
  1091. dst[2] = src[2];
  1092. dst[3] = src[3];
  1093. }
  1094. template<> MOZ_ALWAYS_INLINE void
  1095. pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  1096. {
  1097. float scaleFactor = unpackFromFloat16(src[3]);
  1098. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  1099. dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
  1100. dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
  1101. dst[3] = src[3];
  1102. }
  1103. template<> MOZ_ALWAYS_INLINE void
  1104. pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  1105. {
  1106. float unpackedAlpha = unpackFromFloat16(src[3]);
  1107. float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
  1108. dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
  1109. dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
  1110. dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
  1111. dst[3] = src[3];
  1112. }
  1113. template<> MOZ_ALWAYS_INLINE void
  1114. pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
  1115. {
  1116. dst[0] = src[0];
  1117. dst[1] = src[1];
  1118. dst[2] = src[2];
  1119. dst[3] = src[3];
  1120. }
  1121. template<> MOZ_ALWAYS_INLINE void
  1122. pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
  1123. {
  1124. float scaleFactor = src[3];
  1125. dst[0] = src[0] * scaleFactor;
  1126. dst[1] = src[1] * scaleFactor;
  1127. dst[2] = src[2] * scaleFactor;
  1128. dst[3] = src[3];
  1129. }
  1130. template<> MOZ_ALWAYS_INLINE void
  1131. pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
  1132. {
  1133. float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
  1134. dst[0] = src[0] * scaleFactor;
  1135. dst[1] = src[1] * scaleFactor;
  1136. dst[2] = src[2] * scaleFactor;
  1137. dst[3] = src[3];
  1138. }
  1139. /****** END CODE SHARED WITH WEBKIT ******/
  1140. template<typename SrcType, typename DstType> MOZ_ALWAYS_INLINE void
  1141. convertType(const SrcType* __restrict src, DstType* __restrict dst)
  1142. {
  1143. MOZ_ASSERT(false, "Unimplemented texture format conversion");
  1144. }
  1145. template<> MOZ_ALWAYS_INLINE void
  1146. convertType<uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
  1147. {
  1148. dst[0] = src[0];
  1149. dst[1] = src[1];
  1150. dst[2] = src[2];
  1151. dst[3] = src[3];
  1152. }
  1153. template<> MOZ_ALWAYS_INLINE void
  1154. convertType<uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
  1155. {
  1156. dst[0] = src[0];
  1157. dst[1] = src[1];
  1158. dst[2] = src[2];
  1159. dst[3] = src[3];
  1160. }
  1161. template<> MOZ_ALWAYS_INLINE void
  1162. convertType<float, float>(const float* __restrict src, float* __restrict dst)
  1163. {
  1164. dst[0] = src[0];
  1165. dst[1] = src[1];
  1166. dst[2] = src[2];
  1167. dst[3] = src[3];
  1168. }
  1169. template<> MOZ_ALWAYS_INLINE void
  1170. convertType<uint8_t, float>(const uint8_t* __restrict src, float* __restrict dst)
  1171. {
  1172. const float scaleFactor = 1.f / 255.0f;
  1173. dst[0] = src[0] * scaleFactor;
  1174. dst[1] = src[1] * scaleFactor;
  1175. dst[2] = src[2] * scaleFactor;
  1176. dst[3] = src[3] * scaleFactor;
  1177. }
  1178. template<> MOZ_ALWAYS_INLINE void
  1179. convertType<uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
  1180. {
  1181. const float scaleFactor = 1.f / 255.0f;
  1182. dst[0] = packToFloat16(src[0] * scaleFactor);
  1183. dst[1] = packToFloat16(src[1] * scaleFactor);
  1184. dst[2] = packToFloat16(src[2] * scaleFactor);
  1185. dst[3] = packToFloat16(src[3] * scaleFactor);
  1186. }
  1187. } // end namespace WebGLTexelConversions
  1188. } // end namespace mozilla
  1189. #endif // WEBGLTEXELCONVERSIONS_H_