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

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

Issue 15501004: Moved image packing code out of GraphicsContext3D.cpp and into a new file (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Apple Inc. All rights reserved. 2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Copyright (C) 2010 Mozilla Corporation. All rights reserved. 4 * Copyright (C) 2010 Mozilla Corporation. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 const int maxGaneshTextureCacheCount = 2048; 61 const int maxGaneshTextureCacheCount = 2048;
62 // The limit of the bytes allocated toward textures in the GrContext's bitmap->t exture cache. 62 // The limit of the bytes allocated toward textures in the GrContext's bitmap->t exture cache.
63 const size_t maxGaneshTextureCacheBytes = 96 * 1024 * 1024; 63 const size_t maxGaneshTextureCacheBytes = 96 * 1024 * 1024;
64 64
65 } 65 }
66 66
67 namespace WebCore { 67 namespace WebCore {
68 68
69 namespace { 69 namespace {
70 70
71 GraphicsContext3D::DataFormat getDataFormat(GC3Denum destinationFormat, GC3Denum destinationType)
72 {
73 GraphicsContext3D::DataFormat dstFormat = GraphicsContext3D::DataFormatRGBA8 ;
74 switch (destinationType) {
75 case GraphicsContext3D::UNSIGNED_BYTE:
76 switch (destinationFormat) {
77 case GraphicsContext3D::RGB:
78 dstFormat = GraphicsContext3D::DataFormatRGB8;
79 break;
80 case GraphicsContext3D::RGBA:
81 dstFormat = GraphicsContext3D::DataFormatRGBA8;
82 break;
83 case GraphicsContext3D::ALPHA:
84 dstFormat = GraphicsContext3D::DataFormatA8;
85 break;
86 case GraphicsContext3D::LUMINANCE:
87 dstFormat = GraphicsContext3D::DataFormatR8;
88 break;
89 case GraphicsContext3D::LUMINANCE_ALPHA:
90 dstFormat = GraphicsContext3D::DataFormatRA8;
91 break;
92 default:
93 ASSERT_NOT_REACHED();
94 }
95 break;
96 case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
97 dstFormat = GraphicsContext3D::DataFormatRGBA4444;
98 break;
99 case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
100 dstFormat = GraphicsContext3D::DataFormatRGBA5551;
101 break;
102 case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
103 dstFormat = GraphicsContext3D::DataFormatRGB565;
104 break;
105 case GraphicsContext3D::HALF_FLOAT_OES: // OES_texture_half_float
106 switch (destinationFormat) {
107 case GraphicsContext3D::RGB:
108 dstFormat = GraphicsContext3D::DataFormatRGB16F;
109 break;
110 case GraphicsContext3D::RGBA:
111 dstFormat = GraphicsContext3D::DataFormatRGBA16F;
112 break;
113 case GraphicsContext3D::ALPHA:
114 dstFormat = GraphicsContext3D::DataFormatA16F;
115 break;
116 case GraphicsContext3D::LUMINANCE:
117 dstFormat = GraphicsContext3D::DataFormatR16F;
118 break;
119 case GraphicsContext3D::LUMINANCE_ALPHA:
120 dstFormat = GraphicsContext3D::DataFormatRA16F;
121 break;
122 default:
123 ASSERT_NOT_REACHED();
124 }
125 break;
126 case GraphicsContext3D::FLOAT: // OES_texture_float
127 switch (destinationFormat) {
128 case GraphicsContext3D::RGB:
129 dstFormat = GraphicsContext3D::DataFormatRGB32F;
130 break;
131 case GraphicsContext3D::RGBA:
132 dstFormat = GraphicsContext3D::DataFormatRGBA32F;
133 break;
134 case GraphicsContext3D::ALPHA:
135 dstFormat = GraphicsContext3D::DataFormatA32F;
136 break;
137 case GraphicsContext3D::LUMINANCE:
138 dstFormat = GraphicsContext3D::DataFormatR32F;
139 break;
140 case GraphicsContext3D::LUMINANCE_ALPHA:
141 dstFormat = GraphicsContext3D::DataFormatRA32F;
142 break;
143 default:
144 ASSERT_NOT_REACHED();
145 }
146 break;
147 default:
148 ASSERT_NOT_REACHED();
149 }
150 return dstFormat;
151 }
152
153 void getDrawingParameters(DrawingBuffer* drawingBuffer, WebKit::WebGraphicsConte xt3D* graphicsContext3D, 71 void getDrawingParameters(DrawingBuffer* drawingBuffer, WebKit::WebGraphicsConte xt3D* graphicsContext3D,
154 Platform3DObject* frameBufferId, int* width, int* heig ht) 72 Platform3DObject* frameBufferId, int* width, int* heig ht)
155 { 73 {
156 if (drawingBuffer) { 74 if (drawingBuffer) {
157 *frameBufferId = drawingBuffer->framebuffer(); 75 *frameBufferId = drawingBuffer->framebuffer();
158 *width = drawingBuffer->size().width(); 76 *width = drawingBuffer->size().width();
159 *height = drawingBuffer->size().height(); 77 *height = drawingBuffer->size().height();
160 } else { 78 } else {
161 *frameBufferId = 0; 79 *frameBufferId = 0;
162 *width = graphicsContext3D->width(); 80 *width = graphicsContext3D->width();
163 *height = graphicsContext3D->height(); 81 *height = graphicsContext3D->height();
164 } 82 }
165 } 83 }
166 84
167 // Following Float to Half-Float converion code is from the implementation of ft p://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf,
168 // "Fast Half Float Conversions" by Jeroen van der Zijp, November 2008 (Revised September 2010).
169 // Specially, the basetable[512] and shifttable[512] are generated as follows:
170 /*
171 unsigned short basetable[512];
172 unsigned char shifttable[512];
173
174 void generatetables(){
175 unsigned int i;
176 int e;
177 for (i = 0; i < 256; ++i){
178 e = i - 127;
179 if (e < -24){ // Very small numbers map to zero
180 basetable[i | 0x000] = 0x0000;
181 basetable[i | 0x100] = 0x8000;
182 shifttable[i | 0x000] = 24;
183 shifttable[i | 0x100] = 24;
184 }
185 else if (e < -14) { // Small numbers map to denorms
186 basetable[i | 0x000] = (0x0400>>(-e-14));
187 basetable[i | 0x100] = (0x0400>>(-e-14)) | 0x8000;
188 shifttable[i | 0x000] = -e-1;
189 shifttable[i | 0x100] = -e-1;
190 }
191 else if (e <= 15){ // Normal numbers just lose precision
192 basetable[i | 0x000] = ((e+15)<<10);
193 basetable[i| 0x100] = ((e+15)<<10) | 0x8000;
194 shifttable[i|0x000] = 13;
195 shifttable[i|0x100] = 13;
196 }
197 else if (e<128){ // Large numbers map to Infinity
198 basetable[i|0x000] = 0x7C00;
199 basetable[i|0x100] = 0xFC00;
200 shifttable[i|0x000] = 24;
201 shifttable[i|0x100] = 24;
202 }
203 else { // Infinity and NaN's stay Infinity and NaN's
204 basetable[i|0x000] = 0x7C00;
205 basetable[i|0x100] = 0xFC00;
206 shifttable[i|0x000] = 13;
207 shifttable[i|0x100] = 13;
208 }
209 }
210 }
211 */
212
213 unsigned short baseTable[512] = {
214 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
215 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
216 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
219 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
220 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64, 128, 256,
221 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360,
222 16384, 17408, 18432, 19456, 20480, 21504, 22528, 23552, 24576, 25600, 26624, 27648, 28672, 29696, 30720, 31744,
223 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
224 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
225 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
226 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
227 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
228 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
229 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744, 31744,
230 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
231 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
232 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
233 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
234 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
235 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768,
236 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32769, 32770, 32772, 32776, 32784, 32800, 32832, 32896, 33024,
237 33280, 33792, 34816, 35840, 36864, 37888, 38912, 39936, 40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128,
238 49152, 50176, 51200, 52224, 53248, 54272, 55296, 56320, 57344, 58368, 59392, 60416, 61440, 62464, 63488, 64512,
239 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
240 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
241 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
242 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
243 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
244 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512,
245 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512
246 };
247
248 unsigned char shiftTable[512] = {
249 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
250 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
251 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
252 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
253 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
254 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
255 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
256 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
257 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24,
258 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
259 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
260 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
261 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
262 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
263 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
264 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13,
265 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
266 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
267 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
268 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
269 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
270 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
271 24, 24, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
272 14, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
273 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 24,
274 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
275 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
276 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
277 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
278 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
279 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
280 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 13
281 };
282
283 unsigned short convertFloatToHalfFloat(float f)
284 {
285 unsigned temp = *(reinterpret_cast<unsigned *>(&f));
286 unsigned signexp = (temp >> 23) & 0x1ff;
287 return baseTable[signexp] + ((temp & 0x007fffff) >> shiftTable[signexp]);
288 }
289
290 } // anonymous namespace 85 } // anonymous namespace
291 86
292 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3D> we bContext, bool preserveDrawingBuffer) 87 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3D> we bContext, bool preserveDrawingBuffer)
293 : m_impl(webContext.get()) 88 : m_impl(webContext.get())
294 , m_ownedWebContext(webContext) 89 , m_ownedWebContext(webContext)
295 , m_initializedAvailableExtensions(false) 90 , m_initializedAvailableExtensions(false)
296 , m_layerComposited(false) 91 , m_layerComposited(false)
297 , m_preserveDrawingBuffer(preserveDrawingBuffer) 92 , m_preserveDrawingBuffer(preserveDrawingBuffer)
298 , m_resourceSafety(ResourceSafetyUnknown) 93 , m_resourceSafety(ResourceSafetyUnknown)
299 , m_grContext(0) 94 , m_grContext(0)
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 m_imageWidth = m_skiaImage->bitmap().width(); 822 m_imageWidth = m_skiaImage->bitmap().width();
1028 m_imageHeight = m_skiaImage->bitmap().height(); 823 m_imageHeight = m_skiaImage->bitmap().height();
1029 if (!m_imageWidth || !m_imageHeight) 824 if (!m_imageWidth || !m_imageHeight)
1030 return false; 825 return false;
1031 m_imageSourceUnpackAlignment = 0; 826 m_imageSourceUnpackAlignment = 0;
1032 m_skiaImage->bitmap().lockPixels(); 827 m_skiaImage->bitmap().lockPixels();
1033 m_imagePixelData = m_skiaImage->bitmap().getPixels(); 828 m_imagePixelData = m_skiaImage->bitmap().getPixels();
1034 return true; 829 return true;
1035 } 830 }
1036 831
1037 bool GraphicsContext3D::packImageData(
1038 Image* image,
1039 const void* pixels,
1040 GC3Denum format,
1041 GC3Denum type,
1042 bool flipY,
1043 AlphaOp alphaOp,
1044 DataFormat sourceFormat,
1045 unsigned width,
1046 unsigned height,
1047 unsigned sourceUnpackAlignment,
1048 Vector<uint8_t>& data)
1049 {
1050 if (!pixels)
1051 return false;
1052
1053 unsigned packedSize;
1054 // Output data is tightly packed (alignment == 1).
1055 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
1056 return false;
1057 data.resize(packedSize);
1058
1059 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, widt h, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY))
1060 return false;
1061 if (ImageObserver *observer = image->imageObserver())
1062 observer->didDraw(image);
1063 return true;
1064 }
1065
1066 bool GraphicsContext3D::extractImageData(ImageData* imageData,
1067 GC3Denum format,
1068 GC3Denum type,
1069 bool flipY,
1070 bool premultiplyAlpha,
1071 Vector<uint8_t>& data)
1072 {
1073 if (!imageData)
1074 return false;
1075 int width = imageData->width();
1076 int height = imageData->height();
1077
1078 unsigned int packedSize;
1079 // Output data is tightly packed (alignment == 1).
1080 if (computeImageSizeInBytes(format, type, width, height, 1, &packedSize, 0) != GraphicsContext3D::NO_ERROR)
1081 return false;
1082 data.resize(packedSize);
1083
1084 if (!packPixels(imageData->data()->data(), DataFormatRGBA8, width, height, 0 , format, type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.dat a(), flipY))
1085 return false;
1086
1087 return true;
1088 }
1089
1090 bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int heig ht,
1091 GC3Denum format, GC3Denum type,
1092 unsigned int unpackAlignment,
1093 bool flipY, bool premultiplyAlpha,
1094 const void* pixels,
1095 Vector<uint8_t>& data)
1096 {
1097 // Assumes format, type, etc. have already been validated.
1098 DataFormat sourceDataFormat = getDataFormat(format, type);
1099
1100 // Resize the output buffer.
1101 unsigned int componentsPerPixel, bytesPerComponent;
1102 if (!computeFormatAndTypeParameters(format, type,
1103 &componentsPerPixel,
1104 &bytesPerComponent))
1105 return false;
1106 unsigned int bytesPerPixel = componentsPerPixel * bytesPerComponent;
1107 data.resize(width * height * bytesPerPixel);
1108
1109 if (!packPixels(static_cast<const uint8_t*>(pixels), sourceDataFormat, width , height, unpackAlignment, format, type, (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing), data.data(), flipY))
1110 return false;
1111
1112 return true;
1113 }
1114
1115 namespace {
1116
1117 /* BEGIN CODE SHARED WITH MOZILLA FIREFOX */
1118
1119 // The following packing and unpacking routines are expressed in terms of functi on templates and inline functions to achieve generality and speedup.
1120 // Explicit template specializations correspond to the cases that would occur.
1121 // Some code are merged back from Mozilla code in http://mxr.mozilla.org/mozilla -central/source/content/canvas/src/WebGLTexelConversions.h
1122
1123 //----------------------------------------------------------------------
1124 // Pixel unpacking routines.
1125 template<int format, typename SourceType, typename DstType>
1126 void unpack(const SourceType*, DstType*, unsigned)
1127 {
1128 ASSERT_NOT_REACHED();
1129 }
1130
1131 template<> void unpack<GraphicsContext3D::DataFormatRGB8, uint8_t, uint8_t>(cons t uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1132 {
1133 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1134 destination[0] = source[0];
1135 destination[1] = source[1];
1136 destination[2] = source[2];
1137 destination[3] = 0xFF;
1138 source += 3;
1139 destination += 4;
1140 }
1141 }
1142
1143 template<> void unpack<GraphicsContext3D::DataFormatBGR8, uint8_t, uint8_t>(cons t uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1144 {
1145 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1146 destination[0] = source[2];
1147 destination[1] = source[1];
1148 destination[2] = source[0];
1149 destination[3] = 0xFF;
1150 source += 3;
1151 destination += 4;
1152 }
1153 }
1154
1155 template<> void unpack<GraphicsContext3D::DataFormatARGB8, uint8_t, uint8_t>(con st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1156 {
1157 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1158 destination[0] = source[1];
1159 destination[1] = source[2];
1160 destination[2] = source[3];
1161 destination[3] = source[0];
1162 source += 4;
1163 destination += 4;
1164 }
1165 }
1166
1167 template<> void unpack<GraphicsContext3D::DataFormatABGR8, uint8_t, uint8_t>(con st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1168 {
1169 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1170 destination[0] = source[3];
1171 destination[1] = source[2];
1172 destination[2] = source[1];
1173 destination[3] = source[0];
1174 source += 4;
1175 destination += 4;
1176 }
1177 }
1178
1179 template<> void unpack<GraphicsContext3D::DataFormatBGRA8, uint8_t, uint8_t>(con st uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1180 {
1181 const uint32_t* source32 = reinterpret_cast_ptr<const uint32_t*>(source);
1182 uint32_t* destination32 = reinterpret_cast_ptr<uint32_t*>(destination);
1183 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1184 uint32_t bgra = source32[i];
1185 #if CPU(BIG_ENDIAN)
1186 uint32_t brMask = 0xff00ff00;
1187 uint32_t gaMask = 0x00ff00ff;
1188 #else
1189 uint32_t brMask = 0x00ff00ff;
1190 uint32_t gaMask = 0xff00ff00;
1191 #endif
1192 uint32_t rgba = (((bgra >> 16) | (bgra << 16)) & brMask) | (bgra & gaMas k);
1193 destination32[i] = rgba;
1194 }
1195 }
1196
1197 template<> void unpack<GraphicsContext3D::DataFormatRGBA5551, uint16_t, uint8_t> (const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
1198 {
1199 #if HAVE(ARM_NEON_INTRINSICS)
1200 SIMD::unpackOneRowOfRGBA5551ToRGBA8(source, destination, pixelsPerRow);
1201 #endif
1202 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1203 uint16_t packedValue = source[0];
1204 uint8_t r = packedValue >> 11;
1205 uint8_t g = (packedValue >> 6) & 0x1F;
1206 uint8_t b = (packedValue >> 1) & 0x1F;
1207 destination[0] = (r << 3) | (r & 0x7);
1208 destination[1] = (g << 3) | (g & 0x7);
1209 destination[2] = (b << 3) | (b & 0x7);
1210 destination[3] = (packedValue & 0x1) ? 0xFF : 0x0;
1211 source += 1;
1212 destination += 4;
1213 }
1214 }
1215
1216 template<> void unpack<GraphicsContext3D::DataFormatRGBA4444, uint16_t, uint8_t> (const uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
1217 {
1218 #if HAVE(ARM_NEON_INTRINSICS)
1219 SIMD::unpackOneRowOfRGBA4444ToRGBA8(source, destination, pixelsPerRow);
1220 #endif
1221 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1222 uint16_t packedValue = source[0];
1223 uint8_t r = packedValue >> 12;
1224 uint8_t g = (packedValue >> 8) & 0x0F;
1225 uint8_t b = (packedValue >> 4) & 0x0F;
1226 uint8_t a = packedValue & 0x0F;
1227 destination[0] = r << 4 | r;
1228 destination[1] = g << 4 | g;
1229 destination[2] = b << 4 | b;
1230 destination[3] = a << 4 | a;
1231 source += 1;
1232 destination += 4;
1233 }
1234 }
1235
1236 template<> void unpack<GraphicsContext3D::DataFormatRGB565, uint16_t, uint8_t>(c onst uint16_t* source, uint8_t* destination, unsigned pixelsPerRow)
1237 {
1238 #if HAVE(ARM_NEON_INTRINSICS)
1239 SIMD::unpackOneRowOfRGB565ToRGBA8(source, destination, pixelsPerRow);
1240 #endif
1241 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1242 uint16_t packedValue = source[0];
1243 uint8_t r = packedValue >> 11;
1244 uint8_t g = (packedValue >> 5) & 0x3F;
1245 uint8_t b = packedValue & 0x1F;
1246 destination[0] = (r << 3) | (r & 0x7);
1247 destination[1] = (g << 2) | (g & 0x3);
1248 destination[2] = (b << 3) | (b & 0x7);
1249 destination[3] = 0xFF;
1250 source += 1;
1251 destination += 4;
1252 }
1253 }
1254
1255 template<> void unpack<GraphicsContext3D::DataFormatR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1256 {
1257 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1258 destination[0] = source[0];
1259 destination[1] = source[0];
1260 destination[2] = source[0];
1261 destination[3] = 0xFF;
1262 source += 1;
1263 destination += 4;
1264 }
1265 }
1266
1267 template<> void unpack<GraphicsContext3D::DataFormatRA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1268 {
1269 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1270 destination[0] = source[0];
1271 destination[1] = source[0];
1272 destination[2] = source[0];
1273 destination[3] = source[1];
1274 source += 2;
1275 destination += 4;
1276 }
1277 }
1278
1279 template<> void unpack<GraphicsContext3D::DataFormatAR8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1280 {
1281 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1282 destination[0] = source[1];
1283 destination[1] = source[1];
1284 destination[2] = source[1];
1285 destination[3] = source[0];
1286 source += 2;
1287 destination += 4;
1288 }
1289 }
1290
1291 template<> void unpack<GraphicsContext3D::DataFormatA8, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1292 {
1293 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1294 destination[0] = 0x0;
1295 destination[1] = 0x0;
1296 destination[2] = 0x0;
1297 destination[3] = source[0];
1298 source += 1;
1299 destination += 4;
1300 }
1301 }
1302
1303 template<> void unpack<GraphicsContext3D::DataFormatRGBA8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
1304 {
1305 const float scaleFactor = 1.0f / 255.0f;
1306 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1307 destination[0] = source[0] * scaleFactor;
1308 destination[1] = source[1] * scaleFactor;
1309 destination[2] = source[2] * scaleFactor;
1310 destination[3] = source[3] * scaleFactor;
1311 source += 4;
1312 destination += 4;
1313 }
1314 }
1315
1316 template<> void unpack<GraphicsContext3D::DataFormatBGRA8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
1317 {
1318 const float scaleFactor = 1.0f / 255.0f;
1319 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1320 destination[0] = source[2] * scaleFactor;
1321 destination[1] = source[1] * scaleFactor;
1322 destination[2] = source[0] * scaleFactor;
1323 destination[3] = source[3] * scaleFactor;
1324 source += 4;
1325 destination += 4;
1326 }
1327 }
1328
1329 template<> void unpack<GraphicsContext3D::DataFormatABGR8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
1330 {
1331 const float scaleFactor = 1.0f / 255.0f;
1332 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1333 destination[0] = source[3] * scaleFactor;
1334 destination[1] = source[2] * scaleFactor;
1335 destination[2] = source[1] * scaleFactor;
1336 destination[3] = source[0] * scaleFactor;
1337 source += 4;
1338 destination += 4;
1339 }
1340 }
1341
1342 template<> void unpack<GraphicsContext3D::DataFormatARGB8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
1343 {
1344 const float scaleFactor = 1.0f / 255.0f;
1345 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1346 destination[0] = source[1] * scaleFactor;
1347 destination[1] = source[2] * scaleFactor;
1348 destination[2] = source[3] * scaleFactor;
1349 destination[3] = source[0] * scaleFactor;
1350 source += 4;
1351 destination += 4;
1352 }
1353 }
1354
1355 template<> void unpack<GraphicsContext3D::DataFormatRGB8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
1356 {
1357 const float scaleFactor = 1.0f / 255.0f;
1358 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1359 destination[0] = source[0] * scaleFactor;
1360 destination[1] = source[1] * scaleFactor;
1361 destination[2] = source[2] * scaleFactor;
1362 destination[3] = 1;
1363 source += 3;
1364 destination += 4;
1365 }
1366 }
1367
1368 template<> void unpack<GraphicsContext3D::DataFormatBGR8, uint8_t, float>(const uint8_t* source, float* destination, unsigned pixelsPerRow)
1369 {
1370 const float scaleFactor = 1.0f / 255.0f;
1371 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1372 destination[0] = source[2] * scaleFactor;
1373 destination[1] = source[1] * scaleFactor;
1374 destination[2] = source[0] * scaleFactor;
1375 destination[3] = 1;
1376 source += 3;
1377 destination += 4;
1378 }
1379 }
1380
1381 template<> void unpack<GraphicsContext3D::DataFormatRGB32F, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
1382 {
1383 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1384 destination[0] = source[0];
1385 destination[1] = source[1];
1386 destination[2] = source[2];
1387 destination[3] = 1;
1388 source += 3;
1389 destination += 4;
1390 }
1391 }
1392
1393 template<> void unpack<GraphicsContext3D::DataFormatR32F, float, float>(const fl oat* source, float* destination, unsigned pixelsPerRow)
1394 {
1395 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1396 destination[0] = source[0];
1397 destination[1] = source[0];
1398 destination[2] = source[0];
1399 destination[3] = 1;
1400 source += 1;
1401 destination += 4;
1402 }
1403 }
1404
1405 template<> void unpack<GraphicsContext3D::DataFormatRA32F, float, float>(const f loat* source, float* destination, unsigned pixelsPerRow)
1406 {
1407 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1408 destination[0] = source[0];
1409 destination[1] = source[0];
1410 destination[2] = source[0];
1411 destination[3] = source[1];
1412 source += 2;
1413 destination += 4;
1414 }
1415 }
1416
1417 template<> void unpack<GraphicsContext3D::DataFormatA32F, float, float>(const fl oat* source, float* destination, unsigned pixelsPerRow)
1418 {
1419 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1420 destination[0] = 0;
1421 destination[1] = 0;
1422 destination[2] = 0;
1423 destination[3] = source[0];
1424 source += 1;
1425 destination += 4;
1426 }
1427 }
1428
1429 //----------------------------------------------------------------------
1430 // Pixel packing routines.
1431 //
1432
1433 template<int format, int alphaOp, typename SourceType, typename DstType>
1434 void pack(const SourceType*, DstType*, unsigned)
1435 {
1436 ASSERT_NOT_REACHED();
1437 }
1438
1439 template<> void pack<GraphicsContext3D::DataFormatA8, GraphicsContext3D::AlphaDo Nothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1440 {
1441 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1442 destination[0] = source[3];
1443 source += 4;
1444 destination += 1;
1445 }
1446 }
1447
1448 template<> void pack<GraphicsContext3D::DataFormatR8, GraphicsContext3D::AlphaDo Nothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigned pixelsPerRow)
1449 {
1450 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1451 destination[0] = source[0];
1452 source += 4;
1453 destination += 1;
1454 }
1455 }
1456
1457 template<> void pack<GraphicsContext3D::DataFormatR8, GraphicsContext3D::AlphaDo Premultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsi gned pixelsPerRow)
1458 {
1459 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1460 float scaleFactor = source[3] / 255.0f;
1461 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1462 destination[0] = sourceR;
1463 source += 4;
1464 destination += 1;
1465 }
1466 }
1467
1468 // FIXME: this routine is lossy and must be removed.
1469 template<> void pack<GraphicsContext3D::DataFormatR8, GraphicsContext3D::AlphaDo Unmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsig ned pixelsPerRow)
1470 {
1471 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1472 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
1473 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1474 destination[0] = sourceR;
1475 source += 4;
1476 destination += 1;
1477 }
1478 }
1479
1480 template<> void pack<GraphicsContext3D::DataFormatRA8, GraphicsContext3D::AlphaD oNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsigne d pixelsPerRow)
1481 {
1482 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1483 destination[0] = source[0];
1484 destination[1] = source[3];
1485 source += 4;
1486 destination += 2;
1487 }
1488 }
1489
1490 template<> void pack<GraphicsContext3D::DataFormatRA8, GraphicsContext3D::AlphaD oPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, uns igned pixelsPerRow)
1491 {
1492 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1493 float scaleFactor = source[3] / 255.0f;
1494 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1495 destination[0] = sourceR;
1496 destination[1] = source[3];
1497 source += 4;
1498 destination += 2;
1499 }
1500 }
1501
1502 // FIXME: this routine is lossy and must be removed.
1503 template<> void pack<GraphicsContext3D::DataFormatRA8, GraphicsContext3D::AlphaD oUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsi gned pixelsPerRow)
1504 {
1505 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1506 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
1507 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1508 destination[0] = sourceR;
1509 destination[1] = source[3];
1510 source += 4;
1511 destination += 2;
1512 }
1513 }
1514
1515 template<> void pack<GraphicsContext3D::DataFormatRGB8, GraphicsContext3D::Alpha DoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsign ed pixelsPerRow)
1516 {
1517 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1518 destination[0] = source[0];
1519 destination[1] = source[1];
1520 destination[2] = source[2];
1521 source += 4;
1522 destination += 3;
1523 }
1524 }
1525
1526 template<> void pack<GraphicsContext3D::DataFormatRGB8, GraphicsContext3D::Alpha DoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, un signed pixelsPerRow)
1527 {
1528 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1529 float scaleFactor = source[3] / 255.0f;
1530 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1531 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1532 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1533 destination[0] = sourceR;
1534 destination[1] = sourceG;
1535 destination[2] = sourceB;
1536 source += 4;
1537 destination += 3;
1538 }
1539 }
1540
1541 // FIXME: this routine is lossy and must be removed.
1542 template<> void pack<GraphicsContext3D::DataFormatRGB8, GraphicsContext3D::Alpha DoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, uns igned pixelsPerRow)
1543 {
1544 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1545 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
1546 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1547 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1548 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1549 destination[0] = sourceR;
1550 destination[1] = sourceG;
1551 destination[2] = sourceB;
1552 source += 4;
1553 destination += 3;
1554 }
1555 }
1556
1557
1558 template<> void pack<GraphicsContext3D::DataFormatRGBA8, GraphicsContext3D::Alph aDoNothing, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, unsig ned pixelsPerRow)
1559 {
1560 memcpy(destination, source, pixelsPerRow * 4);
1561 }
1562
1563 template<> void pack<GraphicsContext3D::DataFormatRGBA8, GraphicsContext3D::Alph aDoPremultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, u nsigned pixelsPerRow)
1564 {
1565 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1566 float scaleFactor = source[3] / 255.0f;
1567 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1568 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1569 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1570 destination[0] = sourceR;
1571 destination[1] = sourceG;
1572 destination[2] = sourceB;
1573 destination[3] = source[3];
1574 source += 4;
1575 destination += 4;
1576 }
1577 }
1578
1579 // FIXME: this routine is lossy and must be removed.
1580 template<> void pack<GraphicsContext3D::DataFormatRGBA8, GraphicsContext3D::Alph aDoUnmultiply, uint8_t, uint8_t>(const uint8_t* source, uint8_t* destination, un signed pixelsPerRow)
1581 {
1582 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1583 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
1584 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1585 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1586 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1587 destination[0] = sourceR;
1588 destination[1] = sourceG;
1589 destination[2] = sourceB;
1590 destination[3] = source[3];
1591 source += 4;
1592 destination += 4;
1593 }
1594 }
1595
1596 template<> void pack<GraphicsContext3D::DataFormatRGBA4444, GraphicsContext3D::A lphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
1597 {
1598 #if HAVE(ARM_NEON_INTRINSICS)
1599 SIMD::packOneRowOfRGBA8ToUnsignedShort4444(source, destination, pixelsPerRow );
1600 #endif
1601 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1602 *destination = (((source[0] & 0xF0) << 8)
1603 | ((source[1] & 0xF0) << 4)
1604 | (source[2] & 0xF0)
1605 | (source[3] >> 4));
1606 source += 4;
1607 destination += 1;
1608 }
1609 }
1610
1611 template<> void pack<GraphicsContext3D::DataFormatRGBA4444, GraphicsContext3D::A lphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinati on, unsigned pixelsPerRow)
1612 {
1613 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1614 float scaleFactor = source[3] / 255.0f;
1615 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1616 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1617 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1618 *destination = (((sourceR & 0xF0) << 8)
1619 | ((sourceG & 0xF0) << 4)
1620 | (sourceB & 0xF0)
1621 | (source[3] >> 4));
1622 source += 4;
1623 destination += 1;
1624 }
1625 }
1626
1627 // FIXME: this routine is lossy and must be removed.
1628 template<> void pack<GraphicsContext3D::DataFormatRGBA4444, GraphicsContext3D::A lphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinatio n, unsigned pixelsPerRow)
1629 {
1630 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1631 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
1632 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1633 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1634 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1635 *destination = (((sourceR & 0xF0) << 8)
1636 | ((sourceG & 0xF0) << 4)
1637 | (sourceB & 0xF0)
1638 | (source[3] >> 4));
1639 source += 4;
1640 destination += 1;
1641 }
1642 }
1643
1644 template<> void pack<GraphicsContext3D::DataFormatRGBA5551, GraphicsContext3D::A lphaDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
1645 {
1646 #if HAVE(ARM_NEON_INTRINSICS)
1647 SIMD::packOneRowOfRGBA8ToUnsignedShort5551(source, destination, pixelsPerRow );
1648 #endif
1649 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1650 *destination = (((source[0] & 0xF8) << 8)
1651 | ((source[1] & 0xF8) << 3)
1652 | ((source[2] & 0xF8) >> 2)
1653 | (source[3] >> 7));
1654 source += 4;
1655 destination += 1;
1656 }
1657 }
1658
1659 template<> void pack<GraphicsContext3D::DataFormatRGBA5551, GraphicsContext3D::A lphaDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinati on, unsigned pixelsPerRow)
1660 {
1661 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1662 float scaleFactor = source[3] / 255.0f;
1663 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1664 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1665 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1666 *destination = (((sourceR & 0xF8) << 8)
1667 | ((sourceG & 0xF8) << 3)
1668 | ((sourceB & 0xF8) >> 2)
1669 | (source[3] >> 7));
1670 source += 4;
1671 destination += 1;
1672 }
1673 }
1674
1675 // FIXME: this routine is lossy and must be removed.
1676 template<> void pack<GraphicsContext3D::DataFormatRGBA5551, GraphicsContext3D::A lphaDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destinatio n, unsigned pixelsPerRow)
1677 {
1678 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1679 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
1680 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1681 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1682 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1683 *destination = (((sourceR & 0xF8) << 8)
1684 | ((sourceG & 0xF8) << 3)
1685 | ((sourceB & 0xF8) >> 2)
1686 | (source[3] >> 7));
1687 source += 4;
1688 destination += 1;
1689 }
1690 }
1691
1692 template<> void pack<GraphicsContext3D::DataFormatRGB565, GraphicsContext3D::Alp haDoNothing, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, un signed pixelsPerRow)
1693 {
1694 #if HAVE(ARM_NEON_INTRINSICS)
1695 SIMD::packOneRowOfRGBA8ToUnsignedShort565(source, destination, pixelsPerRow) ;
1696 #endif
1697 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1698 *destination = (((source[0] & 0xF8) << 8)
1699 | ((source[1] & 0xFC) << 3)
1700 | ((source[2] & 0xF8) >> 3));
1701 source += 4;
1702 destination += 1;
1703 }
1704 }
1705
1706 template<> void pack<GraphicsContext3D::DataFormatRGB565, GraphicsContext3D::Alp haDoPremultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination , unsigned pixelsPerRow)
1707 {
1708 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1709 float scaleFactor = source[3] / 255.0f;
1710 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1711 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1712 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1713 *destination = (((sourceR & 0xF8) << 8)
1714 | ((sourceG & 0xFC) << 3)
1715 | ((sourceB & 0xF8) >> 3));
1716 source += 4;
1717 destination += 1;
1718 }
1719 }
1720
1721 // FIXME: this routine is lossy and must be removed.
1722 template<> void pack<GraphicsContext3D::DataFormatRGB565, GraphicsContext3D::Alp haDoUnmultiply, uint8_t, uint16_t>(const uint8_t* source, uint16_t* destination, unsigned pixelsPerRow)
1723 {
1724 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1725 float scaleFactor = source[3] ? 255.0f / source[3] : 1.0f;
1726 uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * s caleFactor);
1727 uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * s caleFactor);
1728 uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * s caleFactor);
1729 *destination = (((sourceR & 0xF8) << 8)
1730 | ((sourceG & 0xFC) << 3)
1731 | ((sourceB & 0xF8) >> 3));
1732 source += 4;
1733 destination += 1;
1734 }
1735 }
1736
1737 template<> void pack<GraphicsContext3D::DataFormatRGB32F, GraphicsContext3D::Alp haDoNothing, float, float>(const float* source, float* destination, unsigned pix elsPerRow)
1738 {
1739 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1740 destination[0] = source[0];
1741 destination[1] = source[1];
1742 destination[2] = source[2];
1743 source += 4;
1744 destination += 3;
1745 }
1746 }
1747
1748 template<> void pack<GraphicsContext3D::DataFormatRGB32F, GraphicsContext3D::Alp haDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
1749 {
1750 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1751 float scaleFactor = source[3];
1752 destination[0] = source[0] * scaleFactor;
1753 destination[1] = source[1] * scaleFactor;
1754 destination[2] = source[2] * scaleFactor;
1755 source += 4;
1756 destination += 3;
1757 }
1758 }
1759
1760 template<> void pack<GraphicsContext3D::DataFormatRGB32F, GraphicsContext3D::Alp haDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
1761 {
1762 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1763 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1764 destination[0] = source[0] * scaleFactor;
1765 destination[1] = source[1] * scaleFactor;
1766 destination[2] = source[2] * scaleFactor;
1767 source += 4;
1768 destination += 3;
1769 }
1770 }
1771
1772 // Used only during RGBA8 or BGRA8 -> floating-point uploads.
1773 template<> void pack<GraphicsContext3D::DataFormatRGBA32F, GraphicsContext3D::Al phaDoNothing, float, float>(const float* source, float* destination, unsigned pi xelsPerRow)
1774 {
1775 memcpy(destination, source, pixelsPerRow * 4 * sizeof(float));
1776 }
1777
1778 template<> void pack<GraphicsContext3D::DataFormatRGBA32F, GraphicsContext3D::Al phaDoPremultiply, float, float>(const float* source, float* destination, unsigne d pixelsPerRow)
1779 {
1780 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1781 float scaleFactor = source[3];
1782 destination[0] = source[0] * scaleFactor;
1783 destination[1] = source[1] * scaleFactor;
1784 destination[2] = source[2] * scaleFactor;
1785 destination[3] = source[3];
1786 source += 4;
1787 destination += 4;
1788 }
1789 }
1790
1791 template<> void pack<GraphicsContext3D::DataFormatRGBA32F, GraphicsContext3D::Al phaDoUnmultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
1792 {
1793 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1794 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1795 destination[0] = source[0] * scaleFactor;
1796 destination[1] = source[1] * scaleFactor;
1797 destination[2] = source[2] * scaleFactor;
1798 destination[3] = source[3];
1799 source += 4;
1800 destination += 4;
1801 }
1802 }
1803
1804 template<> void pack<GraphicsContext3D::DataFormatA32F, GraphicsContext3D::Alpha DoNothing, float, float>(const float* source, float* destination, unsigned pixel sPerRow)
1805 {
1806 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1807 destination[0] = source[3];
1808 source += 4;
1809 destination += 1;
1810 }
1811 }
1812
1813 template<> void pack<GraphicsContext3D::DataFormatR32F, GraphicsContext3D::Alpha DoNothing, float, float>(const float* source, float* destination, unsigned pixel sPerRow)
1814 {
1815 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1816 destination[0] = source[0];
1817 source += 4;
1818 destination += 1;
1819 }
1820 }
1821
1822 template<> void pack<GraphicsContext3D::DataFormatR32F, GraphicsContext3D::Alpha DoPremultiply, float, float>(const float* source, float* destination, unsigned p ixelsPerRow)
1823 {
1824 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1825 float scaleFactor = source[3];
1826 destination[0] = source[0] * scaleFactor;
1827 source += 4;
1828 destination += 1;
1829 }
1830 }
1831
1832 template<> void pack<GraphicsContext3D::DataFormatR32F, GraphicsContext3D::Alpha DoUnmultiply, float, float>(const float* source, float* destination, unsigned pi xelsPerRow)
1833 {
1834 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1835 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1836 destination[0] = source[0] * scaleFactor;
1837 source += 4;
1838 destination += 1;
1839 }
1840 }
1841
1842 template<> void pack<GraphicsContext3D::DataFormatRA32F, GraphicsContext3D::Alph aDoNothing, float, float>(const float* source, float* destination, unsigned pixe lsPerRow)
1843 {
1844 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1845 destination[0] = source[0];
1846 destination[1] = source[3];
1847 source += 4;
1848 destination += 2;
1849 }
1850 }
1851
1852 template<> void pack<GraphicsContext3D::DataFormatRA32F, GraphicsContext3D::Alph aDoPremultiply, float, float>(const float* source, float* destination, unsigned pixelsPerRow)
1853 {
1854 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1855 float scaleFactor = source[3];
1856 destination[0] = source[0] * scaleFactor;
1857 destination[1] = source[3];
1858 source += 4;
1859 destination += 2;
1860 }
1861 }
1862
1863 template<> void pack<GraphicsContext3D::DataFormatRA32F, GraphicsContext3D::Alph aDoUnmultiply, float, float>(const float* source, float* destination, unsigned p ixelsPerRow)
1864 {
1865 for (unsigned int i = 0; i < pixelsPerRow; ++i) {
1866 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1867 destination[0] = source[0] * scaleFactor;
1868 destination[1] = source[3];
1869 source += 4;
1870 destination += 2;
1871 }
1872 }
1873
1874 template<> void pack<GraphicsContext3D::DataFormatRGBA16F, GraphicsContext3D::Al phaDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsig ned pixelsPerRow)
1875 {
1876 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1877 destination[0] = convertFloatToHalfFloat(source[0]);
1878 destination[1] = convertFloatToHalfFloat(source[1]);
1879 destination[2] = convertFloatToHalfFloat(source[2]);
1880 destination[3] = convertFloatToHalfFloat(source[3]);
1881 source += 4;
1882 destination += 4;
1883 }
1884 }
1885
1886 template<> void pack<GraphicsContext3D::DataFormatRGBA16F, GraphicsContext3D::Al phaDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, u nsigned pixelsPerRow)
1887 {
1888 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1889 float scaleFactor = source[3];
1890 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1891 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1892 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1893 destination[3] = convertFloatToHalfFloat(source[3]);
1894 source += 4;
1895 destination += 4;
1896 }
1897 }
1898
1899 template<> void pack<GraphicsContext3D::DataFormatRGBA16F, GraphicsContext3D::Al phaDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, un signed pixelsPerRow)
1900 {
1901 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1902 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1903 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1904 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1905 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1906 destination[3] = convertFloatToHalfFloat(source[3]);
1907 source += 4;
1908 destination += 4;
1909 }
1910 }
1911
1912 template<> void pack<GraphicsContext3D::DataFormatRGB16F, GraphicsContext3D::Alp haDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsign ed pixelsPerRow)
1913 {
1914 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1915 destination[0] = convertFloatToHalfFloat(source[0]);
1916 destination[1] = convertFloatToHalfFloat(source[1]);
1917 destination[2] = convertFloatToHalfFloat(source[2]);
1918 source += 4;
1919 destination += 3;
1920 }
1921 }
1922
1923 template<> void pack<GraphicsContext3D::DataFormatRGB16F, GraphicsContext3D::Alp haDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, un signed pixelsPerRow)
1924 {
1925 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1926 float scaleFactor = source[3];
1927 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1928 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1929 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1930 source += 4;
1931 destination += 3;
1932 }
1933 }
1934
1935 template<> void pack<GraphicsContext3D::DataFormatRGB16F, GraphicsContext3D::Alp haDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, uns igned pixelsPerRow)
1936 {
1937 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1938 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1939 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1940 destination[1] = convertFloatToHalfFloat(source[1] * scaleFactor);
1941 destination[2] = convertFloatToHalfFloat(source[2] * scaleFactor);
1942 source += 4;
1943 destination += 3;
1944 }
1945 }
1946
1947 template<> void pack<GraphicsContext3D::DataFormatRA16F, GraphicsContext3D::Alph aDoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigne d pixelsPerRow)
1948 {
1949 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1950 destination[0] = convertFloatToHalfFloat(source[0]);
1951 destination[1] = convertFloatToHalfFloat(source[3]);
1952 source += 4;
1953 destination += 2;
1954 }
1955 }
1956
1957 template<> void pack<GraphicsContext3D::DataFormatRA16F, GraphicsContext3D::Alph aDoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, uns igned pixelsPerRow)
1958 {
1959 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1960 float scaleFactor = source[3];
1961 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1962 destination[1] = convertFloatToHalfFloat(source[3]);
1963 source += 4;
1964 destination += 2;
1965 }
1966 }
1967
1968 template<> void pack<GraphicsContext3D::DataFormatRA16F, GraphicsContext3D::Alph aDoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsi gned pixelsPerRow)
1969 {
1970 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1971 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
1972 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1973 destination[1] = convertFloatToHalfFloat(source[3]);
1974 source += 4;
1975 destination += 2;
1976 }
1977 }
1978
1979 template<> void pack<GraphicsContext3D::DataFormatR16F, GraphicsContext3D::Alpha DoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
1980 {
1981 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1982 destination[0] = convertFloatToHalfFloat(source[0]);
1983 source += 4;
1984 destination += 1;
1985 }
1986 }
1987
1988 template<> void pack<GraphicsContext3D::DataFormatR16F, GraphicsContext3D::Alpha DoPremultiply, float, uint16_t>(const float* source, uint16_t* destination, unsi gned pixelsPerRow)
1989 {
1990 for (unsigned i = 0; i < pixelsPerRow; ++i) {
1991 float scaleFactor = source[3];
1992 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
1993 source += 4;
1994 destination += 1;
1995 }
1996 }
1997
1998 template<> void pack<GraphicsContext3D::DataFormatR16F, GraphicsContext3D::Alpha DoUnmultiply, float, uint16_t>(const float* source, uint16_t* destination, unsig ned pixelsPerRow)
1999 {
2000 for (unsigned i = 0; i < pixelsPerRow; ++i) {
2001 float scaleFactor = source[3] ? 1.0f / source[3] : 1.0f;
2002 destination[0] = convertFloatToHalfFloat(source[0] * scaleFactor);
2003 source += 4;
2004 destination += 1;
2005 }
2006 }
2007
2008 template<> void pack<GraphicsContext3D::DataFormatA16F, GraphicsContext3D::Alpha DoNothing, float, uint16_t>(const float* source, uint16_t* destination, unsigned pixelsPerRow)
2009 {
2010 for (unsigned i = 0; i < pixelsPerRow; ++i) {
2011 destination[0] = convertFloatToHalfFloat(source[3]);
2012 source += 4;
2013 destination += 1;
2014 }
2015 }
2016
2017 bool HasAlpha(int format)
2018 {
2019 return format == GraphicsContext3D::DataFormatA8
2020 || format == GraphicsContext3D::DataFormatA16F
2021 || format == GraphicsContext3D::DataFormatA32F
2022 || format == GraphicsContext3D::DataFormatRA8
2023 || format == GraphicsContext3D::DataFormatAR8
2024 || format == GraphicsContext3D::DataFormatRA16F
2025 || format == GraphicsContext3D::DataFormatRA32F
2026 || format == GraphicsContext3D::DataFormatRGBA8
2027 || format == GraphicsContext3D::DataFormatBGRA8
2028 || format == GraphicsContext3D::DataFormatARGB8
2029 || format == GraphicsContext3D::DataFormatABGR8
2030 || format == GraphicsContext3D::DataFormatRGBA16F
2031 || format == GraphicsContext3D::DataFormatRGBA32F
2032 || format == GraphicsContext3D::DataFormatRGBA4444
2033 || format == GraphicsContext3D::DataFormatRGBA5551;
2034 }
2035
2036 bool HasColor(int format)
2037 {
2038 return format == GraphicsContext3D::DataFormatRGBA8
2039 || format == GraphicsContext3D::DataFormatRGBA16F
2040 || format == GraphicsContext3D::DataFormatRGBA32F
2041 || format == GraphicsContext3D::DataFormatRGB8
2042 || format == GraphicsContext3D::DataFormatRGB16F
2043 || format == GraphicsContext3D::DataFormatRGB32F
2044 || format == GraphicsContext3D::DataFormatBGR8
2045 || format == GraphicsContext3D::DataFormatBGRA8
2046 || format == GraphicsContext3D::DataFormatARGB8
2047 || format == GraphicsContext3D::DataFormatABGR8
2048 || format == GraphicsContext3D::DataFormatRGBA5551
2049 || format == GraphicsContext3D::DataFormatRGBA4444
2050 || format == GraphicsContext3D::DataFormatRGB565
2051 || format == GraphicsContext3D::DataFormatR8
2052 || format == GraphicsContext3D::DataFormatR16F
2053 || format == GraphicsContext3D::DataFormatR32F
2054 || format == GraphicsContext3D::DataFormatRA8
2055 || format == GraphicsContext3D::DataFormatRA16F
2056 || format == GraphicsContext3D::DataFormatRA32F
2057 || format == GraphicsContext3D::DataFormatAR8;
2058 }
2059
2060 template<int Format>
2061 struct IsFloatFormat {
2062 static const bool Value =
2063 Format == GraphicsContext3D::DataFormatRGBA32F
2064 || Format == GraphicsContext3D::DataFormatRGB32F
2065 || Format == GraphicsContext3D::DataFormatRA32F
2066 || Format == GraphicsContext3D::DataFormatR32F
2067 || Format == GraphicsContext3D::DataFormatA32F;
2068 };
2069
2070 template<int Format>
2071 struct IsHalfFloatFormat {
2072 static const bool Value =
2073 Format == GraphicsContext3D::DataFormatRGBA16F
2074 || Format == GraphicsContext3D::DataFormatRGB16F
2075 || Format == GraphicsContext3D::DataFormatRA16F
2076 || Format == GraphicsContext3D::DataFormatR16F
2077 || Format == GraphicsContext3D::DataFormatA16F;
2078 };
2079
2080 template<int Format>
2081 struct Is16bppFormat {
2082 static const bool Value =
2083 Format == GraphicsContext3D::DataFormatRGBA5551
2084 || Format == GraphicsContext3D::DataFormatRGBA4444
2085 || Format == GraphicsContext3D::DataFormatRGB565;
2086 };
2087
2088 template<int Format, bool IsFloat = IsFloatFormat<Format>::Value, bool IsHalfFlo at = IsHalfFloatFormat<Format>::Value, bool Is16bpp = Is16bppFormat<Format>::Val ue>
2089 struct DataTypeForFormat {
2090 typedef uint8_t Type;
2091 };
2092
2093 template<int Format>
2094 struct DataTypeForFormat<Format, true, false, false> {
2095 typedef float Type;
2096 };
2097
2098 template<int Format>
2099 struct DataTypeForFormat<Format, false, true, false> {
2100 typedef uint16_t Type;
2101 };
2102
2103 template<int Format>
2104 struct DataTypeForFormat<Format, false, false, true> {
2105 typedef uint16_t Type;
2106 };
2107
2108 template<int Format>
2109 struct IntermediateFormat {
2110 static const int Value = (IsFloatFormat<Format>::Value || IsHalfFloatFormat< Format>::Value) ? GraphicsContext3D::DataFormatRGBA32F : GraphicsContext3D::Data FormatRGBA8;
2111 };
2112
2113 unsigned TexelBytesForFormat(GraphicsContext3D::DataFormat format)
2114 {
2115 switch (format) {
2116 case GraphicsContext3D::DataFormatR8:
2117 case GraphicsContext3D::DataFormatA8:
2118 return 1;
2119 case GraphicsContext3D::DataFormatRA8:
2120 case GraphicsContext3D::DataFormatAR8:
2121 case GraphicsContext3D::DataFormatRGBA5551:
2122 case GraphicsContext3D::DataFormatRGBA4444:
2123 case GraphicsContext3D::DataFormatRGB565:
2124 case GraphicsContext3D::DataFormatA16F:
2125 case GraphicsContext3D::DataFormatR16F:
2126 return 2;
2127 case GraphicsContext3D::DataFormatRGB8:
2128 case GraphicsContext3D::DataFormatBGR8:
2129 return 3;
2130 case GraphicsContext3D::DataFormatRGBA8:
2131 case GraphicsContext3D::DataFormatARGB8:
2132 case GraphicsContext3D::DataFormatABGR8:
2133 case GraphicsContext3D::DataFormatBGRA8:
2134 case GraphicsContext3D::DataFormatR32F:
2135 case GraphicsContext3D::DataFormatA32F:
2136 case GraphicsContext3D::DataFormatRA16F:
2137 return 4;
2138 case GraphicsContext3D::DataFormatRGB16F:
2139 return 6;
2140 case GraphicsContext3D::DataFormatRA32F:
2141 case GraphicsContext3D::DataFormatRGBA16F:
2142 return 8;
2143 case GraphicsContext3D::DataFormatRGB32F:
2144 return 12;
2145 case GraphicsContext3D::DataFormatRGBA32F:
2146 return 16;
2147 default:
2148 return 0;
2149 }
2150 }
2151
2152 /* END CODE SHARED WITH MOZILLA FIREFOX */
2153
2154 class FormatConverter {
2155 public:
2156 FormatConverter(unsigned width, unsigned height,
2157 const void* srcStart, void* dstStart, int srcStride, int dstStride)
2158 : m_width(width), m_height(height), m_srcStart(srcStart), m_dstStart(dst Start), m_srcStride(srcStride), m_dstStride(dstStride), m_success(false)
2159 {
2160 const unsigned MaxNumberOfComponents = 4;
2161 const unsigned MaxBytesPerComponent = 4;
2162 m_unpackedIntermediateSrcData = adoptArrayPtr(new uint8_t[m_width * MaxN umberOfComponents *MaxBytesPerComponent]);
2163 ASSERT(m_unpackedIntermediateSrcData.get());
2164 }
2165
2166 void convert(GraphicsContext3D::DataFormat srcFormat, GraphicsContext3D::Dat aFormat dstFormat, GraphicsContext3D::AlphaOp);
2167 bool Success() const { return m_success; }
2168
2169 private:
2170 template<GraphicsContext3D::DataFormat SrcFormat>
2171 void convert(GraphicsContext3D::DataFormat dstFormat, GraphicsContext3D::Alp haOp);
2172
2173 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFor mat DstFormat>
2174 void convert(GraphicsContext3D::AlphaOp);
2175
2176 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFor mat DstFormat, GraphicsContext3D::AlphaOp alphaOp>
2177 void convert();
2178
2179 const unsigned m_width, m_height;
2180 const void* const m_srcStart;
2181 void* const m_dstStart;
2182 const int m_srcStride, m_dstStride;
2183 bool m_success;
2184 OwnArrayPtr<uint8_t> m_unpackedIntermediateSrcData;
2185 };
2186
2187 void FormatConverter::convert(GraphicsContext3D::DataFormat srcFormat, GraphicsC ontext3D::DataFormat dstFormat, GraphicsContext3D::AlphaOp alphaOp)
2188 {
2189 #define FORMATCONVERTER_CASE_SRCFORMAT(SrcFormat) \
2190 case SrcFormat: \
2191 return convert<SrcFormat>(dstFormat, alphaOp);
2192
2193 switch (srcFormat) {
2194 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatR8)
2195 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatA8)
2196 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatR32F)
2197 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatA32F)
2198 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRA8)
2199 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRA32F)
2200 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB8)
2201 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatBGR8)
2202 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB565)
2203 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGB32F)
2204 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA8)
2205 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatARGB8)
2206 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatABGR8)
2207 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatAR8)
2208 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatBGRA8)
2209 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA5551 )
2210 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA4444 )
2211 FORMATCONVERTER_CASE_SRCFORMAT(GraphicsContext3D::DataFormatRGBA32F)
2212 default:
2213 ASSERT_NOT_REACHED();
2214 }
2215 #undef FORMATCONVERTER_CASE_SRCFORMAT
2216 }
2217
2218 template<GraphicsContext3D::DataFormat SrcFormat>
2219 void FormatConverter::convert(GraphicsContext3D::DataFormat dstFormat, GraphicsC ontext3D::AlphaOp alphaOp)
2220 {
2221 #define FORMATCONVERTER_CASE_DSTFORMAT(DstFormat) \
2222 case DstFormat: \
2223 return convert<SrcFormat, DstFormat>(alphaOp);
2224
2225 switch (dstFormat) {
2226 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatR8)
2227 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatR16F)
2228 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatR32F)
2229 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatA8)
2230 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatA16F)
2231 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatA32F)
2232 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRA8)
2233 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRA16F)
2234 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRA32F)
2235 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGB8)
2236 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGB565)
2237 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGB16F)
2238 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGB32F)
2239 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA8)
2240 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA5551 )
2241 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA4444 )
2242 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA16F)
2243 FORMATCONVERTER_CASE_DSTFORMAT(GraphicsContext3D::DataFormatRGBA32F)
2244 default:
2245 ASSERT_NOT_REACHED();
2246 }
2247
2248 #undef FORMATCONVERTER_CASE_DSTFORMAT
2249 }
2250
2251 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFormat DstFormat>
2252 void FormatConverter::convert(GraphicsContext3D::AlphaOp alphaOp)
2253 {
2254 #define FORMATCONVERTER_CASE_ALPHAOP(alphaOp) \
2255 case alphaOp: \
2256 return convert<SrcFormat, DstFormat, alphaOp>();
2257
2258 switch (alphaOp) {
2259 FORMATCONVERTER_CASE_ALPHAOP(GraphicsContext3D::AlphaDoNothing)
2260 FORMATCONVERTER_CASE_ALPHAOP(GraphicsContext3D::AlphaDoPremultiply)
2261 FORMATCONVERTER_CASE_ALPHAOP(GraphicsContext3D::AlphaDoUnmultiply)
2262 default:
2263 ASSERT_NOT_REACHED();
2264 }
2265 #undef FORMATCONVERTER_CASE_ALPHAOP
2266 }
2267
2268 template<GraphicsContext3D::DataFormat SrcFormat, GraphicsContext3D::DataFormat DstFormat, GraphicsContext3D::AlphaOp alphaOp>
2269 void FormatConverter::convert()
2270 {
2271 // Many instantiations of this template function will never be entered, so w e try
2272 // to return immediately in these cases to avoid the compiler to generate us eless code.
2273 if (SrcFormat == DstFormat && alphaOp == GraphicsContext3D::AlphaDoNothing) {
2274 ASSERT_NOT_REACHED();
2275 return;
2276 }
2277 if (!IsFloatFormat<DstFormat>::Value && IsFloatFormat<SrcFormat>::Value) {
2278 ASSERT_NOT_REACHED();
2279 return;
2280 }
2281
2282 // Only textures uploaded from DOM elements or ImageData can allow DstFormat != SrcFormat.
2283 const bool srcFormatComesFromDOMElementOrImageData = GraphicsContext3D::srcF ormatComeFromDOMElementOrImageData(SrcFormat);
2284 if (!srcFormatComesFromDOMElementOrImageData && SrcFormat != DstFormat) {
2285 ASSERT_NOT_REACHED();
2286 return;
2287 }
2288 // Likewise, only textures uploaded from DOM elements or ImageData can possi bly have to be unpremultiplied.
2289 if (!srcFormatComesFromDOMElementOrImageData && alphaOp == GraphicsContext3D ::AlphaDoUnmultiply) {
2290 ASSERT_NOT_REACHED();
2291 return;
2292 }
2293 if ((!HasAlpha(SrcFormat) || !HasColor(SrcFormat) || !HasColor(DstFormat)) & & alphaOp != GraphicsContext3D::AlphaDoNothing) {
2294 ASSERT_NOT_REACHED();
2295 return;
2296 }
2297
2298 typedef typename DataTypeForFormat<SrcFormat>::Type SrcType;
2299 typedef typename DataTypeForFormat<DstFormat>::Type DstType;
2300 const int IntermediateSrcFormat = IntermediateFormat<DstFormat>::Value;
2301 typedef typename DataTypeForFormat<IntermediateSrcFormat>::Type Intermediate SrcType;
2302 const ptrdiff_t srcStrideInElements = m_srcStride / sizeof(SrcType);
2303 const ptrdiff_t dstStrideInElements = m_dstStride / sizeof(DstType);
2304 const bool trivialUnpack = (SrcFormat == GraphicsContext3D::DataFormatRGBA8 && !IsFloatFormat<DstFormat>::Value && !IsHalfFloatFormat<DstFormat>::Value) || SrcFormat == GraphicsContext3D::DataFormatRGBA32F;
2305 const bool trivialPack = (DstFormat == GraphicsContext3D::DataFormatRGBA8 || DstFormat == GraphicsContext3D::DataFormatRGBA32F) && alphaOp == GraphicsContex t3D::AlphaDoNothing && m_dstStride > 0;
2306 ASSERT(!trivialUnpack || !trivialPack);
2307
2308 const SrcType *srcRowStart = static_cast<const SrcType*>(m_srcStart);
2309 DstType* dstRowStart = static_cast<DstType*>(m_dstStart);
2310 if (!trivialUnpack && trivialPack) {
2311 for (size_t i = 0; i < m_height; ++i) {
2312 unpack<SrcFormat>(srcRowStart, dstRowStart, m_width);
2313 srcRowStart += srcStrideInElements;
2314 dstRowStart += dstStrideInElements;
2315 }
2316 } else if (!trivialUnpack && !trivialPack) {
2317 for (size_t i = 0; i < m_height; ++i) {
2318 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermediateSrcType* >(m_unpackedIntermediateSrcData.get()), m_width);
2319 pack<DstFormat, alphaOp>(reinterpret_cast<IntermediateSrcType*>(m_un packedIntermediateSrcData.get()), dstRowStart, m_width);
2320 srcRowStart += srcStrideInElements;
2321 dstRowStart += dstStrideInElements;
2322 }
2323 } else {
2324 for (size_t i = 0; i < m_height; ++i) {
2325 pack<DstFormat, alphaOp>(srcRowStart, dstRowStart, m_width);
2326 srcRowStart += srcStrideInElements;
2327 dstRowStart += dstStrideInElements;
2328 }
2329 }
2330 m_success = true;
2331 return;
2332 }
2333
2334 } // anonymous namespace
2335
2336 bool GraphicsContext3D::packPixels(const uint8_t* sourceData, DataFormat sourceD ataFormat, unsigned width, unsigned height, unsigned sourceUnpackAlignment, unsi gned destinationFormat, unsigned destinationType, AlphaOp alphaOp, void* destina tionData, bool flipY)
2337 {
2338 int validSrc = width * TexelBytesForFormat(sourceDataFormat);
2339 int remainder = sourceUnpackAlignment ? (validSrc % sourceUnpackAlignment) : 0;
2340 int srcStride = remainder ? (validSrc + sourceUnpackAlignment - remainder) : validSrc;
2341
2342 DataFormat dstDataFormat = getDataFormat(destinationFormat, destinationType) ;
2343 int dstStride = width * TexelBytesForFormat(dstDataFormat);
2344 if (flipY) {
2345 destinationData = static_cast<uint8_t*>(destinationData) + dstStride*(he ight - 1);
2346 dstStride = -dstStride;
2347 }
2348 if (!HasAlpha(sourceDataFormat) || !HasColor(sourceDataFormat) || !HasColor( dstDataFormat))
2349 alphaOp = AlphaDoNothing;
2350
2351 if (sourceDataFormat == dstDataFormat && alphaOp == AlphaDoNothing) {
2352 const uint8_t* ptr = sourceData;
2353 const uint8_t* ptrEnd = sourceData + srcStride * height;
2354 unsigned rowSize = (dstStride > 0) ? dstStride: -dstStride;
2355 uint8_t* dst = static_cast<uint8_t*>(destinationData);
2356 while (ptr < ptrEnd) {
2357 memcpy(dst, ptr, rowSize);
2358 ptr += srcStride;
2359 dst += dstStride;
2360 }
2361 return true;
2362 }
2363
2364 FormatConverter converter(width, height, sourceData, destinationData, srcStr ide, dstStride);
2365 converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
2366 if (!converter.Success())
2367 return false;
2368 return true;
2369 }
2370
2371 unsigned GraphicsContext3D::getClearBitsByAttachmentType(GC3Denum attachment) 832 unsigned GraphicsContext3D::getClearBitsByAttachmentType(GC3Denum attachment)
2372 { 833 {
2373 switch (attachment) { 834 switch (attachment) {
2374 case GraphicsContext3D::COLOR_ATTACHMENT0: 835 case GraphicsContext3D::COLOR_ATTACHMENT0:
2375 case Extensions3D::COLOR_ATTACHMENT1_EXT: 836 case Extensions3D::COLOR_ATTACHMENT1_EXT:
2376 case Extensions3D::COLOR_ATTACHMENT2_EXT: 837 case Extensions3D::COLOR_ATTACHMENT2_EXT:
2377 case Extensions3D::COLOR_ATTACHMENT3_EXT: 838 case Extensions3D::COLOR_ATTACHMENT3_EXT:
2378 case Extensions3D::COLOR_ATTACHMENT4_EXT: 839 case Extensions3D::COLOR_ATTACHMENT4_EXT:
2379 case Extensions3D::COLOR_ATTACHMENT5_EXT: 840 case Extensions3D::COLOR_ATTACHMENT5_EXT:
2380 case Extensions3D::COLOR_ATTACHMENT6_EXT: 841 case Extensions3D::COLOR_ATTACHMENT6_EXT:
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
2566 } 1027 }
2567 1028
2568 bool GraphicsContext3D::isExtensionEnabled(const String& name) 1029 bool GraphicsContext3D::isExtensionEnabled(const String& name)
2569 { 1030 {
2570 initializeExtensions(); 1031 initializeExtensions();
2571 String mappedName = mapExtensionName(name); 1032 String mappedName = mapExtensionName(name);
2572 return m_enabledExtensions.contains(mappedName); 1033 return m_enabledExtensions.contains(mappedName);
2573 } 1034 }
2574 1035
2575 } // namespace WebCore 1036 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/GraphicsContext3D.h ('k') | Source/core/platform/graphics/GraphicsContext3DImagePacking.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698