Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(564)

Side by Side Diff: sky/engine/platform/graphics/gpu/WebGLImageConversion.cpp

Issue 1229113003: Remove some unneeded DEPS from //sky (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/engine/platform/graphics/gpu/WebGLImageConversion.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "sky/engine/platform/graphics/gpu/WebGLImageConversion.h"
6
7 #include "platform/image-decoders/ImageDecoder.h"
8 #include "sky/engine/platform/CheckedInt.h"
9 #include "sky/engine/platform/graphics/ImageObserver.h"
10 #include "sky/engine/platform/graphics/cpu/arm/WebGLImageConversionNEON.h"
11 #include "sky/engine/wtf/OwnPtr.h"
12 #include "sky/engine/wtf/PassOwnPtr.h"
13
14 namespace blink {
15
16 namespace {
17
18 WebGLImageConversion::DataFormat getDataFormat(GLenum destinationFormat, GLenum destinationType)
19 {
20 WebGLImageConversion::DataFormat dstFormat = WebGLImageConversion::DataForma tRGBA8;
21 switch (destinationType) {
22 case GL_UNSIGNED_BYTE:
23 switch (destinationFormat) {
24 case GL_RGB:
25 dstFormat = WebGLImageConversion::DataFormatRGB8;
26 break;
27 case GL_RGBA:
28 dstFormat = WebGLImageConversion::DataFormatRGBA8;
29 break;
30 case GL_ALPHA:
31 dstFormat = WebGLImageConversion::DataFormatA8;
32 break;
33 case GL_LUMINANCE:
34 dstFormat = WebGLImageConversion::DataFormatR8;
35 break;
36 case GL_LUMINANCE_ALPHA:
37 dstFormat = WebGLImageConversion::DataFormatRA8;
38 break;
39 default:
40 ASSERT_NOT_REACHED();
41 }
42 break;
43 case GL_UNSIGNED_SHORT_4_4_4_4:
44 dstFormat = WebGLImageConversion::DataFormatRGBA4444;
45 break;
46 case GL_UNSIGNED_SHORT_5_5_5_1:
47 dstFormat = WebGLImageConversion::DataFormatRGBA5551;
48 break;
49 case GL_UNSIGNED_SHORT_5_6_5:
50 dstFormat = WebGLImageConversion::DataFormatRGB565;
51 break;
52 case GL_HALF_FLOAT_OES: // OES_texture_half_float
53 switch (destinationFormat) {
54 case GL_RGB:
55 dstFormat = WebGLImageConversion::DataFormatRGB16F;
56 break;
57 case GL_RGBA:
58 dstFormat = WebGLImageConversion::DataFormatRGBA16F;
59 break;
60 case GL_ALPHA:
61 dstFormat = WebGLImageConversion::DataFormatA16F;
62 break;
63 case GL_LUMINANCE:
64 dstFormat = WebGLImageConversion::DataFormatR16F;
65 break;
66 case GL_LUMINANCE_ALPHA:
67 dstFormat = WebGLImageConversion::DataFormatRA16F;
68 break;
69 default:
70 ASSERT_NOT_REACHED();
71 }
72 break;
73 case GL_FLOAT: // OES_texture_float
74 switch (destinationFormat) {
75 case GL_RGB:
76 dstFormat = WebGLImageConversion::DataFormatRGB32F;
77 break;
78 case GL_RGBA:
79 dstFormat = WebGLImageConversion::DataFormatRGBA32F;
80 break;
81 case GL_ALPHA:
82 dstFormat = WebGLImageConversion::DataFormatA32F;
83 break;
84 case GL_LUMINANCE:
85 dstFormat = WebGLImageConversion::DataFormatR32F;
86 break;
87 case GL_LUMINANCE_ALPHA:
88 dstFormat = WebGLImageConversion::DataFormatRA32F;
89 break;
90 default:
91 ASSERT_NOT_REACHED();
92 }
93 break;
94 default:
95 ASSERT_NOT_REACHED();
96 }
97 return dstFormat;
98 }
99
100 // Following Float to Half-Float converion code is from the implementation of ft p://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf,
101 // "Fast Half Float Conversions" by Jeroen van der Zijp, November 2008 (Revised September 2010).
102 // Specially, the basetable[512] and shifttable[512] are generated as follows:
103 /*
104 unsigned short basetable[512];
105 unsigned char shifttable[512];
106
107 void generatetables(){
108 unsigned int i;
109 int e;
110 for (i = 0; i < 256; ++i){
111 e = i - 127;
112 if (e < -24){ // Very small numbers map to zero
113 basetable[i | 0x000] = 0x0000;
114 basetable[i | 0x100] = 0x8000;
115 shifttable[i | 0x000] = 24;
116 shifttable[i | 0x100] = 24;
117 }
118 else if (e < -14) { // Small numbers map to denorms
119 basetable[i | 0x000] = (0x0400>>(-e-14));
120 basetable[i | 0x100] = (0x0400>>(-e-14)) | 0x8000;
121 shifttable[i | 0x000] = -e-1;
122 shifttable[i | 0x100] = -e-1;
123 }
124 else if (e <= 15){ // Normal numbers just lose precision
125 basetable[i | 0x000] = ((e+15)<<10);
126 basetable[i| 0x100] = ((e+15)<<10) | 0x8000;
127 shifttable[i|0x000] = 13;
128 shifttable[i|0x100] = 13;
129 }
130 else if (e<128){ // Large numbers map to Infinity
131 basetable[i|0x000] = 0x7C00;
132 basetable[i|0x100] = 0xFC00;
133 shifttable[i|0x000] = 24;
134 shifttable[i|0x100] = 24;
135 }
136 else { // Infinity and NaN's stay Infinity and NaN's
137 basetable[i|0x000] = 0x7C00;
138 basetable[i|0x100] = 0xFC00;
139 shifttable[i|0x000] = 13;
140 shifttable[i|0x100] = 13;
141 }
142 }
143 }
144 */
145
146 unsigned short baseTable[512] = {
147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
148 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
152 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
153 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64, 128, 256,
154 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360,
155 16384, 17408, 18432, 19456, 20480, 21504, 22528, 23552, 24576, 25600, 26624, 27648, 28672, 29696, 30720, 31744,
156 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
157 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
158 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
159 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
160 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
161 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
162 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
163 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
164 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
165 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
166 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
167 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
168 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
169 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32769, 32770, 32772, 32776, 32784, 32800, 32832, 32896, 33024,
170 33280, 33792, 34816, 35840, 36864, 37888, 38912, 39936, 40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128,
171 49152, 50176, 51200, 52224, 53248, 54272, 55296, 56320, 57344, 58368, 59392, 60416, 61440, 62464, 63488, 64512,
172 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
173 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
174 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
175 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
176 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
177 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
178 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512
179 };
180
181 unsigned char shiftTable[512] = {
182 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
183 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
184 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
185 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
186 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
187 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
188 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
189 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
190 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24,
191 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
192 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
193 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
194 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
195 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
196 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
197 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13,
198 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
199 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
200 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
201 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
202 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
203 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
204 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
205 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
206 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24,
207 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
208 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
209 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
210 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
211 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
212 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
213 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13
214 };
215
216 unsigned short convertFloatToHalfFloat(float f)
217 {
218 unsigned temp = *(reinterpret_cast<unsigned *>(&f));
219 unsigned signexp = (temp >> 23) & 0x1ff;
220 return baseTable[signexp] + ((temp & 0x007fffff) >> shiftTable[signexp]);
221 }
222
223 /* BEGIN CODE SHARED WITH MOZILLA FIREFOX */
224
225 // The following packing and unpacking routines are expressed in terms of functi on templates and inline functions to achieve generality and speedup.
226 // Explicit template specializations correspond to the cases that would occur.
227 // Some code are merged back from Mozilla code in http://mxr.mozilla.org/mozilla -central/source/content/canvas/src/WebGLTexelConversions.h
228
229 //----------------------------------------------------------------------
230 // Pixel unpacking routines.
231 template<int format, typename SourceType, typename DstType>
232 void unpack(const SourceType*, DstType*, unsigned)
233 {
234 ASSERT_NOT_REACHED();
235 }
236
237 template<> void unpack<WebGLImageConversion::DataFormatRGB8, uint8_t, uint8_t>(c onst uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
238 {
239 for (unsigned i = 0; i < pixelsPerRow; ++i) {
240 destination[0] = source[0];
241 destination[1] = source[1];
242 destination[2] = source[2];
243 destination[3] = 0xFF;
244 source += 3;
245 destination += 4;
246 }
247 }
248
249 template<> void unpack<WebGLImageConversion::DataFormatBGR8, uint8_t, uint8_t>(c onst uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
250 {
251 for (unsigned i = 0; i < pixelsPerRow; ++i) {
252 destination[0] = source[2];
253 destination[1] = source[1];
254 destination[2] = source[0];
255 destination[3] = 0xFF;
256 source += 3;
257 destination += 4;
258 }
259 }
260
261 template<> void unpack<WebGLImageConversion::DataFormatARGB8, uint8_t, uint8_t>( const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
262 {
263 for (unsigned i = 0; i < pixelsPerRow; ++i) {
264 destination[0] = source[1];
265 destination[1] = source[2];
266 destination[2] = source[3];
267 destination[3] = source[0];
268 source += 4;
269 destination += 4;
270 }
271 }
272
273 template<> void unpack<WebGLImageConversion::DataFormatABGR8, uint8_t, uint8_t>( const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
274 {
275 for (unsigned i = 0; i < pixelsPerRow; ++i) {
276 destination[0] = source[3];
277 destination[1] = source[2];
278 destination[2] = source[1];
279 destination[3] = source[0];
280 source += 4;
281 destination += 4;
282 }
283 }
284
285 template<> void unpack<WebGLImageConversion::DataFormatBGRA8, uint8_t, uint8_t>( const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
286 {
287 const uint32_t* source32 = reinterpret_cast_ptr<const uint32_t*>(source);
288 uint32_t* destination32 = reinterpret_cast_ptr<uint32_t*>(destination);
289 for (unsigned i = 0; i < pixelsPerRow; ++i) {
290 uint32_t bgra = source32[i];
291 #if CPU(BIG_ENDIAN)
292 uint32_t brMask = 0xff00ff00;
293 uint32_t gaMask = 0x00ff00ff;
294 #else
295 uint32_t brMask = 0x00ff00ff;
296 uint32_t gaMask = 0xff00ff00;
297 #endif
298 uint32_t rgba = (((bgra >> 16) | (bgra << 16)) & brMask) | (bgra & gaMas k);
299 destination32[i] = rgba;
300 }
301 }
302
303 template<> void unpack<WebGLImageConversion::DataFormatRGBA5551, uint16_t, uint8 _t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
304 {
305 #if HAVE(ARM_NEON_INTRINSICS)
306 SIMD::unpackOneRowOfRGBA5551ToRGBA8(source, destination, pixelsPerRow);
307 #endif
308 for (unsigned i = 0; i < pixelsPerRow; ++i) {
309 uint16_t packedValue = source[0];
310 uint8_t r = packedValue >> 11;
311 uint8_t g = (packedValue >> 6) & 0x1F;
312 uint8_t b = (packedValue >> 1) & 0x1F;
313 destination[0] = (r << 3) | (r & 0x7);
314 destination[1] = (g << 3) | (g & 0x7);
315 destination[2] = (b << 3) | (b & 0x7);
316 destination[3] = (packedValue & 0x1) ? 0xFF : 0x0;
317 source += 1;
318 destination += 4;
319 }
320 }
321
322 template<> void unpack<WebGLImageConversion::DataFormatRGBA4444, uint16_t, uint8 _t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
323 {
324 #if HAVE(ARM_NEON_INTRINSICS)
325 SIMD::unpackOneRowOfRGBA4444ToRGBA8(source, destination, pixelsPerRow);
326 #endif
327 for (unsigned i = 0; i < pixelsPerRow; ++i) {
328 uint16_t packedValue = source[0];
329 uint8_t r = packedValue >> 12;
330 uint8_t g = (packedValue >> 8) & 0x0F;
331 uint8_t b = (packedValue >> 4) & 0x0F;
332 uint8_t a = packedValue & 0x0F;
333 destination[0] = r << 4 | r;
334 destination[1] = g << 4 | g;
335 destination[2] = b << 4 | b;
336 destination[3] = a << 4 | a;
337 source += 1;
338 destination += 4;
339 }
340 }
341
342 template<> void unpack<WebGLImageConversion::DataFormatRGB565, uint16_t, uint8_t >(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
343 {
344 #if HAVE(ARM_NEON_INTRINSICS)
345 SIMD::unpackOneRowOfRGB565ToRGBA8(source, destination, pixelsPerRow);
346 #endif
347 for (unsigned i = 0; i < pixelsPerRow; ++i) {
348 uint16_t packedValue = source[0];
349 uint8_t r = packedValue >> 11;
350 uint8_t g = (packedValue >> 5) & 0x3F;
351 uint8_t b = packedValue & 0x1F;
352 destination[0] = (r << 3) | (r & 0x7);
353 destination[1] = (g << 2) | (g & 0x3);
354 destination[2] = (b << 3) | (b & 0x7);
355 destination[3] = 0xFF;
356 source += 1;
357 destination += 4;
358 }
359 }
360
361 template<> void unpack<WebGLImageConversion::DataFormatR8, uint8_t, uint8_t>(con st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
362 {
363 for (unsigned i = 0; i < pixelsPerRow; ++i) {
364 destination[0] = source[0];
365 destination[1] = source[0];
366 destination[2] = source[0];
367 destination[3] = 0xFF;
368 source += 1;
369 destination += 4;
370 }
371 }
372
373 template<> void unpack<WebGLImageConversion::DataFormatRA8, uint8_t, uint8_t>(co nst uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
374 {
375 for (unsigned i = 0; i < pixelsPerRow; ++i) {
376 destination[0] = source[0];
377 destination[1] = source[0];
378 destination[2] = source[0];
379 destination[3] = source[1];
380 source += 2;
381 destination += 4;
382 }
383 }
384
385 template<> void unpack<WebGLImageConversion::DataFormatAR8, uint8_t, uint8_t>(co nst uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
386 {
387 for (unsigned i = 0; i < pixelsPerRow; ++i) {
388 destination[0] = source[1];
389 destination[1] = source[1];
390 destination[2] = source[1];
391 destination[3] = source[0];
392 source += 2;
393 destination += 4;
394 }
395 }
396
397 template<> void unpack<WebGLImageConversion::DataFormatA8, uint8_t, uint8_t>(con st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
398 {
399 for (unsigned i = 0; i < pixelsPerRow; ++i) {
400 destination[0] = 0x0;
401 destination[1] = 0x0;
402 destination[2] = 0x0;
403 destination[3] = source[0];
404 source += 1;
405 destination += 4;
406 }
407 }
408
409 template<> void unpack<WebGLImageConversion::DataFormatRGBA8, uint8_t, float>(co nst uint8_t* source, float* destination, unsigned pixelsPerRow)
410 {
411 const float scaleFactor = 1.0f / 255.0f;
412 for (unsigned i = 0; i < pixelsPerRow; ++i) {
413 destination[0] = source[0] * scaleFactor;
414 destination[1] = source[1] * scaleFactor;
415 destination[2] = source[2] * scaleFactor;
416 destination[3] = source[3] * scaleFactor;
417 source += 4;
418 destination += 4;
419 }
420 }
421
422 template<> void unpack<WebGLImageConversion::DataFormatBGRA8, uint8_t, float>(co nst uint8_t* source, float* destination, unsigned pixelsPerRow)
423 {
424 const float scaleFactor = 1.0f / 255.0f;
425 for (unsigned i = 0; i < pixelsPerRow; ++i) {
426 destination[0] = source[2] * scaleFactor;
427 destination[1] = source[1] * scaleFactor;
428 destination[2] = source[0] * scaleFactor;
429 destination[3] = source[3] * scaleFactor;
430 source += 4;
431 destination += 4;
432 }
433 }
434
435 template<> void unpack<WebGLImageConversion::DataFormatABGR8, uint8_t, float>(co nst uint8_t* source, float* destination, unsigned pixelsPerRow)
436 {
437 const float scaleFactor = 1.0f / 255.0f;
438 for (unsigned i = 0; i < pixelsPerRow; ++i) {
439 destination[0] = source[3] * scaleFactor;
440 destination[1] = source[2] * scaleFactor;
441 destination[2] = source[1] * scaleFactor;
442 destination[3] = source[0] * scaleFactor;
443 source += 4;
444 destination += 4;
445 }
446 }
447
448 template<> void unpack<WebGLImageConversion::DataFormatARGB8, uint8_t, float>(co nst uint8_t* source, float* destination, unsigned pixelsPerRow)
449 {
450 const float scaleFactor = 1.0f / 255.0f;
451 for (unsigned i = 0; i < pixelsPerRow; ++i) {
452 destination[0] = source[1] * scaleFactor;
453 destination[1] = source[2] * scaleFactor;
454 destination[2] = source[3] * scaleFactor;
455 destination[3] = source[0] * scaleFactor;
456 source += 4;
457 destination += 4;
458 }
459 }
460
461 template<> void unpack<WebGLImageConversion::DataFormatRGB8, uint8_t, float>(con st uint8_t* source, float* destination, unsigned pixelsPerRow)
462 {
463 const float scaleFactor = 1.0f / 255.0f;
464 for (unsigned i = 0; i < pixelsPerRow; ++i) {
465 destination[0] = source[0] * scaleFactor;
466 destination[1] = source[1] * scaleFactor;
467 destination[2] = source[2] * scaleFactor;
468 destination[3] = 1;
469 source += 3;
470 destination += 4;
471 }
472 }
473
474 template<> void unpack<WebGLImageConversion::DataFormatBGR8, uint8_t, float>(con st uint8_t* source, float* destination, unsigned pixelsPerRow)
475 {
476 const float scaleFactor = 1.0f / 255.0f;
477 for (unsigned i = 0; i < pixelsPerRow; ++i) {
478 destination[0] = source[2] * scaleFactor;
479 destination[1] = source[1] * scaleFactor;
480 destination[2] = source[0] * scaleFactor;
481 destination[3] = 1;
482 source += 3;
483 destination += 4;
484 }
485 }
486
487 template<> void unpack<WebGLImageConversion::DataFormatRGB32F, float, float>(con st float* source, float* destination, unsigned pixelsPerRow)
488 {
489 for (unsigned i = 0; i < pixelsPerRow; ++i) {
490 destination[0] = source[0];
491 destination[1] = source[1];
492 destination[2] = source[2];
493 destination[3] = 1;
494 source += 3;
495 destination += 4;
496 }
497 }
498
499 template<> void unpack<WebGLImageConversion::DataFormatR32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
500 {
501 for (unsigned i = 0; i < pixelsPerRow; ++i) {
502 destination[0] = source[0];
503 destination[1] = source[0];
504 destination[2] = source[0];
505 destination[3] = 1;
506 source += 1;
507 destination += 4;
508 }
509 }
510
511 template<> void unpack<WebGLImageConversion::DataFormatRA32F, float, float>(cons t float* source, float* destination, unsigned pixelsPerRow)
512 {
513 for (unsigned i = 0; i < pixelsPerRow; ++i) {
514 destination[0] = source[0];
515 destination[1] = source[0];
516 destination[2] = source[0];
517 destination[3] = source[1];
518 source += 2;
519 destination += 4;
520 }
521 }
522
523 template<> void unpack<WebGLImageConversion::DataFormatA32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
524 {
525 for (unsigned i = 0; i < pixelsPerRow; ++i) {
526 destination[0] = 0;
527 destination[1] = 0;
528 destination[2] = 0;
529 destination[3] = source[0];
530 source += 1;
531 destination += 4;
532 }
533 }
534
535 //----------------------------------------------------------------------
536 // Pixel packing routines.
537 //
538
539 template<int format, int alphaOp, typename SourceType, typename DstType>
540 void pack(const SourceType*, DstType*, unsigned)
541 {
542 ASSERT_NOT_REACHED();
543 }
544
545 template<> void pack<WebGLImageConversion::DataFormatA8, WebGLImageConversion::A lphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, un signed pixelsPerRow)
546 {
547 for (unsigned i = 0; i < pixelsPerRow; ++i) {
548 destination[0] = source[3];
549 source += 4;
550 destination += 1;
551 }
552 }
553
554 template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::A lphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, un signed pixelsPerRow)
555 {
556 for (unsigned i = 0; i < pixelsPerRow; ++i) {
557 destination[0] = source[0];
558 source += 4;
559 destination += 1;
560 }
561 }
562
563 template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::A lphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination , unsigned pixelsPerRow)
564 {
565 for (unsigned i = 0; i < pixelsPerRow; ++i) {
566 float scaleFactor = source[3] / 255.0f;
567 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
568 destination[0] = sourceR;
569 source += 4;
570 destination += 1;
571 }
572 }
573
574 // FIXME: this routine is lossy and must be removed.
575 template<> void pack<WebGLImageConversion::DataFormatR8, WebGLImageConversion::A lphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
576 {
577 for (unsigned i = 0; i < pixelsPerRow; ++i) {
578 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
579 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
580 destination[0] = sourceR;
581 source += 4;
582 destination += 1;
583 }
584 }
585
586 template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion:: AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, u nsigned pixelsPerRow)
587 {
588 for (unsigned i = 0; i < pixelsPerRow; ++i) {
589 destination[0] = source[0];
590 destination[1] = source[3];
591 source += 4;
592 destination += 2;
593 }
594 }
595
596 template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion:: AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinatio n, unsigned pixelsPerRow)
597 {
598 for (unsigned i = 0; i < pixelsPerRow; ++i) {
599 float scaleFactor = source[3] / 255.0f;
600 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
601 destination[0] = sourceR;
602 destination[1] = source[3];
603 source += 4;
604 destination += 2;
605 }
606 }
607
608 // FIXME: this routine is lossy and must be removed.
609 template<> void pack<WebGLImageConversion::DataFormatRA8, WebGLImageConversion:: AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination , unsigned pixelsPerRow)
610 {
611 for (unsigned i = 0; i < pixelsPerRow; ++i) {
612 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
613 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
614 destination[0] = sourceR;
615 destination[1] = source[3];
616 source += 4;
617 destination += 2;
618 }
619 }
620
621 template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion: :AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
622 {
623 for (unsigned i = 0; i < pixelsPerRow; ++i) {
624 destination[0] = source[0];
625 destination[1] = source[1];
626 destination[2] = source[2];
627 source += 4;
628 destination += 3;
629 }
630 }
631
632 template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion: :AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinati on, unsigned pixelsPerRow)
633 {
634 for (unsigned i = 0; i < pixelsPerRow; ++i) {
635 float scaleFactor = source[3] / 255.0f;
636 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
637 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
638 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
639 destination[0] = sourceR;
640 destination[1] = sourceG;
641 destination[2] = sourceB;
642 source += 4;
643 destination += 3;
644 }
645 }
646
647 // FIXME: this routine is lossy and must be removed.
648 template<> void pack<WebGLImageConversion::DataFormatRGB8, WebGLImageConversion: :AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinatio n, unsigned pixelsPerRow)
649 {
650 for (unsigned i = 0; i < pixelsPerRow; ++i) {
651 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
652 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
653 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
654 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
655 destination[0] = sourceR;
656 destination[1] = sourceG;
657 destination[2] = sourceB;
658 source += 4;
659 destination += 3;
660 }
661 }
662
663
664 template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion ::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
665 {
666 memcpy(destination, source, pixelsPerRow * 4);
667 }
668
669 template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion ::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinat ion, unsigned pixelsPerRow)
670 {
671 for (unsigned i = 0; i < pixelsPerRow; ++i) {
672 float scaleFactor = source[3] / 255.0f;
673 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
674 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
675 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
676 destination[0] = sourceR;
677 destination[1] = sourceG;
678 destination[2] = sourceB;
679 destination[3] = source[3];
680 source += 4;
681 destination += 4;
682 }
683 }
684
685 // FIXME: this routine is lossy and must be removed.
686 template<> void pack<WebGLImageConversion::DataFormatRGBA8, WebGLImageConversion ::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destinati on, unsigned pixelsPerRow)
687 {
688 for (unsigned i = 0; i < pixelsPerRow; ++i) {
689 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
690 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
691 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
692 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
693 destination[0] = sourceR;
694 destination[1] = sourceG;
695 destination[2] = sourceB;
696 destination[3] = source[3];
697 source += 4;
698 destination += 4;
699 }
700 }
701
702 template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConvers ion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destina tion, unsigned pixelsPerRow)
703 {
704 #if HAVE(ARM_NEON_INTRINSICS)
705 SIMD::packOneRowOfRGBA8ToUnsignedShort4444(source, destination, pixelsPerRow );
706 #endif
707 for (unsigned i = 0; i < pixelsPerRow; ++i) {
708 *destination = (((source[0] & 0xF0) << 8)
709 | ((source[1] & 0xF0) << 4)
710 | (source[2] & 0xF0)
711 | (source[3] >> 4));
712 source += 4;
713 destination += 1;
714 }
715 }
716
717 template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConvers ion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* des tination, unsigned pixelsPerRow)
718 {
719 for (unsigned i = 0; i < pixelsPerRow; ++i) {
720 float scaleFactor = source[3] / 255.0f;
721 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
722 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
723 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
724 *destination = (((sourceR & 0xF0) << 8)
725 | ((sourceG & 0xF0) << 4)
726 | (sourceB & 0xF0)
727 | (source[3] >> 4));
728 source += 4;
729 destination += 1;
730 }
731 }
732
733 // FIXME: this routine is lossy and must be removed.
734 template<> void pack<WebGLImageConversion::DataFormatRGBA4444, WebGLImageConvers ion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* dest ination, unsigned pixelsPerRow)
735 {
736 for (unsigned i = 0; i < pixelsPerRow; ++i) {
737 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
738 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
739 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
740 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
741 *destination = (((sourceR & 0xF0) << 8)
742 | ((sourceG & 0xF0) << 4)
743 | (sourceB & 0xF0)
744 | (source[3] >> 4));
745 source += 4;
746 destination += 1;
747 }
748 }
749
750 template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConvers ion::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destina tion, unsigned pixelsPerRow)
751 {
752 #if HAVE(ARM_NEON_INTRINSICS)
753 SIMD::packOneRowOfRGBA8ToUnsignedShort5551(source, destination, pixelsPerRow );
754 #endif
755 for (unsigned i = 0; i < pixelsPerRow; ++i) {
756 *destination = (((source[0] & 0xF8) << 8)
757 | ((source[1] & 0xF8) << 3)
758 | ((source[2] & 0xF8) >> 2)
759 | (source[3] >> 7));
760 source += 4;
761 destination += 1;
762 }
763 }
764
765 template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConvers ion::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* des tination, unsigned pixelsPerRow)
766 {
767 for (unsigned i = 0; i < pixelsPerRow; ++i) {
768 float scaleFactor = source[3] / 255.0f;
769 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
770 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
771 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
772 *destination = (((sourceR & 0xF8) << 8)
773 | ((sourceG & 0xF8) << 3)
774 | ((sourceB & 0xF8) >> 2)
775 | (source[3] >> 7));
776 source += 4;
777 destination += 1;
778 }
779 }
780
781 // FIXME: this routine is lossy and must be removed.
782 template<> void pack<WebGLImageConversion::DataFormatRGBA5551, WebGLImageConvers ion::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* dest ination, unsigned pixelsPerRow)
783 {
784 for (unsigned i = 0; i < pixelsPerRow; ++i) {
785 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
786 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
787 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
788 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
789 *destination = (((sourceR & 0xF8) << 8)
790 | ((sourceG & 0xF8) << 3)
791 | ((sourceB & 0xF8) >> 2)
792 | (source[3] >> 7));
793 source += 4;
794 destination += 1;
795 }
796 }
797
798 template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversio n::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinati on, unsigned pixelsPerRow)
799 {
800 #if HAVE(ARM_NEON_INTRINSICS)
801 SIMD::packOneRowOfRGBA8ToUnsignedShort565(source, destination, pixelsPerRow) ;
802 #endif
803 for (unsigned i = 0; i < pixelsPerRow; ++i) {
804 *destination = (((source[0] & 0xF8) << 8)
805 | ((source[1] & 0xFC) << 3)
806 | ((source[2] & 0xF8) >> 3));
807 source += 4;
808 destination += 1;
809 }
810 }
811
812 template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversio n::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* desti nation, unsigned pixelsPerRow)
813 {
814 for (unsigned i = 0; i < pixelsPerRow; ++i) {
815 float scaleFactor = source[3] / 255.0f;
816 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
817 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
818 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
819 *destination = (((sourceR & 0xF8) << 8)
820 | ((sourceG & 0xFC) << 3)
821 | ((sourceB & 0xF8) >> 3));
822 source += 4;
823 destination += 1;
824 }
825 }
826
827 // FIXME: this routine is lossy and must be removed.
828 template<> void pack<WebGLImageConversion::DataFormatRGB565, WebGLImageConversio n::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destin ation, unsigned pixelsPerRow)
829 {
830 for (unsigned i = 0; i < pixelsPerRow; ++i) {
831 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
832 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
833 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
834 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
835 *destination = (((sourceR & 0xF8) << 8)
836 | ((sourceG & 0xFC) << 3)
837 | ((sourceB & 0xF8) >> 3));
838 source += 4;
839 destination += 1;
840 }
841 }
842
843 template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversio n::AlphaDoNothing, float, float>(const float* source, float* destination, unsign ed pixelsPerRow)
844 {
845 for (unsigned i = 0; i < pixelsPerRow; ++i) {
846 destination[0] = source[0];
847 destination[1] = source[1];
848 destination[2] = source[2];
849 source += 4;
850 destination += 3;
851 }
852 }
853
854 template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversio n::AlphaDoPremultiply, float, float>(const float* source, float* destination, un signed pixelsPerRow)
855 {
856 for (unsigned i = 0; i < pixelsPerRow; ++i) {
857 float scaleFactor = source[3];
858 destination[0] = source[0] * scaleFactor;
859 destination[1] = source[1] * scaleFactor;
860 destination[2] = source[2] * scaleFactor;
861 source += 4;
862 destination += 3;
863 }
864 }
865
866 template<> void pack<WebGLImageConversion::DataFormatRGB32F, WebGLImageConversio n::AlphaDoUnmultiply, float, float>(const float* source, float* destination, uns igned pixelsPerRow)
867 {
868 for (unsigned i = 0; i < pixelsPerRow; ++i) {
869 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
870 destination[0] = source[0] * scaleFactor;
871 destination[1] = source[1] * scaleFactor;
872 destination[2] = source[2] * scaleFactor;
873 source += 4;
874 destination += 3;
875 }
876 }
877
878 // Used only during RGBA8 or BGRA8 -> floating-point uploads.
879 template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversi on::AlphaDoNothing, float, float>(const float* source, float* destination, unsig ned pixelsPerRow)
880 {
881 memcpy(destination, source, pixelsPerRow * 4 * sizeof(float));
882 }
883
884 template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversi on::AlphaDoPremultiply, float, float>(const float* source, float* destination, u nsigned pixelsPerRow)
885 {
886 for (unsigned i = 0; i < pixelsPerRow; ++i) {
887 float scaleFactor = source[3];
888 destination[0] = source[0] * scaleFactor;
889 destination[1] = source[1] * scaleFactor;
890 destination[2] = source[2] * scaleFactor;
891 destination[3] = source[3];
892 source += 4;
893 destination += 4;
894 }
895 }
896
897 template<> void pack<WebGLImageConversion::DataFormatRGBA32F, WebGLImageConversi on::AlphaDoUnmultiply, float, float>(const float* source, float* destination, un signed pixelsPerRow)
898 {
899 for (unsigned i = 0; i < pixelsPerRow; ++i) {
900 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
901 destination[0] = source[0] * scaleFactor;
902 destination[1] = source[1] * scaleFactor;
903 destination[2] = source[2] * scaleFactor;
904 destination[3] = source[3];
905 source += 4;
906 destination += 4;
907 }
908 }
909
910 template<> void pack<WebGLImageConversion::DataFormatA32F, WebGLImageConversion: :AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
911 {
912 for (unsigned i = 0; i < pixelsPerRow; ++i) {
913 destination[0] = source[3];
914 source += 4;
915 destination += 1;
916 }
917 }
918
919 template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion: :AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
920 {
921 for (unsigned i = 0; i < pixelsPerRow; ++i) {
922 destination[0] = source[0];
923 source += 4;
924 destination += 1;
925 }
926 }
927
928 template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion: :AlphaDoPremultiply, float, float>(const float* source, float* destination, unsi gned pixelsPerRow)
929 {
930 for (unsigned i = 0; i < pixelsPerRow; ++i) {
931 float scaleFactor = source[3];
932 destination[0] = source[0] * scaleFactor;
933 source += 4;
934 destination += 1;
935 }
936 }
937
938 template<> void pack<WebGLImageConversion::DataFormatR32F, WebGLImageConversion: :AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsig ned pixelsPerRow)
939 {
940 for (unsigned i = 0; i < pixelsPerRow; ++i) {
941 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
942 destination[0] = source[0] * scaleFactor;
943 source += 4;
944 destination += 1;
945 }
946 }
947
948 template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion ::AlphaDoNothing, float, float>(const float* source, float* destination, unsigne d pixelsPerRow)
949 {
950 for (unsigned i = 0; i < pixelsPerRow; ++i) {
951 destination[0] = source[0];
952 destination[1] = source[3];
953 source += 4;
954 destination += 2;
955 }
956 }
957
958 template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion ::AlphaDoPremultiply, float, float>(const float* source, float* destination, uns igned pixelsPerRow)
959 {
960 for (unsigned i = 0; i < pixelsPerRow; ++i) {
961 float scaleFactor = source[3];
962 destination[0] = source[0] * scaleFactor;
963 destination[1] = source[3];
964 source += 4;
965 destination += 2;
966 }
967 }
968
969 template<> void pack<WebGLImageConversion::DataFormatRA32F, WebGLImageConversion ::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsi gned pixelsPerRow)
970 {
971 for (unsigned i = 0; i < pixelsPerRow; ++i) {
972 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
973 destination[0] = source[0] * scaleFactor;
974 destination[1] = source[3];
975 source += 4;
976 destination += 2;
977 }
978 }
979
980 template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversi on::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
981 {
982 for (unsigned i = 0; i < pixelsPerRow; ++i) {
983 destination[0] = convertFloatToHalfFloat(source[0]);
984 destination[1] = convertFloatToHalfFloat(source[1]);
985 destination[2] = convertFloatToHalfFloat(source[2]);
986 destination[3] = convertFloatToHalfFloat(source[3]);
987 source += 4;
988 destination += 4;
989 }
990 }
991
992 template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversi on::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destinat ion, unsigned pixelsPerRow)
993 {
994 for (unsigned i = 0; i < pixelsPerRow; ++i) {
995 float scaleFactor = source[3];
996 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
997 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
998 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
999 destination[3] = convertFloatToHalfFloat(source[3]);
1000 source += 4;
1001 destination += 4;
1002 }
1003 }
1004
1005 template<> void pack<WebGLImageConversion::DataFormatRGBA16F, WebGLImageConversi on::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destinati on, unsigned pixelsPerRow)
1006 {
1007 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1008 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1009 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1010 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1011 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1012 destination[3] = convertFloatToHalfFloat(source[3]);
1013 source += 4;
1014 destination += 4;
1015 }
1016 }
1017
1018 template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversio n::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1019 {
1020 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1021 destination[0] = convertFloatToHalfFloat(source[0]);
1022 destination[1] = convertFloatToHalfFloat(source[1]);
1023 destination[2] = convertFloatToHalfFloat(source[2]);
1024 source += 4;
1025 destination += 3;
1026 }
1027 }
1028
1029 template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversio n::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destinati on, unsigned pixelsPerRow)
1030 {
1031 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1032 float scaleFactor = source[3];
1033 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1034 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1035 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1036 source += 4;
1037 destination += 3;
1038 }
1039 }
1040
1041 template<> void pack<WebGLImageConversion::DataFormatRGB16F, WebGLImageConversio n::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destinatio n, unsigned pixelsPerRow)
1042 {
1043 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1044 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1045 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1046 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1047 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1048 source += 4;
1049 destination += 3;
1050 }
1051 }
1052
1053 template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion ::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, u nsigned pixelsPerRow)
1054 {
1055 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1056 destination[0] = convertFloatToHalfFloat(source[0]);
1057 destination[1] = convertFloatToHalfFloat(source[3]);
1058 source += 4;
1059 destination += 2;
1060 }
1061 }
1062
1063 template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion ::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destinatio n, unsigned pixelsPerRow)
1064 {
1065 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1066 float scaleFactor = source[3];
1067 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1068 destination[1] = convertFloatToHalfFloat(source[3]);
1069 source += 4;
1070 destination += 2;
1071 }
1072 }
1073
1074 template<> void pack<WebGLImageConversion::DataFormatRA16F, WebGLImageConversion ::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination , unsigned pixelsPerRow)
1075 {
1076 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1077 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1078 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1079 destination[1] = convertFloatToHalfFloat(source[3]);
1080 source += 4;
1081 destination += 2;
1082 }
1083 }
1084
1085 template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion: :AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, un signed pixelsPerRow)
1086 {
1087 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1088 destination[0] = convertFloatToHalfFloat(source[0]);
1089 source += 4;
1090 destination += 1;
1091 }
1092 }
1093
1094 template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion: :AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination , unsigned pixelsPerRow)
1095 {
1096 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1097 float scaleFactor = source[3];
1098 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1099 source += 4;
1100 destination += 1;
1101 }
1102 }
1103
1104 template<> void pack<WebGLImageConversion::DataFormatR16F, WebGLImageConversion: :AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1105 {
1106 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1107 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1108 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1109 source += 4;
1110 destination += 1;
1111 }
1112 }
1113
1114 template<> void pack<WebGLImageConversion::DataFormatA16F, WebGLImageConversion: :AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, un signed pixelsPerRow)
1115 {
1116 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1117 destination[0] = convertFloatToHalfFloat(source[3]);
1118 source += 4;
1119 destination += 1;
1120 }
1121 }
1122
1123 bool HasAlpha(int format)
1124 {
1125 return format == WebGLImageConversion::DataFormatA8
1126 || format == WebGLImageConversion::DataFormatA16F
1127 || format == WebGLImageConversion::DataFormatA32F
1128 || format == WebGLImageConversion::DataFormatRA8
1129 || format == WebGLImageConversion::DataFormatAR8
1130 || format == WebGLImageConversion::DataFormatRA16F
1131 || format == WebGLImageConversion::DataFormatRA32F
1132 || format == WebGLImageConversion::DataFormatRGBA8
1133 || format == WebGLImageConversion::DataFormatBGRA8
1134 || format == WebGLImageConversion::DataFormatARGB8
1135 || format == WebGLImageConversion::DataFormatABGR8
1136 || format == WebGLImageConversion::DataFormatRGBA16F
1137 || format == WebGLImageConversion::DataFormatRGBA32F
1138 || format == WebGLImageConversion::DataFormatRGBA4444
1139 || format == WebGLImageConversion::DataFormatRGBA5551;
1140 }
1141
1142 bool HasColor(int format)
1143 {
1144 return format == WebGLImageConversion::DataFormatRGBA8
1145 || format == WebGLImageConversion::DataFormatRGBA16F
1146 || format == WebGLImageConversion::DataFormatRGBA32F
1147 || format == WebGLImageConversion::DataFormatRGB8
1148 || format == WebGLImageConversion::DataFormatRGB16F
1149 || format == WebGLImageConversion::DataFormatRGB32F
1150 || format == WebGLImageConversion::DataFormatBGR8
1151 || format == WebGLImageConversion::DataFormatBGRA8
1152 || format == WebGLImageConversion::DataFormatARGB8
1153 || format == WebGLImageConversion::DataFormatABGR8
1154 || format == WebGLImageConversion::DataFormatRGBA5551
1155 || format == WebGLImageConversion::DataFormatRGBA4444
1156 || format == WebGLImageConversion::DataFormatRGB565
1157 || format == WebGLImageConversion::DataFormatR8
1158 || format == WebGLImageConversion::DataFormatR16F
1159 || format == WebGLImageConversion::DataFormatR32F
1160 || format == WebGLImageConversion::DataFormatRA8
1161 || format == WebGLImageConversion::DataFormatRA16F
1162 || format == WebGLImageConversion::DataFormatRA32F
1163 || format == WebGLImageConversion::DataFormatAR8;
1164 }
1165
1166 template<int Format>
1167 struct IsFloatFormat {
1168 static const bool Value =
1169 Format == WebGLImageConversion::DataFormatRGBA32F
1170 || Format == WebGLImageConversion::DataFormatRGB32F
1171 || Format == WebGLImageConversion::DataFormatRA32F
1172 || Format == WebGLImageConversion::DataFormatR32F
1173 || Format == WebGLImageConversion::DataFormatA32F;
1174 };
1175
1176 template<int Format>
1177 struct IsHalfFloatFormat {
1178 static const bool Value =
1179 Format == WebGLImageConversion::DataFormatRGBA16F
1180 || Format == WebGLImageConversion::DataFormatRGB16F
1181 || Format == WebGLImageConversion::DataFormatRA16F
1182 || Format == WebGLImageConversion::DataFormatR16F
1183 || Format == WebGLImageConversion::DataFormatA16F;
1184 };
1185
1186 template<int Format>
1187 struct Is16bppFormat {
1188 static const bool Value =
1189 Format == WebGLImageConversion::DataFormatRGBA5551
1190 || Format == WebGLImageConversion::DataFormatRGBA4444
1191 || Format == WebGLImageConversion::DataFormatRGB565;
1192 };
1193
1194 template<int Format, bool IsFloat = IsFloatFormat<Format>::Value, bool IsHalfFlo at = IsHalfFloatFormat<Format>::Value, bool Is16bpp = Is16bppFormat<Format>::Val ue>
1195 struct DataTypeForFormat {
1196 typedef uint8_t Type;
1197 };
1198
1199 template<int Format>
1200 struct DataTypeForFormat<Format, true, false, false> {
1201 typedef float Type;
1202 };
1203
1204 template<int Format>
1205 struct DataTypeForFormat<Format, false, true, false> {
1206 typedef uint16_t Type;
1207 };
1208
1209 template<int Format>
1210 struct DataTypeForFormat<Format, false, false, true> {
1211 typedef uint16_t Type;
1212 };
1213
1214 template<int Format>
1215 struct IntermediateFormat {
1216 static const int Value = (IsFloatFormat<Format>::Value || IsHalfFloatFormat< Format>::Value) ? WebGLImageConversion::DataFormatRGBA32F : WebGLImageConversion ::DataFormatRGBA8;
1217 };
1218
1219 unsigned TexelBytesForFormat(WebGLImageConversion::DataFormat format)
1220 {
1221 switch (format) {
1222 case WebGLImageConversion::DataFormatR8:
1223 case WebGLImageConversion::DataFormatA8:
1224 return 1;
1225 case WebGLImageConversion::DataFormatRA8:
1226 case WebGLImageConversion::DataFormatAR8:
1227 case WebGLImageConversion::DataFormatRGBA5551:
1228 case WebGLImageConversion::DataFormatRGBA4444:
1229 case WebGLImageConversion::DataFormatRGB565:
1230 case WebGLImageConversion::DataFormatA16F:
1231 case WebGLImageConversion::DataFormatR16F:
1232 return 2;
1233 case WebGLImageConversion::DataFormatRGB8:
1234 case WebGLImageConversion::DataFormatBGR8:
1235 return 3;
1236 case WebGLImageConversion::DataFormatRGBA8:
1237 case WebGLImageConversion::DataFormatARGB8:
1238 case WebGLImageConversion::DataFormatABGR8:
1239 case WebGLImageConversion::DataFormatBGRA8:
1240 case WebGLImageConversion::DataFormatR32F:
1241 case WebGLImageConversion::DataFormatA32F:
1242 case WebGLImageConversion::DataFormatRA16F:
1243 return 4;
1244 case WebGLImageConversion::DataFormatRGB16F:
1245 return 6;
1246 case WebGLImageConversion::DataFormatRA32F:
1247 case WebGLImageConversion::DataFormatRGBA16F:
1248 return 8;
1249 case WebGLImageConversion::DataFormatRGB32F:
1250 return 12;
1251 case WebGLImageConversion::DataFormatRGBA32F:
1252 return 16;
1253 default:
1254 return 0;
1255 }
1256 }
1257
1258 /* END CODE SHARED WITH MOZILLA FIREFOX */
1259
1260 class FormatConverter {
1261 public:
1262 FormatConverter(unsigned width, unsigned height,
1263 const void* srcStart, void* dstStart, int srcStride, int dstStride)
1264 : m_width(width), m_height(height), m_srcStart(srcStart), m_dstStart(dst Start), m_srcStride(srcStride), m_dstStride(dstStride), m_success(false)
1265 {
1266 const unsigned MaxNumberOfComponents = 4;
1267 const unsigned MaxBytesPerComponent = 4;
1268 m_unpackedIntermediateSrcData = adoptArrayPtr(new uint8_t[m_width * MaxN umberOfComponents *MaxBytesPerComponent]);
1269 ASSERT(m_unpackedIntermediateSrcData.get());
1270 }
1271
1272 void convert(WebGLImageConversion::DataFormat srcFormat, WebGLImageConversio n::DataFormat dstFormat, WebGLImageConversion::AlphaOp);
1273 bool Success() const { return m_success; }
1274
1275 private:
1276 template<WebGLImageConversion::DataFormat SrcFormat>
1277 void convert(WebGLImageConversion::DataFormat dstFormat, WebGLImageConversio n::AlphaOp);
1278
1279 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::D ataFormat DstFormat>
1280 void convert(WebGLImageConversion::AlphaOp);
1281
1282 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::D ataFormat DstFormat, WebGLImageConversion::AlphaOp alphaOp>
1283 void convert();
1284
1285 const unsigned m_width, m_height;
1286 const void* const m_srcStart;
1287 void* const m_dstStart;
1288 const int m_srcStride, m_dstStride;
1289 bool m_success;
1290 OwnPtr<uint8_t[]> m_unpackedIntermediateSrcData;
1291 };
1292
1293 void FormatConverter::convert(WebGLImageConversion::DataFormat srcFormat, WebGLI mageConversion::DataFormat dstFormat, WebGLImageConversion::AlphaOp alphaOp)
1294 {
1295 #define FORMATCONVERTER_CASE_SRCFORMAT(SrcFormat) \
1296 case SrcFormat: \
1297 return convert<SrcFormat>(dstFormat, alphaOp);
1298
1299 switch (srcFormat) {
1300 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatR8)
1301 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatA8)
1302 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatR32F)
1303 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatA32F)
1304 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRA8)
1305 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRA32F )
1306 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB8)
1307 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatBGR8)
1308 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB56 5)
1309 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGB32 F)
1310 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA8 )
1311 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatARGB8 )
1312 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatABGR8 )
1313 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatAR8)
1314 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatBGRA8 )
1315 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA5 551)
1316 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA4 444)
1317 FORMATCONVERTER_CASE_SRCFORMAT(WebGLImageConversion::DataFormatRGBA3 2F)
1318 default:
1319 ASSERT_NOT_REACHED();
1320 }
1321 #undef FORMATCONVERTER_CASE_SRCFORMAT
1322 }
1323
1324 template<WebGLImageConversion::DataFormat SrcFormat>
1325 void FormatConverter::convert(WebGLImageConversion::DataFormat dstFormat, WebGLI mageConversion::AlphaOp alphaOp)
1326 {
1327 #define FORMATCONVERTER_CASE_DSTFORMAT(DstFormat) \
1328 case DstFormat: \
1329 return convert<SrcFormat, DstFormat>(alphaOp);
1330
1331 switch (dstFormat) {
1332 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR8)
1333 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR16F)
1334 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatR32F)
1335 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA8)
1336 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA16F)
1337 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatA32F)
1338 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA8)
1339 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA16F )
1340 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRA32F )
1341 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB8)
1342 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB56 5)
1343 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB16 F)
1344 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGB32 F)
1345 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA8 )
1346 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA5 551)
1347 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA4 444)
1348 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA1 6F)
1349 FORMATCONVERTER_CASE_DSTFORMAT(WebGLImageConversion::DataFormatRGBA3 2F)
1350 default:
1351 ASSERT_NOT_REACHED();
1352 }
1353
1354 #undef FORMATCONVERTER_CASE_DSTFORMAT
1355 }
1356
1357 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataF ormat DstFormat>
1358 void FormatConverter::convert(WebGLImageConversion::AlphaOp alphaOp)
1359 {
1360 #define FORMATCONVERTER_CASE_ALPHAOP(alphaOp) \
1361 case alphaOp: \
1362 return convert<SrcFormat, DstFormat, alphaOp>();
1363
1364 switch (alphaOp) {
1365 FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoNothing)
1366 FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoPremultipl y)
1367 FORMATCONVERTER_CASE_ALPHAOP(WebGLImageConversion::AlphaDoUnmultiply )
1368 default:
1369 ASSERT_NOT_REACHED();
1370 }
1371 #undef FORMATCONVERTER_CASE_ALPHAOP
1372 }
1373
1374 template<WebGLImageConversion::DataFormat SrcFormat, WebGLImageConversion::DataF ormat DstFormat, WebGLImageConversion::AlphaOp alphaOp>
1375 void FormatConverter::convert()
1376 {
1377 // Many instantiations of this template function will never be entered, so w e try
1378 // to return immediately in these cases to avoid the compiler to generate us eless code.
1379 if (SrcFormat == DstFormat && alphaOp == WebGLImageConversion::AlphaDoNothin g) {
1380 ASSERT_NOT_REACHED();
1381 return;
1382 }
1383 if (!IsFloatFormat<DstFormat>::Value && IsFloatFormat<SrcFormat>::Value) {
1384 ASSERT_NOT_REACHED();
1385 return;
1386 }
1387
1388 // Only textures uploaded from DOM elements or ImageData can allow DstFormat != SrcFormat.
1389 const bool srcFormatComesFromDOMElementOrImageData = WebGLImageConversion::s rcFormatComeFromDOMElementOrImageData(SrcFormat);
1390 if (!srcFormatComesFromDOMElementOrImageData && SrcFormat != DstFormat) {
1391 ASSERT_NOT_REACHED();
1392 return;
1393 }
1394 // Likewise, only textures uploaded from DOM elements or ImageData can possi bly have to be unpremultiplied.
1395 if (!srcFormatComesFromDOMElementOrImageData && alphaOp == WebGLImageConvers ion::AlphaDoUnmultiply) {
1396 ASSERT_NOT_REACHED();
1397 return;
1398 }
1399 if ((!HasAlpha(SrcFormat) || !HasColor(SrcFormat) || !HasColor(DstFormat)) & & alphaOp != WebGLImageConversion::AlphaDoNothing) {
1400 ASSERT_NOT_REACHED();
1401 return;
1402 }
1403
1404 typedef typename DataTypeForFormat<SrcFormat>::Type SrcType;
1405 typedef typename DataTypeForFormat<DstFormat>::Type DstType;
1406 const int IntermediateSrcFormat = IntermediateFormat<DstFormat>::Value;
1407 typedef typename DataTypeForFormat<IntermediateSrcFormat>::Type Intermediate SrcType;
1408 const ptrdiff_t srcStrideInElements = m_srcStride / sizeof(SrcType);
1409 const ptrdiff_t dstStrideInElements = m_dstStride / sizeof(DstType);
1410 const bool trivialUnpack = (SrcFormat == WebGLImageConversion::DataFormatRGB A8 && !IsFloatFormat<DstFormat>::Value && !IsHalfFloatFormat<DstFormat>::Value) || SrcFormat == WebGLImageConversion::DataFormatRGBA32F;
1411 const bool trivialPack = (DstFormat == WebGLImageConversion::DataFormatRGBA8 || DstFormat == WebGLImageConversion::DataFormatRGBA32F) && alphaOp == WebGLIma geConversion::AlphaDoNothing && m_dstStride > 0;
1412 ASSERT(!trivialUnpack || !trivialPack);
1413
1414 const SrcType *srcRowStart = static_cast<const SrcType*>(m_srcStart);
1415 DstType* dstRowStart = static_cast<DstType*>(m_dstStart);
1416 if (!trivialUnpack && trivialPack) {
1417 for (size_t i = 0; i < m_height; ++i) {
1418 unpack<SrcFormat>(srcRowStart, dstRowStart, m_width);
1419 srcRowStart += srcStrideInElements;
1420 dstRowStart += dstStrideInElements;
1421 }
1422 } else if (!trivialUnpack && !trivialPack) {
1423 for (size_t i = 0; i < m_height; ++i) {
1424 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermediateSrcType* >(m_unpackedIntermediateSrcData.get()), m_width);
1425 pack<DstFormat, alphaOp>(reinterpret_cast<IntermediateSrcType*>(m_un packedIntermediateSrcData.get()), dstRowStart, m_width);
1426 srcRowStart += srcStrideInElements;
1427 dstRowStart += dstStrideInElements;
1428 }
1429 } else {
1430 for (size_t i = 0; i < m_height; ++i) {
1431 pack<DstFormat, alphaOp>(srcRowStart, dstRowStart, m_width);
1432 srcRowStart += srcStrideInElements;
1433 dstRowStart += dstStrideInElements;
1434 }
1435 }
1436 m_success = true;
1437 return;
1438 }
1439
1440 } // anonymous namespace
1441
1442 bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent)
1443 {
1444 switch (format) {
1445 case GL_ALPHA:
1446 case GL_LUMINANCE:
1447 case GL_DEPTH_COMPONENT:
1448 case GL_DEPTH_STENCIL_OES:
1449 *componentsPerPixel = 1;
1450 break;
1451 case GL_LUMINANCE_ALPHA:
1452 *componentsPerPixel = 2;
1453 break;
1454 case GL_RGB:
1455 *componentsPerPixel = 3;
1456 break;
1457 case GL_RGBA:
1458 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888
1459 *componentsPerPixel = 4;
1460 break;
1461 default:
1462 return false;
1463 }
1464 switch (type) {
1465 case GL_UNSIGNED_BYTE:
1466 *bytesPerComponent = sizeof(GLubyte);
1467 break;
1468 case GL_UNSIGNED_SHORT:
1469 *bytesPerComponent = sizeof(GLushort);
1470 break;
1471 case GL_UNSIGNED_SHORT_5_6_5:
1472 case GL_UNSIGNED_SHORT_4_4_4_4:
1473 case GL_UNSIGNED_SHORT_5_5_5_1:
1474 *componentsPerPixel = 1;
1475 *bytesPerComponent = sizeof(GLushort);
1476 break;
1477 case GL_UNSIGNED_INT_24_8_OES:
1478 case GL_UNSIGNED_INT:
1479 *bytesPerComponent = sizeof(GLuint);
1480 break;
1481 case GL_FLOAT: // OES_texture_float
1482 *bytesPerComponent = sizeof(GLfloat);
1483 break;
1484 case GL_HALF_FLOAT_OES: // OES_texture_half_float
1485 *bytesPerComponent = sizeof(GLushort);
1486 break;
1487 default:
1488 return false;
1489 }
1490 return true;
1491 }
1492
1493 GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLint alignment, unsigned* imageSizeInBytes, uns igned* paddingInBytes)
1494 {
1495 ASSERT(imageSizeInBytes);
1496 ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8) ;
1497 if (width < 0 || height < 0)
1498 return GL_INVALID_VALUE;
1499 unsigned bytesPerComponent, componentsPerPixel;
1500 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &compo nentsPerPixel))
1501 return GL_INVALID_ENUM;
1502 if (!width || !height) {
1503 *imageSizeInBytes = 0;
1504 if (paddingInBytes)
1505 *paddingInBytes = 0;
1506 return GL_NO_ERROR;
1507 }
1508 CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel);
1509 checkedValue *= width;
1510 if (!checkedValue.isValid())
1511 return GL_INVALID_VALUE;
1512 unsigned validRowSize = checkedValue.value();
1513 unsigned padding = 0;
1514 unsigned residual = validRowSize % alignment;
1515 if (residual) {
1516 padding = alignment - residual;
1517 checkedValue += padding;
1518 }
1519 // Last row needs no padding.
1520 checkedValue *= (height - 1);
1521 checkedValue += validRowSize;
1522 if (!checkedValue.isValid())
1523 return GL_INVALID_VALUE;
1524 *imageSizeInBytes = checkedValue.value();
1525 if (paddingInBytes)
1526 *paddingInBytes = padding;
1527 return GL_NO_ERROR;
1528 }
1529
1530 WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomS ource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile )
1531 {
1532 m_image = image;
1533 m_imageHtmlDomSource = imageHtmlDomSource;
1534 m_extractSucceeded = extractImage(premultiplyAlpha, ignoreGammaAndColorProfi le);
1535 }
1536
1537 WebGLImageConversion::ImageExtractor::~ImageExtractor()
1538 {
1539 if (m_skiaImage)
1540 m_skiaImage->bitmap().unlockPixels();
1541 }
1542
1543 bool WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, b ool ignoreGammaAndColorProfile)
1544 {
1545 if (!m_image)
1546 return false;
1547 m_skiaImage = m_image->nativeImageForCurrentFrame();
1548 m_alphaOp = AlphaDoNothing;
1549 bool hasAlpha = m_skiaImage ? !m_skiaImage->bitmap().isOpaque() : true;
1550 if ((!m_skiaImage || ignoreGammaAndColorProfile || (hasAlpha && !premultiply Alpha)) && m_image->data()) {
1551 // Attempt to get raw unpremultiplied image data.
1552 OwnPtr<ImageDecoder> decoder(ImageDecoder::create(
1553 *(m_image->data()), ImageSource::AlphaNotPremultiplied,
1554 ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnore d : ImageSource::GammaAndColorProfileApplied));
1555 if (!decoder)
1556 return false;
1557 decoder->setData(m_image->data(), true);
1558 if (!decoder->frameCount())
1559 return false;
1560 ImageFrame* frame = decoder->frameBufferAtIndex(0);
1561 if (!frame || frame->status() != ImageFrame::FrameComplete)
1562 return false;
1563 hasAlpha = frame->hasAlpha();
1564 m_nativeImage = frame->asNewNativeImage();
1565 if (!m_nativeImage.get() || !m_nativeImage->isDataComplete() || !m_nativ eImage->bitmap().width() || !m_nativeImage->bitmap().height())
1566 return false;
1567 if (m_nativeImage->bitmap().colorType() != kN32_SkColorType)
1568 return false;
1569 m_skiaImage = m_nativeImage.get();
1570 if (hasAlpha && premultiplyAlpha)
1571 m_alphaOp = AlphaDoPremultiply;
1572 } else if (!premultiplyAlpha && hasAlpha) {
1573 // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAl pha had been applied and the alpha value for each pixel is 0xFF
1574 // which is true at present and may be changed in the future and needs a djustment accordingly.
1575 // 2. For texImage2D with HTMLCanvasElement input in which Alpha is alre ady Premultiplied in this port,
1576 // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to fals e.
1577 if (m_imageHtmlDomSource != HtmlDomVideo)
1578 m_alphaOp = AlphaDoUnmultiply;
1579 }
1580 if (!m_skiaImage)
1581 return false;
1582
1583 m_imageSourceFormat = SK_B32_SHIFT ? DataFormatRGBA8 : DataFormatBGRA8;
1584 m_imageWidth = m_skiaImage->bitmap().width();
1585 m_imageHeight = m_skiaImage->bitmap().height();
1586 if (!m_imageWidth || !m_imageHeight) {
1587 m_skiaImage.clear();
1588 return false;
1589 }
1590 // Fail if the image was downsampled because of memory limits.
1591 if (m_imageWidth != (unsigned)m_image->size().width() || m_imageHeight != (u nsigned)m_image->size().height()) {
1592 m_skiaImage.clear();
1593 return false;
1594 }
1595 m_imageSourceUnpackAlignment = 0;
1596 m_skiaImage->bitmap().lockPixels();
1597 m_imagePixelData = m_skiaImage->bitmap().getPixels();
1598 return true;
1599 }
1600
1601 unsigned WebGLImageConversion::getClearBitsByFormat(GLenum format)
1602 {
1603 switch (format) {
1604 case GL_ALPHA:
1605 case GL_LUMINANCE:
1606 case GL_LUMINANCE_ALPHA:
1607 case GL_RGB:
1608 case GL_RGB565:
1609 case GL_RGBA:
1610 case GL_RGBA4:
1611 case GL_RGB5_A1:
1612 return GL_COLOR_BUFFER_BIT;
1613 case GL_DEPTH_COMPONENT16:
1614 case GL_DEPTH_COMPONENT:
1615 return GL_DEPTH_BUFFER_BIT;
1616 case GL_STENCIL_INDEX8:
1617 return GL_STENCIL_BUFFER_BIT;
1618 case GL_DEPTH_STENCIL_OES:
1619 return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
1620 default:
1621 return 0;
1622 }
1623 }
1624
1625 unsigned WebGLImageConversion::getChannelBitsByFormat(GLenum format)
1626 {
1627 switch (format) {
1628 case GL_ALPHA:
1629 return ChannelAlpha;
1630 case GL_LUMINANCE:
1631 return ChannelRGB;
1632 case GL_LUMINANCE_ALPHA:
1633 return ChannelRGBA;
1634 case GL_RGB:
1635 case GL_RGB565:
1636 return ChannelRGB;
1637 case GL_RGBA:
1638 case GL_RGBA4:
1639 case GL_RGB5_A1:
1640 return ChannelRGBA;
1641 case GL_DEPTH_COMPONENT16:
1642 case GL_DEPTH_COMPONENT:
1643 return ChannelDepth;
1644 case GL_STENCIL_INDEX8:
1645 return ChannelStencil;
1646 case GL_DEPTH_STENCIL_OES:
1647 return ChannelDepth | ChannelStencil;
1648 default:
1649 return 0;
1650 }
1651 }
1652
1653 bool WebGLImageConversion::packImageData(
1654 Image* image,
1655 const void* pixels,
1656 GLenum format,
1657 GLenum type,
1658 bool flipY,
1659 AlphaOp alphaOp,
1660 DataFormat sourceFormat,
1661 unsigned width,
1662 unsigned height,
1663 unsigned sourceUnpackAlignment,
1664 Vector<uint8_t>& data)
1665 {
1666 if (!pixels)
1667 return false;
1668
1669 unsigned packedSize;
1670 // Output data is tightly packed (alignment == 1).
1671 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
1672 return false;
1673 data.resize(packedSize);
1674
1675 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, widt h, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY))
1676 return false;
1677 if (ImageObserver *observer = image->imageObserver())
1678 observer->didDraw(image);
1679 return true;
1680 }
1681
1682 bool WebGLImageConversion::extractImageData(
1683 const uint8_t* imageData,
1684 const IntSize& imageDataSize,
1685 GLenum format,
1686 GLenum type,
1687 bool flipY,
1688 bool premultiplyAlpha,
1689 Vector<uint8_t>& data)
1690 {
1691 if (!imageData)
1692 return false;
1693 int width = imageDataSize.width();
1694 int height = imageDataSize.height();
1695
1696 unsigned packedSize;
1697 // Output data is tightly packed (alignment == 1).
1698 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
1699 return false;
1700 data.resize(packedSize);
1701
1702 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY))
1703 return false;
1704
1705 return true;
1706 }
1707
1708 bool WebGLImageConversion::extractTextureData(
1709 unsigned width,
1710 unsigned height,
1711 GLenum format, GLenum type,
1712 unsigned unpackAlignment,
1713 bool flipY, bool premultiplyAlpha,
1714 const void* pixels,
1715 Vector<uint8_t>& data)
1716 {
1717 // Assumes format, type, etc. have already been validated.
1718 DataFormat sourceDataFormat = getDataFormat(format, type);
1719
1720 // Resize the output buffer.
1721 unsigned int componentsPerPixel, bytesPerComponent;
1722 if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &byte sPerComponent))
1723 return false;
1724 unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent;
1725 data.resize(width * height * bytesPerPixel);
1726
1727 if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width , height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), data.data(), flipY))
1728 return false;
1729
1730 return true;
1731 }
1732
1733 bool WebGLImageConversion::packPixels(
1734 const uint8_t* sourceData,
1735 DataFormat sourceDataFormat,
1736 unsigned width,
1737 unsigned height,
1738 unsigned sourceUnpackAlignment,
1739 unsigned destinationFormat,
1740 unsigned destinationType,
1741 AlphaOp alphaOp,
1742 void* destinationData,
1743 bool flipY)
1744 {
1745 int validSrc = width * TexelBytesForFormat(sourceDataFormat);
1746 int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
1747 int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
1748
1749 DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType) ;
1750 int dstStride = width * TexelBytesForFormat(dstDataFormat);
1751 if (flipY) {
1752 destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(he ight - 1);
1753 dstStride = -dstStride;
1754 }
1755 if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || !HasColor( dstDataFormat))
1756 alphaOp = AlphaDoNothing;
1757
1758 if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) {
1759 const uint8_t* ptr = sourceData;
1760 const uint8_t* ptrEnd = sourceData + srcStride * height;
1761 unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride;
1762 uint8_t* dst = static_cast<uint8_t*>(destinationData);
1763 while (ptr < ptrEnd) {
1764 memcpy(dst, ptr, rowSize);
1765 ptr += srcStride;
1766 dst += dstStride;
1767 }
1768 return true;
1769 }
1770
1771 FormatConverter converter(width, height, sourceData, destinationData, srcStr ide, dstStride);
1772 converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
1773 if (!converter.Success())
1774 return false;
1775 return true;
1776 }
1777
1778 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/platform/graphics/gpu/WebGLImageConversion.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698