2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * Copyright (C) 2010 Mozilla Corporation. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
28 #include "platform/graphics/GraphicsContext3D.h"
30 #include "platform/graphics/cpu/arm/GraphicsContext3DNEON.h"
31 #include "platform/image-decoders/ImageDecoder.h"
32 #include "platform/graphics/ImageObserver.h"
38 GraphicsContext3D::DataFormat getDataFormat(GLenum destinationFormat, GLenum destinationType)
40 GraphicsContext3D::DataFormat dstFormat = GraphicsContext3D::DataFormatRGBA8;
41 switch (destinationType) {
42 case GL_UNSIGNED_BYTE:
43 switch (destinationFormat) {
45 dstFormat = GraphicsContext3D::DataFormatRGB8;
48 dstFormat = GraphicsContext3D::DataFormatRGBA8;
51 dstFormat = GraphicsContext3D::DataFormatA8;
54 dstFormat = GraphicsContext3D::DataFormatR8;
56 case GL_LUMINANCE_ALPHA:
57 dstFormat = GraphicsContext3D::DataFormatRA8;
63 case GL_UNSIGNED_SHORT_4_4_4_4:
64 dstFormat = GraphicsContext3D::DataFormatRGBA4444;
66 case GL_UNSIGNED_SHORT_5_5_5_1:
67 dstFormat = GraphicsContext3D::DataFormatRGBA5551;
69 case GL_UNSIGNED_SHORT_5_6_5:
70 dstFormat = GraphicsContext3D::DataFormatRGB565;
72 case GL_HALF_FLOAT_OES: // OES_texture_half_float
73 switch (destinationFormat) {
75 dstFormat = GraphicsContext3D::DataFormatRGB16F;
78 dstFormat = GraphicsContext3D::DataFormatRGBA16F;
81 dstFormat = GraphicsContext3D::DataFormatA16F;
84 dstFormat = GraphicsContext3D::DataFormatR16F;
86 case GL_LUMINANCE_ALPHA:
87 dstFormat = GraphicsContext3D::DataFormatRA16F;
93 case GL_FLOAT: // OES_texture_float
94 switch (destinationFormat) {
96 dstFormat = GraphicsContext3D::DataFormatRGB32F;
99 dstFormat = GraphicsContext3D::DataFormatRGBA32F;
102 dstFormat = GraphicsContext3D::DataFormatA32F;
105 dstFormat = GraphicsContext3D::DataFormatR32F;
107 case GL_LUMINANCE_ALPHA:
108 dstFormat = GraphicsContext3D::DataFormatRA32F;
111 ASSERT_NOT_REACHED();
115 ASSERT_NOT_REACHED();
120 // Following Float to Half-Float converion code is from the implementation of ftp://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:
124 unsigned short basetable[512];
125 unsigned char shifttable[512];
127 void generatetables(){
130 for (i = 0; i < 256; ++i){
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;
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;
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;
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;
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;
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
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
236 unsigned short convertFloatToHalfFloat(float f)
238 unsigned temp = *(reinterpret_cast<unsigned *>(&f));
239 unsigned signexp = (temp >> 23) & 0x1ff;
240 return baseTable[signexp] + ((temp & 0x007fffff) >> shiftTable[signexp]);
243 /* BEGIN CODE SHARED WITH MOZILLA FIREFOX */
245 // The following packing and unpacking routines are expressed in terms of function 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
249 //----------------------------------------------------------------------
250 // Pixel unpacking routines.
251 template<int format, typename SourceType, typename DstType>
252 void unpack(const SourceType*, DstType*, unsigned)
254 ASSERT_NOT_REACHED();
257 template<> void unpack<GraphicsContext3D::DataFormatRGB8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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;
269 template<> void unpack<GraphicsContext3D::DataFormatBGR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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;
281 template<> void unpack<GraphicsContext3D::DataFormatARGB8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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];
293 template<> void unpack<GraphicsContext3D::DataFormatABGR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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];
305 template<> void unpack<GraphicsContext3D::DataFormatBGRA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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];
312 uint32_t brMask = 0xff00ff00;
313 uint32_t gaMask = 0x00ff00ff;
315 uint32_t brMask = 0x00ff00ff;
316 uint32_t gaMask = 0xff00ff00;
318 uint32_t rgba = (((bgra >> 16) | (bgra << 16)) & brMask) | (bgra & gaMask);
319 destination32[i] = rgba;
323 template<> void unpack<GraphicsContext3D::DataFormatRGBA5551, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
325 #if HAVE(ARM_NEON_INTRINSICS)
326 SIMD::unpackOneRowOfRGBA5551ToRGBA8(source, destination, pixelsPerRow);
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;
342 template<> void unpack<GraphicsContext3D::DataFormatRGBA4444, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
344 #if HAVE(ARM_NEON_INTRINSICS)
345 SIMD::unpackOneRowOfRGBA4444ToRGBA8(source, destination, pixelsPerRow);
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;
362 template<> void unpack<GraphicsContext3D::DataFormatRGB565, uint16_t, uint8_t>(const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
364 #if HAVE(ARM_NEON_INTRINSICS)
365 SIMD::unpackOneRowOfRGB565ToRGBA8(source, destination, pixelsPerRow);
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;
381 template<> void unpack<GraphicsContext3D::DataFormatR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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;
393 template<> void unpack<GraphicsContext3D::DataFormatRA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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];
405 template<> void unpack<GraphicsContext3D::DataFormatAR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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];
417 template<> void unpack<GraphicsContext3D::DataFormatA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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];
429 template<> void unpack<GraphicsContext3D::DataFormatRGBA8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
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;
442 template<> void unpack<GraphicsContext3D::DataFormatBGRA8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
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;
455 template<> void unpack<GraphicsContext3D::DataFormatABGR8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
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;
468 template<> void unpack<GraphicsContext3D::DataFormatARGB8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
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;
481 template<> void unpack<GraphicsContext3D::DataFormatRGB8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
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;
494 template<> void unpack<GraphicsContext3D::DataFormatBGR8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
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;
507 template<> void unpack<GraphicsContext3D::DataFormatRGB32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
509 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
510 destination[0] = source[0];
511 destination[1] = source[1];
512 destination[2] = source[2];
519 template<> void unpack<GraphicsContext3D::DataFormatR32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
521 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
522 destination[0] = source[0];
523 destination[1] = source[0];
524 destination[2] = source[0];
531 template<> void unpack<GraphicsContext3D::DataFormatRA32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
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];
543 template<> void unpack<GraphicsContext3D::DataFormatA32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
545 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
549 destination[3] = source[0];
555 //----------------------------------------------------------------------
556 // Pixel packing routines.
559 template<int format, int alphaOp, typename SourceType, typename DstType>
560 void pack(const SourceType*, DstType*, unsigned)
562 ASSERT_NOT_REACHED();
565 template<> void pack<GraphicsContext3D::DataFormatA8, GraphicsContext3D::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
567 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
568 destination[0] = source[3];
574 template<> void pack<GraphicsContext3D::DataFormatR8, GraphicsContext3D::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
576 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
577 destination[0] = source[0];
583 template<> void pack<GraphicsContext3D::DataFormatR8, GraphicsContext3D::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
588 destination[0] = sourceR;
594 // FIXME: this routine is lossy and must be removed.
595 template<> void pack<GraphicsContext3D::DataFormatR8, GraphicsContext3D::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
600 destination[0] = sourceR;
606 template<> void pack<GraphicsContext3D::DataFormatRA8, GraphicsContext3D::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
608 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
609 destination[0] = source[0];
610 destination[1] = source[3];
616 template<> void pack<GraphicsContext3D::DataFormatRA8, GraphicsContext3D::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
621 destination[0] = sourceR;
622 destination[1] = source[3];
628 // FIXME: this routine is lossy and must be removed.
629 template<> void pack<GraphicsContext3D::DataFormatRA8, GraphicsContext3D::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
634 destination[0] = sourceR;
635 destination[1] = source[3];
641 template<> void pack<GraphicsContext3D::DataFormatRGB8, GraphicsContext3D::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
643 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
644 destination[0] = source[0];
645 destination[1] = source[1];
646 destination[2] = source[2];
652 template<> void pack<GraphicsContext3D::DataFormatRGB8, GraphicsContext3D::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
657 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
658 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
659 destination[0] = sourceR;
660 destination[1] = sourceG;
661 destination[2] = sourceB;
667 // FIXME: this routine is lossy and must be removed.
668 template<> void pack<GraphicsContext3D::DataFormatRGB8, GraphicsContext3D::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
673 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
674 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
675 destination[0] = sourceR;
676 destination[1] = sourceG;
677 destination[2] = sourceB;
684 template<> void pack<GraphicsContext3D::DataFormatRGBA8, GraphicsContext3D::AlphaDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
686 memcpy(destination, source, pixelsPerRow * 4);
689 template<> void pack<GraphicsContext3D::DataFormatRGBA8, GraphicsContext3D::AlphaDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
694 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
695 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
696 destination[0] = sourceR;
697 destination[1] = sourceG;
698 destination[2] = sourceB;
699 destination[3] = source[3];
705 // FIXME: this routine is lossy and must be removed.
706 template<> void pack<GraphicsContext3D::DataFormatRGBA8, GraphicsContext3D::AlphaDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
711 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
712 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
713 destination[0] = sourceR;
714 destination[1] = sourceG;
715 destination[2] = sourceB;
716 destination[3] = source[3];
722 template<> void pack<GraphicsContext3D::DataFormatRGBA4444, GraphicsContext3D::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
724 #if HAVE(ARM_NEON_INTRINSICS)
725 SIMD::packOneRowOfRGBA8ToUnsignedShort4444(source, destination, pixelsPerRow);
727 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
728 *destination = (((source[0] & 0xF0) << 8)
729 | ((source[1] & 0xF0) << 4)
737 template<> void pack<GraphicsContext3D::DataFormatRGBA4444, GraphicsContext3D::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
742 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
743 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
744 *destination = (((sourceR & 0xF0) << 8)
745 | ((sourceG & 0xF0) << 4)
753 // FIXME: this routine is lossy and must be removed.
754 template<> void pack<GraphicsContext3D::DataFormatRGBA4444, GraphicsContext3D::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
759 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
760 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
761 *destination = (((sourceR & 0xF0) << 8)
762 | ((sourceG & 0xF0) << 4)
770 template<> void pack<GraphicsContext3D::DataFormatRGBA5551, GraphicsContext3D::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
772 #if HAVE(ARM_NEON_INTRINSICS)
773 SIMD::packOneRowOfRGBA8ToUnsignedShort5551(source, destination, pixelsPerRow);
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)
785 template<> void pack<GraphicsContext3D::DataFormatRGBA5551, GraphicsContext3D::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
790 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
791 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
792 *destination = (((sourceR & 0xF8) << 8)
793 | ((sourceG & 0xF8) << 3)
794 | ((sourceB & 0xF8) >> 2)
801 // FIXME: this routine is lossy and must be removed.
802 template<> void pack<GraphicsContext3D::DataFormatRGBA5551, GraphicsContext3D::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
807 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
808 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
809 *destination = (((sourceR & 0xF8) << 8)
810 | ((sourceG & 0xF8) << 3)
811 | ((sourceB & 0xF8) >> 2)
818 template<> void pack<GraphicsContext3D::DataFormatRGB565, GraphicsContext3D::AlphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
820 #if HAVE(ARM_NEON_INTRINSICS)
821 SIMD::packOneRowOfRGBA8ToUnsignedShort565(source, destination, pixelsPerRow);
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));
832 template<> void pack<GraphicsContext3D::DataFormatRGB565, GraphicsContext3D::AlphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
837 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
838 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
839 *destination = (((sourceR & 0xF8) << 8)
840 | ((sourceG & 0xFC) << 3)
841 | ((sourceB & 0xF8) >> 3));
847 // FIXME: this routine is lossy and must be removed.
848 template<> void pack<GraphicsContext3D::DataFormatRGB565, GraphicsContext3D::AlphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
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]) * scaleFactor);
853 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
854 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
855 *destination = (((sourceR & 0xF8) << 8)
856 | ((sourceG & 0xFC) << 3)
857 | ((sourceB & 0xF8) >> 3));
863 template<> void pack<GraphicsContext3D::DataFormatRGB32F, GraphicsContext3D::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
865 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
866 destination[0] = source[0];
867 destination[1] = source[1];
868 destination[2] = source[2];
874 template<> void pack<GraphicsContext3D::DataFormatRGB32F, GraphicsContext3D::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
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;
886 template<> void pack<GraphicsContext3D::DataFormatRGB32F, GraphicsContext3D::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
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;
898 // Used only during RGBA8 or BGRA8 -> floating-point uploads.
899 template<> void pack<GraphicsContext3D::DataFormatRGBA32F, GraphicsContext3D::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
901 memcpy(destination, source, pixelsPerRow * 4 * sizeof(float));
904 template<> void pack<GraphicsContext3D::DataFormatRGBA32F, GraphicsContext3D::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
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];
917 template<> void pack<GraphicsContext3D::DataFormatRGBA32F, GraphicsContext3D::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
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];
930 template<> void pack<GraphicsContext3D::DataFormatA32F, GraphicsContext3D::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
932 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
933 destination[0] = source[3];
939 template<> void pack<GraphicsContext3D::DataFormatR32F, GraphicsContext3D::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
941 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
942 destination[0] = source[0];
948 template<> void pack<GraphicsContext3D::DataFormatR32F, GraphicsContext3D::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
950 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
951 float scaleFactor = source[3];
952 destination[0] = source[0] * scaleFactor;
958 template<> void pack<GraphicsContext3D::DataFormatR32F, GraphicsContext3D::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
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;
968 template<> void pack<GraphicsContext3D::DataFormatRA32F, GraphicsContext3D::AlphaDoNothing, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
970 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
971 destination[0] = source[0];
972 destination[1] = source[3];
978 template<> void pack<GraphicsContext3D::DataFormatRA32F, GraphicsContext3D::AlphaDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
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];
989 template<> void pack<GraphicsContext3D::DataFormatRA32F, GraphicsContext3D::AlphaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
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];
1000 template<> void pack<GraphicsContext3D::DataFormatRGBA16F, GraphicsContext3D::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
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]);
1012 template<> void pack<GraphicsContext3D::DataFormatRGBA16F, GraphicsContext3D::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
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]);
1025 template<> void pack<GraphicsContext3D::DataFormatRGBA16F, GraphicsContext3D::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
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]);
1038 template<> void pack<GraphicsContext3D::DataFormatRGB16F, GraphicsContext3D::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
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]);
1049 template<> void pack<GraphicsContext3D::DataFormatRGB16F, GraphicsContext3D::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
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);
1061 template<> void pack<GraphicsContext3D::DataFormatRGB16F, GraphicsContext3D::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
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);
1073 template<> void pack<GraphicsContext3D::DataFormatRA16F, GraphicsContext3D::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1075 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1076 destination[0] = convertFloatToHalfFloat(source[0]);
1077 destination[1] = convertFloatToHalfFloat(source[3]);
1083 template<> void pack<GraphicsContext3D::DataFormatRA16F, GraphicsContext3D::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
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]);
1094 template<> void pack<GraphicsContext3D::DataFormatRA16F, GraphicsContext3D::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
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]);
1105 template<> void pack<GraphicsContext3D::DataFormatR16F, GraphicsContext3D::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1107 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1108 destination[0] = convertFloatToHalfFloat(source[0]);
1114 template<> void pack<GraphicsContext3D::DataFormatR16F, GraphicsContext3D::AlphaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1116 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1117 float scaleFactor = source[3];
1118 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1124 template<> void pack<GraphicsContext3D::DataFormatR16F, GraphicsContext3D::AlphaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
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);
1134 template<> void pack<GraphicsContext3D::DataFormatA16F, GraphicsContext3D::AlphaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1136 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1137 destination[0] = convertFloatToHalfFloat(source[3]);
1143 bool HasAlpha(int format)
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;
1162 bool HasColor(int format)
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;
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;
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;
1206 template<int Format>
1207 struct Is16bppFormat {
1208 static const bool Value =
1209 Format == GraphicsContext3D::DataFormatRGBA5551
1210 || Format == GraphicsContext3D::DataFormatRGBA4444
1211 || Format == GraphicsContext3D::DataFormatRGB565;
1214 template<int Format, bool IsFloat = IsFloatFormat<Format>::Value, bool IsHalfFloat = IsHalfFloatFormat<Format>::Value, bool Is16bpp = Is16bppFormat<Format>::Value>
1215 struct DataTypeForFormat {
1216 typedef uint8_t Type;
1219 template<int Format>
1220 struct DataTypeForFormat<Format, true, false, false> {
1224 template<int Format>
1225 struct DataTypeForFormat<Format, false, true, false> {
1226 typedef uint16_t Type;
1229 template<int Format>
1230 struct DataTypeForFormat<Format, false, false, true> {
1231 typedef uint16_t Type;
1234 template<int Format>
1235 struct IntermediateFormat {
1236 static const int Value = (IsFloatFormat<Format>::Value || IsHalfFloatFormat<Format>::Value) ? GraphicsContext3D::DataFormatRGBA32F : GraphicsContext3D::DataFormatRGBA8;
1239 unsigned TexelBytesForFormat(GraphicsContext3D::DataFormat format)
1242 case GraphicsContext3D::DataFormatR8:
1243 case GraphicsContext3D::DataFormatA8:
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:
1253 case GraphicsContext3D::DataFormatRGB8:
1254 case GraphicsContext3D::DataFormatBGR8:
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:
1264 case GraphicsContext3D::DataFormatRGB16F:
1266 case GraphicsContext3D::DataFormatRA32F:
1267 case GraphicsContext3D::DataFormatRGBA16F:
1269 case GraphicsContext3D::DataFormatRGB32F:
1271 case GraphicsContext3D::DataFormatRGBA32F:
1278 /* END CODE SHARED WITH MOZILLA FIREFOX */
1280 class FormatConverter {
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(dstStart), m_srcStride(srcStride), m_dstStride(dstStride), m_success(false)
1286 const unsigned MaxNumberOfComponents = 4;
1287 const unsigned MaxBytesPerComponent = 4;
1288 m_unpackedIntermediateSrcData = adoptArrayPtr(new uint8_t[m_width * MaxNumberOfComponents *MaxBytesPerComponent]);
1289 ASSERT(m_unpackedIntermediateSrcData.get());
1292 void convert(GraphicsContext3D::DataFormat srcFormat, GraphicsContext3D::DataFormat dstFormat, GraphicsContext3D::AlphaOp);
1293 bool Success() const { return m_success; }
1296 template<GraphicsContext3D::DataFormat SrcFormat>
1297 void convert(GraphicsContext3D::DataFormat dstFormat, GraphicsContext3D::AlphaOp);
1299 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFormat DstFormat>
1300 void convert(GraphicsContext3D::AlphaOp);
1302 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFormat DstFormat, GraphicsContext3D::AlphaOp alphaOp>
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;
1310 OwnPtr<uint8_t[]> m_unpackedIntermediateSrcData;
1313 void FormatConverter::convert(GraphicsContext3D::DataFormat srcFormat, GraphicsContext3D::DataFormat dstFormat, GraphicsContext3D::AlphaOp alphaOp)
1315 #define FORMATCONVERTER_CASE_SRCFORMAT(SrcFormat) \
1317 return convert<SrcFormat>(dstFormat, alphaOp);
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)
1339 ASSERT_NOT_REACHED();
1341 #undef FORMATCONVERTER_CASE_SRCFORMAT
1344 template<GraphicsContext3D::DataFormat SrcFormat>
1345 void FormatConverter::convert(GraphicsContext3D::DataFormat dstFormat, GraphicsContext3D::AlphaOp alphaOp)
1347 #define FORMATCONVERTER_CASE_DSTFORMAT(DstFormat) \
1349 return convert<SrcFormat, DstFormat>(alphaOp);
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)
1371 ASSERT_NOT_REACHED();
1374 #undef FORMATCONVERTER_CASE_DSTFORMAT
1377 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFormat DstFormat>
1378 void FormatConverter::convert(GraphicsContext3D::AlphaOp alphaOp)
1380 #define FORMATCONVERTER_CASE_ALPHAOP(alphaOp) \
1382 return convert<SrcFormat, DstFormat, alphaOp>();
1385 FORMATCONVERTER_CASE_ALPHAOP(GraphicsContext3D::AlphaDoNothing)
1386 FORMATCONVERTER_CASE_ALPHAOP(GraphicsContext3D::AlphaDoPremultiply)
1387 FORMATCONVERTER_CASE_ALPHAOP(GraphicsContext3D::AlphaDoUnmultiply)
1389 ASSERT_NOT_REACHED();
1391 #undef FORMATCONVERTER_CASE_ALPHAOP
1394 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFormat DstFormat, GraphicsContext3D::AlphaOp alphaOp>
1395 void FormatConverter::convert()
1397 // Many instantiations of this template function will never be entered, so we try
1398 // to return immediately in these cases to avoid the compiler to generate useless code.
1399 if (SrcFormat == DstFormat && alphaOp == GraphicsContext3D::AlphaDoNothing) {
1400 ASSERT_NOT_REACHED();
1403 if (!IsFloatFormat<DstFormat>::Value && IsFloatFormat<SrcFormat>::Value) {
1404 ASSERT_NOT_REACHED();
1408 // Only textures uploaded from DOM elements or ImageData can allow DstFormat != SrcFormat.
1409 const bool srcFormatComesFromDOMElementOrImageData = GraphicsContext3D::srcFormatComeFromDOMElementOrImageData(SrcFormat);
1410 if (!srcFormatComesFromDOMElementOrImageData && SrcFormat != DstFormat) {
1411 ASSERT_NOT_REACHED();
1414 // Likewise, only textures uploaded from DOM elements or ImageData can possibly have to be unpremultiplied.
1415 if (!srcFormatComesFromDOMElementOrImageData && alphaOp == GraphicsContext3D::AlphaDoUnmultiply) {
1416 ASSERT_NOT_REACHED();
1419 if ((!HasAlpha(SrcFormat) || !HasColor(SrcFormat) || !HasColor(DstFormat)) && alphaOp != GraphicsContext3D::AlphaDoNothing) {
1420 ASSERT_NOT_REACHED();
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 IntermediateSrcType;
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 == GraphicsContext3D::AlphaDoNothing && m_dstStride > 0;
1432 ASSERT(!trivialUnpack || !trivialPack);
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;
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_unpackedIntermediateSrcData.get()), dstRowStart, m_width);
1446 srcRowStart += srcStrideInElements;
1447 dstRowStart += dstStrideInElements;
1450 for (size_t i = 0; i < m_height; ++i) {
1451 pack<DstFormat, alphaOp>(srcRowStart, dstRowStart, m_width);
1452 srcRowStart += srcStrideInElements;
1453 dstRowStart += dstStrideInElements;
1460 } // anonymous namespace
1462 bool GraphicsContext3D::packImageData(
1469 DataFormat sourceFormat,
1472 unsigned sourceUnpackAlignment,
1473 Vector<uint8_t>& data)
1478 unsigned packedSize;
1479 // Output data is tightly packed (alignment == 1).
1480 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
1482 data.resize(packedSize);
1484 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, width, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY))
1486 if (ImageObserver *observer = image->imageObserver())
1487 observer->didDraw(image);
1491 bool GraphicsContext3D::extractImageData(
1492 const uint8_t* imageData,
1493 const IntSize& imageDataSize,
1497 bool premultiplyAlpha,
1498 Vector<uint8_t>& data)
1502 int width = imageDataSize.width();
1503 int height = imageDataSize.height();
1505 unsigned packedSize;
1506 // Output data is tightly packed (alignment == 1).
1507 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GL_NO_ERROR)
1509 data.resize(packedSize);
1511 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY))
1517 bool GraphicsContext3D::extractTextureData(
1520 GLenum format, GLenum type,
1521 unsigned unpackAlignment,
1522 bool flipY, bool premultiplyAlpha,
1524 Vector<uint8_t>& data)
1526 // Assumes format, type, etc. have already been validated.
1527 DataFormat sourceDataFormat = getDataFormat(format, type);
1529 // Resize the output buffer.
1530 unsigned int componentsPerPixel, bytesPerComponent;
1531 if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
1533 unsigned bytesPerPixel = componentsPerPixel * bytesPerComponent;
1534 data.resize(width * height * bytesPerPixel);
1536 if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width, height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), data.data(), flipY))
1542 bool GraphicsContext3D::packPixels(
1543 const uint8_t* sourceData,
1544 DataFormat sourceDataFormat,
1547 unsigned sourceUnpackAlignment,
1548 unsigned destinationFormat,
1549 unsigned destinationType,
1551 void* destinationData,
1554 int validSrc = width * TexelBytesForFormat(sourceDataFormat);
1555 int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
1556 int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
1558 DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType);
1559 int dstStride = width * TexelBytesForFormat(dstDataFormat);
1561 destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(height - 1);
1562 dstStride = -dstStride;
1564 if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || !HasColor(dstDataFormat))
1565 alphaOp = AlphaDoNothing;
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);
1580 FormatConverter converter(width, height, sourceData, destinationData, srcStride, dstStride);
1581 converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
1582 if (!converter.Success())
1587 } // namespace WebCore