OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | |
3 * Copyright (C) 2010 Mozilla Corporation. All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright | |
11 * notice, this list of conditions and the following disclaimer in the | |
12 * documentation and/or other materials provided with the distribution. | |
13 * | |
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 */ | |
26 | |
27 #include "config.h" | |
28 #include "core/platform/graphics/GraphicsContext3D.h" | |
29 | |
30 #include "core/platform/graphics/cpu/arm/GraphicsContext3DNEON.h" | |
31 #include "core/platform/image-decoders/ImageDecoder.h" | |
32 #include "platform/graphics/ImageObserver.h" | |
33 | |
34 namespace WebCore { | |
35 | |
36 namespace { | |
37 | |
38 GraphicsContext3D::DataFormat getDataFormat(GC3Denum destinationFormat, GC3Denum
destinationType) | |
39 { | |
40 GraphicsContext3D::DataFormat dstFormat = GraphicsContext3D::DataFormatRGBA8
; | |
41 switch (destinationType) { | |
42 case GraphicsContext3D::UNSIGNED_BYTE: | |
43 switch (destinationFormat) { | |
44 case GraphicsContext3D::RGB: | |
45 dstFormat = GraphicsContext3D::DataFormatRGB8; | |
46 break; | |
47 case GraphicsContext3D::RGBA: | |
48 dstFormat = GraphicsContext3D::DataFormatRGBA8; | |
49 break; | |
50 case GraphicsContext3D::ALPHA: | |
51 dstFormat = GraphicsContext3D::DataFormatA8; | |
52 break; | |
53 case GraphicsContext3D::LUMINANCE: | |
54 dstFormat = GraphicsContext3D::DataFormatR8; | |
55 break; | |
56 case GraphicsContext3D::LUMINANCE_ALPHA: | |
57 dstFormat = GraphicsContext3D::DataFormatRA8; | |
58 break; | |
59 default: | |
60 ASSERT_NOT_REACHED(); | |
61 } | |
62 break; | |
63 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: | |
64 dstFormat = GraphicsContext3D::DataFormatRGBA4444; | |
65 break; | |
66 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: | |
67 dstFormat = GraphicsContext3D::DataFormatRGBA5551; | |
68 break; | |
69 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: | |
70 dstFormat = GraphicsContext3D::DataFormatRGB565; | |
71 break; | |
72 case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float | |
73 switch (destinationFormat) { | |
74 case GraphicsContext3D::RGB: | |
75 dstFormat = GraphicsContext3D::DataFormatRGB16F; | |
76 break; | |
77 case GraphicsContext3D::RGBA: | |
78 dstFormat = GraphicsContext3D::DataFormatRGBA16F; | |
79 break; | |
80 case GraphicsContext3D::ALPHA: | |
81 dstFormat = GraphicsContext3D::DataFormatA16F; | |
82 break; | |
83 case GraphicsContext3D::LUMINANCE: | |
84 dstFormat = GraphicsContext3D::DataFormatR16F; | |
85 break; | |
86 case GraphicsContext3D::LUMINANCE_ALPHA: | |
87 dstFormat = GraphicsContext3D::DataFormatRA16F; | |
88 break; | |
89 default: | |
90 ASSERT_NOT_REACHED(); | |
91 } | |
92 break; | |
93 case GraphicsContext3D::FLOAT: // OES_texture_float | |
94 switch (destinationFormat) { | |
95 case GraphicsContext3D::RGB: | |
96 dstFormat = GraphicsContext3D::DataFormatRGB32F; | |
97 break; | |
98 case GraphicsContext3D::RGBA: | |
99 dstFormat = GraphicsContext3D::DataFormatRGBA32F; | |
100 break; | |
101 case GraphicsContext3D::ALPHA: | |
102 dstFormat = GraphicsContext3D::DataFormatA32F; | |
103 break; | |
104 case GraphicsContext3D::LUMINANCE: | |
105 dstFormat = GraphicsContext3D::DataFormatR32F; | |
106 break; | |
107 case GraphicsContext3D::LUMINANCE_ALPHA: | |
108 dstFormat = GraphicsContext3D::DataFormatRA32F; | |
109 break; | |
110 default: | |
111 ASSERT_NOT_REACHED(); | |
112 } | |
113 break; | |
114 default: | |
115 ASSERT_NOT_REACHED(); | |
116 } | |
117 return dstFormat; | |
118 } | |
119 | |
120 // Following Float to Half-Float converion code is from the implementation of ft
p://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf, | |
121 // "Fast Half Float Conversions" by Jeroen van der Zijp, November 2008 (Revised
September 2010). | |
122 // Specially, the basetable[512] and shifttable[512] are generated as follows: | |
123 /* | |
124 unsigned short basetable[512]; | |
125 unsigned char shifttable[512]; | |
126 | |
127 void generatetables(){ | |
128 unsigned int i; | |
129 int e; | |
130 for (i = 0; i < 256; ++i){ | |
131 e = i - 127; | |
132 if (e < -24){ // Very small numbers map to zero | |
133 basetable[i | 0x000] = 0x0000; | |
134 basetable[i | 0x100] = 0x8000; | |
135 shifttable[i | 0x000] = 24; | |
136 shifttable[i | 0x100] = 24; | |
137 } | |
138 else if (e < -14) { // Small numbers map to denorms | |
139 basetable[i | 0x000] = (0x0400>>(-e-14)); | |
140 basetable[i | 0x100] = (0x0400>>(-e-14)) | 0x8000; | |
141 shifttable[i | 0x000] = -e-1; | |
142 shifttable[i | 0x100] = -e-1; | |
143 } | |
144 else if (e <= 15){ // Normal numbers just lose precision | |
145 basetable[i | 0x000] = ((e+15)<<10); | |
146 basetable[i| 0x100] = ((e+15)<<10) | 0x8000; | |
147 shifttable[i|0x000] = 13; | |
148 shifttable[i|0x100] = 13; | |
149 } | |
150 else if (e<128){ // Large numbers map to Infinity | |
151 basetable[i|0x000] = 0x7C00; | |
152 basetable[i|0x100] = 0xFC00; | |
153 shifttable[i|0x000] = 24; | |
154 shifttable[i|0x100] = 24; | |
155 } | |
156 else { // Infinity and NaN's stay Infinity and NaN's | |
157 basetable[i|0x000] = 0x7C00; | |
158 basetable[i|0x100] = 0xFC00; | |
159 shifttable[i|0x000] = 13; | |
160 shifttable[i|0x100] = 13; | |
161 } | |
162 } | |
163 } | |
164 */ | |
165 | |
166 unsigned short baseTable[512] = { | |
167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, | |
168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, | |
169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, | |
170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, | |
171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, | |
172 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, | |
173 0, 0, 0, 0, 0, 0, 0, 1, 2, 4,
8, 16, 32, 64, 128, 256, | |
174 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216,
10240, 11264, 12288, 13312, 14336, 15360, | |
175 16384, 17408, 18432, 19456, 20480, 21504, 22528, 23552, 24576, 25600,
26624, 27648, 28672, 29696, 30720, 31744, | |
176 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
31744, 31744, 31744, 31744, 31744, 31744, | |
177 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
31744, 31744, 31744, 31744, 31744, 31744, | |
178 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
31744, 31744, 31744, 31744, 31744, 31744, | |
179 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
31744, 31744, 31744, 31744, 31744, 31744, | |
180 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
31744, 31744, 31744, 31744, 31744, 31744, | |
181 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
31744, 31744, 31744, 31744, 31744, 31744, | |
182 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
31744, 31744, 31744, 31744, 31744, 31744, | |
183 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
32768, 32768, 32768, 32768, 32768, 32768, | |
184 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
32768, 32768, 32768, 32768, 32768, 32768, | |
185 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
32768, 32768, 32768, 32768, 32768, 32768, | |
186 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
32768, 32768, 32768, 32768, 32768, 32768, | |
187 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
32768, 32768, 32768, 32768, 32768, 32768, | |
188 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
32768, 32768, 32768, 32768, 32768, 32768, | |
189 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32769, 32770, 32772,
32776, 32784, 32800, 32832, 32896, 33024, | |
190 33280, 33792, 34816, 35840, 36864, 37888, 38912, 39936, 40960, 41984,
43008, 44032, 45056, 46080, 47104, 48128, | |
191 49152, 50176, 51200, 52224, 53248, 54272, 55296, 56320, 57344, 58368,
59392, 60416, 61440, 62464, 63488, 64512, | |
192 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
64512, 64512, 64512, 64512, 64512, 64512, | |
193 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
64512, 64512, 64512, 64512, 64512, 64512, | |
194 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
64512, 64512, 64512, 64512, 64512, 64512, | |
195 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
64512, 64512, 64512, 64512, 64512, 64512, | |
196 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
64512, 64512, 64512, 64512, 64512, 64512, | |
197 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
64512, 64512, 64512, 64512, 64512, 64512, | |
198 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
64512, 64512, 64512, 64512, 64512, 64512 | |
199 }; | |
200 | |
201 unsigned char shiftTable[512] = { | |
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, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
205 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
206 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 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, 23, 22, 21,
20, 19, 18, 17, 16, 15, | |
209 14, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, | |
210 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 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, 24, | |
214 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
215 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
216 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
217 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 13, | |
218 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
219 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
220 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
221 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
222 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
223 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
224 24, 24, 24, 24, 24, 24, 24, 23, 22, 21,
20, 19, 18, 17, 16, 15, | |
225 14, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, | |
226 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 24, | |
227 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
228 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
229 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
230 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
231 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
232 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, | |
233 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 13 | |
234 }; | |
235 | |
236 unsigned short convertFloatToHalfFloat(float f) | |
237 { | |
238 unsigned temp = *(reinterpret_cast<unsigned *>(&f)); | |
239 unsigned signexp = (temp >> 23) & 0x1ff; | |
240 return baseTable[signexp] + ((temp & 0x007fffff) >> shiftTable[signexp]); | |
241 } | |
242 | |
243 /* BEGIN CODE SHARED WITH MOZILLA FIREFOX */ | |
244 | |
245 // The following packing and unpacking routines are expressed in terms of functi
on templates and inline functions to achieve generality and speedup. | |
246 // Explicit template specializations correspond to the cases that would occur. | |
247 // Some code are merged back from Mozilla code in http://mxr.mozilla.org/mozilla
-central/source/content/canvas/src/WebGLTexelConversions.h | |
248 | |
249 //---------------------------------------------------------------------- | |
250 // Pixel unpacking routines. | |
251 template<int format, typename SourceType, typename DstType> | |
252 void unpack(const SourceType*, DstType*, unsigned) | |
253 { | |
254 ASSERT_NOT_REACHED(); | |
255 } | |
256 | |
257 template<> void unpack<GraphicsContext3D::DataFormatRGB8, uint8_t, uint8_t>(cons
t uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
258 { | |
259 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
260 destination[0] = source[0]; | |
261 destination[1] = source[1]; | |
262 destination[2] = source[2]; | |
263 destination[3] = 0xFF; | |
264 source += 3; | |
265 destination += 4; | |
266 } | |
267 } | |
268 | |
269 template<> void unpack<GraphicsContext3D::DataFormatBGR8, uint8_t, uint8_t>(cons
t uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
270 { | |
271 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
272 destination[0] = source[2]; | |
273 destination[1] = source[1]; | |
274 destination[2] = source[0]; | |
275 destination[3] = 0xFF; | |
276 source += 3; | |
277 destination += 4; | |
278 } | |
279 } | |
280 | |
281 template<> void unpack<GraphicsContext3D::DataFormatARGB8, uint8_t, uint8_t>(con
st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
282 { | |
283 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
284 destination[0] = source[1]; | |
285 destination[1] = source[2]; | |
286 destination[2] = source[3]; | |
287 destination[3] = source[0]; | |
288 source += 4; | |
289 destination += 4; | |
290 } | |
291 } | |
292 | |
293 template<> void unpack<GraphicsContext3D::DataFormatABGR8, uint8_t, uint8_t>(con
st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
294 { | |
295 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
296 destination[0] = source[3]; | |
297 destination[1] = source[2]; | |
298 destination[2] = source[1]; | |
299 destination[3] = source[0]; | |
300 source += 4; | |
301 destination += 4; | |
302 } | |
303 } | |
304 | |
305 template<> void unpack<GraphicsContext3D::DataFormatBGRA8, uint8_t, uint8_t>(con
st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
306 { | |
307 const uint32_t* source32 = reinterpret_cast_ptr<const uint32_t*>(source); | |
308 uint32_t* destination32 = reinterpret_cast_ptr<uint32_t*>(destination); | |
309 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
310 uint32_t bgra = source32[i]; | |
311 #if CPU(BIG_ENDIAN) | |
312 uint32_t brMask = 0xff00ff00; | |
313 uint32_t gaMask = 0x00ff00ff; | |
314 #else | |
315 uint32_t brMask = 0x00ff00ff; | |
316 uint32_t gaMask = 0xff00ff00; | |
317 #endif | |
318 uint32_t rgba = (((bgra >> 16) | (bgra << 16)) & brMask) | (bgra & gaMas
k); | |
319 destination32[i] = rgba; | |
320 } | |
321 } | |
322 | |
323 template<> void unpack<GraphicsContext3D::DataFormatRGBA5551, uint16_t, uint8_t>
(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
324 { | |
325 #if HAVE(ARM_NEON_INTRINSICS) | |
326 SIMD::unpackOneRowOfRGBA5551ToRGBA8(source, destination, pixelsPerRow); | |
327 #endif | |
328 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
329 uint16_t packedValue = source[0]; | |
330 uint8_t r = packedValue >> 11; | |
331 uint8_t g = (packedValue >> 6) & 0x1F; | |
332 uint8_t b = (packedValue >> 1) & 0x1F; | |
333 destination[0] = (r << 3) | (r & 0x7); | |
334 destination[1] = (g << 3) | (g & 0x7); | |
335 destination[2] = (b << 3) | (b & 0x7); | |
336 destination[3] = (packedValue & 0x1) ? 0xFF : 0x0; | |
337 source += 1; | |
338 destination += 4; | |
339 } | |
340 } | |
341 | |
342 template<> void unpack<GraphicsContext3D::DataFormatRGBA4444, uint16_t, uint8_t>
(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
343 { | |
344 #if HAVE(ARM_NEON_INTRINSICS) | |
345 SIMD::unpackOneRowOfRGBA4444ToRGBA8(source, destination, pixelsPerRow); | |
346 #endif | |
347 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
348 uint16_t packedValue = source[0]; | |
349 uint8_t r = packedValue >> 12; | |
350 uint8_t g = (packedValue >> 8) & 0x0F; | |
351 uint8_t b = (packedValue >> 4) & 0x0F; | |
352 uint8_t a = packedValue & 0x0F; | |
353 destination[0] = r << 4 | r; | |
354 destination[1] = g << 4 | g; | |
355 destination[2] = b << 4 | b; | |
356 destination[3] = a << 4 | a; | |
357 source += 1; | |
358 destination += 4; | |
359 } | |
360 } | |
361 | |
362 template<> void unpack<GraphicsContext3D::DataFormatRGB565, uint16_t, uint8_t>(c
onst uint16_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
363 { | |
364 #if HAVE(ARM_NEON_INTRINSICS) | |
365 SIMD::unpackOneRowOfRGB565ToRGBA8(source, destination, pixelsPerRow); | |
366 #endif | |
367 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
368 uint16_t packedValue = source[0]; | |
369 uint8_t r = packedValue >> 11; | |
370 uint8_t g = (packedValue >> 5) & 0x3F; | |
371 uint8_t b = packedValue & 0x1F; | |
372 destination[0] = (r << 3) | (r & 0x7); | |
373 destination[1] = (g << 2) | (g & 0x3); | |
374 destination[2] = (b << 3) | (b & 0x7); | |
375 destination[3] = 0xFF; | |
376 source += 1; | |
377 destination += 4; | |
378 } | |
379 } | |
380 | |
381 template<> void unpack<GraphicsContext3D::DataFormatR8, uint8_t, uint8_t>(const
uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
382 { | |
383 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
384 destination[0] = source[0]; | |
385 destination[1] = source[0]; | |
386 destination[2] = source[0]; | |
387 destination[3] = 0xFF; | |
388 source += 1; | |
389 destination += 4; | |
390 } | |
391 } | |
392 | |
393 template<> void unpack<GraphicsContext3D::DataFormatRA8, uint8_t, uint8_t>(const
uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
394 { | |
395 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
396 destination[0] = source[0]; | |
397 destination[1] = source[0]; | |
398 destination[2] = source[0]; | |
399 destination[3] = source[1]; | |
400 source += 2; | |
401 destination += 4; | |
402 } | |
403 } | |
404 | |
405 template<> void unpack<GraphicsContext3D::DataFormatAR8, uint8_t, uint8_t>(const
uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
406 { | |
407 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
408 destination[0] = source[1]; | |
409 destination[1] = source[1]; | |
410 destination[2] = source[1]; | |
411 destination[3] = source[0]; | |
412 source += 2; | |
413 destination += 4; | |
414 } | |
415 } | |
416 | |
417 template<> void unpack<GraphicsContext3D::DataFormatA8, uint8_t, uint8_t>(const
uint8_t* source, uint8_t* destination, unsigned pixelsPerRow) | |
418 { | |
419 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
420 destination[0] = 0x0; | |
421 destination[1] = 0x0; | |
422 destination[2] = 0x0; | |
423 destination[3] = source[0]; | |
424 source += 1; | |
425 destination += 4; | |
426 } | |
427 } | |
428 | |
429 template<> void unpack<GraphicsContext3D::DataFormatRGBA8, uint8_t, float>(const
uint8_t* source, float* destination, unsigned pixelsPerRow) | |
430 { | |
431 const float scaleFactor = 1.0f / 255.0f; | |
432 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
433 destination[0] = source[0] * scaleFactor; | |
434 destination[1] = source[1] * scaleFactor; | |
435 destination[2] = source[2] * scaleFactor; | |
436 destination[3] = source[3] * scaleFactor; | |
437 source += 4; | |
438 destination += 4; | |
439 } | |
440 } | |
441 | |
442 template<> void unpack<GraphicsContext3D::DataFormatBGRA8, uint8_t, float>(const
uint8_t* source, float* destination, unsigned pixelsPerRow) | |
443 { | |
444 const float scaleFactor = 1.0f / 255.0f; | |
445 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
446 destination[0] = source[2] * scaleFactor; | |
447 destination[1] = source[1] * scaleFactor; | |
448 destination[2] = source[0] * scaleFactor; | |
449 destination[3] = source[3] * scaleFactor; | |
450 source += 4; | |
451 destination += 4; | |
452 } | |
453 } | |
454 | |
455 template<> void unpack<GraphicsContext3D::DataFormatABGR8, uint8_t, float>(const
uint8_t* source, float* destination, unsigned pixelsPerRow) | |
456 { | |
457 const float scaleFactor = 1.0f / 255.0f; | |
458 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
459 destination[0] = source[3] * scaleFactor; | |
460 destination[1] = source[2] * scaleFactor; | |
461 destination[2] = source[1] * scaleFactor; | |
462 destination[3] = source[0] * scaleFactor; | |
463 source += 4; | |
464 destination += 4; | |
465 } | |
466 } | |
467 | |
468 template<> void unpack<GraphicsContext3D::DataFormatARGB8, uint8_t, float>(const
uint8_t* source, float* destination, unsigned pixelsPerRow) | |
469 { | |
470 const float scaleFactor = 1.0f / 255.0f; | |
471 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
472 destination[0] = source[1] * scaleFactor; | |
473 destination[1] = source[2] * scaleFactor; | |
474 destination[2] = source[3] * scaleFactor; | |
475 destination[3] = source[0] * scaleFactor; | |
476 source += 4; | |
477 destination += 4; | |
478 } | |
479 } | |
480 | |
481 template<> void unpack<GraphicsContext3D::DataFormatRGB8, uint8_t, float>(const
uint8_t* source, float* destination, unsigned pixelsPerRow) | |
482 { | |
483 const float scaleFactor = 1.0f / 255.0f; | |
484 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
485 destination[0] = source[0] * scaleFactor; | |
486 destination[1] = source[1] * scaleFactor; | |
487 destination[2] = source[2] * scaleFactor; | |
488 destination[3] = 1; | |
489 source += 3; | |
490 destination += 4; | |
491 } | |
492 } | |
493 | |
494 template<> void unpack<GraphicsContext3D::DataFormatBGR8, uint8_t, float>(const
uint8_t* source, float* destination, unsigned pixelsPerRow) | |
495 { | |
496 const float scaleFactor = 1.0f / 255.0f; | |
497 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
498 destination[0] = source[2] * scaleFactor; | |
499 destination[1] = source[1] * scaleFactor; | |
500 destination[2] = source[0] * scaleFactor; | |
501 destination[3] = 1; | |
502 source += 3; | |
503 destination += 4; | |
504 } | |
505 } | |
506 | |
507 template<> void unpack<GraphicsContext3D::DataFormatRGB32F, float, float>(const
float* source, float* destination, unsigned pixelsPerRow) | |
508 { | |
509 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
510 destination[0] = source[0]; | |
511 destination[1] = source[1]; | |
512 destination[2] = source[2]; | |
513 destination[3] = 1; | |
514 source += 3; | |
515 destination += 4; | |
516 } | |
517 } | |
518 | |
519 template<> void unpack<GraphicsContext3D::DataFormatR32F, float, float>(const fl
oat* source, float* destination, unsigned pixelsPerRow) | |
520 { | |
521 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
522 destination[0] = source[0]; | |
523 destination[1] = source[0]; | |
524 destination[2] = source[0]; | |
525 destination[3] = 1; | |
526 source += 1; | |
527 destination += 4; | |
528 } | |
529 } | |
530 | |
531 template<> void unpack<GraphicsContext3D::DataFormatRA32F, float, float>(const f
loat* source, float* destination, unsigned pixelsPerRow) | |
532 { | |
533 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
534 destination[0] = source[0]; | |
535 destination[1] = source[0]; | |
536 destination[2] = source[0]; | |
537 destination[3] = source[1]; | |
538 source += 2; | |
539 destination += 4; | |
540 } | |
541 } | |
542 | |
543 template<> void unpack<GraphicsContext3D::DataFormatA32F, float, float>(const fl
oat* source, float* destination, unsigned pixelsPerRow) | |
544 { | |
545 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
546 destination[0] = 0; | |
547 destination[1] = 0; | |
548 destination[2] = 0; | |
549 destination[3] = source[0]; | |
550 source += 1; | |
551 destination += 4; | |
552 } | |
553 } | |
554 | |
555 //---------------------------------------------------------------------- | |
556 // Pixel packing routines. | |
557 // | |
558 | |
559 template<int format, int alphaOp, typename SourceType, typename DstType> | |
560 void pack(const SourceType*, DstType*, unsigned) | |
561 { | |
562 ASSERT_NOT_REACHED(); | |
563 } | |
564 | |
565 template<> void pack<GraphicsContext3D::DataFormatA8, GraphicsContext3D::AlphaDo
Nothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned
pixelsPerRow) | |
566 { | |
567 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
568 destination[0] = source[3]; | |
569 source += 4; | |
570 destination += 1; | |
571 } | |
572 } | |
573 | |
574 template<> void pack<GraphicsContext3D::DataFormatR8, GraphicsContext3D::AlphaDo
Nothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned
pixelsPerRow) | |
575 { | |
576 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
577 destination[0] = source[0]; | |
578 source += 4; | |
579 destination += 1; | |
580 } | |
581 } | |
582 | |
583 template<> void pack<GraphicsContext3D::DataFormatR8, GraphicsContext3D::AlphaDo
Premultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsi
gned pixelsPerRow) | |
584 { | |
585 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
586 float scaleFactor = source[3] / 255.0f; | |
587 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
588 destination[0] = sourceR; | |
589 source += 4; | |
590 destination += 1; | |
591 } | |
592 } | |
593 | |
594 // FIXME: this routine is lossy and must be removed. | |
595 template<> void pack<GraphicsContext3D::DataFormatR8, GraphicsContext3D::AlphaDo
Unmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsig
ned pixelsPerRow) | |
596 { | |
597 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
598 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
599 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
600 destination[0] = sourceR; | |
601 source += 4; | |
602 destination += 1; | |
603 } | |
604 } | |
605 | |
606 template<> void pack<GraphicsContext3D::DataFormatRA8, GraphicsContext3D::AlphaD
oNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigne
d pixelsPerRow) | |
607 { | |
608 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
609 destination[0] = source[0]; | |
610 destination[1] = source[3]; | |
611 source += 4; | |
612 destination += 2; | |
613 } | |
614 } | |
615 | |
616 template<> void pack<GraphicsContext3D::DataFormatRA8, GraphicsContext3D::AlphaD
oPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, uns
igned pixelsPerRow) | |
617 { | |
618 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
619 float scaleFactor = source[3] / 255.0f; | |
620 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
621 destination[0] = sourceR; | |
622 destination[1] = source[3]; | |
623 source += 4; | |
624 destination += 2; | |
625 } | |
626 } | |
627 | |
628 // FIXME: this routine is lossy and must be removed. | |
629 template<> void pack<GraphicsContext3D::DataFormatRA8, GraphicsContext3D::AlphaD
oUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsi
gned pixelsPerRow) | |
630 { | |
631 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
632 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
633 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
634 destination[0] = sourceR; | |
635 destination[1] = source[3]; | |
636 source += 4; | |
637 destination += 2; | |
638 } | |
639 } | |
640 | |
641 template<> void pack<GraphicsContext3D::DataFormatRGB8, GraphicsContext3D::Alpha
DoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsign
ed pixelsPerRow) | |
642 { | |
643 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
644 destination[0] = source[0]; | |
645 destination[1] = source[1]; | |
646 destination[2] = source[2]; | |
647 source += 4; | |
648 destination += 3; | |
649 } | |
650 } | |
651 | |
652 template<> void pack<GraphicsContext3D::DataFormatRGB8, GraphicsContext3D::Alpha
DoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, un
signed pixelsPerRow) | |
653 { | |
654 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
655 float scaleFactor = source[3] / 255.0f; | |
656 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
657 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
658 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
659 destination[0] = sourceR; | |
660 destination[1] = sourceG; | |
661 destination[2] = sourceB; | |
662 source += 4; | |
663 destination += 3; | |
664 } | |
665 } | |
666 | |
667 // FIXME: this routine is lossy and must be removed. | |
668 template<> void pack<GraphicsContext3D::DataFormatRGB8, GraphicsContext3D::Alpha
DoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, uns
igned pixelsPerRow) | |
669 { | |
670 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
671 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
672 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
673 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
674 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
675 destination[0] = sourceR; | |
676 destination[1] = sourceG; | |
677 destination[2] = sourceB; | |
678 source += 4; | |
679 destination += 3; | |
680 } | |
681 } | |
682 | |
683 | |
684 template<> void pack<GraphicsContext3D::DataFormatRGBA8, GraphicsContext3D::Alph
aDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsig
ned pixelsPerRow) | |
685 { | |
686 memcpy(destination, source, pixelsPerRow * 4); | |
687 } | |
688 | |
689 template<> void pack<GraphicsContext3D::DataFormatRGBA8, GraphicsContext3D::Alph
aDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, u
nsigned pixelsPerRow) | |
690 { | |
691 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
692 float scaleFactor = source[3] / 255.0f; | |
693 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
694 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
695 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
696 destination[0] = sourceR; | |
697 destination[1] = sourceG; | |
698 destination[2] = sourceB; | |
699 destination[3] = source[3]; | |
700 source += 4; | |
701 destination += 4; | |
702 } | |
703 } | |
704 | |
705 // FIXME: this routine is lossy and must be removed. | |
706 template<> void pack<GraphicsContext3D::DataFormatRGBA8, GraphicsContext3D::Alph
aDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, un
signed pixelsPerRow) | |
707 { | |
708 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
709 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
710 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
711 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
712 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
713 destination[0] = sourceR; | |
714 destination[1] = sourceG; | |
715 destination[2] = sourceB; | |
716 destination[3] = source[3]; | |
717 source += 4; | |
718 destination += 4; | |
719 } | |
720 } | |
721 | |
722 template<> void pack<GraphicsContext3D::DataFormatRGBA4444, GraphicsContext3D::A
lphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination,
unsigned pixelsPerRow) | |
723 { | |
724 #if HAVE(ARM_NEON_INTRINSICS) | |
725 SIMD::packOneRowOfRGBA8ToUnsignedShort4444(source, destination, pixelsPerRow
); | |
726 #endif | |
727 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
728 *destination = (((source[0] & 0xF0) << 8) | |
729 | ((source[1] & 0xF0) << 4) | |
730 | (source[2] & 0xF0) | |
731 | (source[3] >> 4)); | |
732 source += 4; | |
733 destination += 1; | |
734 } | |
735 } | |
736 | |
737 template<> void pack<GraphicsContext3D::DataFormatRGBA4444, GraphicsContext3D::A
lphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinati
on, unsigned pixelsPerRow) | |
738 { | |
739 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
740 float scaleFactor = source[3] / 255.0f; | |
741 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
742 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
743 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
744 *destination = (((sourceR & 0xF0) << 8) | |
745 | ((sourceG & 0xF0) << 4) | |
746 | (sourceB & 0xF0) | |
747 | (source[3] >> 4)); | |
748 source += 4; | |
749 destination += 1; | |
750 } | |
751 } | |
752 | |
753 // FIXME: this routine is lossy and must be removed. | |
754 template<> void pack<GraphicsContext3D::DataFormatRGBA4444, GraphicsContext3D::A
lphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinatio
n, unsigned pixelsPerRow) | |
755 { | |
756 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
757 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
758 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
759 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
760 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
761 *destination = (((sourceR & 0xF0) << 8) | |
762 | ((sourceG & 0xF0) << 4) | |
763 | (sourceB & 0xF0) | |
764 | (source[3] >> 4)); | |
765 source += 4; | |
766 destination += 1; | |
767 } | |
768 } | |
769 | |
770 template<> void pack<GraphicsContext3D::DataFormatRGBA5551, GraphicsContext3D::A
lphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination,
unsigned pixelsPerRow) | |
771 { | |
772 #if HAVE(ARM_NEON_INTRINSICS) | |
773 SIMD::packOneRowOfRGBA8ToUnsignedShort5551(source, destination, pixelsPerRow
); | |
774 #endif | |
775 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
776 *destination = (((source[0] & 0xF8) << 8) | |
777 | ((source[1] & 0xF8) << 3) | |
778 | ((source[2] & 0xF8) >> 2) | |
779 | (source[3] >> 7)); | |
780 source += 4; | |
781 destination += 1; | |
782 } | |
783 } | |
784 | |
785 template<> void pack<GraphicsContext3D::DataFormatRGBA5551, GraphicsContext3D::A
lphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinati
on, unsigned pixelsPerRow) | |
786 { | |
787 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
788 float scaleFactor = source[3] / 255.0f; | |
789 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
790 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
791 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
792 *destination = (((sourceR & 0xF8) << 8) | |
793 | ((sourceG & 0xF8) << 3) | |
794 | ((sourceB & 0xF8) >> 2) | |
795 | (source[3] >> 7)); | |
796 source += 4; | |
797 destination += 1; | |
798 } | |
799 } | |
800 | |
801 // FIXME: this routine is lossy and must be removed. | |
802 template<> void pack<GraphicsContext3D::DataFormatRGBA5551, GraphicsContext3D::A
lphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinatio
n, unsigned pixelsPerRow) | |
803 { | |
804 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
805 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
806 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
807 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
808 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
809 *destination = (((sourceR & 0xF8) << 8) | |
810 | ((sourceG & 0xF8) << 3) | |
811 | ((sourceB & 0xF8) >> 2) | |
812 | (source[3] >> 7)); | |
813 source += 4; | |
814 destination += 1; | |
815 } | |
816 } | |
817 | |
818 template<> void pack<GraphicsContext3D::DataFormatRGB565, GraphicsContext3D::Alp
haDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, un
signed pixelsPerRow) | |
819 { | |
820 #if HAVE(ARM_NEON_INTRINSICS) | |
821 SIMD::packOneRowOfRGBA8ToUnsignedShort565(source, destination, pixelsPerRow)
; | |
822 #endif | |
823 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
824 *destination = (((source[0] & 0xF8) << 8) | |
825 | ((source[1] & 0xFC) << 3) | |
826 | ((source[2] & 0xF8) >> 3)); | |
827 source += 4; | |
828 destination += 1; | |
829 } | |
830 } | |
831 | |
832 template<> void pack<GraphicsContext3D::DataFormatRGB565, GraphicsContext3D::Alp
haDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination
, unsigned pixelsPerRow) | |
833 { | |
834 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
835 float scaleFactor = source[3] / 255.0f; | |
836 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
837 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
838 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
839 *destination = (((sourceR & 0xF8) << 8) | |
840 | ((sourceG & 0xFC) << 3) | |
841 | ((sourceB & 0xF8) >> 3)); | |
842 source += 4; | |
843 destination += 1; | |
844 } | |
845 } | |
846 | |
847 // FIXME: this routine is lossy and must be removed. | |
848 template<> void pack<GraphicsContext3D::DataFormatRGB565, GraphicsContext3D::Alp
haDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination,
unsigned pixelsPerRow) | |
849 { | |
850 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
851 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f; | |
852 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s
caleFactor); | |
853 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s
caleFactor); | |
854 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s
caleFactor); | |
855 *destination = (((sourceR & 0xF8) << 8) | |
856 | ((sourceG & 0xFC) << 3) | |
857 | ((sourceB & 0xF8) >> 3)); | |
858 source += 4; | |
859 destination += 1; | |
860 } | |
861 } | |
862 | |
863 template<> void pack<GraphicsContext3D::DataFormatRGB32F, GraphicsContext3D::Alp
haDoNothing, float, float>(const float* source, float* destination, unsigned pix
elsPerRow) | |
864 { | |
865 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
866 destination[0] = source[0]; | |
867 destination[1] = source[1]; | |
868 destination[2] = source[2]; | |
869 source += 4; | |
870 destination += 3; | |
871 } | |
872 } | |
873 | |
874 template<> void pack<GraphicsContext3D::DataFormatRGB32F, GraphicsContext3D::Alp
haDoPremultiply, float, float>(const float* source, float* destination, unsigned
pixelsPerRow) | |
875 { | |
876 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
877 float scaleFactor = source[3]; | |
878 destination[0] = source[0] * scaleFactor; | |
879 destination[1] = source[1] * scaleFactor; | |
880 destination[2] = source[2] * scaleFactor; | |
881 source += 4; | |
882 destination += 3; | |
883 } | |
884 } | |
885 | |
886 template<> void pack<GraphicsContext3D::DataFormatRGB32F, GraphicsContext3D::Alp
haDoUnmultiply, float, float>(const float* source, float* destination, unsigned
pixelsPerRow) | |
887 { | |
888 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
889 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
890 destination[0] = source[0] * scaleFactor; | |
891 destination[1] = source[1] * scaleFactor; | |
892 destination[2] = source[2] * scaleFactor; | |
893 source += 4; | |
894 destination += 3; | |
895 } | |
896 } | |
897 | |
898 // Used only during RGBA8 or BGRA8 -> floating-point uploads. | |
899 template<> void pack<GraphicsContext3D::DataFormatRGBA32F, GraphicsContext3D::Al
phaDoNothing, float, float>(const float* source, float* destination, unsigned pi
xelsPerRow) | |
900 { | |
901 memcpy(destination, source, pixelsPerRow * 4 * sizeof(float)); | |
902 } | |
903 | |
904 template<> void pack<GraphicsContext3D::DataFormatRGBA32F, GraphicsContext3D::Al
phaDoPremultiply, float, float>(const float* source, float* destination, unsigne
d pixelsPerRow) | |
905 { | |
906 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
907 float scaleFactor = source[3]; | |
908 destination[0] = source[0] * scaleFactor; | |
909 destination[1] = source[1] * scaleFactor; | |
910 destination[2] = source[2] * scaleFactor; | |
911 destination[3] = source[3]; | |
912 source += 4; | |
913 destination += 4; | |
914 } | |
915 } | |
916 | |
917 template<> void pack<GraphicsContext3D::DataFormatRGBA32F, GraphicsContext3D::Al
phaDoUnmultiply, float, float>(const float* source, float* destination, unsigned
pixelsPerRow) | |
918 { | |
919 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
920 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
921 destination[0] = source[0] * scaleFactor; | |
922 destination[1] = source[1] * scaleFactor; | |
923 destination[2] = source[2] * scaleFactor; | |
924 destination[3] = source[3]; | |
925 source += 4; | |
926 destination += 4; | |
927 } | |
928 } | |
929 | |
930 template<> void pack<GraphicsContext3D::DataFormatA32F, GraphicsContext3D::Alpha
DoNothing, float, float>(const float* source, float* destination, unsigned pixel
sPerRow) | |
931 { | |
932 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
933 destination[0] = source[3]; | |
934 source += 4; | |
935 destination += 1; | |
936 } | |
937 } | |
938 | |
939 template<> void pack<GraphicsContext3D::DataFormatR32F, GraphicsContext3D::Alpha
DoNothing, float, float>(const float* source, float* destination, unsigned pixel
sPerRow) | |
940 { | |
941 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
942 destination[0] = source[0]; | |
943 source += 4; | |
944 destination += 1; | |
945 } | |
946 } | |
947 | |
948 template<> void pack<GraphicsContext3D::DataFormatR32F, GraphicsContext3D::Alpha
DoPremultiply, float, float>(const float* source, float* destination, unsigned p
ixelsPerRow) | |
949 { | |
950 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
951 float scaleFactor = source[3]; | |
952 destination[0] = source[0] * scaleFactor; | |
953 source += 4; | |
954 destination += 1; | |
955 } | |
956 } | |
957 | |
958 template<> void pack<GraphicsContext3D::DataFormatR32F, GraphicsContext3D::Alpha
DoUnmultiply, float, float>(const float* source, float* destination, unsigned pi
xelsPerRow) | |
959 { | |
960 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
961 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
962 destination[0] = source[0] * scaleFactor; | |
963 source += 4; | |
964 destination += 1; | |
965 } | |
966 } | |
967 | |
968 template<> void pack<GraphicsContext3D::DataFormatRA32F, GraphicsContext3D::Alph
aDoNothing, float, float>(const float* source, float* destination, unsigned pixe
lsPerRow) | |
969 { | |
970 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
971 destination[0] = source[0]; | |
972 destination[1] = source[3]; | |
973 source += 4; | |
974 destination += 2; | |
975 } | |
976 } | |
977 | |
978 template<> void pack<GraphicsContext3D::DataFormatRA32F, GraphicsContext3D::Alph
aDoPremultiply, float, float>(const float* source, float* destination, unsigned
pixelsPerRow) | |
979 { | |
980 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
981 float scaleFactor = source[3]; | |
982 destination[0] = source[0] * scaleFactor; | |
983 destination[1] = source[3]; | |
984 source += 4; | |
985 destination += 2; | |
986 } | |
987 } | |
988 | |
989 template<> void pack<GraphicsContext3D::DataFormatRA32F, GraphicsContext3D::Alph
aDoUnmultiply, float, float>(const float* source, float* destination, unsigned p
ixelsPerRow) | |
990 { | |
991 for (unsigned int i = 0; i < pixelsPerRow; ++i) { | |
992 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
993 destination[0] = source[0] * scaleFactor; | |
994 destination[1] = source[3]; | |
995 source += 4; | |
996 destination += 2; | |
997 } | |
998 } | |
999 | |
1000 template<> void pack<GraphicsContext3D::DataFormatRGBA16F, GraphicsContext3D::Al
phaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsig
ned pixelsPerRow) | |
1001 { | |
1002 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1003 destination[0] = convertFloatToHalfFloat(source[0]); | |
1004 destination[1] = convertFloatToHalfFloat(source[1]); | |
1005 destination[2] = convertFloatToHalfFloat(source[2]); | |
1006 destination[3] = convertFloatToHalfFloat(source[3]); | |
1007 source += 4; | |
1008 destination += 4; | |
1009 } | |
1010 } | |
1011 | |
1012 template<> void pack<GraphicsContext3D::DataFormatRGBA16F, GraphicsContext3D::Al
phaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, u
nsigned pixelsPerRow) | |
1013 { | |
1014 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1015 float scaleFactor = source[3]; | |
1016 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
1017 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor); | |
1018 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor); | |
1019 destination[3] = convertFloatToHalfFloat(source[3]); | |
1020 source += 4; | |
1021 destination += 4; | |
1022 } | |
1023 } | |
1024 | |
1025 template<> void pack<GraphicsContext3D::DataFormatRGBA16F, GraphicsContext3D::Al
phaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, un
signed pixelsPerRow) | |
1026 { | |
1027 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1028 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
1029 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
1030 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor); | |
1031 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor); | |
1032 destination[3] = convertFloatToHalfFloat(source[3]); | |
1033 source += 4; | |
1034 destination += 4; | |
1035 } | |
1036 } | |
1037 | |
1038 template<> void pack<GraphicsContext3D::DataFormatRGB16F, GraphicsContext3D::Alp
haDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsign
ed pixelsPerRow) | |
1039 { | |
1040 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1041 destination[0] = convertFloatToHalfFloat(source[0]); | |
1042 destination[1] = convertFloatToHalfFloat(source[1]); | |
1043 destination[2] = convertFloatToHalfFloat(source[2]); | |
1044 source += 4; | |
1045 destination += 3; | |
1046 } | |
1047 } | |
1048 | |
1049 template<> void pack<GraphicsContext3D::DataFormatRGB16F, GraphicsContext3D::Alp
haDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, un
signed pixelsPerRow) | |
1050 { | |
1051 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1052 float scaleFactor = source[3]; | |
1053 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
1054 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor); | |
1055 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor); | |
1056 source += 4; | |
1057 destination += 3; | |
1058 } | |
1059 } | |
1060 | |
1061 template<> void pack<GraphicsContext3D::DataFormatRGB16F, GraphicsContext3D::Alp
haDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, uns
igned pixelsPerRow) | |
1062 { | |
1063 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1064 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
1065 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
1066 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor); | |
1067 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor); | |
1068 source += 4; | |
1069 destination += 3; | |
1070 } | |
1071 } | |
1072 | |
1073 template<> void pack<GraphicsContext3D::DataFormatRA16F, GraphicsContext3D::Alph
aDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigne
d pixelsPerRow) | |
1074 { | |
1075 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1076 destination[0] = convertFloatToHalfFloat(source[0]); | |
1077 destination[1] = convertFloatToHalfFloat(source[3]); | |
1078 source += 4; | |
1079 destination += 2; | |
1080 } | |
1081 } | |
1082 | |
1083 template<> void pack<GraphicsContext3D::DataFormatRA16F, GraphicsContext3D::Alph
aDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, uns
igned pixelsPerRow) | |
1084 { | |
1085 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1086 float scaleFactor = source[3]; | |
1087 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
1088 destination[1] = convertFloatToHalfFloat(source[3]); | |
1089 source += 4; | |
1090 destination += 2; | |
1091 } | |
1092 } | |
1093 | |
1094 template<> void pack<GraphicsContext3D::DataFormatRA16F, GraphicsContext3D::Alph
aDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsi
gned pixelsPerRow) | |
1095 { | |
1096 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1097 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
1098 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
1099 destination[1] = convertFloatToHalfFloat(source[3]); | |
1100 source += 4; | |
1101 destination += 2; | |
1102 } | |
1103 } | |
1104 | |
1105 template<> void pack<GraphicsContext3D::DataFormatR16F, GraphicsContext3D::Alpha
DoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned
pixelsPerRow) | |
1106 { | |
1107 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1108 destination[0] = convertFloatToHalfFloat(source[0]); | |
1109 source += 4; | |
1110 destination += 1; | |
1111 } | |
1112 } | |
1113 | |
1114 template<> void pack<GraphicsContext3D::DataFormatR16F, GraphicsContext3D::Alpha
DoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsi
gned pixelsPerRow) | |
1115 { | |
1116 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1117 float scaleFactor = source[3]; | |
1118 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
1119 source += 4; | |
1120 destination += 1; | |
1121 } | |
1122 } | |
1123 | |
1124 template<> void pack<GraphicsContext3D::DataFormatR16F, GraphicsContext3D::Alpha
DoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsig
ned pixelsPerRow) | |
1125 { | |
1126 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1127 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f; | |
1128 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor); | |
1129 source += 4; | |
1130 destination += 1; | |
1131 } | |
1132 } | |
1133 | |
1134 template<> void pack<GraphicsContext3D::DataFormatA16F, GraphicsContext3D::Alpha
DoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned
pixelsPerRow) | |
1135 { | |
1136 for (unsigned i = 0; i < pixelsPerRow; ++i) { | |
1137 destination[0] = convertFloatToHalfFloat(source[3]); | |
1138 source += 4; | |
1139 destination += 1; | |
1140 } | |
1141 } | |
1142 | |
1143 bool HasAlpha(int format) | |
1144 { | |
1145 return format == GraphicsContext3D::DataFormatA8 | |
1146 || format == GraphicsContext3D::DataFormatA16F | |
1147 || format == GraphicsContext3D::DataFormatA32F | |
1148 || format == GraphicsContext3D::DataFormatRA8 | |
1149 || format == GraphicsContext3D::DataFormatAR8 | |
1150 || format == GraphicsContext3D::DataFormatRA16F | |
1151 || format == GraphicsContext3D::DataFormatRA32F | |
1152 || format == GraphicsContext3D::DataFormatRGBA8 | |
1153 || format == GraphicsContext3D::DataFormatBGRA8 | |
1154 || format == GraphicsContext3D::DataFormatARGB8 | |
1155 || format == GraphicsContext3D::DataFormatABGR8 | |
1156 || format == GraphicsContext3D::DataFormatRGBA16F | |
1157 || format == GraphicsContext3D::DataFormatRGBA32F | |
1158 || format == GraphicsContext3D::DataFormatRGBA4444 | |
1159 || format == GraphicsContext3D::DataFormatRGBA5551; | |
1160 } | |
1161 | |
1162 bool HasColor(int format) | |
1163 { | |
1164 return format == GraphicsContext3D::DataFormatRGBA8 | |
1165 || format == GraphicsContext3D::DataFormatRGBA16F | |
1166 || format == GraphicsContext3D::DataFormatRGBA32F | |
1167 || format == GraphicsContext3D::DataFormatRGB8 | |
1168 || format == GraphicsContext3D::DataFormatRGB16F | |
1169 || format == GraphicsContext3D::DataFormatRGB32F | |
1170 || format == GraphicsContext3D::DataFormatBGR8 | |
1171 || format == GraphicsContext3D::DataFormatBGRA8 | |
1172 || format == GraphicsContext3D::DataFormatARGB8 | |
1173 || format == GraphicsContext3D::DataFormatABGR8 | |
1174 || format == GraphicsContext3D::DataFormatRGBA5551 | |
1175 || format == GraphicsContext3D::DataFormatRGBA4444 | |
1176 || format == GraphicsContext3D::DataFormatRGB565 | |
1177 || format == GraphicsContext3D::DataFormatR8 | |
1178 || format == GraphicsContext3D::DataFormatR16F | |
1179 || format == GraphicsContext3D::DataFormatR32F | |
1180 || format == GraphicsContext3D::DataFormatRA8 | |
1181 || format == GraphicsContext3D::DataFormatRA16F | |
1182 || format == GraphicsContext3D::DataFormatRA32F | |
1183 || format == GraphicsContext3D::DataFormatAR8; | |
1184 } | |
1185 | |
1186 template<int Format> | |
1187 struct IsFloatFormat { | |
1188 static const bool Value = | |
1189 Format == GraphicsContext3D::DataFormatRGBA32F | |
1190 || Format == GraphicsContext3D::DataFormatRGB32F | |
1191 || Format == GraphicsContext3D::DataFormatRA32F | |
1192 || Format == GraphicsContext3D::DataFormatR32F | |
1193 || Format == GraphicsContext3D::DataFormatA32F; | |
1194 }; | |
1195 | |
1196 template<int Format> | |
1197 struct IsHalfFloatFormat { | |
1198 static const bool Value = | |
1199 Format == GraphicsContext3D::DataFormatRGBA16F | |
1200 || Format == GraphicsContext3D::DataFormatRGB16F | |
1201 || Format == GraphicsContext3D::DataFormatRA16F | |
1202 || Format == GraphicsContext3D::DataFormatR16F | |
1203 || Format == GraphicsContext3D::DataFormatA16F; | |
1204 }; | |
1205 | |
1206 template<int Format> | |
1207 struct Is16bppFormat { | |
1208 static const bool Value = | |
1209 Format == GraphicsContext3D::DataFormatRGBA5551 | |
1210 || Format == GraphicsContext3D::DataFormatRGBA4444 | |
1211 || Format == GraphicsContext3D::DataFormatRGB565; | |
1212 }; | |
1213 | |
1214 template<int Format, bool IsFloat = IsFloatFormat<Format>::Value, bool IsHalfFlo
at = IsHalfFloatFormat<Format>::Value, bool Is16bpp = Is16bppFormat<Format>::Val
ue> | |
1215 struct DataTypeForFormat { | |
1216 typedef uint8_t Type; | |
1217 }; | |
1218 | |
1219 template<int Format> | |
1220 struct DataTypeForFormat<Format, true, false, false> { | |
1221 typedef float Type; | |
1222 }; | |
1223 | |
1224 template<int Format> | |
1225 struct DataTypeForFormat<Format, false, true, false> { | |
1226 typedef uint16_t Type; | |
1227 }; | |
1228 | |
1229 template<int Format> | |
1230 struct DataTypeForFormat<Format, false, false, true> { | |
1231 typedef uint16_t Type; | |
1232 }; | |
1233 | |
1234 template<int Format> | |
1235 struct IntermediateFormat { | |
1236 static const int Value = (IsFloatFormat<Format>::Value || IsHalfFloatFormat<
Format>::Value) ? GraphicsContext3D::DataFormatRGBA32F : GraphicsContext3D::Data
FormatRGBA8; | |
1237 }; | |
1238 | |
1239 unsigned TexelBytesForFormat(GraphicsContext3D::DataFormat format) | |
1240 { | |
1241 switch (format) { | |
1242 case GraphicsContext3D::DataFormatR8: | |
1243 case GraphicsContext3D::DataFormatA8: | |
1244 return 1; | |
1245 case GraphicsContext3D::DataFormatRA8: | |
1246 case GraphicsContext3D::DataFormatAR8: | |
1247 case GraphicsContext3D::DataFormatRGBA5551: | |
1248 case GraphicsContext3D::DataFormatRGBA4444: | |
1249 case GraphicsContext3D::DataFormatRGB565: | |
1250 case GraphicsContext3D::DataFormatA16F: | |
1251 case GraphicsContext3D::DataFormatR16F: | |
1252 return 2; | |
1253 case GraphicsContext3D::DataFormatRGB8: | |
1254 case GraphicsContext3D::DataFormatBGR8: | |
1255 return 3; | |
1256 case GraphicsContext3D::DataFormatRGBA8: | |
1257 case GraphicsContext3D::DataFormatARGB8: | |
1258 case GraphicsContext3D::DataFormatABGR8: | |
1259 case GraphicsContext3D::DataFormatBGRA8: | |
1260 case GraphicsContext3D::DataFormatR32F: | |
1261 case GraphicsContext3D::DataFormatA32F: | |
1262 case GraphicsContext3D::DataFormatRA16F: | |
1263 return 4; | |
1264 case GraphicsContext3D::DataFormatRGB16F: | |
1265 return 6; | |
1266 case GraphicsContext3D::DataFormatRA32F: | |
1267 case GraphicsContext3D::DataFormatRGBA16F: | |
1268 return 8; | |
1269 case GraphicsContext3D::DataFormatRGB32F: | |
1270 return 12; | |
1271 case GraphicsContext3D::DataFormatRGBA32F: | |
1272 return 16; | |
1273 default: | |
1274 return 0; | |
1275 } | |
1276 } | |
1277 | |
1278 /* END CODE SHARED WITH MOZILLA FIREFOX */ | |
1279 | |
1280 class FormatConverter { | |
1281 public: | |
1282 FormatConverter(unsigned width, unsigned height, | |
1283 const void* srcStart, void* dstStart, int srcStride, int dstStride) | |
1284 : m_width(width), m_height(height), m_srcStart(srcStart), m_dstStart(dst
Start), m_srcStride(srcStride), m_dstStride(dstStride), m_success(false) | |
1285 { | |
1286 const unsigned MaxNumberOfComponents = 4; | |
1287 const unsigned MaxBytesPerComponent = 4; | |
1288 m_unpackedIntermediateSrcData = adoptArrayPtr(new uint8_t[m_width * MaxN
umberOfComponents *MaxBytesPerComponent]); | |
1289 ASSERT(m_unpackedIntermediateSrcData.get()); | |
1290 } | |
1291 | |
1292 void convert(GraphicsContext3D::DataFormat srcFormat, GraphicsContext3D::Dat
aFormat dstFormat, GraphicsContext3D::AlphaOp); | |
1293 bool Success() const { return m_success; } | |
1294 | |
1295 private: | |
1296 template<GraphicsContext3D::DataFormat SrcFormat> | |
1297 void convert(GraphicsContext3D::DataFormat dstFormat, GraphicsContext3D::Alp
haOp); | |
1298 | |
1299 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFor
mat DstFormat> | |
1300 void convert(GraphicsContext3D::AlphaOp); | |
1301 | |
1302 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFor
mat DstFormat, GraphicsContext3D::AlphaOp alphaOp> | |
1303 void convert(); | |
1304 | |
1305 const unsigned m_width, m_height; | |
1306 const void* const m_srcStart; | |
1307 void* const m_dstStart; | |
1308 const int m_srcStride, m_dstStride; | |
1309 bool m_success; | |
1310 OwnPtr<uint8_t[]> m_unpackedIntermediateSrcData; | |
1311 }; | |
1312 | |
1313 void FormatConverter::convert(GraphicsContext3D::DataFormat srcFormat, GraphicsC
ontext3D::DataFormat dstFormat, GraphicsContext3D::AlphaOp alphaOp) | |
1314 { | |
1315 #define FORMATCONVERTER_CASE_SRCFORMAT(SrcFormat) \ | |
1316 case SrcFormat: \ | |
1317 return convert<SrcFormat>(dstFormat, alphaOp); | |
1318 | |
1319 switch (srcFormat) { | |
1320 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatR8) | |
1321 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatA8) | |
1322 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatR32F) | |
1323 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatA32F) | |
1324 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRA8) | |
1325 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRA32F) | |
1326 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB8) | |
1327 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatBGR8) | |
1328 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB565) | |
1329 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB32F) | |
1330 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA8) | |
1331 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatARGB8) | |
1332 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatABGR8) | |
1333 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatAR8) | |
1334 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatBGRA8) | |
1335 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA5551
) | |
1336 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA4444
) | |
1337 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA32F) | |
1338 default: | |
1339 ASSERT_NOT_REACHED(); | |
1340 } | |
1341 #undef FORMATCONVERTER_CASE_SRCFORMAT | |
1342 } | |
1343 | |
1344 template<GraphicsContext3D::DataFormat SrcFormat> | |
1345 void FormatConverter::convert(GraphicsContext3D::DataFormat dstFormat, GraphicsC
ontext3D::AlphaOp alphaOp) | |
1346 { | |
1347 #define FORMATCONVERTER_CASE_DSTFORMAT(DstFormat) \ | |
1348 case DstFormat: \ | |
1349 return convert<SrcFormat, DstFormat>(alphaOp); | |
1350 | |
1351 switch (dstFormat) { | |
1352 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatR8) | |
1353 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatR16F) | |
1354 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatR32F) | |
1355 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatA8) | |
1356 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatA16F) | |
1357 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatA32F) | |
1358 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRA8) | |
1359 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRA16F) | |
1360 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRA32F) | |
1361 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGB8) | |
1362 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGB565) | |
1363 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGB16F) | |
1364 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGB32F) | |
1365 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA8) | |
1366 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA5551
) | |
1367 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA4444
) | |
1368 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA16F) | |
1369 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA32F) | |
1370 default: | |
1371 ASSERT_NOT_REACHED(); | |
1372 } | |
1373 | |
1374 #undef FORMATCONVERTER_CASE_DSTFORMAT | |
1375 } | |
1376 | |
1377 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFormat
DstFormat> | |
1378 void FormatConverter::convert(GraphicsContext3D::AlphaOp alphaOp) | |
1379 { | |
1380 #define FORMATCONVERTER_CASE_ALPHAOP(alphaOp) \ | |
1381 case alphaOp: \ | |
1382 return convert<SrcFormat, DstFormat, alphaOp>(); | |
1383 | |
1384 switch (alphaOp) { | |
1385 FORMATCONVERTER_CASE_ALPHAOP(GraphicsContext3D::AlphaDoNothing) | |
1386 FORMATCONVERTER_CASE_ALPHAOP(GraphicsContext3D::AlphaDoPremultiply) | |
1387 FORMATCONVERTER_CASE_ALPHAOP(GraphicsContext3D::AlphaDoUnmultiply) | |
1388 default: | |
1389 ASSERT_NOT_REACHED(); | |
1390 } | |
1391 #undef FORMATCONVERTER_CASE_ALPHAOP | |
1392 } | |
1393 | |
1394 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFormat
DstFormat, GraphicsContext3D::AlphaOp alphaOp> | |
1395 void FormatConverter::convert() | |
1396 { | |
1397 // Many instantiations of this template function will never be entered, so w
e try | |
1398 // to return immediately in these cases to avoid the compiler to generate us
eless code. | |
1399 if (SrcFormat == DstFormat && alphaOp == GraphicsContext3D::AlphaDoNothing)
{ | |
1400 ASSERT_NOT_REACHED(); | |
1401 return; | |
1402 } | |
1403 if (!IsFloatFormat<DstFormat>::Value && IsFloatFormat<SrcFormat>::Value) { | |
1404 ASSERT_NOT_REACHED(); | |
1405 return; | |
1406 } | |
1407 | |
1408 // Only textures uploaded from DOM elements or ImageData can allow DstFormat
!= SrcFormat. | |
1409 const bool srcFormatComesFromDOMElementOrImageData = GraphicsContext3D::srcF
ormatComeFromDOMElementOrImageData(SrcFormat); | |
1410 if (!srcFormatComesFromDOMElementOrImageData && SrcFormat != DstFormat) { | |
1411 ASSERT_NOT_REACHED(); | |
1412 return; | |
1413 } | |
1414 // Likewise, only textures uploaded from DOM elements or ImageData can possi
bly have to be unpremultiplied. | |
1415 if (!srcFormatComesFromDOMElementOrImageData && alphaOp == GraphicsContext3D
::AlphaDoUnmultiply) { | |
1416 ASSERT_NOT_REACHED(); | |
1417 return; | |
1418 } | |
1419 if ((!HasAlpha(SrcFormat) || !HasColor(SrcFormat) || !HasColor(DstFormat)) &
& alphaOp != GraphicsContext3D::AlphaDoNothing) { | |
1420 ASSERT_NOT_REACHED(); | |
1421 return; | |
1422 } | |
1423 | |
1424 typedef typename DataTypeForFormat<SrcFormat>::Type SrcType; | |
1425 typedef typename DataTypeForFormat<DstFormat>::Type DstType; | |
1426 const int IntermediateSrcFormat = IntermediateFormat<DstFormat>::Value; | |
1427 typedef typename DataTypeForFormat<IntermediateSrcFormat>::Type Intermediate
SrcType; | |
1428 const ptrdiff_t srcStrideInElements = m_srcStride / sizeof(SrcType); | |
1429 const ptrdiff_t dstStrideInElements = m_dstStride / sizeof(DstType); | |
1430 const bool trivialUnpack = (SrcFormat == GraphicsContext3D::DataFormatRGBA8
&& !IsFloatFormat<DstFormat>::Value && !IsHalfFloatFormat<DstFormat>::Value) ||
SrcFormat == GraphicsContext3D::DataFormatRGBA32F; | |
1431 const bool trivialPack = (DstFormat == GraphicsContext3D::DataFormatRGBA8 ||
DstFormat == GraphicsContext3D::DataFormatRGBA32F) && alphaOp == GraphicsContex
t3D::AlphaDoNothing && m_dstStride > 0; | |
1432 ASSERT(!trivialUnpack || !trivialPack); | |
1433 | |
1434 const SrcType *srcRowStart = static_cast<const SrcType*>(m_srcStart); | |
1435 DstType* dstRowStart = static_cast<DstType*>(m_dstStart); | |
1436 if (!trivialUnpack && trivialPack) { | |
1437 for (size_t i = 0; i < m_height; ++i) { | |
1438 unpack<SrcFormat>(srcRowStart, dstRowStart, m_width); | |
1439 srcRowStart += srcStrideInElements; | |
1440 dstRowStart += dstStrideInElements; | |
1441 } | |
1442 } else if (!trivialUnpack && !trivialPack) { | |
1443 for (size_t i = 0; i < m_height; ++i) { | |
1444 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermediateSrcType*
>(m_unpackedIntermediateSrcData.get()), m_width); | |
1445 pack<DstFormat, alphaOp>(reinterpret_cast<IntermediateSrcType*>(m_un
packedIntermediateSrcData.get()), dstRowStart, m_width); | |
1446 srcRowStart += srcStrideInElements; | |
1447 dstRowStart += dstStrideInElements; | |
1448 } | |
1449 } else { | |
1450 for (size_t i = 0; i < m_height; ++i) { | |
1451 pack<DstFormat, alphaOp>(srcRowStart, dstRowStart, m_width); | |
1452 srcRowStart += srcStrideInElements; | |
1453 dstRowStart += dstStrideInElements; | |
1454 } | |
1455 } | |
1456 m_success = true; | |
1457 return; | |
1458 } | |
1459 | |
1460 } // anonymous namespace | |
1461 | |
1462 bool GraphicsContext3D::packImageData( | |
1463 Image* image, | |
1464 const void* pixels, | |
1465 GC3Denum format, | |
1466 GC3Denum type, | |
1467 bool flipY, | |
1468 AlphaOp alphaOp, | |
1469 DataFormat sourceFormat, | |
1470 unsigned width, | |
1471 unsigned height, | |
1472 unsigned sourceUnpackAlignment, | |
1473 Vector<uint8_t>& data) | |
1474 { | |
1475 if (!pixels) | |
1476 return false; | |
1477 | |
1478 unsigned packedSize; | |
1479 // Output data is tightly packed (alignment == 1). | |
1480 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0)
!= GraphicsContext3D::NO_ERROR) | |
1481 return false; | |
1482 data.resize(packedSize); | |
1483 | |
1484 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, widt
h, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY)) | |
1485 return false; | |
1486 if (ImageObserver *observer = image->imageObserver()) | |
1487 observer->didDraw(image); | |
1488 return true; | |
1489 } | |
1490 | |
1491 bool GraphicsContext3D::extractImageData( | |
1492 const uint8_t* imageData, | |
1493 const IntSize& imageDataSize, | |
1494 GC3Denum format, | |
1495 GC3Denum type, | |
1496 bool flipY, | |
1497 bool premultiplyAlpha, | |
1498 Vector<uint8_t>& data) | |
1499 { | |
1500 if (!imageData) | |
1501 return false; | |
1502 int width = imageDataSize.width(); | |
1503 int height = imageDataSize.height(); | |
1504 | |
1505 unsigned packedSize; | |
1506 // Output data is tightly packed (alignment == 1). | |
1507 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0)
!= GraphicsContext3D::NO_ERROR) | |
1508 return false; | |
1509 data.resize(packedSize); | |
1510 | |
1511 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type,
premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY)) | |
1512 return false; | |
1513 | |
1514 return true; | |
1515 } | |
1516 | |
1517 bool GraphicsContext3D::extractTextureData( | |
1518 unsigned width, | |
1519 unsigned height, | |
1520 GC3Denum format, GC3Denum type, | |
1521 unsigned unpackAlignment, | |
1522 bool flipY, bool premultiplyAlpha, | |
1523 const void* pixels, | |
1524 Vector<uint8_t>& data) | |
1525 { | |
1526 // Assumes format, type, etc. have already been validated. | |
1527 DataFormat sourceDataFormat = getDataFormat(format, type); | |
1528 | |
1529 // Resize the output buffer. | |
1530 unsigned int componentsPerPixel, bytesPerComponent; | |
1531 if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &byte
sPerComponent)) | |
1532 return false; | |
1533 unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent; | |
1534 data.resize(width * height * bytesPerPixel); | |
1535 | |
1536 if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width
, height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply
: AlphaDoNothing), data.data(), flipY)) | |
1537 return false; | |
1538 | |
1539 return true; | |
1540 } | |
1541 | |
1542 bool GraphicsContext3D::packPixels( | |
1543 const uint8_t* sourceData, | |
1544 DataFormat sourceDataFormat, | |
1545 unsigned width, | |
1546 unsigned height, | |
1547 unsigned sourceUnpackAlignment, | |
1548 unsigned destinationFormat, | |
1549 unsigned destinationType, | |
1550 AlphaOp alphaOp, | |
1551 void* destinationData, | |
1552 bool flipY) | |
1553 { | |
1554 int validSrc = width * TexelBytesForFormat(sourceDataFormat); | |
1555 int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) :
0; | |
1556 int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) :
validSrc; | |
1557 | |
1558 DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType)
; | |
1559 int dstStride = width * TexelBytesForFormat(dstDataFormat); | |
1560 if (flipY) { | |
1561 destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(he
ight - 1); | |
1562 dstStride = -dstStride; | |
1563 } | |
1564 if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || !HasColor(
dstDataFormat)) | |
1565 alphaOp = AlphaDoNothing; | |
1566 | |
1567 if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) { | |
1568 const uint8_t* ptr = sourceData; | |
1569 const uint8_t* ptrEnd = sourceData + srcStride * height; | |
1570 unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride; | |
1571 uint8_t* dst = static_cast<uint8_t*>(destinationData); | |
1572 while (ptr < ptrEnd) { | |
1573 memcpy(dst, ptr, rowSize); | |
1574 ptr += srcStride; | |
1575 dst += dstStride; | |
1576 } | |
1577 return true; | |
1578 } | |
1579 | |
1580 FormatConverter converter(width, height, sourceData, destinationData, srcStr
ide, dstStride); | |
1581 converter.convert(sourceDataFormat, dstDataFormat, alphaOp); | |
1582 if (!converter.Success()) | |
1583 return false; | |
1584 return true; | |
1585 } | |
1586 | |
1587 } // namespace WebCore | |
1588 | |
OLD | NEW |