Home | History | Annotate | Download | only in graphics
      1 /*
      2  * Copyright (C) 2010 Apple Inc. All rights reserved.
      3  * Copyright (C) 2010 Google Inc. 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 
     29 #if ENABLE(WEBGL)
     30 
     31 #include "GraphicsContext3D.h"
     32 
     33 #include "ArrayBufferView.h"
     34 #include "CheckedInt.h"
     35 #include "DrawingBuffer.h"
     36 #include "Extensions3D.h"
     37 #include "Image.h"
     38 #include "ImageData.h"
     39 
     40 #include <wtf/OwnArrayPtr.h>
     41 #include <wtf/PassOwnArrayPtr.h>
     42 
     43 namespace WebCore {
     44 
     45 namespace {
     46 
     47     uint8_t convertColor16LittleTo8(uint16_t value)
     48     {
     49         return value >> 8;
     50     }
     51 
     52     uint8_t convertColor16BigTo8(uint16_t value)
     53     {
     54         return static_cast<uint8_t>(value & 0x00FF);
     55     }
     56 
     57 } // anonymous namespace
     58 
     59 
     60 PassRefPtr<DrawingBuffer> GraphicsContext3D::createDrawingBuffer(const IntSize& size)
     61 {
     62     return DrawingBuffer::create(this, size);
     63 }
     64 
     65 bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint unpackAlignment)
     66 {
     67     ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8);
     68     OwnArrayPtr<unsigned char> zero;
     69     if (width > 0 && height > 0) {
     70         unsigned int size;
     71         GC3Denum error = computeImageSizeInBytes(format, type, width, height, unpackAlignment, &size, 0);
     72         if (error != GraphicsContext3D::NO_ERROR) {
     73             synthesizeGLError(error);
     74             return false;
     75         }
     76         zero = adoptArrayPtr(new unsigned char[size]);
     77         if (!zero) {
     78             synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
     79             return false;
     80         }
     81         memset(zero.get(), 0, size);
     82     }
     83     return texImage2D(target, level, internalformat, width, height, border, format, type, zero.get());
     84 }
     85 
     86 bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format,
     87                                                        GC3Denum type,
     88                                                        unsigned int* componentsPerPixel,
     89                                                        unsigned int* bytesPerComponent)
     90 {
     91     switch (format) {
     92     case GraphicsContext3D::ALPHA:
     93         *componentsPerPixel = 1;
     94         break;
     95     case GraphicsContext3D::LUMINANCE:
     96         *componentsPerPixel = 1;
     97         break;
     98     case GraphicsContext3D::LUMINANCE_ALPHA:
     99         *componentsPerPixel = 2;
    100         break;
    101     case GraphicsContext3D::RGB:
    102         *componentsPerPixel = 3;
    103         break;
    104     case GraphicsContext3D::RGBA:
    105     case Extensions3D::BGRA_EXT: // GL_EXT_texture_format_BGRA8888
    106         *componentsPerPixel = 4;
    107         break;
    108     default:
    109         return false;
    110     }
    111     switch (type) {
    112     case GraphicsContext3D::UNSIGNED_BYTE:
    113         *bytesPerComponent = sizeof(GC3Dubyte);
    114         break;
    115     case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
    116     case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
    117     case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
    118         *componentsPerPixel = 1;
    119         *bytesPerComponent = sizeof(GC3Dushort);
    120         break;
    121     case GraphicsContext3D::FLOAT: // OES_texture_float
    122         *bytesPerComponent = sizeof(GC3Dfloat);
    123         break;
    124     default:
    125         return false;
    126     }
    127     return true;
    128 }
    129 
    130 GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum type, GC3Dsizei width, GC3Dsizei height, GC3Dint alignment,
    131                                                     unsigned int* imageSizeInBytes, unsigned int* paddingInBytes)
    132 {
    133     ASSERT(imageSizeInBytes);
    134     ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8);
    135     if (width < 0 || height < 0)
    136         return GraphicsContext3D::INVALID_VALUE;
    137     unsigned int bytesPerComponent, componentsPerPixel;
    138     if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &componentsPerPixel))
    139         return GraphicsContext3D::INVALID_ENUM;
    140     if (!width || !height) {
    141         *imageSizeInBytes = 0;
    142         if (paddingInBytes)
    143             *paddingInBytes = 0;
    144         return GraphicsContext3D::NO_ERROR;
    145     }
    146     CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel);
    147     checkedValue *=  width;
    148     if (!checkedValue.valid())
    149         return GraphicsContext3D::INVALID_VALUE;
    150     unsigned int validRowSize = checkedValue.value();
    151     unsigned int padding = 0;
    152     unsigned int residual = validRowSize % alignment;
    153     if (residual) {
    154         padding = alignment - residual;
    155         checkedValue += padding;
    156     }
    157     // Last row needs no padding.
    158     checkedValue *= (height - 1);
    159     checkedValue += validRowSize;
    160     if (!checkedValue.valid())
    161         return GraphicsContext3D::INVALID_VALUE;
    162     *imageSizeInBytes = checkedValue.value();
    163     if (paddingInBytes)
    164         *paddingInBytes = padding;
    165     return GraphicsContext3D::NO_ERROR;
    166 }
    167 
    168 bool GraphicsContext3D::extractImageData(Image* image,
    169                                          GC3Denum format,
    170                                          GC3Denum type,
    171                                          bool flipY,
    172                                          bool premultiplyAlpha,
    173                                          bool ignoreGammaAndColorProfile,
    174                                          Vector<uint8_t>& data)
    175 {
    176     if (!image)
    177         return false;
    178     if (!getImageData(image, format, type, premultiplyAlpha, ignoreGammaAndColorProfile, data))
    179         return false;
    180     if (flipY) {
    181         unsigned int componentsPerPixel, bytesPerComponent;
    182         if (!computeFormatAndTypeParameters(format, type,
    183                                             &componentsPerPixel,
    184                                             &bytesPerComponent))
    185             return false;
    186         // The image data is tightly packed, and we upload it as such.
    187         unsigned int unpackAlignment = 1;
    188         flipVertically(data.data(), image->width(), image->height(),
    189                        componentsPerPixel * bytesPerComponent,
    190                        unpackAlignment);
    191     }
    192     return true;
    193 }
    194 
    195 bool GraphicsContext3D::extractImageData(ImageData* imageData,
    196                                          GC3Denum format,
    197                                          GC3Denum type,
    198                                          bool flipY,
    199                                          bool premultiplyAlpha,
    200                                          Vector<uint8_t>& data)
    201 {
    202     if (!imageData)
    203         return false;
    204     int width = imageData->width();
    205     int height = imageData->height();
    206     int dataBytes = width * height * 4;
    207     data.resize(dataBytes);
    208     if (!packPixels(imageData->data()->data()->data(),
    209                     SourceFormatRGBA8,
    210                     width,
    211                     height,
    212                     0,
    213                     format,
    214                     type,
    215                     premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing,
    216                     data.data()))
    217         return false;
    218     if (flipY) {
    219         unsigned int componentsPerPixel, bytesPerComponent;
    220         if (!computeFormatAndTypeParameters(format, type,
    221                                             &componentsPerPixel,
    222                                             &bytesPerComponent))
    223             return false;
    224         // The image data is tightly packed, and we upload it as such.
    225         unsigned int unpackAlignment = 1;
    226         flipVertically(data.data(), width, height,
    227                        componentsPerPixel * bytesPerComponent,
    228                        unpackAlignment);
    229     }
    230     return true;
    231 }
    232 
    233 bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int height,
    234                                            GC3Denum format, GC3Denum type,
    235                                            unsigned int unpackAlignment,
    236                                            bool flipY, bool premultiplyAlpha,
    237                                            const void* pixels,
    238                                            Vector<uint8_t>& data)
    239 {
    240     // Assumes format, type, etc. have already been validated.
    241     SourceDataFormat sourceDataFormat = SourceFormatRGBA8;
    242     switch (type) {
    243     case UNSIGNED_BYTE:
    244         switch (format) {
    245         case RGBA:
    246             sourceDataFormat = SourceFormatRGBA8;
    247             break;
    248         case RGB:
    249             sourceDataFormat = SourceFormatRGB8;
    250             break;
    251         case ALPHA:
    252             sourceDataFormat = SourceFormatA8;
    253             break;
    254         case LUMINANCE:
    255             sourceDataFormat = SourceFormatR8;
    256             break;
    257         case LUMINANCE_ALPHA:
    258             sourceDataFormat = SourceFormatRA8;
    259             break;
    260         default:
    261             ASSERT_NOT_REACHED();
    262         }
    263         break;
    264     case FLOAT: // OES_texture_float
    265         switch (format) {
    266         case RGBA:
    267             sourceDataFormat = SourceFormatRGBA32F;
    268             break;
    269         case RGB:
    270             sourceDataFormat = SourceFormatRGB32F;
    271             break;
    272         case ALPHA:
    273             sourceDataFormat = SourceFormatA32F;
    274             break;
    275         case LUMINANCE:
    276             sourceDataFormat = SourceFormatR32F;
    277             break;
    278         case LUMINANCE_ALPHA:
    279             sourceDataFormat = SourceFormatRA32F;
    280             break;
    281         default:
    282             ASSERT_NOT_REACHED();
    283         }
    284         break;
    285     case UNSIGNED_SHORT_5_5_5_1:
    286         sourceDataFormat = SourceFormatRGBA5551;
    287         break;
    288     case UNSIGNED_SHORT_4_4_4_4:
    289         sourceDataFormat = SourceFormatRGBA4444;
    290         break;
    291     case UNSIGNED_SHORT_5_6_5:
    292         sourceDataFormat = SourceFormatRGB565;
    293         break;
    294     default:
    295         ASSERT_NOT_REACHED();
    296     }
    297 
    298     // Resize the output buffer.
    299     unsigned int componentsPerPixel, bytesPerComponent;
    300     if (!computeFormatAndTypeParameters(format, type,
    301                                         &componentsPerPixel,
    302                                         &bytesPerComponent))
    303         return false;
    304     unsigned int bytesPerPixel = componentsPerPixel * bytesPerComponent;
    305     data.resize(width * height * bytesPerPixel);
    306 
    307     if (!packPixels(static_cast<const uint8_t*>(pixels),
    308                     sourceDataFormat,
    309                     width, height, unpackAlignment,
    310                     format, type,
    311                     (premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing),
    312                     data.data()))
    313         return false;
    314     // The pixel data is now tightly packed.
    315     if (flipY)
    316         flipVertically(data.data(), width, height, bytesPerPixel, 1);
    317     return true;
    318 }
    319 
    320 void GraphicsContext3D::flipVertically(void* imageData,
    321                                        unsigned int width,
    322                                        unsigned int height,
    323                                        unsigned int bytesPerPixel,
    324                                        unsigned int unpackAlignment)
    325 {
    326     if (!width || !height)
    327         return;
    328     unsigned int validRowBytes = width * bytesPerPixel;
    329     unsigned int totalRowBytes = validRowBytes;
    330     unsigned int remainder = validRowBytes % unpackAlignment;
    331     if (remainder)
    332         totalRowBytes += (unpackAlignment - remainder);
    333     uint8_t* tempRow = new uint8_t[validRowBytes];
    334     uint8_t* data = static_cast<uint8_t*>(imageData);
    335     for (unsigned i = 0; i < height / 2; i++) {
    336         uint8_t* lowRow = data + (totalRowBytes * i);
    337         uint8_t* highRow = data + (totalRowBytes * (height - i - 1));
    338         memcpy(tempRow, lowRow, validRowBytes);
    339         memcpy(lowRow, highRow, validRowBytes);
    340         memcpy(highRow, tempRow, validRowBytes);
    341     }
    342     delete[] tempRow;
    343 }
    344 
    345 // These functions can not be static, or gcc will not allow them to be
    346 // used as template parameters. Use an anonymous namespace to prevent
    347 // the need to declare prototypes for them.
    348 namespace {
    349 
    350 //----------------------------------------------------------------------
    351 // Pixel unpacking routines.
    352 
    353 void unpackRGBA8ToRGBA8(const uint8_t* source, uint8_t* destination)
    354 {
    355     destination[0] = source[0];
    356     destination[1] = source[1];
    357     destination[2] = source[2];
    358     destination[3] = source[3];
    359 }
    360 
    361 void unpackRGBA16LittleToRGBA8(const uint16_t* source, uint8_t* destination)
    362 {
    363     destination[0] = convertColor16LittleTo8(source[0]);
    364     destination[1] = convertColor16LittleTo8(source[1]);
    365     destination[2] = convertColor16LittleTo8(source[2]);
    366     destination[3] = convertColor16LittleTo8(source[3]);
    367 }
    368 
    369 void unpackRGBA16BigToRGBA8(const uint16_t* source, uint8_t* destination)
    370 {
    371     destination[0] = convertColor16BigTo8(source[0]);
    372     destination[1] = convertColor16BigTo8(source[1]);
    373     destination[2] = convertColor16BigTo8(source[2]);
    374     destination[3] = convertColor16BigTo8(source[3]);
    375 }
    376 
    377 void unpackRGB8ToRGBA8(const uint8_t* source, uint8_t* destination)
    378 {
    379     destination[0] = source[0];
    380     destination[1] = source[1];
    381     destination[2] = source[2];
    382     destination[3] = 0xFF;
    383 }
    384 
    385 void unpackRGB16LittleToRGBA8(const uint16_t* source, uint8_t* destination)
    386 {
    387     destination[0] = convertColor16LittleTo8(source[0]);
    388     destination[1] = convertColor16LittleTo8(source[1]);
    389     destination[2] = convertColor16LittleTo8(source[2]);
    390     destination[3] = 0xFF;
    391 }
    392 
    393 void unpackRGB16BigToRGBA8(const uint16_t* source, uint8_t* destination)
    394 {
    395     destination[0] = convertColor16BigTo8(source[0]);
    396     destination[1] = convertColor16BigTo8(source[1]);
    397     destination[2] = convertColor16BigTo8(source[2]);
    398     destination[3] = 0xFF;
    399 }
    400 
    401 void unpackBGR8ToRGBA8(const uint8_t* source, uint8_t* destination)
    402 {
    403     destination[0] = source[2];
    404     destination[1] = source[1];
    405     destination[2] = source[0];
    406     destination[3] = 0xFF;
    407 }
    408 
    409 void unpackARGB8ToRGBA8(const uint8_t* source, uint8_t* destination)
    410 {
    411     destination[0] = source[1];
    412     destination[1] = source[2];
    413     destination[2] = source[3];
    414     destination[3] = source[0];
    415 }
    416 
    417 void unpackARGB16LittleToRGBA8(const uint16_t* source, uint8_t* destination)
    418 {
    419     destination[0] = convertColor16LittleTo8(source[1]);
    420     destination[1] = convertColor16LittleTo8(source[2]);
    421     destination[2] = convertColor16LittleTo8(source[3]);
    422     destination[3] = convertColor16LittleTo8(source[0]);
    423 }
    424 
    425 void unpackARGB16BigToRGBA8(const uint16_t* source, uint8_t* destination)
    426 {
    427     destination[0] = convertColor16BigTo8(source[1]);
    428     destination[1] = convertColor16BigTo8(source[2]);
    429     destination[2] = convertColor16BigTo8(source[3]);
    430     destination[3] = convertColor16BigTo8(source[0]);
    431 }
    432 
    433 void unpackABGR8ToRGBA8(const uint8_t* source, uint8_t* destination)
    434 {
    435     destination[0] = source[3];
    436     destination[1] = source[2];
    437     destination[2] = source[1];
    438     destination[3] = source[0];
    439 }
    440 
    441 void unpackBGRA8ToRGBA8(const uint8_t* source, uint8_t* destination)
    442 {
    443     destination[0] = source[2];
    444     destination[1] = source[1];
    445     destination[2] = source[0];
    446     destination[3] = source[3];
    447 }
    448 
    449 void unpackBGRA16LittleToRGBA8(const uint16_t* source, uint8_t* destination)
    450 {
    451     destination[0] = convertColor16LittleTo8(source[2]);
    452     destination[1] = convertColor16LittleTo8(source[1]);
    453     destination[2] = convertColor16LittleTo8(source[0]);
    454     destination[3] = convertColor16LittleTo8(source[3]);
    455 }
    456 
    457 void unpackBGRA16BigToRGBA8(const uint16_t* source, uint8_t* destination)
    458 {
    459     destination[0] = convertColor16BigTo8(source[2]);
    460     destination[1] = convertColor16BigTo8(source[1]);
    461     destination[2] = convertColor16BigTo8(source[0]);
    462     destination[3] = convertColor16BigTo8(source[3]);
    463 }
    464 
    465 void unpackRGBA5551ToRGBA8(const uint16_t* source, uint8_t* destination)
    466 {
    467     uint16_t packedValue = source[0];
    468     uint8_t r = packedValue >> 11;
    469     uint8_t g = (packedValue >> 6) & 0x1F;
    470     uint8_t b = (packedValue >> 1) & 0x1F;
    471     destination[0] = (r << 3) | (r & 0x7);
    472     destination[1] = (g << 3) | (g & 0x7);
    473     destination[2] = (b << 3) | (b & 0x7);
    474     destination[3] = (packedValue & 0x1) ? 0xFF : 0x0;
    475 }
    476 
    477 void unpackRGBA4444ToRGBA8(const uint16_t* source, uint8_t* destination)
    478 {
    479     uint16_t packedValue = source[0];
    480     uint8_t r = packedValue >> 12;
    481     uint8_t g = (packedValue >> 8) & 0x0F;
    482     uint8_t b = (packedValue >> 4) & 0x0F;
    483     uint8_t a = packedValue & 0x0F;
    484     destination[0] = r << 4 | r;
    485     destination[1] = g << 4 | g;
    486     destination[2] = b << 4 | b;
    487     destination[3] = a << 4 | a;
    488 }
    489 
    490 void unpackRGB565ToRGBA8(const uint16_t* source, uint8_t* destination)
    491 {
    492     uint16_t packedValue = source[0];
    493     uint8_t r = packedValue >> 11;
    494     uint8_t g = (packedValue >> 5) & 0x3F;
    495     uint8_t b = packedValue & 0x1F;
    496     destination[0] = (r << 3) | (r & 0x7);
    497     destination[1] = (g << 2) | (g & 0x3);
    498     destination[2] = (b << 3) | (b & 0x7);
    499     destination[3] = 0xFF;
    500 }
    501 
    502 void unpackR8ToRGBA8(const uint8_t* source, uint8_t* destination)
    503 {
    504     destination[0] = source[0];
    505     destination[1] = source[0];
    506     destination[2] = source[0];
    507     destination[3] = 0xFF;
    508 }
    509 
    510 void unpackR16LittleToRGBA8(const uint16_t* source, uint8_t* destination)
    511 {
    512     destination[0] = convertColor16LittleTo8(source[0]);
    513     destination[1] = convertColor16LittleTo8(source[0]);
    514     destination[2] = convertColor16LittleTo8(source[0]);
    515     destination[3] = 0xFF;
    516 }
    517 
    518 void unpackR16BigToRGBA8(const uint16_t* source, uint8_t* destination)
    519 {
    520     destination[0] = convertColor16BigTo8(source[0]);
    521     destination[1] = convertColor16BigTo8(source[0]);
    522     destination[2] = convertColor16BigTo8(source[0]);
    523     destination[3] = 0xFF;
    524 }
    525 
    526 void unpackRA8ToRGBA8(const uint8_t* source, uint8_t* destination)
    527 {
    528     destination[0] = source[0];
    529     destination[1] = source[0];
    530     destination[2] = source[0];
    531     destination[3] = source[1];
    532 }
    533 
    534 void unpackRA16LittleToRGBA8(const uint16_t* source, uint8_t* destination)
    535 {
    536     destination[0] = convertColor16LittleTo8(source[0]);
    537     destination[1] = convertColor16LittleTo8(source[0]);
    538     destination[2] = convertColor16LittleTo8(source[0]);
    539     destination[3] = convertColor16LittleTo8(source[1]);
    540 }
    541 
    542 void unpackRA16BigToRGBA8(const uint16_t* source, uint8_t* destination)
    543 {
    544     destination[0] = convertColor16BigTo8(source[0]);
    545     destination[1] = convertColor16BigTo8(source[0]);
    546     destination[2] = convertColor16BigTo8(source[0]);
    547     destination[3] = convertColor16BigTo8(source[1]);
    548 }
    549 
    550 void unpackAR8ToRGBA8(const uint8_t* source, uint8_t* destination)
    551 {
    552     destination[0] = source[1];
    553     destination[1] = source[1];
    554     destination[2] = source[1];
    555     destination[3] = source[0];
    556 }
    557 
    558 void unpackAR16LittleToRGBA8(const uint16_t* source, uint8_t* destination)
    559 {
    560     destination[0] = convertColor16LittleTo8(source[1]);
    561     destination[1] = convertColor16LittleTo8(source[1]);
    562     destination[2] = convertColor16LittleTo8(source[1]);
    563     destination[3] = convertColor16LittleTo8(source[0]);
    564 }
    565 
    566 void unpackAR16BigToRGBA8(const uint16_t* source, uint8_t* destination)
    567 {
    568     destination[0] = convertColor16BigTo8(source[1]);
    569     destination[1] = convertColor16BigTo8(source[1]);
    570     destination[2] = convertColor16BigTo8(source[1]);
    571     destination[3] = convertColor16BigTo8(source[0]);
    572 }
    573 
    574 void unpackA8ToRGBA8(const uint8_t* source, uint8_t* destination)
    575 {
    576     destination[0] = 0x0;
    577     destination[1] = 0x0;
    578     destination[2] = 0x0;
    579     destination[3] = source[0];
    580 }
    581 
    582 void unpackA16LittleToRGBA8(const uint16_t* source, uint8_t* destination)
    583 {
    584     destination[0] = 0x0;
    585     destination[1] = 0x0;
    586     destination[2] = 0x0;
    587     destination[3] = convertColor16LittleTo8(source[0]);
    588 }
    589 
    590 void unpackA16BigToRGBA8(const uint16_t* source, uint8_t* destination)
    591 {
    592     destination[0] = 0x0;
    593     destination[1] = 0x0;
    594     destination[2] = 0x0;
    595     destination[3] = convertColor16BigTo8(source[0]);
    596 }
    597 
    598 void unpackRGB32FToRGBA32F(const float* source, float* destination)
    599 {
    600     destination[0] = source[0];
    601     destination[1] = source[1];
    602     destination[2] = source[2];
    603     destination[3] = 1;
    604 }
    605 
    606 void unpackR32FToRGBA32F(const float* source, float* destination)
    607 {
    608     destination[0] = source[0];
    609     destination[1] = source[0];
    610     destination[2] = source[0];
    611     destination[3] = 1;
    612 }
    613 
    614 void unpackRA32FToRGBA32F(const float* source, float* destination)
    615 {
    616     destination[0] = source[0];
    617     destination[1] = source[0];
    618     destination[2] = source[0];
    619     destination[3] = source[1];
    620 }
    621 
    622 void unpackA32FToRGBA32F(const float* source, float* destination)
    623 {
    624     destination[0] = 0;
    625     destination[1] = 0;
    626     destination[2] = 0;
    627     destination[3] = source[0];
    628 }
    629 
    630 //----------------------------------------------------------------------
    631 // Pixel packing routines.
    632 //
    633 
    634 void packRGBA8ToA8(const uint8_t* source, uint8_t* destination)
    635 {
    636     destination[0] = source[3];
    637 }
    638 
    639 void packRGBA8ToR8(const uint8_t* source, uint8_t* destination)
    640 {
    641     destination[0] = source[0];
    642 }
    643 
    644 void packRGBA8ToR8Premultiply(const uint8_t* source, uint8_t* destination)
    645 {
    646     float scaleFactor = source[3] / 255.0f;
    647     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    648     destination[0] = sourceR;
    649 }
    650 
    651 // FIXME: this routine is lossy and must be removed.
    652 void packRGBA8ToR8Unmultiply(const uint8_t* source, uint8_t* destination)
    653 {
    654     float scaleFactor = 1.0f / (source[3] ? source[3] / 255.0f : 1.0f);
    655     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    656     destination[0] = sourceR;
    657 }
    658 
    659 void packRGBA8ToRA8(const uint8_t* source, uint8_t* destination)
    660 {
    661     destination[0] = source[0];
    662     destination[1] = source[3];
    663 }
    664 
    665 void packRGBA8ToRA8Premultiply(const uint8_t* source, uint8_t* destination)
    666 {
    667     float scaleFactor = source[3] / 255.0f;
    668     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    669     destination[0] = sourceR;
    670     destination[1] = source[3];
    671 }
    672 
    673 // FIXME: this routine is lossy and must be removed.
    674 void packRGBA8ToRA8Unmultiply(const uint8_t* source, uint8_t* destination)
    675 {
    676     float scaleFactor = 1.0f / (source[3] ? source[3] / 255.0f : 1.0f);
    677     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    678     destination[0] = sourceR;
    679     destination[1] = source[3];
    680 }
    681 
    682 void packRGBA8ToRGB8(const uint8_t* source, uint8_t* destination)
    683 {
    684     destination[0] = source[0];
    685     destination[1] = source[1];
    686     destination[2] = source[2];
    687 }
    688 
    689 void packRGBA8ToRGB8Premultiply(const uint8_t* source, uint8_t* destination)
    690 {
    691     float scaleFactor = source[3] / 255.0f;
    692     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    693     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    694     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    695     destination[0] = sourceR;
    696     destination[1] = sourceG;
    697     destination[2] = sourceB;
    698 }
    699 
    700 // FIXME: this routine is lossy and must be removed.
    701 void packRGBA8ToRGB8Unmultiply(const uint8_t* source, uint8_t* destination)
    702 {
    703     float scaleFactor = 1.0f / (source[3] ? source[3] / 255.0f : 1.0f);
    704     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    705     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    706     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    707     destination[0] = sourceR;
    708     destination[1] = sourceG;
    709     destination[2] = sourceB;
    710 }
    711 
    712 // This is only used when the source format is different than SourceFormatRGBA8.
    713 void packRGBA8ToRGBA8(const uint8_t* source, uint8_t* destination)
    714 {
    715     destination[0] = source[0];
    716     destination[1] = source[1];
    717     destination[2] = source[2];
    718     destination[3] = source[3];
    719 }
    720 
    721 void packRGBA8ToRGBA8Premultiply(const uint8_t* source, uint8_t* destination)
    722 {
    723     float scaleFactor = source[3] / 255.0f;
    724     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    725     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    726     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    727     destination[0] = sourceR;
    728     destination[1] = sourceG;
    729     destination[2] = sourceB;
    730     destination[3] = source[3];
    731 }
    732 
    733 // FIXME: this routine is lossy and must be removed.
    734 void packRGBA8ToRGBA8Unmultiply(const uint8_t* source, uint8_t* destination)
    735 {
    736     float scaleFactor = 1.0f / (source[3] ? source[3] / 255.0f : 1.0f);
    737     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    738     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    739     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    740     destination[0] = sourceR;
    741     destination[1] = sourceG;
    742     destination[2] = sourceB;
    743     destination[3] = source[3];
    744 }
    745 
    746 void packRGBA8ToUnsignedShort4444(const uint8_t* source, uint16_t* destination)
    747 {
    748     *destination = (((source[0] & 0xF0) << 8)
    749                     | ((source[1] & 0xF0) << 4)
    750                     | (source[2] & 0xF0)
    751                     | (source[3] >> 4));
    752 }
    753 
    754 void packRGBA8ToUnsignedShort4444Premultiply(const uint8_t* source, uint16_t* destination)
    755 {
    756     float scaleFactor = source[3] / 255.0f;
    757     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    758     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    759     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    760     *destination = (((sourceR & 0xF0) << 8)
    761                     | ((sourceG & 0xF0) << 4)
    762                     | (sourceB & 0xF0)
    763                     | (source[3] >> 4));
    764 }
    765 
    766 // FIXME: this routine is lossy and must be removed.
    767 void packRGBA8ToUnsignedShort4444Unmultiply(const uint8_t* source, uint16_t* destination)
    768 {
    769     float scaleFactor = 1.0f / (source[3] ? source[3] / 255.0f : 1.0f);
    770     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    771     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    772     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    773     *destination = (((sourceR & 0xF0) << 8)
    774                     | ((sourceG & 0xF0) << 4)
    775                     | (sourceB & 0xF0)
    776                     | (source[3] >> 4));
    777 }
    778 
    779 void packRGBA8ToUnsignedShort5551(const uint8_t* source, uint16_t* destination)
    780 {
    781     *destination = (((source[0] & 0xF8) << 8)
    782                     | ((source[1] & 0xF8) << 3)
    783                     | ((source[2] & 0xF8) >> 2)
    784                     | (source[3] >> 7));
    785 }
    786 
    787 void packRGBA8ToUnsignedShort5551Premultiply(const uint8_t* source, uint16_t* destination)
    788 {
    789     float scaleFactor = source[3] / 255.0f;
    790     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    791     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    792     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    793     *destination = (((sourceR & 0xF8) << 8)
    794                     | ((sourceG & 0xF8) << 3)
    795                     | ((sourceB & 0xF8) >> 2)
    796                     | (source[3] >> 7));
    797 }
    798 
    799 // FIXME: this routine is lossy and must be removed.
    800 void packRGBA8ToUnsignedShort5551Unmultiply(const uint8_t* source, uint16_t* destination)
    801 {
    802     float scaleFactor = 1.0f / (source[3] ? source[3] / 255.0f : 1.0f);
    803     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    804     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    805     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    806     *destination = (((sourceR & 0xF8) << 8)
    807                     | ((sourceG & 0xF8) << 3)
    808                     | ((sourceB & 0xF8) >> 2)
    809                     | (source[3] >> 7));
    810 }
    811 
    812 void packRGBA8ToUnsignedShort565(const uint8_t* source, uint16_t* destination)
    813 {
    814     *destination = (((source[0] & 0xF8) << 8)
    815                     | ((source[1] & 0xFC) << 3)
    816                     | ((source[2] & 0xF8) >> 3));
    817 }
    818 
    819 void packRGBA8ToUnsignedShort565Premultiply(const uint8_t* source, uint16_t* destination)
    820 {
    821     float scaleFactor = source[3] / 255.0f;
    822     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    823     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    824     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    825     *destination = (((sourceR & 0xF8) << 8)
    826                     | ((sourceG & 0xFC) << 3)
    827                     | ((sourceB & 0xF8) >> 3));
    828 }
    829 
    830 // FIXME: this routine is lossy and must be removed.
    831 void packRGBA8ToUnsignedShort565Unmultiply(const uint8_t* source, uint16_t* destination)
    832 {
    833     float scaleFactor = 1.0f / (source[3] ? source[3] / 255.0f : 1.0f);
    834     uint8_t sourceR = static_cast<uint8_t>(static_cast<float>(source[0]) * scaleFactor);
    835     uint8_t sourceG = static_cast<uint8_t>(static_cast<float>(source[1]) * scaleFactor);
    836     uint8_t sourceB = static_cast<uint8_t>(static_cast<float>(source[2]) * scaleFactor);
    837     *destination = (((sourceR & 0xF8) << 8)
    838                     | ((sourceG & 0xFC) << 3)
    839                     | ((sourceB & 0xF8) >> 3));
    840 }
    841 
    842 void packRGBA32FToRGB32F(const float* source, float* destination)
    843 {
    844     destination[0] = source[0];
    845     destination[1] = source[1];
    846     destination[2] = source[2];
    847 }
    848 
    849 void packRGBA32FToRGB32FPremultiply(const float* source, float* destination)
    850 {
    851     float scaleFactor = source[3];
    852     destination[0] = source[0] * scaleFactor;
    853     destination[1] = source[1] * scaleFactor;
    854     destination[2] = source[2] * scaleFactor;
    855 }
    856 
    857 void packRGBA32FToRGBA32FPremultiply(const float* source, float* destination)
    858 {
    859     float scaleFactor = source[3];
    860     destination[0] = source[0] * scaleFactor;
    861     destination[1] = source[1] * scaleFactor;
    862     destination[2] = source[2] * scaleFactor;
    863     destination[3] = source[3];
    864 }
    865 
    866 void packRGBA32FToA32F(const float* source, float* destination)
    867 {
    868     destination[0] = source[3];
    869 }
    870 
    871 void packRGBA32FToR32F(const float* source, float* destination)
    872 {
    873     destination[0] = source[0];
    874 }
    875 
    876 void packRGBA32FToR32FPremultiply(const float* source, float* destination)
    877 {
    878     float scaleFactor = source[3];
    879     destination[0] = source[0] * scaleFactor;
    880 }
    881 
    882 
    883 void packRGBA32FToRA32F(const float* source, float* destination)
    884 {
    885     destination[0] = source[0];
    886     destination[1] = source[3];
    887 }
    888 
    889 void packRGBA32FToRA32FPremultiply(const float* source, float* destination)
    890 {
    891     float scaleFactor = source[3];
    892     destination[0] = source[0] * scaleFactor;
    893     destination[1] = scaleFactor;
    894 }
    895 
    896 } // anonymous namespace
    897 
    898 // This is used whenever unpacking is necessary; i.e., the source data
    899 // is not in RGBA8/RGBA32F format, or the unpack alignment specifies
    900 // that rows are not tightly packed.
    901 template<typename SourceType, typename IntermediateType, typename DestType,
    902          void unpackingFunc(const SourceType*, IntermediateType*),
    903          void packingFunc(const IntermediateType*, DestType*)>
    904 static void doUnpackingAndPacking(const SourceType* sourceData,
    905                                   unsigned int width,
    906                                   unsigned int height,
    907                                   unsigned int sourceElementsPerPixel,
    908                                   unsigned int sourceElementsPerRow,
    909                                   DestType* destinationData,
    910                                   unsigned int destinationElementsPerPixel)
    911 {
    912     if (!sourceElementsPerRow) {
    913         unsigned int numElements = width * height * sourceElementsPerPixel;
    914         const SourceType* endPointer = sourceData + numElements;
    915         IntermediateType temporaryRGBAData[4];
    916         while (sourceData < endPointer) {
    917             unpackingFunc(sourceData, temporaryRGBAData);
    918             packingFunc(temporaryRGBAData, destinationData);
    919             sourceData += sourceElementsPerPixel;
    920             destinationData += destinationElementsPerPixel;
    921         }
    922     } else {
    923         IntermediateType temporaryRGBAData[4];
    924         for (unsigned int y = 0; y < height; ++y) {
    925             const SourceType* currentSource = sourceData;
    926             for (unsigned int x = 0; x < width; ++x) {
    927                 unpackingFunc(currentSource, temporaryRGBAData);
    928                 packingFunc(temporaryRGBAData, destinationData);
    929                 currentSource += sourceElementsPerPixel;
    930                 destinationData += destinationElementsPerPixel;
    931             }
    932             sourceData += sourceElementsPerRow;
    933         }
    934     }
    935 }
    936 
    937 template<typename SourceType>
    938 static void computeIncrementParameters(unsigned int width,
    939                                        unsigned int bytesPerPixel,
    940                                        unsigned int unpackAlignment,
    941                                        unsigned int* sourceElementsPerPixel,
    942                                        unsigned int* sourceElementsPerRow)
    943 {
    944     unsigned int elementSizeInBytes = sizeof(SourceType);
    945     ASSERT(elementSizeInBytes <= bytesPerPixel);
    946     ASSERT(!(bytesPerPixel % elementSizeInBytes));
    947     unsigned int validRowBytes = width * bytesPerPixel;
    948     unsigned int totalRowBytes = validRowBytes;
    949     if (unpackAlignment) {
    950         unsigned int remainder = validRowBytes % unpackAlignment;
    951         if (remainder)
    952             totalRowBytes += (unpackAlignment - remainder);
    953     }
    954     *sourceElementsPerPixel = bytesPerPixel / elementSizeInBytes;
    955     if (validRowBytes == totalRowBytes)
    956         *sourceElementsPerRow = 0;
    957     else
    958         *sourceElementsPerRow = totalRowBytes / elementSizeInBytes;
    959 }
    960 
    961 // This handles all conversions with a faster path for tightly packed RGBA8 source data.
    962 template<typename DestType, void packingFunc(const uint8_t*, DestType*)>
    963 static void doPacking(const void* sourceData,
    964                       GraphicsContext3D::SourceDataFormat sourceDataFormat,
    965                       unsigned int width,
    966                       unsigned int height,
    967                       unsigned int sourceUnpackAlignment,
    968                       DestType* destinationData,
    969                       unsigned int destinationElementsPerPixel)
    970 {
    971     switch (sourceDataFormat) {
    972     case GraphicsContext3D::SourceFormatRGBA8: {
    973         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
    974         computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
    975         if (!sourceElementsPerRow) {
    976             const uint8_t* source = static_cast<const uint8_t*>(sourceData);
    977             unsigned int numElements = width * height * 4;
    978             const uint8_t* endPointer = source + numElements;
    979             while (source < endPointer) {
    980                 packingFunc(source, destinationData);
    981                 source += sourceElementsPerPixel;
    982                 destinationData += destinationElementsPerPixel;
    983             }
    984         } else {
    985             doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackRGBA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
    986         }
    987         break;
    988     }
    989     case GraphicsContext3D::SourceFormatRGBA16Little: {
    990         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
    991         computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
    992         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackRGBA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
    993         break;
    994     }
    995     case GraphicsContext3D::SourceFormatRGBA16Big: {
    996         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
    997         computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
    998         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackRGBA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
    999         break;
   1000     }
   1001     case GraphicsContext3D::SourceFormatRGB8: {
   1002         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1003         computeIncrementParameters<uint8_t>(width, 3, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1004         doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackRGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1005         break;
   1006     }
   1007     case GraphicsContext3D::SourceFormatRGB16Little: {
   1008         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1009         computeIncrementParameters<uint16_t>(width, 6, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1010         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackRGB16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1011         break;
   1012     }
   1013     case GraphicsContext3D::SourceFormatRGB16Big: {
   1014         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1015         computeIncrementParameters<uint16_t>(width, 6, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1016         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackRGB16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1017         break;
   1018     }
   1019     case GraphicsContext3D::SourceFormatBGR8: {
   1020         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1021         computeIncrementParameters<uint8_t>(width, 3, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1022         doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackBGR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1023         break;
   1024     }
   1025     case GraphicsContext3D::SourceFormatARGB8: {
   1026         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1027         computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1028         doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackARGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1029         break;
   1030     }
   1031     case GraphicsContext3D::SourceFormatARGB16Little: {
   1032         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1033         computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1034         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackARGB16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1035         break;
   1036     }
   1037     case GraphicsContext3D::SourceFormatARGB16Big: {
   1038         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1039         computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1040         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackARGB16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1041         break;
   1042     }
   1043     case GraphicsContext3D::SourceFormatABGR8: {
   1044         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1045         computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1046         doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackABGR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1047         break;
   1048     }
   1049     case GraphicsContext3D::SourceFormatBGRA8: {
   1050         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1051         computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1052         doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackBGRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1053         break;
   1054     }
   1055     case GraphicsContext3D::SourceFormatBGRA16Little: {
   1056         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1057         computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1058         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackBGRA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1059         break;
   1060     }
   1061     case GraphicsContext3D::SourceFormatBGRA16Big: {
   1062         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1063         computeIncrementParameters<uint16_t>(width, 8, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1064         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackBGRA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1065         break;
   1066     }
   1067     case GraphicsContext3D::SourceFormatRGBA5551: {
   1068         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1069         computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1070         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackRGBA5551ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1071         break;
   1072     }
   1073     case GraphicsContext3D::SourceFormatRGBA4444: {
   1074         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1075         computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1076         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackRGBA4444ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1077         break;
   1078     }
   1079     case GraphicsContext3D::SourceFormatRGB565: {
   1080         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1081         computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1082         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackRGB565ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1083         break;
   1084     }
   1085     case GraphicsContext3D::SourceFormatR8: {
   1086         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1087         computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1088         doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1089         break;
   1090     }
   1091     case GraphicsContext3D::SourceFormatR16Little: {
   1092         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1093         computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1094         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackR16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1095         break;
   1096     }
   1097     case GraphicsContext3D::SourceFormatR16Big: {
   1098         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1099         computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1100         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackR16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1101         break;
   1102     }
   1103     case GraphicsContext3D::SourceFormatRA8: {
   1104         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1105         computeIncrementParameters<uint8_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1106         doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1107         break;
   1108     }
   1109     case GraphicsContext3D::SourceFormatRA16Little: {
   1110         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1111         computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1112         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackRA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1113         break;
   1114     }
   1115     case GraphicsContext3D::SourceFormatRA16Big: {
   1116         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1117         computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1118         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackRA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1119         break;
   1120     }
   1121     case GraphicsContext3D::SourceFormatAR8: {
   1122         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1123         computeIncrementParameters<uint8_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1124         doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackAR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1125         break;
   1126     }
   1127     case GraphicsContext3D::SourceFormatAR16Little: {
   1128         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1129         computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1130         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackAR16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1131         break;
   1132     }
   1133     case GraphicsContext3D::SourceFormatAR16Big: {
   1134         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1135         computeIncrementParameters<uint16_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1136         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackAR16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1137         break;
   1138     }
   1139     case GraphicsContext3D::SourceFormatA8: {
   1140         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1141         computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1142         doUnpackingAndPacking<uint8_t, uint8_t, DestType, unpackA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1143         break;
   1144     }
   1145     case GraphicsContext3D::SourceFormatA16Little: {
   1146         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1147         computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1148         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackA16LittleToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1149         break;
   1150     }
   1151     case GraphicsContext3D::SourceFormatA16Big: {
   1152         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1153         computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1154         doUnpackingAndPacking<uint16_t, uint8_t, DestType, unpackA16BigToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1155         break;
   1156     }
   1157     default:
   1158         ASSERT(false);
   1159     }
   1160 }
   1161 
   1162 // This specialized routine is used only for floating-point texture uploads. It
   1163 // does not need to be as general as doPacking, above; because there are
   1164 // currently no native floating-point image formats in WebKit, there are only a
   1165 // few upload paths.
   1166 template<void packingFunc(const float*, float*)>
   1167 static void doFloatingPointPacking(const void* sourceData,
   1168                                    GraphicsContext3D::SourceDataFormat sourceDataFormat,
   1169                                    unsigned int width,
   1170                                    unsigned int height,
   1171                                    unsigned int sourceUnpackAlignment,
   1172                                    float* destinationData,
   1173                                    unsigned int destinationElementsPerPixel)
   1174 {
   1175     switch (sourceDataFormat) {
   1176     case GraphicsContext3D::SourceFormatRGBA8: {
   1177         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1178         computeIncrementParameters<float>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1179         ASSERT(!sourceElementsPerRow); // Guaranteed because each color channel is sizeof(float) bytes.
   1180         const float* source = static_cast<const float*>(sourceData);
   1181         unsigned int numElements = width * height * 4;
   1182         const float* endPointer = source + numElements;
   1183         while (source < endPointer) {
   1184             packingFunc(source, destinationData);
   1185             source += sourceElementsPerPixel;
   1186             destinationData += destinationElementsPerPixel;
   1187         }
   1188         break;
   1189     }
   1190     case GraphicsContext3D::SourceFormatRGB32F: {
   1191         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1192         computeIncrementParameters<float>(width, 3, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1193         doUnpackingAndPacking<float, float, float, unpackRGB32FToRGBA32F, packingFunc>(static_cast<const float*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1194         break;
   1195     }
   1196     case GraphicsContext3D::SourceFormatR32F: {
   1197         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1198         computeIncrementParameters<float>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1199         doUnpackingAndPacking<float, float, float, unpackR32FToRGBA32F, packingFunc>(static_cast<const float*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1200         break;
   1201     }
   1202     case GraphicsContext3D::SourceFormatRA32F: {
   1203         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1204         computeIncrementParameters<float>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1205         doUnpackingAndPacking<float, float, float, unpackRA32FToRGBA32F, packingFunc>(static_cast<const float*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1206         break;
   1207     }
   1208     case GraphicsContext3D::SourceFormatA32F: {
   1209         unsigned int sourceElementsPerPixel, sourceElementsPerRow;
   1210         computeIncrementParameters<float>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
   1211         doUnpackingAndPacking<float, float, float, unpackA32FToRGBA32F, packingFunc>(static_cast<const float*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
   1212         break;
   1213     }
   1214     default:
   1215         ASSERT_NOT_REACHED();
   1216     }
   1217 }
   1218 
   1219 bool GraphicsContext3D::packPixels(const uint8_t* sourceData,
   1220                                    GraphicsContext3D::SourceDataFormat sourceDataFormat,
   1221                                    unsigned int width,
   1222                                    unsigned int height,
   1223                                    unsigned int sourceUnpackAlignment,
   1224                                    unsigned int destinationFormat,
   1225                                    unsigned int destinationType,
   1226                                    AlphaOp alphaOp,
   1227                                    void* destinationData)
   1228 {
   1229     switch (destinationType) {
   1230     case UNSIGNED_BYTE: {
   1231         uint8_t* destination = static_cast<uint8_t*>(destinationData);
   1232         if (sourceDataFormat == SourceFormatRGBA8 && destinationFormat == RGBA && sourceUnpackAlignment <= 4 && alphaOp == AlphaDoNothing) {
   1233             // No conversion necessary.
   1234             memcpy(destinationData, sourceData, width * height * 4);
   1235             break;
   1236         }
   1237         switch (destinationFormat) {
   1238         case RGB:
   1239             switch (alphaOp) {
   1240             case AlphaDoNothing:
   1241                 doPacking<uint8_t, packRGBA8ToRGB8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
   1242                 break;
   1243             case AlphaDoPremultiply:
   1244                 doPacking<uint8_t, packRGBA8ToRGB8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
   1245                 break;
   1246             case AlphaDoUnmultiply:
   1247                 doPacking<uint8_t, packRGBA8ToRGB8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
   1248                 break;
   1249             }
   1250             break;
   1251         case RGBA:
   1252             switch (alphaOp) {
   1253             case AlphaDoNothing:
   1254                 ASSERT(sourceDataFormat != SourceFormatRGBA8 || sourceUnpackAlignment > 4); // Handled above with fast case.
   1255                 doPacking<uint8_t, packRGBA8ToRGBA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
   1256                 break;
   1257             case AlphaDoPremultiply:
   1258                 doPacking<uint8_t, packRGBA8ToRGBA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
   1259                 break;
   1260             case AlphaDoUnmultiply:
   1261                 doPacking<uint8_t, packRGBA8ToRGBA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
   1262                 break;
   1263             default:
   1264                 ASSERT_NOT_REACHED();
   1265             }
   1266             break;
   1267         case ALPHA:
   1268             // From the desktop OpenGL conversion rules (OpenGL 2.1
   1269             // specification, Table 3.15), the alpha channel is chosen
   1270             // from the RGBA data.
   1271             doPacking<uint8_t, packRGBA8ToA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1272             break;
   1273         case LUMINANCE:
   1274             // From the desktop OpenGL conversion rules (OpenGL 2.1
   1275             // specification, Table 3.15), the red channel is chosen
   1276             // from the RGBA data.
   1277             switch (alphaOp) {
   1278             case AlphaDoNothing:
   1279                 doPacking<uint8_t, packRGBA8ToR8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1280                 break;
   1281             case AlphaDoPremultiply:
   1282                 doPacking<uint8_t, packRGBA8ToR8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1283                 break;
   1284             case AlphaDoUnmultiply:
   1285                 doPacking<uint8_t, packRGBA8ToR8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1286                 break;
   1287             }
   1288             break;
   1289         case LUMINANCE_ALPHA:
   1290             // From the desktop OpenGL conversion rules (OpenGL 2.1
   1291             // specification, Table 3.15), the red and alpha channels
   1292             // are chosen from the RGBA data.
   1293             switch (alphaOp) {
   1294             case AlphaDoNothing:
   1295                 doPacking<uint8_t, packRGBA8ToRA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
   1296                 break;
   1297             case AlphaDoPremultiply:
   1298                 doPacking<uint8_t, packRGBA8ToRA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
   1299                 break;
   1300             case AlphaDoUnmultiply:
   1301                 doPacking<uint8_t, packRGBA8ToRA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
   1302                 break;
   1303             }
   1304             break;
   1305         }
   1306         break;
   1307     }
   1308     case UNSIGNED_SHORT_4_4_4_4: {
   1309         uint16_t* destination = static_cast<uint16_t*>(destinationData);
   1310         switch (alphaOp) {
   1311         case AlphaDoNothing:
   1312             doPacking<uint16_t, packRGBA8ToUnsignedShort4444>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1313             break;
   1314         case AlphaDoPremultiply:
   1315             doPacking<uint16_t, packRGBA8ToUnsignedShort4444Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1316             break;
   1317         case AlphaDoUnmultiply:
   1318             doPacking<uint16_t, packRGBA8ToUnsignedShort4444Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1319             break;
   1320         }
   1321         break;
   1322     }
   1323     case UNSIGNED_SHORT_5_5_5_1: {
   1324         uint16_t* destination = static_cast<uint16_t*>(destinationData);
   1325         switch (alphaOp) {
   1326         case AlphaDoNothing:
   1327             doPacking<uint16_t, packRGBA8ToUnsignedShort5551>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1328             break;
   1329         case AlphaDoPremultiply:
   1330             doPacking<uint16_t, packRGBA8ToUnsignedShort5551Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1331             break;
   1332         case AlphaDoUnmultiply:
   1333             doPacking<uint16_t, packRGBA8ToUnsignedShort5551Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1334             break;
   1335         }
   1336         break;
   1337     }
   1338     case UNSIGNED_SHORT_5_6_5: {
   1339         uint16_t* destination = static_cast<uint16_t*>(destinationData);
   1340         switch (alphaOp) {
   1341         case AlphaDoNothing:
   1342             doPacking<uint16_t, packRGBA8ToUnsignedShort565>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1343             break;
   1344         case AlphaDoPremultiply:
   1345             doPacking<uint16_t, packRGBA8ToUnsignedShort565Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1346             break;
   1347         case AlphaDoUnmultiply:
   1348             doPacking<uint16_t, packRGBA8ToUnsignedShort565Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1349             break;
   1350         }
   1351         break;
   1352     }
   1353     case FLOAT: {
   1354         // OpenGL ES, and therefore WebGL, require that the format and
   1355         // internalformat be identical, which implies that the source and
   1356         // destination formats will both be floating-point in this branch -- at
   1357         // least, until WebKit supports floating-point image formats natively.
   1358         ASSERT(sourceDataFormat == SourceFormatRGBA32F || sourceDataFormat == SourceFormatRGB32F
   1359                || sourceDataFormat == SourceFormatRA32F || sourceDataFormat == SourceFormatR32F
   1360                || sourceDataFormat == SourceFormatA32F);
   1361         // Because WebKit doesn't use floating-point color channels for anything
   1362         // internally, there's no chance we have to do a (lossy) unmultiply
   1363         // operation.
   1364         ASSERT(alphaOp == AlphaDoNothing || alphaOp == AlphaDoPremultiply);
   1365         // For the source formats with an even number of channels (RGBA32F,
   1366         // RA32F) it is guaranteed that the pixel data is tightly packed because
   1367         // unpack alignment <= sizeof(float) * number of channels.
   1368         float* destination = static_cast<float*>(destinationData);
   1369         if (alphaOp == AlphaDoNothing
   1370             && ((sourceDataFormat == SourceFormatRGBA32F && destinationFormat == RGBA)
   1371                 || (sourceDataFormat == SourceFormatRA32F && destinationFormat == LUMINANCE_ALPHA))) {
   1372             // No conversion necessary.
   1373             int numChannels = (sourceDataFormat == SourceFormatRGBA32F ? 4 : 2);
   1374             memcpy(destinationData, sourceData, width * height * numChannels * sizeof(float));
   1375             break;
   1376         }
   1377         switch (destinationFormat) {
   1378         case RGB:
   1379             switch (alphaOp) {
   1380             case AlphaDoNothing:
   1381                 doFloatingPointPacking<packRGBA32FToRGB32F>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
   1382                 break;
   1383             case AlphaDoPremultiply:
   1384                 doFloatingPointPacking<packRGBA32FToRGB32FPremultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
   1385                 break;
   1386             default:
   1387                 ASSERT_NOT_REACHED();
   1388             }
   1389             break;
   1390         case RGBA:
   1391             // AlphaDoNothing is handled above with fast path.
   1392             ASSERT(alphaOp == AlphaDoPremultiply);
   1393             doFloatingPointPacking<packRGBA32FToRGBA32FPremultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
   1394             break;
   1395         case ALPHA:
   1396             // From the desktop OpenGL conversion rules (OpenGL 2.1
   1397             // specification, Table 3.15), the alpha channel is chosen
   1398             // from the RGBA data.
   1399             doFloatingPointPacking<packRGBA32FToA32F>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1400             break;
   1401         case LUMINANCE:
   1402             // From the desktop OpenGL conversion rules (OpenGL 2.1
   1403             // specification, Table 3.15), the red channel is chosen
   1404             // from the RGBA data.
   1405             switch (alphaOp) {
   1406             case AlphaDoNothing:
   1407                 doFloatingPointPacking<packRGBA32FToR32F>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1408                 break;
   1409             case AlphaDoPremultiply:
   1410                 doFloatingPointPacking<packRGBA32FToR32FPremultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
   1411                 break;
   1412             default:
   1413                 ASSERT_NOT_REACHED();
   1414             }
   1415             break;
   1416         case LUMINANCE_ALPHA:
   1417             // From the desktop OpenGL conversion rules (OpenGL 2.1
   1418             // specification, Table 3.15), the red and alpha channels
   1419             // are chosen from the RGBA data.
   1420             switch (alphaOp) {
   1421             case AlphaDoNothing:
   1422                 doFloatingPointPacking<packRGBA32FToRA32F>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
   1423                 break;
   1424             case AlphaDoPremultiply:
   1425                 doFloatingPointPacking<packRGBA32FToRA32FPremultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
   1426                 break;
   1427             default:
   1428                 ASSERT_NOT_REACHED();
   1429             }
   1430             break;
   1431         }
   1432         break;
   1433     }
   1434     }
   1435     return true;
   1436 }
   1437 
   1438 } // namespace WebCore
   1439 
   1440 #endif // ENABLE(WEBGL)
   1441