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

Side by Side Diff: Source/core/platform/graphics/GraphicsContext3DImagePacking.cpp

Issue 99103006: Moving GraphicsContext and dependencies from core to platform. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Final patch - fixes Android Created 7 years 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 | Annotate | Revision Log
OLDNEW
(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
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/GraphicsContext3D.cpp ('k') | Source/core/platform/graphics/GraphicsContextAnnotation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698