Changeset 62145 in webkit


Ignore:
Timestamp:
Jun 29, 2010 1:16:52 PM (14 years ago)
Author:
kbr@google.com
Message:

2010-06-29 Kenneth Russell <kbr@google.com>

Reviewed by Dimitri Glazkov.

Support UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL for texImage2D taking ArrayBufferView
https://bugs.webkit.org/show_bug.cgi?id=40398

Added support for UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL pixel store
parameters to texImage2D and texSubImage2D entry points taking ArrayBufferView.
More cleanly separated the unpacking and packing phases of user-supplied pixel data
in GraphicsContext3D, and added support for unpack alignment. Fixed bug in handling
of unpackAlignment in GraphicsContext3D::flipVertically. Necessarily added
validation of the amount of data passed to texImage2D and texSubImage2D. Modified
fast/canvas/webgl/tex-image-with-format-and-type.html to include premultiplied alpha
tests for relevant source formats; added new test which exercises all combinations
of UNPACK_FLIP_Y_WEBGL, UNPACK_PREMULTIPLY_ALPHA_WEBGL, and UNPACK_ALIGNMENT pixel
store parameters.

Test: fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view.html

  • html/canvas/WebGLRenderingContext.cpp: (WebCore::WebGLRenderingContext::texImage2D): (WebCore::WebGLRenderingContext::texSubImage2D): (WebCore::WebGLRenderingContext::validateTexFuncData):
  • html/canvas/WebGLRenderingContext.h:
  • platform/graphics/GraphicsContext3D.cpp: (WebCore::GraphicsContext3D::extractImageData): (WebCore::GraphicsContext3D::extractTextureData): (WebCore::GraphicsContext3D::flipVertically): (WebCore::doUnpackingAndPacking): (WebCore::computeIncrementParameters): (WebCore::doPacking): (WebCore::GraphicsContext3D::packPixels):
  • platform/graphics/GraphicsContext3D.h: (WebCore::GraphicsContext3D::):
  • platform/graphics/cg/GraphicsContext3DCG.cpp: (WebCore::GraphicsContext3D::getImageData):
  • platform/graphics/qt/GraphicsContext3DQt.cpp: (WebCore::GraphicsContext3D::getImageData):
  • platform/graphics/skia/GraphicsContext3DSkia.cpp: (WebCore::GraphicsContext3D::getImageData):

2010-06-29 Kenneth Russell <kbr@google.com>

Reviewed by Dimitri Glazkov.

Support UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL for texImage2D taking ArrayBufferView
https://bugs.webkit.org/show_bug.cgi?id=40398

Added support for UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL pixel store
parameters to texImage2D and texSubImage2D entry points taking ArrayBufferView.
More cleanly separated the unpacking and packing phases of user-supplied pixel data
in GraphicsContext3D, and added support for unpack alignment. Fixed bug in handling
of unpackAlignment in GraphicsContext3D::flipVertically. Necessarily added
validation of the amount of data passed to texImage2D and texSubImage2D. Modified
fast/canvas/webgl/tex-image-with-format-and-type.html to include premultiplied alpha
tests for relevant source formats; added new test which exercises all combinations
of UNPACK_FLIP_Y_WEBGL, UNPACK_PREMULTIPLY_ALPHA_WEBGL, and UNPACK_ALIGNMENT pixel
store parameters.

  • fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view-expected.txt: Added.
  • fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view.html: Added.
  • fast/canvas/webgl/tex-image-with-format-and-type-expected.txt:
  • fast/canvas/webgl/tex-image-with-format-and-type.html:
Location:
trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r62141 r62145  
     12010-06-29  Kenneth Russell  <kbr@google.com>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        Support UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL for texImage2D taking ArrayBufferView
     6        https://bugs.webkit.org/show_bug.cgi?id=40398
     7
     8        Added support for UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL pixel store
     9        parameters to texImage2D and texSubImage2D entry points taking ArrayBufferView.
     10        More cleanly separated the unpacking and packing phases of user-supplied pixel data
     11        in GraphicsContext3D, and added support for unpack alignment. Fixed bug in handling
     12        of unpackAlignment in GraphicsContext3D::flipVertically. Necessarily added
     13        validation of the amount of data passed to texImage2D and texSubImage2D. Modified
     14        fast/canvas/webgl/tex-image-with-format-and-type.html to include premultiplied alpha
     15        tests for relevant source formats; added new test which exercises all combinations
     16        of UNPACK_FLIP_Y_WEBGL, UNPACK_PREMULTIPLY_ALPHA_WEBGL, and UNPACK_ALIGNMENT pixel
     17        store parameters.
     18
     19        * fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view-expected.txt: Added.
     20        * fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view.html: Added.
     21        * fast/canvas/webgl/tex-image-with-format-and-type-expected.txt:
     22        * fast/canvas/webgl/tex-image-with-format-and-type.html:
     23
    1242010-06-29  Robert Hogan  <robert@webkit.org>
    225
  • trunk/LayoutTests/fast/canvas/webgl/tex-image-with-format-and-type-expected.txt

    r61715 r62145  
    1 Verify texImage2D and texSubImage2D code paths taking HTML data with all format/type combinations
     1Verify texImage2D and texSubImage2D code paths taking both HTML and user-specified data with all format/type combinations
    22
    33On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
    44
    5 Regression test for https://bugs.webkit.org/show_bug.cgi?id=40319 : Implement format conversions in texImage2D and texSubImage2D taking HTML data
     5Regression test for:
     6https://bugs.webkit.org/show_bug.cgi?id=40319 : Implement format conversions in texImage2D and texSubImage2D taking HTML data
     7https://bugs.webkit.org/show_bug.cgi?id=40398 : Support UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL for texImage2D taking ArrayBufferView
    68Testing texImage2D with Image at 256x1
    79PASS RGBA/UNSIGNED_BYTE should maintain full precision of data
     
    132134Testing texSubImage2D with ImageData at 256x1
    133135PASS UNPACK_PREMULTIPLY_ALPHA_WEBGL with LUMINANCE_ALPHA/UNSIGNED_BYTE
     136Testing texImage2D with raw data at 256x1
     137PASS UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_BYTE
     138Testing texImage2D with raw data at 256x1
     139PASS UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_SHORT_4_4_4_4
     140Testing texImage2D with raw data at 256x1
     141PASS UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_SHORT_5_5_5_1
     142Testing texImage2D with raw data at 256x1
     143PASS UNPACK_PREMULTIPLY_ALPHA_WEBGL with LUMINANCE_ALPHA/UNSIGNED_BYTE
     144Testing texSubImage2D with raw data at 256x1
     145PASS UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_BYTE
     146Testing texSubImage2D with raw data at 256x1
     147PASS UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_SHORT_4_4_4_4
     148Testing texSubImage2D with raw data at 256x1
     149PASS UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_SHORT_5_5_5_1
     150Testing texSubImage2D with raw data at 256x1
     151PASS UNPACK_PREMULTIPLY_ALPHA_WEBGL with LUMINANCE_ALPHA/UNSIGNED_BYTE
    134152PASS successfullyParsed is true
    135153
  • trunk/LayoutTests/fast/canvas/webgl/tex-image-with-format-and-type.html

    r61715 r62145  
    3939var testCases = [];
    4040
     41var DataMode = {
     42    IMAGE: 0,
     43    IMAGE_DATA: 1,
     44
     45    NUM_HTML_MODES: 2,
     46
     47    RAW_DATA: 2,
     48
     49    // This must remain the last mode.
     50    NUM_MODES: 3
     51};
     52
    4153function init()
    4254{
     
    4759    }
    4860
    49     description('Verify texImage2D and texSubImage2D code paths taking HTML data with all format/type combinations');
    50 
    51     debug('Regression test for <a href="https://bugs.webkit.org/show_bug.cgi?id=40319">https://bugs.webkit.org/show_bug.cgi?id=40319</a> : <code>Implement format conversions in texImage2D and texSubImage2D taking HTML data</code>');
     61    description('Verify texImage2D and texSubImage2D code paths taking both HTML and user-specified data with all format/type combinations');
     62
     63    debug('Regression test for:');
     64    debug('<a href="https://bugs.webkit.org/show_bug.cgi?id=40319">https://bugs.webkit.org/show_bug.cgi?id=40319</a> : <code>Implement format conversions in texImage2D and texSubImage2D taking HTML data</code>');
     65    debug('<a href="https://bugs.webkit.org/show_bug.cgi?id=40398">https://bugs.webkit.org/show_bug.cgi?id=40398</a> : <code>Support UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL for texImage2D taking ArrayBufferView</code>');
    5266
    5367    gl = initWebGL("example", "vshader", "fshader", [ "g_Position", "g_TexCoord0" ], [ 0, 0, 0, 1 ], 1);
     
    92106    // Verify that uploading to packed pixel formats performs the
    93107    // required conversion and associated loss of precision.
    94     for (var useImageData = 0; useImageData < 2; ++useImageData) {
     108    for (var dataMode = 0; dataMode < DataMode.NUM_HTML_MODES; ++dataMode) {
    95109        for (var useTexSubImage2D = 0; useTexSubImage2D < 2; ++useTexSubImage2D) {
    96110            testCases.push({
    97                 useImageData: !!useImageData,
     111                dataMode: dataMode,
    98112                useTexSubImage2D: !!useTexSubImage2D,
    99113                width: 256,
     
    109123            });
    110124            testCases.push({
    111                 useImageData: !!useImageData,
     125                dataMode: dataMode,
    112126                useTexSubImage2D: !!useTexSubImage2D,
    113127                width: 256,
     
    123137            });
    124138            testCases.push({
    125                 useImageData: !!useImageData,
     139                dataMode: dataMode,
    126140                useTexSubImage2D: !!useTexSubImage2D,
    127141                width: 256,
     
    137151            });
    138152            testCases.push({
    139                 useImageData: !!useImageData,
     153                dataMode: dataMode,
    140154                useTexSubImage2D: !!useTexSubImage2D,
    141155                width: 256,
     
    151165            });
    152166            testCases.push({
    153                 useImageData: !!useImageData,
     167                dataMode: dataMode,
    154168                useTexSubImage2D: !!useTexSubImage2D,
    155169                width: 256,
     
    165179            });
    166180            testCases.push({
    167                 useImageData: !!useImageData,
     181                dataMode: dataMode,
    168182                useTexSubImage2D: !!useTexSubImage2D,
    169183                width: 256,
     
    179193            });
    180194            testCases.push({
    181                 useImageData: !!useImageData,
     195                dataMode: dataMode,
    182196                useTexSubImage2D: !!useTexSubImage2D,
    183197                width: 256,
     
    193207            });
    194208            testCases.push({
    195                 useImageData: !!useImageData,
     209                dataMode: dataMode,
    196210                useTexSubImage2D: !!useTexSubImage2D,
    197211                width: 256,
     
    212226    // store parameter and sending down a zero alpha causes the color
    213227    // channels to go to zero.
    214     for (var useImageData = 0; useImageData < 2; ++useImageData) {
     228    for (var dataMode = 0; dataMode < DataMode.NUM_MODES; ++dataMode) {
    215229        for (var useTexSubImage2D = 0; useTexSubImage2D < 2; ++useTexSubImage2D) {
    216230            testCases.push({
    217                 useImageData: !!useImageData,
     231                dataMode: dataMode,
    218232                useTexSubImage2D: !!useTexSubImage2D,
    219233                width: 256,
     
    227241            });
    228242            testCases.push({
    229                 useImageData: !!useImageData,
     243                dataMode: dataMode,
    230244                useTexSubImage2D: !!useTexSubImage2D,
    231245                width: 256,
     
    239253            });
    240254            testCases.push({
    241                 useImageData: !!useImageData,
     255                dataMode: dataMode,
    242256                useTexSubImage2D: !!useTexSubImage2D,
    243257                width: 256,
     
    250264                description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGBA/UNSIGNED_SHORT_5_5_5_1"
    251265            });
    252             testCases.push({
    253                 useImageData: !!useImageData,
    254                 useTexSubImage2D: !!useTexSubImage2D,
    255                 width: 256,
    256                 height: 1,
    257                 generator: generateTransparentGrayscaleRamp,
    258                 premultiplyAlpha: true,
    259                 format: gl.RGB,
    260                 type: gl.UNSIGNED_BYTE,
    261                 verifier: colorChannelsAreZero,
    262                 description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGB/UNSIGNED_BYTE"
    263             });
    264             testCases.push({
    265                 useImageData: !!useImageData,
    266                 useTexSubImage2D: !!useTexSubImage2D,
    267                 width: 256,
    268                 height: 1,
    269                 generator: generateTransparentGrayscaleRamp,
    270                 premultiplyAlpha: true,
    271                 format: gl.RGB,
    272                 type: gl.UNSIGNED_SHORT_5_6_5,
    273                 verifier: colorChannelsAreZero,
    274                 description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGB/UNSIGNED_SHORT_5_6_5"
    275             });
    276             testCases.push({
    277                 useImageData: !!useImageData,
    278                 useTexSubImage2D: !!useTexSubImage2D,
    279                 width: 256,
    280                 height: 1,
    281                 generator: generateTransparentGrayscaleRamp,
    282                 premultiplyAlpha: true,
    283                 format: gl.ALPHA,
    284                 type: gl.UNSIGNED_BYTE,
    285                 verifier: colorChannelsAreZero,
    286                 description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with ALPHA/UNSIGNED_BYTE"
    287             });
    288             testCases.push({
    289                 useImageData: !!useImageData,
    290                 useTexSubImage2D: !!useTexSubImage2D,
    291                 width: 256,
    292                 height: 1,
    293                 generator: generateTransparentGrayscaleRamp,
    294                 premultiplyAlpha: true,
    295                 format: gl.LUMINANCE,
    296                 type: gl.UNSIGNED_BYTE,
    297                 verifier: colorChannelsAreZero,
    298                 description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with LUMINANCE/UNSIGNED_BYTE"
    299             });
    300             testCases.push({
    301                 useImageData: !!useImageData,
     266            // The following few tests are invalid for the raw data
     267            // mode because there is either no alpha channel or no
     268            // separate alpha channel.
     269            if (dataMode != DataMode.RAW_DATA) {
     270                testCases.push({
     271                    dataMode: dataMode,
     272                    useTexSubImage2D: !!useTexSubImage2D,
     273                    width: 256,
     274                    height: 1,
     275                    generator: generateTransparentGrayscaleRamp,
     276                    premultiplyAlpha: true,
     277                    format: gl.RGB,
     278                    type: gl.UNSIGNED_BYTE,
     279                    verifier: colorChannelsAreZero,
     280                    description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGB/UNSIGNED_BYTE"
     281                });
     282                testCases.push({
     283                    dataMode: dataMode,
     284                    useTexSubImage2D: !!useTexSubImage2D,
     285                    width: 256,
     286                    height: 1,
     287                    generator: generateTransparentGrayscaleRamp,
     288                    premultiplyAlpha: true,
     289                    format: gl.RGB,
     290                    type: gl.UNSIGNED_SHORT_5_6_5,
     291                    verifier: colorChannelsAreZero,
     292                    description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with RGB/UNSIGNED_SHORT_5_6_5"
     293                });
     294                testCases.push({
     295                    dataMode: dataMode,
     296                    useTexSubImage2D: !!useTexSubImage2D,
     297                    width: 256,
     298                    height: 1,
     299                    generator: generateTransparentGrayscaleRamp,
     300                    premultiplyAlpha: true,
     301                    format: gl.ALPHA,
     302                    type: gl.UNSIGNED_BYTE,
     303                    verifier: colorChannelsAreZero,
     304                    description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with ALPHA/UNSIGNED_BYTE"
     305                });
     306                testCases.push({
     307                    dataMode: dataMode,
     308                    useTexSubImage2D: !!useTexSubImage2D,
     309                    width: 256,
     310                    height: 1,
     311                    generator: generateTransparentGrayscaleRamp,
     312                    premultiplyAlpha: true,
     313                    format: gl.LUMINANCE,
     314                    type: gl.UNSIGNED_BYTE,
     315                    verifier: colorChannelsAreZero,
     316                    description: "UNPACK_PREMULTIPLY_ALPHA_WEBGL with LUMINANCE/UNSIGNED_BYTE"
     317                });
     318            }
     319            testCases.push({
     320                dataMode: dataMode,
    302321                useTexSubImage2D: !!useTexSubImage2D,
    303322                width: 256,
     
    323342        var testCase = testCases[i];
    324343        var wrapper = null;
    325         if (testCase.useImageData)
     344        switch (testCase.dataMode) {
     345        case DataMode.IMAGE:
     346            wrapper = new ImageWrapper(testCase.width, testCase.height);
     347            break;
     348        case DataMode.IMAGE_DATA:
    326349            wrapper = new ImageDataWrapper(testCase.width, testCase.height);
    327         else
    328             wrapper = new ImageWrapper(testCase.width, testCase.height);
     350            break;
     351        case DataMode.RAW_DATA:
     352            switch (testCase.type) {
     353            case gl.UNSIGNED_BYTE:
     354                switch (testCase.format) {
     355                case gl.RGBA:
     356                    wrapper = new RGBA8DataWrapper(testCase.width, testCase.height);
     357                    break;
     358                case gl.RGB:
     359                    wrapper = new RGB8DataWrapper(testCase.width, testCase.height);
     360                    break;
     361                case gl.ALPHA:
     362                    wrapper = new A8DataWrapper(testCase.width, testCase.height);
     363                    break;
     364                case gl.LUMINANCE:
     365                    wrapper = new L8DataWrapper(testCase.width, testCase.height);
     366                    break;
     367                case gl.LUMINANCE_ALPHA:
     368                    wrapper = new LA8DataWrapper(testCase.width, testCase.height);
     369                    break;
     370                }
     371                break;
     372            case gl.UNSIGNED_SHORT_4_4_4_4:
     373                wrapper = new RGBA4444DataWrapper(testCase.width, testCase.height);
     374                break;
     375            case gl.UNSIGNED_SHORT_5_5_5_1:
     376                wrapper = new RGBA5551DataWrapper(testCase.width, testCase.height);
     377                break;
     378            case gl.UNSIGNED_SHORT_5_6_5:
     379                wrapper = new RGB565DataWrapper(testCase.width, testCase.height);
     380                break;
     381            }
     382        }
    329383        testCase.wrapper = wrapper;
    330384        testCase.generator(wrapper);
     
    360414function testCaseToString(testCase)
    361415{
     416    var mode;
     417    switch (testCase.dataMode) {
     418    case DataMode.IMAGE:
     419        mode = "Image";
     420        break;
     421    case DataMode.IMAGE_DATA:
     422        mode = "ImageData";
     423        break;
     424    case DataMode.RAW_DATA:
     425        mode = "raw data";
     426        break;
     427    }
    362428    return (testCase.useTexSubImage2D ? "texSubImage2D" : "texImage2D") +
    363             " with " + (testCase.useImageData ? "ImageData" : "Image") +
    364             " at " + testCase.width + "x" + testCase.height;
     429            " with " + mode +  " at " + testCase.width + "x" + testCase.height;
    365430}
    366431
     
    383448        gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.width, testCase.height, 0,
    384449                      testCase.format, testCase.type, null);
    385         gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, testCase.format, testCase.type, data);
    386     } else {
    387         gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.format, testCase.type, data);
    388     }
    389 
     450    }
     451    switch (testCase.dataMode) {
     452    case DataMode.IMAGE:
     453    case DataMode.IMAGE_DATA:
     454        if (testCase.useTexSubImage2D)
     455            gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, testCase.format, testCase.type, data);
     456        else
     457            gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.format, testCase.type, data);
     458        break;
     459    case DataMode.RAW_DATA:
     460        if (testCase.useTexSubImage2D)
     461            gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, testCase.width, testCase.height, testCase.format, testCase.type, data);
     462        else
     463            gl.texImage2D(gl.TEXTURE_2D, 0, testCase.format, testCase.width, testCase.height, 0, testCase.format, testCase.type, data);
     464        break;
     465    }
    390466    // Point the uniform sampler to texture unit 0.
    391467    gl.uniform1i(textureLoc, 0);
     
    412488
    413489//----------------------------------------------------------------------
    414 // Wrappers for programmatic construction of Image and ImageData
     490// Wrappers for programmatic construction of Image, ImageData and raw texture data
    415491//
    416492
     
    474550};
    475551
     552function TextureDataWrapper(width, height)
     553{
     554    this.width_ = width;
     555    this.height_ = height;
     556}
     557
     558TextureDataWrapper.prototype.getWidth = function() {
     559    return this.width_;
     560};
     561
     562TextureDataWrapper.prototype.getHeight = function() {
     563    return this.height_;
     564};
     565
     566TextureDataWrapper.prototype.generateData = function() {
     567    this.data = this.data_;
     568    maybeRunTests();
     569};
     570
     571function RGBA8DataWrapper(width, height)
     572{
     573    TextureDataWrapper.call(this, width, height);
     574    this.data_ = new Uint8Array(4 * width * height);
     575}
     576
     577RGBA8DataWrapper.prototype = new TextureDataWrapper;
     578
     579RGBA8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
     580    var index = 4 * (this.width_ * y + x);
     581    this.data_[index] = r;
     582    this.data_[index + 1] = g;
     583    this.data_[index + 2] = b;
     584    this.data_[index + 3] = a;
     585};
     586
     587function RGBA5551DataWrapper(width, height)
     588{
     589    TextureDataWrapper.call(this, width, height);
     590    this.data_ = new Uint16Array(width * height);
     591}
     592
     593RGBA5551DataWrapper.prototype = new TextureDataWrapper;
     594
     595RGBA5551DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
     596    var value = (((r & 0xF8) << 8)
     597                 | ((g & 0xF8) << 3)
     598                 | ((b & 0xF8) >> 2)
     599                 | (a >> 7));
     600    this.data_[this.width_ * y + x] = value;
     601};
     602
     603function RGBA4444DataWrapper(width, height)
     604{
     605    TextureDataWrapper.call(this, width, height);
     606    this.data_ = new Uint16Array(width * height);
     607}
     608
     609RGBA4444DataWrapper.prototype = new TextureDataWrapper;
     610
     611RGBA4444DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
     612    var value = (((r & 0xF0) << 8)
     613                 | ((g & 0xF0) << 4)
     614                 | (b & 0xF0)
     615                 | (a >> 4));
     616    this.data_[this.width_ * y + x] = value;
     617};
     618
     619function RGB8DataWrapper(width, height)
     620{
     621    TextureDataWrapper.call(this, width, height);
     622    this.data_ = new Uint8Array(3 * width * height);
     623}
     624
     625RGB8DataWrapper.prototype = new TextureDataWrapper;
     626
     627RGB8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
     628    var index = 3 * (this.width_ * y + x);
     629    this.data_[index] = r;
     630    this.data_[index + 1] = g;
     631    this.data_[index + 2] = b;
     632};
     633
     634function RGB565DataWrapper(width, height)
     635{
     636    TextureDataWrapper.call(this, width, height);
     637    this.data_ = new Uint16Array(width * height);
     638}
     639
     640RGB565DataWrapper.prototype = new TextureDataWrapper;
     641
     642RGB565DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
     643    var value = (((r & 0xF8) << 8)
     644                 | ((g & 0xFC) << 3)
     645                 | ((b & 0xF8) >> 3));
     646    this.data_[this.width_ * y + x] = value;
     647};
     648
     649function A8DataWrapper(width, height)
     650{
     651    TextureDataWrapper.call(this, width, height);
     652    this.data_ = new Uint8Array(width * height);
     653}
     654
     655A8DataWrapper.prototype = new TextureDataWrapper;
     656
     657A8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
     658    this.data_[this.width_ * y + x] = a;
     659};
     660
     661function L8DataWrapper(width, height)
     662{
     663    TextureDataWrapper.call(this, width, height);
     664    this.data_ = new Uint8Array(width * height);
     665}
     666
     667L8DataWrapper.prototype = new TextureDataWrapper;
     668
     669L8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
     670    this.data_[this.width_ * y + x] = r;
     671};
     672
     673function LA8DataWrapper(width, height)
     674{
     675    TextureDataWrapper.call(this, width, height);
     676    this.data_ = new Uint8Array(2 * width * height);
     677}
     678
     679LA8DataWrapper.prototype = new TextureDataWrapper;
     680
     681LA8DataWrapper.prototype.setPixel = function(x, y, r, g, b, a) {
     682    var index = 2 * (this.width_ * y + x);
     683    this.data_[index] = r;
     684    this.data_[index + 1] = a;
     685};
     686
    476687//----------------------------------------------------------------------
    477688// Color ramp generation functions
     
    552763            if (array[i + j] != 0) {
    553764                passed = false;
    554                 if (++numFailures < 5)
    555                     debug("  array[" + i + "] should have been 0, was " + array[i]);
     765                if (++numFailures <= 5)
     766                    debug("  array[" + (i + j) + "] should have been 0, was " + array[i + j]);
    556767            }
    557768
  • trunk/WebCore/ChangeLog

    r62144 r62145  
     12010-06-29  Kenneth Russell  <kbr@google.com>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        Support UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL for texImage2D taking ArrayBufferView
     6        https://bugs.webkit.org/show_bug.cgi?id=40398
     7
     8        Added support for UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL pixel store
     9        parameters to texImage2D and texSubImage2D entry points taking ArrayBufferView.
     10        More cleanly separated the unpacking and packing phases of user-supplied pixel data
     11        in GraphicsContext3D, and added support for unpack alignment. Fixed bug in handling
     12        of unpackAlignment in GraphicsContext3D::flipVertically. Necessarily added
     13        validation of the amount of data passed to texImage2D and texSubImage2D. Modified
     14        fast/canvas/webgl/tex-image-with-format-and-type.html to include premultiplied alpha
     15        tests for relevant source formats; added new test which exercises all combinations
     16        of UNPACK_FLIP_Y_WEBGL, UNPACK_PREMULTIPLY_ALPHA_WEBGL, and UNPACK_ALIGNMENT pixel
     17        store parameters.
     18
     19        Test: fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view.html
     20
     21        * html/canvas/WebGLRenderingContext.cpp:
     22        (WebCore::WebGLRenderingContext::texImage2D):
     23        (WebCore::WebGLRenderingContext::texSubImage2D):
     24        (WebCore::WebGLRenderingContext::validateTexFuncData):
     25        * html/canvas/WebGLRenderingContext.h:
     26        * platform/graphics/GraphicsContext3D.cpp:
     27        (WebCore::GraphicsContext3D::extractImageData):
     28        (WebCore::GraphicsContext3D::extractTextureData):
     29        (WebCore::GraphicsContext3D::flipVertically):
     30        (WebCore::doUnpackingAndPacking):
     31        (WebCore::computeIncrementParameters):
     32        (WebCore::doPacking):
     33        (WebCore::GraphicsContext3D::packPixels):
     34        * platform/graphics/GraphicsContext3D.h:
     35        (WebCore::GraphicsContext3D::):
     36        * platform/graphics/cg/GraphicsContext3DCG.cpp:
     37        (WebCore::GraphicsContext3D::getImageData):
     38        * platform/graphics/qt/GraphicsContext3DQt.cpp:
     39        (WebCore::GraphicsContext3D::getImageData):
     40        * platform/graphics/skia/GraphicsContext3DSkia.cpp:
     41        (WebCore::GraphicsContext3D::getImageData):
     42
    1432010-06-29  Patrick Gansterer  <paroga@paroga.com>
    244
  • trunk/WebCore/html/canvas/WebGLRenderingContext.cpp

    r62018 r62145  
    19941994                                       unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
    19951995{
    1996     // FIXME: Need to make sure passed buffer has enough bytes to define the texture
     1996    if (!validateTexFuncData(width, height, format, type, pixels))
     1997        return;
     1998    void* data = pixels ? pixels->baseAddress() : 0;
     1999    Vector<uint8_t> tempData;
     2000    bool changeUnpackAlignment = false;
     2001    if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
     2002        if (!m_context->extractTextureData(width, height, format, type,
     2003                                           m_unpackAlignment,
     2004                                           m_unpackFlipY, m_unpackPremultiplyAlpha,
     2005                                           pixels,
     2006                                           tempData))
     2007            return;
     2008        data = tempData.data();
     2009        changeUnpackAlignment = true;
     2010    }
     2011    if (changeUnpackAlignment)
     2012        m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
    19972013    texImage2DBase(target, level, internalformat, width, height, border,
    1998                    format, type, pixels ? pixels->baseAddress() : 0, ec);
     2014                   format, type, data, ec);
     2015    if (changeUnpackAlignment)
     2016        m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
    19992017}
    20002018
     
    22502268                                          unsigned format, unsigned type, ArrayBufferView* pixels, ExceptionCode& ec)
    22512269{
    2252     // FIXME: Need to make sure passed buffer has enough bytes to define the texture
    2253     texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, pixels ? pixels->baseAddress() : 0, ec);
     2270    if (!validateTexFuncData(width, height, format, type, pixels))
     2271        return;
     2272    void* data = pixels ? pixels->baseAddress() : 0;
     2273    Vector<uint8_t> tempData;
     2274    bool changeUnpackAlignment = false;
     2275    if (pixels && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
     2276        if (!m_context->extractTextureData(width, height, format, type,
     2277                                           m_unpackAlignment,
     2278                                           m_unpackFlipY, m_unpackPremultiplyAlpha,
     2279                                           pixels,
     2280                                           tempData))
     2281            return;
     2282        data = tempData.data();
     2283        changeUnpackAlignment = true;
     2284    }
     2285    if (changeUnpackAlignment)
     2286        m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, 1);
     2287    texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, ec);
     2288    if (changeUnpackAlignment)
     2289        m_context->pixelStorei(GraphicsContext3D::UNPACK_ALIGNMENT, m_unpackAlignment);
    22542290}
    22552291
     
    34873523}
    34883524
     3525bool WebGLRenderingContext::validateTexFuncData(long width, long height,
     3526                                                unsigned long format, unsigned long type,
     3527                                                ArrayBufferView* pixels)
     3528{
     3529    if (!pixels)
     3530        return true;
     3531
     3532    if (!validateTexFuncFormatAndType(format, type))
     3533        return false;
     3534
     3535    switch (type) {
     3536    case GraphicsContext3D::UNSIGNED_BYTE:
     3537        if (!pixels->isUnsignedByteArray()) {
     3538            m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
     3539            return false;
     3540        }
     3541        break;
     3542    case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
     3543    case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
     3544    case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
     3545        if (!pixels->isUnsignedShortArray()) {
     3546            m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
     3547            return false;
     3548        }
     3549        break;
     3550    default:
     3551        ASSERT_NOT_REACHED();
     3552    }
     3553
     3554    unsigned long componentsPerPixel, bytesPerComponent;
     3555    if (!m_context->computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent)) {
     3556        m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
     3557        return false;
     3558    }
     3559
     3560    if (!width || !height)
     3561        return true;
     3562    unsigned int validRowBytes = width * componentsPerPixel * bytesPerComponent;
     3563    unsigned int totalRowBytes = validRowBytes;
     3564    unsigned int remainder = validRowBytes % m_unpackAlignment;
     3565    if (remainder)
     3566        totalRowBytes += (m_unpackAlignment - remainder);
     3567    unsigned int totalBytesRequired = (height - 1) * totalRowBytes + validRowBytes;
     3568    if (pixels->byteLength() < totalBytesRequired) {
     3569        m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
     3570        return false;
     3571    }
     3572    return true;
     3573}
     3574
    34893575bool WebGLRenderingContext::validateDrawMode(unsigned long mode)
    34903576{
  • trunk/WebCore/html/canvas/WebGLRenderingContext.h

    r62018 r62145  
    427427
    428428        // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
    429         // Generate GL error and return false if parameters are invalid.
     429        // Generates GL error and returns false if parameters are invalid.
    430430        bool validateTexFuncFormatAndType(unsigned long format, unsigned long type);
    431431
    432432        // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
    433         // Generate GL error and return false if parameters are invalid.
     433        // Generates GL error and returns false if parameters are invalid.
    434434        bool validateTexFuncParameters(unsigned long target, long level,
    435435                                       unsigned long internalformat,
     
    437437                                       unsigned long format, unsigned long type);
    438438
     439        // Helper function to validate that the given ArrayBufferView
     440        // is of the correct type and contains enough data for the texImage call.
     441        // Generates GL error and returns false if parameters are invalid.
     442        bool validateTexFuncData(long width, long height,
     443                                 unsigned long format, unsigned long type,
     444                                 ArrayBufferView* pixels);
     445
    439446        // Helper function to validate mode for draw{Arrays/Elements}.
    440447        bool validateDrawMode(unsigned long);
  • trunk/WebCore/platform/graphics/GraphicsContext3D.cpp

    r61715 r62145  
    3131#include "GraphicsContext3D.h"
    3232
     33#include "ArrayBufferView.h"
    3334#include "Image.h"
    3435#include "ImageData.h"
     
    119120                    width,
    120121                    height,
     122                    0,
    121123                    format,
    122124                    type,
     
    139141}
    140142
     143bool GraphicsContext3D::extractTextureData(unsigned int width, unsigned int height,
     144                                           unsigned int format, unsigned int type,
     145                                           unsigned int unpackAlignment,
     146                                           bool flipY, bool premultiplyAlpha,
     147                                           ArrayBufferView* pixels,
     148                                           Vector<uint8_t>& data)
     149{
     150    // Assumes format, type, etc. have already been validated.
     151    SourceDataFormat sourceDataFormat = kSourceFormatRGBA8;
     152    switch (type) {
     153    case UNSIGNED_BYTE:
     154        switch (format) {
     155        case RGBA:
     156            sourceDataFormat = kSourceFormatRGBA8;
     157            break;
     158        case RGB:
     159            sourceDataFormat = kSourceFormatRGB8;
     160            break;
     161        case ALPHA:
     162            sourceDataFormat = kSourceFormatA8;
     163            break;
     164        case LUMINANCE:
     165            sourceDataFormat = kSourceFormatR8;
     166            break;
     167        case LUMINANCE_ALPHA:
     168            sourceDataFormat = kSourceFormatRA8;
     169            break;
     170        default:
     171            ASSERT_NOT_REACHED();
     172        }
     173        break;
     174    case UNSIGNED_SHORT_5_5_5_1:
     175        sourceDataFormat = kSourceFormatRGBA5551;
     176        break;
     177    case UNSIGNED_SHORT_4_4_4_4:
     178        sourceDataFormat = kSourceFormatRGBA4444;
     179        break;
     180    case UNSIGNED_SHORT_5_6_5:
     181        sourceDataFormat = kSourceFormatRGB565;
     182        break;
     183    default:
     184        ASSERT_NOT_REACHED();
     185    }
     186
     187    // Resize the output buffer.
     188    unsigned long componentsPerPixel, bytesPerComponent;
     189    if (!computeFormatAndTypeParameters(format, type,
     190                                        &componentsPerPixel,
     191                                        &bytesPerComponent))
     192        return false;
     193    unsigned long bytesPerPixel = componentsPerPixel * bytesPerComponent;
     194    data.resize(width * height * bytesPerPixel);
     195
     196    if (!packPixels(static_cast<uint8_t*>(pixels->baseAddress()),
     197                    sourceDataFormat,
     198                    width, height, unpackAlignment,
     199                    format, type,
     200                    (premultiplyAlpha ? kAlphaDoPremultiply : kAlphaDoNothing),
     201                    data.data()))
     202        return false;
     203    // The pixel data is now tightly packed.
     204    if (flipY)
     205        flipVertically(data.data(), width, height, bytesPerPixel, 1);
     206    return true;
     207}
     208
    141209void GraphicsContext3D::flipVertically(void* imageData,
    142210                                       unsigned int width,
     
    151219    unsigned int remainder = validRowBytes % unpackAlignment;
    152220    if (remainder)
    153         totalRowBytes += remainder;
     221        totalRowBytes += (unpackAlignment - remainder);
    154222    uint8_t* tempRow = new uint8_t[validRowBytes];
    155223    uint8_t* data = static_cast<uint8_t*>(imageData);
     
    172240// Pixel unpacking routines.
    173241
     242void unpackRGBA8ToRGBA8(const uint8_t* source, uint8_t* destination)
     243{
     244    destination[0] = source[0];
     245    destination[1] = source[1];
     246    destination[2] = source[2];
     247    destination[3] = source[3];
     248}
     249
    174250void unpackRGB8ToRGBA8(const uint8_t* source, uint8_t* destination)
    175251{
     
    188264}
    189265
     266void unpackRGBA5551ToRGBA8(const uint16_t* source, uint8_t* destination)
     267{
     268    uint16_t packedValue = source[0];
     269    uint8_t r = packedValue >> 11;
     270    uint8_t g = (packedValue >> 6) & 0x1F;
     271    uint8_t b = (packedValue >> 1) & 0x1F;
     272    destination[0] = (r << 3) | (r & 0x7);
     273    destination[1] = (g << 3) | (g & 0x7);
     274    destination[2] = (b << 3) | (b & 0x7);
     275    destination[3] = (packedValue & 0x1) ? 0xFF : 0x0;
     276}
     277
     278void unpackRGBA4444ToRGBA8(const uint16_t* source, uint8_t* destination)
     279{
     280    uint16_t packedValue = source[0];
     281    uint8_t r = packedValue >> 12;
     282    uint8_t g = (packedValue >> 8) & 0x0F;
     283    uint8_t b = (packedValue >> 4) & 0x0F;
     284    uint8_t a = packedValue & 0x0F;
     285    destination[0] = r << 4 | r;
     286    destination[1] = g << 4 | g;
     287    destination[2] = b << 4 | b;
     288    destination[3] = a << 4 | a;
     289}
     290
     291void unpackRGB565ToRGBA8(const uint16_t* source, uint8_t* destination)
     292{
     293    uint16_t packedValue = source[0];
     294    uint8_t r = packedValue >> 11;
     295    uint8_t g = (packedValue >> 5) & 0x3F;
     296    uint8_t b = packedValue & 0x1F;
     297    destination[0] = (r << 3) | (r & 0x7);
     298    destination[1] = (g << 2) | (g & 0x3);
     299    destination[2] = (b << 3) | (b & 0x7);
     300    destination[3] = 0xFF;
     301}
     302
     303void unpackR8ToRGBA8(const uint8_t* source, uint8_t* destination)
     304{
     305    destination[0] = source[0];
     306    destination[1] = source[0];
     307    destination[2] = source[0];
     308    destination[3] = 0xFF;
     309}
     310
     311void unpackRA8ToRGBA8(const uint8_t* source, uint8_t* destination)
     312{
     313    destination[0] = source[0];
     314    destination[1] = source[0];
     315    destination[2] = source[0];
     316    destination[3] = source[1];
     317}
     318
     319void unpackA8ToRGBA8(const uint8_t* source, uint8_t* destination)
     320{
     321    destination[0] = 0x0;
     322    destination[1] = 0x0;
     323    destination[2] = 0x0;
     324    destination[3] = source[0];
     325}
     326
    190327//----------------------------------------------------------------------
    191328// Pixel packing routines.
     
    402539
    403540// This is used whenever unpacking is necessary; i.e., the source data
    404 // is not in RGBA8 format.
     541// is not in RGBA8 format, or the unpack alignment specifies that rows
     542// are not tightly packed.
    405543template<typename SourceType, typename DestType,
    406544         void unpackingFunc(const SourceType*, uint8_t*),
    407545         void packingFunc(const uint8_t*, DestType*)>
    408546static void doUnpackingAndPacking(const SourceType* sourceData,
    409                                   unsigned int numElements,
     547                                  unsigned int width,
     548                                  unsigned int height,
    410549                                  unsigned int sourceElementsPerPixel,
     550                                  unsigned int sourceElementsPerRow,
    411551                                  DestType* destinationData,
    412552                                  unsigned int destinationElementsPerPixel)
    413553{
    414     const SourceType* endPointer = sourceData + numElements;
    415     uint8_t temporaryRGBAData[4];
    416     while (sourceData < endPointer) {
    417         unpackingFunc(sourceData, temporaryRGBAData);
    418         packingFunc(temporaryRGBAData, destinationData);
    419         sourceData += sourceElementsPerPixel;
    420         destinationData += destinationElementsPerPixel;
    421     }
    422 }
    423 
    424 // This handles all conversions with a faster path for RGBA8 source data.
    425 template<typename SourceType, typename DestType, void packingFunc(const SourceType*, DestType*)>
    426 static void doPacking(const SourceType* sourceData,
    427                       GraphicsContext3D::SourceDataFormat sourceDataFormat,
    428                       unsigned int numElements,
    429                       unsigned int sourceElementsPerPixel,
    430                       DestType* destinationData,
    431                       unsigned int destinationElementsPerPixel)
    432 {
    433     switch (sourceDataFormat) {
    434     case GraphicsContext3D::kSourceFormatRGBA8: {
     554    if (!sourceElementsPerRow) {
     555        unsigned int numElements = width * height * sourceElementsPerPixel;
    435556        const SourceType* endPointer = sourceData + numElements;
     557        uint8_t temporaryRGBAData[4];
    436558        while (sourceData < endPointer) {
    437             packingFunc(sourceData, destinationData);
     559            unpackingFunc(sourceData, temporaryRGBAData);
     560            packingFunc(temporaryRGBAData, destinationData);
    438561            sourceData += sourceElementsPerPixel;
    439562            destinationData += destinationElementsPerPixel;
    440563        }
     564    } else {
     565        uint8_t temporaryRGBAData[4];
     566        for (unsigned int y = 0; y < height; ++y) {
     567            const SourceType* currentSource = sourceData;
     568            for (unsigned int x = 0; x < width; ++x) {
     569                unpackingFunc(currentSource, temporaryRGBAData);
     570                packingFunc(temporaryRGBAData, destinationData);
     571                currentSource += sourceElementsPerPixel;
     572                destinationData += destinationElementsPerPixel;
     573            }
     574            sourceData += sourceElementsPerRow;
     575        }
     576    }
     577}
     578
     579template<typename SourceType>
     580static void computeIncrementParameters(unsigned int width,
     581                                       unsigned int bytesPerPixel,
     582                                       unsigned int unpackAlignment,
     583                                       unsigned int* sourceElementsPerPixel,
     584                                       unsigned int* sourceElementsPerRow)
     585{
     586    unsigned int elementSizeInBytes = sizeof(SourceType);
     587    ASSERT(elementSizeInBytes <= bytesPerPixel);
     588    unsigned int validRowBytes = width * bytesPerPixel;
     589    unsigned int totalRowBytes = validRowBytes;
     590    if (unpackAlignment) {
     591        unsigned int remainder = validRowBytes % unpackAlignment;
     592        if (remainder)
     593            totalRowBytes += (unpackAlignment - remainder);
     594    }
     595    *sourceElementsPerPixel = bytesPerPixel / elementSizeInBytes;
     596    if (validRowBytes == totalRowBytes)
     597        *sourceElementsPerRow = 0;
     598    else
     599        *sourceElementsPerRow = totalRowBytes / elementSizeInBytes;
     600}
     601
     602// This handles all conversions with a faster path for tightly packed RGBA8 source data.
     603template<typename DestType, void packingFunc(const uint8_t*, DestType*)>
     604static void doPacking(const void* sourceData,
     605                      GraphicsContext3D::SourceDataFormat sourceDataFormat,
     606                      unsigned int width,
     607                      unsigned int height,
     608                      unsigned int sourceUnpackAlignment,
     609                      DestType* destinationData,
     610                      unsigned int destinationElementsPerPixel)
     611{
     612    switch (sourceDataFormat) {
     613    case GraphicsContext3D::kSourceFormatRGBA8: {
     614        unsigned int sourceElementsPerPixel, sourceElementsPerRow;
     615        computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
     616        if (!sourceElementsPerRow) {
     617            const uint8_t* source = static_cast<const uint8_t*>(sourceData);
     618            unsigned int numElements = width * height * 4;
     619            const uint8_t* endPointer = source + numElements;
     620            while (source < endPointer) {
     621                packingFunc(source, destinationData);
     622                source += sourceElementsPerPixel;
     623                destinationData += destinationElementsPerPixel;
     624            }
     625        } else {
     626            doUnpackingAndPacking<uint8_t, DestType, unpackRGBA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
     627        }
    441628        break;
    442629    }
    443630    case GraphicsContext3D::kSourceFormatRGB8: {
    444         doUnpackingAndPacking<SourceType, DestType, unpackRGB8ToRGBA8, packingFunc>(sourceData, numElements, sourceElementsPerPixel, destinationData, destinationElementsPerPixel);
     631        unsigned int sourceElementsPerPixel, sourceElementsPerRow;
     632        computeIncrementParameters<uint8_t>(width, 3, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
     633        doUnpackingAndPacking<uint8_t, DestType, unpackRGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
    445634        break;
    446635    }
    447636    case GraphicsContext3D::kSourceFormatBGRA8: {
    448         doUnpackingAndPacking<SourceType, DestType, unpackBGRA8ToRGBA8, packingFunc>(sourceData, numElements, sourceElementsPerPixel, destinationData, destinationElementsPerPixel);
     637        unsigned int sourceElementsPerPixel, sourceElementsPerRow;
     638        computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
     639        doUnpackingAndPacking<uint8_t, DestType, unpackBGRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
     640        break;
     641    }
     642    case GraphicsContext3D::kSourceFormatRGBA5551: {
     643        unsigned int sourceElementsPerPixel, sourceElementsPerRow;
     644        computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
     645        doUnpackingAndPacking<uint16_t, DestType, unpackRGBA5551ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
     646        break;
     647    }
     648    case GraphicsContext3D::kSourceFormatRGBA4444: {
     649        unsigned int sourceElementsPerPixel, sourceElementsPerRow;
     650        computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
     651        doUnpackingAndPacking<uint16_t, DestType, unpackRGBA4444ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
     652        break;
     653    }
     654    case GraphicsContext3D::kSourceFormatRGB565: {
     655        unsigned int sourceElementsPerPixel, sourceElementsPerRow;
     656        computeIncrementParameters<uint16_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
     657        doUnpackingAndPacking<uint16_t, DestType, unpackRGB565ToRGBA8, packingFunc>(static_cast<const uint16_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
     658        break;
     659    }
     660    case GraphicsContext3D::kSourceFormatR8: {
     661        unsigned int sourceElementsPerPixel, sourceElementsPerRow;
     662        computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
     663        doUnpackingAndPacking<uint8_t, DestType, unpackR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
     664        break;
     665    }
     666    case GraphicsContext3D::kSourceFormatRA8: {
     667        unsigned int sourceElementsPerPixel, sourceElementsPerRow;
     668        computeIncrementParameters<uint8_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
     669        doUnpackingAndPacking<uint8_t, DestType, unpackRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
     670        break;
     671    }
     672    case GraphicsContext3D::kSourceFormatA8: {
     673        unsigned int sourceElementsPerPixel, sourceElementsPerRow;
     674        computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
     675        doUnpackingAndPacking<uint8_t, DestType, unpackA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
    449676        break;
    450677    }
     
    456683                                   unsigned int width,
    457684                                   unsigned int height,
     685                                   unsigned int sourceUnpackAlignment,
    458686                                   unsigned int destinationFormat,
    459687                                   unsigned int destinationType,
     
    461689                                   void* destinationData)
    462690{
    463     unsigned int sourceElementsPerPixel = 4;
    464     unsigned int numElements = width * height * sourceElementsPerPixel;
    465691    switch (destinationType) {
    466692    case UNSIGNED_BYTE: {
    467693        uint8_t* destination = static_cast<uint8_t*>(destinationData);
    468         if (sourceDataFormat == kSourceFormatRGBA8 && destinationFormat == RGBA && alphaOp == kAlphaDoNothing) {
     694        if (sourceDataFormat == kSourceFormatRGBA8 && destinationFormat == RGBA && sourceUnpackAlignment <= 4 && alphaOp == kAlphaDoNothing) {
    469695            // No conversion necessary.
    470             memcpy(destinationData, sourceData, numElements);
     696            memcpy(destinationData, sourceData, width * height * 4);
    471697            break;
    472698        }
     
    475701            switch (alphaOp) {
    476702            case kAlphaDoNothing:
    477                 doPacking<uint8_t, uint8_t, packRGBA8ToRGB8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 3);
     703                doPacking<uint8_t, packRGBA8ToRGB8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
    478704                break;
    479705            case kAlphaDoPremultiply:
    480                 doPacking<uint8_t, uint8_t, packRGBA8ToRGB8Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 3);
     706                doPacking<uint8_t, packRGBA8ToRGB8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
    481707                break;
    482708            case kAlphaDoUnmultiply:
    483                 doPacking<uint8_t, uint8_t, packRGBA8ToRGB8Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 3);
     709                doPacking<uint8_t, packRGBA8ToRGB8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 3);
    484710                break;
    485711            }
     
    488714            switch (alphaOp) {
    489715            case kAlphaDoNothing:
    490                 ASSERT(sourceDataFormat != kSourceFormatRGBA8); // Handled above with fast case.
    491                 doPacking<uint8_t, uint8_t, packRGBA8ToRGBA8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 4);
     716                ASSERT(sourceDataFormat != kSourceFormatRGBA8 || sourceUnpackAlignment > 4); // Handled above with fast case.
     717                doPacking<uint8_t, packRGBA8ToRGBA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
    492718                break;
    493719            case kAlphaDoPremultiply:
    494                 doPacking<uint8_t, uint8_t, packRGBA8ToRGBA8Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 4);
     720                doPacking<uint8_t, packRGBA8ToRGBA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
    495721                break;
    496722            case kAlphaDoUnmultiply:
    497                 doPacking<uint8_t, uint8_t, packRGBA8ToRGBA8Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 4);
     723                doPacking<uint8_t, packRGBA8ToRGBA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 4);
    498724                break;
    499725            default:
     
    505731            // specification, Table 3.15), the alpha channel is chosen
    506732            // from the RGBA data.
    507             doPacking<uint8_t, uint8_t, packRGBA8ToA8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     733            doPacking<uint8_t, packRGBA8ToA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    508734            break;
    509735        case LUMINANCE:
     
    513739            switch (alphaOp) {
    514740            case kAlphaDoNothing:
    515                 doPacking<uint8_t, uint8_t, packRGBA8ToR8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     741                doPacking<uint8_t, packRGBA8ToR8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    516742                break;
    517743            case kAlphaDoPremultiply:
    518                 doPacking<uint8_t, uint8_t, packRGBA8ToR8Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     744                doPacking<uint8_t, packRGBA8ToR8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    519745                break;
    520746            case kAlphaDoUnmultiply:
    521                 doPacking<uint8_t, uint8_t, packRGBA8ToR8Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     747                doPacking<uint8_t, packRGBA8ToR8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    522748                break;
    523749            }
     
    529755            switch (alphaOp) {
    530756            case kAlphaDoNothing:
    531                 doPacking<uint8_t, uint8_t, packRGBA8ToRA8>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 2);
     757                doPacking<uint8_t, packRGBA8ToRA8>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
    532758                break;
    533759            case kAlphaDoPremultiply:
    534                 doPacking<uint8_t, uint8_t, packRGBA8ToRA8Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 2);
     760                doPacking<uint8_t, packRGBA8ToRA8Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
    535761                break;
    536762            case kAlphaDoUnmultiply:
    537                 doPacking<uint8_t, uint8_t, packRGBA8ToRA8Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 2);
     763                doPacking<uint8_t, packRGBA8ToRA8Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 2);
    538764                break;
    539765            }
     
    546772        switch (alphaOp) {
    547773        case kAlphaDoNothing:
    548             doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort4444>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     774            doPacking<uint16_t, packRGBA8ToUnsignedShort4444>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    549775            break;
    550776        case kAlphaDoPremultiply:
    551             doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort4444Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     777            doPacking<uint16_t, packRGBA8ToUnsignedShort4444Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    552778            break;
    553779        case kAlphaDoUnmultiply:
    554             doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort4444Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     780            doPacking<uint16_t, packRGBA8ToUnsignedShort4444Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    555781            break;
    556782        }
     
    561787        switch (alphaOp) {
    562788        case kAlphaDoNothing:
    563             doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort5551>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     789            doPacking<uint16_t, packRGBA8ToUnsignedShort5551>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    564790            break;
    565791        case kAlphaDoPremultiply:
    566             doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort5551Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     792            doPacking<uint16_t, packRGBA8ToUnsignedShort5551Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    567793            break;
    568794        case kAlphaDoUnmultiply:
    569             doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort5551Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     795            doPacking<uint16_t, packRGBA8ToUnsignedShort5551Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    570796            break;
    571797        }
     
    576802        switch (alphaOp) {
    577803        case kAlphaDoNothing:
    578             doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort565>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     804            doPacking<uint16_t, packRGBA8ToUnsignedShort565>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    579805            break;
    580806        case kAlphaDoPremultiply:
    581             doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort565Premultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     807            doPacking<uint16_t, packRGBA8ToUnsignedShort565Premultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    582808            break;
    583809        case kAlphaDoUnmultiply:
    584             doPacking<uint8_t, uint16_t, packRGBA8ToUnsignedShort565Unmultiply>(sourceData, sourceDataFormat, numElements, sourceElementsPerPixel, destination, 1);
     810            doPacking<uint16_t, packRGBA8ToUnsignedShort565Unmultiply>(sourceData, sourceDataFormat, width, height, sourceUnpackAlignment, destination, 1);
    585811            break;
    586812        }
  • trunk/WebCore/platform/graphics/GraphicsContext3D.h

    r62130 r62145  
    499499                              Vector<uint8_t>& data);
    500500
     501        // Helper function which extracts the user-supplied texture
     502        // data, applying the flipY and premultiplyAlpha parameters.
     503        // If the data is not tightly packed according to the passed
     504        // unpackAlignment, the output data will be tightly packed.
     505        // Returns true if successful, false if any error occurred.
     506        bool extractTextureData(unsigned int width, unsigned int height,
     507                                unsigned int format, unsigned int type,
     508                                unsigned int unpackAlignment,
     509                                bool flipY, bool premultiplyAlpha,
     510                                ArrayBufferView* pixels,
     511                                Vector<uint8_t>& data);
     512
    501513        // Flips the given image data vertically, in-place.
    502514        void flipVertically(void* imageData,
     
    513525            kSourceFormatRGBA8,
    514526            kSourceFormatRGB8,
    515             kSourceFormatBGRA8
     527            kSourceFormatBGRA8,
     528            kSourceFormatRGBA5551,
     529            kSourceFormatRGBA4444,
     530            kSourceFormatRGB565,
     531            kSourceFormatR8,
     532            kSourceFormatRA8,
     533            kSourceFormatA8
    516534        };
    517535
     
    757775        // Helper for getImageData which implements packing of pixel
    758776        // data into the specified OpenGL destination format and type.
    759         // Source data must be in RGBA format with no gaps between
    760         // rows. Destination data will have no gaps between rows.
     777        // A sourceUnpackAlignment of zero indicates that the source
     778        // data is tightly packed. Non-zero values may take a slow path.
     779        // Destination data will have no gaps between rows.
    761780        bool packPixels(const uint8_t* sourceData,
    762781                        SourceDataFormat sourceDataFormat,
    763782                        unsigned int width,
    764783                        unsigned int height,
     784                        unsigned int sourceUnpackAlignment,
    765785                        unsigned int destinationFormat,
    766786                        unsigned int destinationType,
  • trunk/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp

    r61715 r62145  
    101101        // FIXME: must fetch the image data before the premultiplication step.
    102102        neededAlphaOp = kAlphaDoUnmultiply;
    103     return packPixels(tempVector.data(), kSourceFormatRGBA8, width, height,
     103    return packPixels(tempVector.data(), kSourceFormatRGBA8, width, height, 0,
    104104                      format, type, neededAlphaOp, outputVector.data());
    105105}
  • trunk/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp

    r61715 r62145  
    16381638    QImage nativeImage = nativePixmap->toImage().convertToFormat(QImage::Format_ARGB32);
    16391639    outputVector.resize(nativeImage.byteCount());
    1640     return packPixels(nativeImage.rgbSwapped().bits(), kSourceFormatRGBA8, image->width(), image->height(),
     1640    return packPixels(nativeImage.rgbSwapped().bits(), kSourceFormatRGBA8, image->width(), image->height(), 0,
    16411641                      format, type, neededAlphaOp, outputVector.data());
    16421642}
  • trunk/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp

    r61715 r62145  
    6464        // FIXME: must fetch the image data before the premultiplication step
    6565        neededAlphaOp = kAlphaDoUnmultiply;
    66     return packPixels(pixels, kSourceFormatBGRA8, skiaImage->width(), height,
     66    return packPixels(pixels, kSourceFormatBGRA8, skiaImage->width(), height, 0,
    6767                      format, type, neededAlphaOp, outputVector.data());
    6868}
Note: See TracChangeset for help on using the changeset viewer.