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