tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

tcuTextureUtil.js (29498B)


      1 /*-------------------------------------------------------------------------
      2 * drawElements Quality Program OpenGL ES Utilities
      3 * ------------------------------------------------
      4 *
      5 * Copyright 2014 The Android Open Source Project
      6 *
      7 * Licensed under the Apache License, Version 2.0 (the "License");
      8 * you may not use this file except in compliance with the License.
      9 * You may obtain a tcuTextureUtil.copy of the License at
     10 *
     11 *      http://www.apache.org/licenses/LICENSE-2.0
     12 *
     13 * Unless required by applicable law or agreed to in writing, software
     14 * distributed under the License is distributed on an "AS IS" BASIS,
     15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 * See the License for the specific language governing permissions and
     17 * limitations under the License.
     18 *
     19 */
     20 
     21 'use strict';
     22 goog.provide('framework.common.tcuTextureUtil');
     23 goog.require('framework.common.tcuTexture');
     24 goog.require('framework.delibs.debase.deMath');
     25 goog.require('framework.delibs.debase.deRandom');
     26 
     27 goog.scope(function() {
     28 
     29 var tcuTextureUtil = framework.common.tcuTextureUtil;
     30 var tcuTexture = framework.common.tcuTexture;
     31 var deMath = framework.delibs.debase.deMath;
     32 var deRandom = framework.delibs.debase.deRandom;
     33 
     34 var DE_ASSERT = function(x) {
     35    if (!x)
     36        throw new Error('Assert failed');
     37 };
     38 
     39 /**
     40 * @param {number} t
     41 * @param {number} minVal
     42 * @param {number} maxVal
     43 * @return {number}
     44 */
     45 tcuTextureUtil.linearInterpolate = function(t, minVal, maxVal) {
     46    return minVal + (maxVal - minVal) * t;
     47 };
     48 
     49 /** tcuTextureUtil.linearChannelToSRGB
     50 * @param {number} cl
     51 * @return {number}
     52 */
     53 tcuTextureUtil.linearChannelToSRGB = function(cl) {
     54    if (cl <= 0.0)
     55        return 0.0;
     56    else if (cl < 0.0031308)
     57        return 12.92 * cl;
     58    else if (cl < 1.0)
     59        return 1.055 * Math.pow(cl, 0.41666) - 0.055;
     60    else
     61        return 1.0;
     62 };
     63 
     64 /**
     65 * Convert sRGB to linear colorspace
     66 * @param {Array<number>} cs
     67 * @return {Array<number>}
     68 */
     69 tcuTextureUtil.sRGBToLinear = function(cs) {
     70    return [tcuTextureUtil.sRGBChannelToLinear(cs[0]),
     71            tcuTextureUtil.sRGBChannelToLinear(cs[1]),
     72            tcuTextureUtil.sRGBChannelToLinear(cs[2]),
     73            cs[3]];
     74 };
     75 
     76 /**
     77 * @param {number} cs
     78 * @return {number}
     79 */
     80 tcuTextureUtil.sRGBChannelToLinear = function(cs) {
     81    if (cs <= 0.04045)
     82        return cs / 12.92;
     83    else
     84        return Math.pow((cs + 0.055) / 1.055, 2.4);
     85 };
     86 
     87 /** tcuTextureUtil.linearToSRGB
     88 * @param {Array<number>} cl
     89 * @return {Array<number>}
     90 */
     91 tcuTextureUtil.linearToSRGB = function(cl) {
     92    return [tcuTextureUtil.linearChannelToSRGB(cl[0]),
     93            tcuTextureUtil.linearChannelToSRGB(cl[1]),
     94            tcuTextureUtil.linearChannelToSRGB(cl[2]),
     95            cl[3]
     96            ];
     97 };
     98 
     99 /**
    100 * tcuTextureUtil.getSubregion
    101 * @param {tcuTexture.PixelBufferAccess} access
    102 * @param {number} x
    103 * @param {number} y
    104 * @param {number} z
    105 * @param {number} width
    106 * @param {number} height
    107 * @param {number} depth
    108 * @return {tcuTexture.PixelBufferAccess}
    109 */
    110 tcuTextureUtil.getSubregion = function(access, x, y, z, width, height, depth) {
    111 
    112    DE_ASSERT(deMath.deInBounds32(x, 0, access.getWidth()) && deMath.deInRange32(x + width, x, access.getWidth()));
    113    DE_ASSERT(deMath.deInBounds32(y, 0, access.getHeight()) && deMath.deInRange32(y + height, y, access.getHeight()));
    114    DE_ASSERT(deMath.deInBounds32(z, 0, access.getDepth()) && deMath.deInRange32(z + depth, z, access.getDepth()));
    115 
    116    return new tcuTexture.PixelBufferAccess({
    117        format: access.getFormat(),
    118        width: width,
    119        height: height,
    120        depth: depth,
    121        rowPitch: access.getRowPitch(),
    122        slicePitch: access.getSlicePitch(),
    123        offset: access.m_offset + access.getFormat().getPixelSize() * x + access.getRowPitch() * y + access.getSlicePitch() * z,
    124        data: access.getBuffer()
    125        });
    126 };
    127 
    128 /**
    129 * @param {tcuTexture.PixelBufferAccess} access
    130 * @param {Array<number>} minVal
    131 * @param {Array<number>} maxVal
    132 */
    133 tcuTextureUtil.fillWithComponentGradients1D = function(access, minVal, maxVal) {
    134    DE_ASSERT(access.getHeight() == 1);
    135    for (var x = 0; x < access.getWidth(); x++) {
    136        var s = (x + 0.5) / access.getWidth();
    137 
    138        var r = tcuTextureUtil.linearInterpolate(s, minVal[0], maxVal[0]);
    139        var g = tcuTextureUtil.linearInterpolate(s, minVal[1], maxVal[1]);
    140        var b = tcuTextureUtil.linearInterpolate(s, minVal[2], maxVal[2]);
    141        var a = tcuTextureUtil.linearInterpolate(s, minVal[3], maxVal[3]);
    142 
    143        access.setPixel([r, g, b, a], x, 0);
    144    }
    145 };
    146 
    147 /**
    148 * @param {tcuTexture.PixelBufferAccess} access
    149 * @param {Array<number>} minVal
    150 * @param {Array<number>} maxVal
    151 */
    152 tcuTextureUtil.fillWithComponentGradients2D = function(access, minVal, maxVal) {
    153    for (var y = 0; y < access.getHeight(); y++) {
    154        var t = (y + 0.5) / access.getHeight();
    155        for (var x = 0; x < access.getWidth(); x++) {
    156            var s = (x + 0.5) / access.getWidth();
    157 
    158            var r = tcuTextureUtil.linearInterpolate((s + t) * 0.5, minVal[0], maxVal[0]);
    159            var g = tcuTextureUtil.linearInterpolate((s + (1 - t)) * 0.5, minVal[1], maxVal[1]);
    160            var b = tcuTextureUtil.linearInterpolate(((1 - s) + t) * 0.5, minVal[2], maxVal[2]);
    161            var a = tcuTextureUtil.linearInterpolate(((1 - s) + (1 - t)) * 0.5, minVal[3], maxVal[3]);
    162 
    163            access.setPixel([r, g, b, a], x, y);
    164        }
    165    }
    166 };
    167 
    168 /**
    169 * @param {tcuTexture.PixelBufferAccess} dst
    170 * @param {Array<number>} minVal
    171 * @param {Array<number>} maxVal
    172 */
    173 tcuTextureUtil.fillWithComponentGradients3D = function(dst, minVal, maxVal) {
    174    for (var z = 0; z < dst.getDepth(); z++) {
    175        var p = (z + 0.5) / dst.getDepth();
    176        var b = tcuTextureUtil.linearInterpolate(p, minVal[2], maxVal[2]);
    177        for (var y = 0; y < dst.getHeight(); y++) {
    178            var t = (y + 0.5) / dst.getHeight();
    179            var g = tcuTextureUtil.linearInterpolate(t, minVal[1], maxVal[1]);
    180            for (var x = 0; x < dst.getWidth(); x++) {
    181                var s = (x + 0.5) / dst.getWidth();
    182                var r = tcuTextureUtil.linearInterpolate(s, minVal[0], maxVal[0]);
    183                var a = tcuTextureUtil.linearInterpolate(1 - (s + t + p) / 3, minVal[3], maxVal[3]);
    184                dst.setPixel([r, g, b, a], x, y, z);
    185            }
    186        }
    187    }
    188 };
    189 
    190 /**
    191 * @param {tcuTexture.PixelBufferAccess} access
    192 * @param {Array<number>} minVal
    193 * @param {Array<number>} maxVal
    194 */
    195 tcuTextureUtil.fillWithComponentGradients = function(access, minVal, maxVal) {
    196    if (access.getHeight() == 1 && access.getDepth() == 1)
    197        tcuTextureUtil.fillWithComponentGradients1D(access, minVal, maxVal);
    198    else if (access.getDepth() == 1)
    199        tcuTextureUtil.fillWithComponentGradients2D(access, minVal, maxVal);
    200    else
    201        tcuTextureUtil.fillWithComponentGradients3D(access, minVal, maxVal);
    202 };
    203 
    204 /**
    205 * @param {tcuTexture.PixelBufferAccess} dst
    206 */
    207 tcuTextureUtil.fillWithRGBAQuads = function(dst) {
    208    checkMessage(dst.getDepth() == 1, 'Depth must be 1');
    209    var width = dst.getWidth();
    210    var height = dst.getHeight();
    211    var left = width / 2;
    212    var top = height / 2;
    213 
    214    tcuTextureUtil.getSubregion(dst, 0, 0, 0, left, top, 1).clear([1.0, 0.0, 0.0, 1.0]);
    215    tcuTextureUtil.getSubregion(dst, left, 0, 0, width - left, top, 1).clear([0.0, 1.0, 0.0, 1.0]);
    216    tcuTextureUtil.getSubregion(dst, 0, top, 0, left, height - top, 1).clear([0.0, 0.0, 1.0, 0.0]);
    217    tcuTextureUtil.getSubregion(dst, left, top, 0, width - left, height - top, 1).clear([0.5, 0.5, 0.5, 1.0]);
    218 };
    219 
    220 // \todo [2012-11-13 pyry] There is much better metaballs code in CL SIR value generators.
    221 /**
    222 * @param {tcuTexture.PixelBufferAccess} dst
    223 * @param {number} numBalls
    224 * @param {number} seed
    225 */
    226 tcuTextureUtil.fillWithMetaballs = function(dst, numBalls, seed) {
    227    checkMessage(dst.getDepth() == 1, 'Depth must be 1');
    228    var points = [];
    229    var rnd = new deRandom.Random(seed);
    230 
    231    for (var i = 0; i < numBalls; i++) {
    232        var x = rnd.getFloat();
    233        var y = rnd.getFloat();
    234        points[i] = [x, y];
    235    }
    236 
    237    for (var y = 0; y < dst.getHeight(); y++)
    238    for (var x = 0; x < dst.getWidth(); x++) {
    239        var p = [x / dst.getWidth(), y / dst.getHeight()];
    240 
    241        var sum = 0.0;
    242        for (var pointNdx = 0; pointNdx < points.length; pointNdx++) {
    243            var d = deMath.subtract(p, points[pointNdx]);
    244            var f = 0.01 / (d[0] * d[0] + d[1] * d[1]);
    245 
    246            sum += f;
    247        }
    248 
    249        dst.setPixel([sum, sum, sum, sum], x, y);
    250    }
    251 };
    252 
    253 /**
    254 * Create tcuTextureUtil.TextureFormatInfo.
    255 * @constructor
    256 * @param {Array<number>} valueMin
    257 * @param {Array<number>} valueMax
    258 * @param {Array<number>} lookupScale
    259 * @param {Array<number>} lookupBias
    260 */
    261 tcuTextureUtil.TextureFormatInfo = function(valueMin, valueMax, lookupScale, lookupBias) {
    262    /** @type {Array<number>} */ this.valueMin = valueMin;
    263    /** @type {Array<number>} */ this.valueMax = valueMax;
    264    /** @type {Array<number>} */ this.lookupScale = lookupScale;
    265    /** @type {Array<number>} */ this.lookupBias = lookupBias;
    266 };
    267 
    268 /**
    269 * @param {?tcuTexture.ChannelType} channelType
    270 * @return {Array<number>}
    271 */
    272 tcuTextureUtil.getChannelValueRange = function(channelType) {
    273    var cMin = 0;
    274    var cMax = 0;
    275 
    276    switch (channelType) {
    277        // Signed normalized formats.
    278        case tcuTexture.ChannelType.SNORM_INT8:
    279        case tcuTexture.ChannelType.SNORM_INT16: cMin = -1; cMax = 1; break;
    280 
    281        // Unsigned normalized formats.
    282        case tcuTexture.ChannelType.UNORM_INT8:
    283        case tcuTexture.ChannelType.UNORM_INT16:
    284        case tcuTexture.ChannelType.UNORM_SHORT_565:
    285        case tcuTexture.ChannelType.UNORM_SHORT_4444:
    286        case tcuTexture.ChannelType.UNORM_INT_101010:
    287        case tcuTexture.ChannelType.UNORM_INT_1010102_REV: cMin = 0; cMax = 1; break;
    288 
    289        // Misc formats.
    290        case tcuTexture.ChannelType.SIGNED_INT8: cMin = -128; cMax = 127; break;
    291        case tcuTexture.ChannelType.SIGNED_INT16: cMin = -32768; cMax = 32767; break;
    292        case tcuTexture.ChannelType.SIGNED_INT32: cMin = -2147483648; cMax = 2147483647; break;
    293        case tcuTexture.ChannelType.UNSIGNED_INT8: cMin = 0; cMax = 255; break;
    294        case tcuTexture.ChannelType.UNSIGNED_INT16: cMin = 0; cMax = 65535; break;
    295        case tcuTexture.ChannelType.UNSIGNED_INT32: cMin = 0; cMax = 4294967295; break;
    296        case tcuTexture.ChannelType.HALF_FLOAT: cMin = -1e3; cMax = 1e3; break;
    297        case tcuTexture.ChannelType.FLOAT: cMin = -1e5; cMax = 1e5; break;
    298        case tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV: cMin = 0; cMax = 1e4; break;
    299        case tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV: cMin = 0; cMax = 1e5; break;
    300 
    301        default:
    302            DE_ASSERT(false);
    303    }
    304 
    305    return [cMin, cMax];
    306 };
    307 
    308 /**
    309 * Creates an array by choosing between 'a' and 'b' based on 'cond' array.
    310 * @param {Array | number} a
    311 * @param {Array | number} b
    312 * @param {Array<boolean>} cond Condtions
    313 * @return {Array}
    314 */
    315 tcuTextureUtil.select = function(a, b, cond) {
    316 
    317    /*DE_ASSERT(!(a.length && !b.length)
    318                || !(!a.length && b.length)
    319                || !((a.length && b.length) && ((a.length != b.length) || (b.length != cond.length) || (a.length != cond.length))));*/
    320 
    321    if (a.length && !b.length) throw new Error('second input parameter is not a vector');
    322    if (!a.length && b.length) throw new Error('first input parameter is not a vector');
    323    if ((a.length && b.length) && ((a.length != b.length) || (b.length != cond.length) || (a.length != cond.length))) throw new Error('different size vectors');
    324 
    325    var dst = [];
    326    for (var i = 0; i < cond.length; i++)
    327        if (cond[i]) {
    328            if (a.length) dst.push(a[i]);
    329            else dst.push(a);
    330        } else {
    331            if (b.length) dst.push(b[i]);
    332            else dst.push(b);
    333        }
    334    return dst;
    335 };
    336 
    337 /**
    338 * Get standard parameters for testing texture format
    339 *
    340 * Returns tcuTextureUtil.TextureFormatInfo that describes good parameters for exercising
    341 * given TextureFormat. Parameters include value ranges per channel and
    342 * suitable lookup scaling and bias in order to reduce result back to
    343 * 0..1 range.
    344 *
    345 * @param {tcuTexture.TextureFormat} format
    346 * @return {tcuTextureUtil.TextureFormatInfo}
    347 */
    348 tcuTextureUtil.getTextureFormatInfo = function(format) {
    349    // Special cases.
    350    if (format.isEqual(new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV)))
    351        return new tcuTextureUtil.TextureFormatInfo([0, 0, 0, 0],
    352                                 [1023, 1023, 1023, 3],
    353                                 [1 / 1023, 1 / 1023, 1 / 1023, 1 / 3],
    354                                 [0, 0, 0, 0]);
    355    else if (format.order == tcuTexture.ChannelOrder.D || format.order == tcuTexture.ChannelOrder.DS)
    356        return new tcuTextureUtil.TextureFormatInfo([0, 0, 0, 0],
    357                                 [1, 1, 1, 0],
    358                                 [1, 1, 1, 1],
    359                                 [0, 0, 0, 0]); // Depth / stencil formats.
    360    else if (format.isEqual(new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_SHORT_5551)))
    361        return new tcuTextureUtil.TextureFormatInfo([0, 0, 0, 0.5],
    362                                 [1, 1, 1, 1.5],
    363                                 [1, 1, 1, 1],
    364                                 [0, 0, 0, 0]);
    365 
    366    var cRange = tcuTextureUtil.getChannelValueRange(format.type);
    367    var chnMask = null;
    368 
    369    switch (format.order) {
    370        case tcuTexture.ChannelOrder.R: chnMask = [true, false, false, false]; break;
    371        case tcuTexture.ChannelOrder.A: chnMask = [false, false, false, true]; break;
    372        case tcuTexture.ChannelOrder.L: chnMask = [true, true, true, false]; break;
    373        case tcuTexture.ChannelOrder.LA: chnMask = [true, true, true, true]; break;
    374        case tcuTexture.ChannelOrder.RG: chnMask = [true, true, false, false]; break;
    375        case tcuTexture.ChannelOrder.RGB: chnMask = [true, true, true, false]; break;
    376        case tcuTexture.ChannelOrder.RGBA: chnMask = [true, true, true, true]; break;
    377        case tcuTexture.ChannelOrder.sRGB: chnMask = [true, true, true, false]; break;
    378        case tcuTexture.ChannelOrder.sRGBA: chnMask = [true, true, true, true]; break;
    379        case tcuTexture.ChannelOrder.D: chnMask = [true, true, true, false]; break;
    380        case tcuTexture.ChannelOrder.DS: chnMask = [true, true, true, true]; break;
    381        default:
    382            DE_ASSERT(false);
    383    }
    384 
    385    var scale = 1 / (cRange[1] - cRange[0]);
    386    var bias = -cRange[0] * scale;
    387 
    388    return new tcuTextureUtil.TextureFormatInfo(tcuTextureUtil.select(cRange[0], 0, chnMask),
    389                             tcuTextureUtil.select(cRange[1], 0, chnMask),
    390                             tcuTextureUtil.select(scale, 1, chnMask),
    391                             tcuTextureUtil.select(bias, 0, chnMask));
    392 };
    393 
    394 /** tcuTextureUtil.getChannelBitDepth
    395 * @param {?tcuTexture.ChannelType} channelType
    396 * @return {Array<number>}
    397 */
    398 tcuTextureUtil.getChannelBitDepth = function(channelType) {
    399 
    400    switch (channelType) {
    401        case tcuTexture.ChannelType.SNORM_INT8: return [8, 8, 8, 8];
    402        case tcuTexture.ChannelType.SNORM_INT16: return [16, 16, 16, 16];
    403        case tcuTexture.ChannelType.SNORM_INT32: return [32, 32, 32, 32];
    404        case tcuTexture.ChannelType.UNORM_INT8: return [8, 8, 8, 8];
    405        case tcuTexture.ChannelType.UNORM_INT16: return [16, 16, 16, 16];
    406        case tcuTexture.ChannelType.UNORM_INT32: return [32, 32, 32, 32];
    407        case tcuTexture.ChannelType.UNORM_SHORT_565: return [5, 6, 5, 0];
    408        case tcuTexture.ChannelType.UNORM_SHORT_4444: return [4, 4, 4, 4];
    409        case tcuTexture.ChannelType.UNORM_SHORT_555: return [5, 5, 5, 0];
    410        case tcuTexture.ChannelType.UNORM_SHORT_5551: return [5, 5, 5, 1];
    411        case tcuTexture.ChannelType.UNORM_INT_101010: return [10, 10, 10, 0];
    412        case tcuTexture.ChannelType.UNORM_INT_1010102_REV: return [10, 10, 10, 2];
    413        case tcuTexture.ChannelType.SIGNED_INT8: return [8, 8, 8, 8];
    414        case tcuTexture.ChannelType.SIGNED_INT16: return [16, 16, 16, 16];
    415        case tcuTexture.ChannelType.SIGNED_INT32: return [32, 32, 32, 32];
    416        case tcuTexture.ChannelType.UNSIGNED_INT8: return [8, 8, 8, 8];
    417        case tcuTexture.ChannelType.UNSIGNED_INT16: return [16, 16, 16, 16];
    418        case tcuTexture.ChannelType.UNSIGNED_INT32: return [32, 32, 32, 32];
    419        case tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV: return [10, 10, 10, 2];
    420        case tcuTexture.ChannelType.UNSIGNED_INT_24_8: return [24, 0, 0, 8];
    421        case tcuTexture.ChannelType.HALF_FLOAT: return [16, 16, 16, 16];
    422        case tcuTexture.ChannelType.FLOAT: return [32, 32, 32, 32];
    423        case tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV: return [11, 11, 10, 0];
    424        case tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV: return [9, 9, 9, 0];
    425        case tcuTexture.ChannelType.FLOAT_UNSIGNED_INT_24_8_REV: return [32, 0, 0, 8];
    426        default:
    427            DE_ASSERT(false);
    428            return [0, 0, 0, 0];
    429    }
    430 };
    431 
    432 /** tcuTextureUtil.getTextureFormatBitDepth
    433 * @param {tcuTexture.TextureFormat} format
    434 * @return {Array<number>}
    435 */
    436 tcuTextureUtil.getTextureFormatBitDepth = function(format) {
    437 
    438    /** @type {Array<number>} */ var chnBits = tcuTextureUtil.getChannelBitDepth(format.type); // IVec4
    439    /** @type {Array<boolean>} */ var chnMask = [false, false, false, false]; // BVec4
    440    /** @type {Array<number>} */ var chnSwz = [0, 1, 2, 3]; // IVec4
    441 
    442    switch (format.order) {
    443        case tcuTexture.ChannelOrder.R: chnMask = [true, false, false, false]; break;
    444        case tcuTexture.ChannelOrder.A: chnMask = [false, false, false, true]; break;
    445        case tcuTexture.ChannelOrder.RA: chnMask = [true, false, false, true]; break;
    446        case tcuTexture.ChannelOrder.L: chnMask = [true, true, true, false]; break;
    447        case tcuTexture.ChannelOrder.I: chnMask = [true, true, true, true]; break;
    448        case tcuTexture.ChannelOrder.LA: chnMask = [true, true, true, true]; break;
    449        case tcuTexture.ChannelOrder.RG: chnMask = [true, true, false, false]; break;
    450        case tcuTexture.ChannelOrder.RGB: chnMask = [true, true, true, false]; break;
    451        case tcuTexture.ChannelOrder.RGBA: chnMask = [true, true, true, true]; break;
    452        case tcuTexture.ChannelOrder.BGRA: chnMask = [true, true, true, true]; chnSwz = [2, 1, 0, 3]; break;
    453        case tcuTexture.ChannelOrder.ARGB: chnMask = [true, true, true, true]; chnSwz = [1, 2, 3, 0]; break;
    454        case tcuTexture.ChannelOrder.sRGB: chnMask = [true, true, true, false]; break;
    455        case tcuTexture.ChannelOrder.sRGBA: chnMask = [true, true, true, true]; break;
    456        case tcuTexture.ChannelOrder.D: chnMask = [true, false, false, false]; break;
    457        case tcuTexture.ChannelOrder.DS: chnMask = [true, false, false, true]; break;
    458        case tcuTexture.ChannelOrder.S: chnMask = [false, false, false, true]; break;
    459        default:
    460            DE_ASSERT(false);
    461    }
    462 
    463    return tcuTextureUtil.select(deMath.swizzle(chnBits, [chnSwz[0], chnSwz[1], chnSwz[2], chnSwz[3]]), [0, 0, 0, 0], chnMask);
    464 
    465 };
    466 
    467 /** tcuTextureUtil.fillWithGrid
    468 * @const @param {tcuTexture.PixelBufferAccess} access
    469 * @param {number} cellSize
    470 * @param {Array<number>} colorA
    471 * @param {Array<number>} colorB
    472 */
    473 tcuTextureUtil.fillWithGrid = function(access, cellSize, colorA, colorB) {
    474    if (access.getHeight() == 1 && access.getDepth() == 1)
    475        tcuTextureUtil.fillWithGrid1D(access, cellSize, colorA, colorB);
    476    else if (access.getDepth() == 1)
    477        tcuTextureUtil.fillWithGrid2D(access, cellSize, colorA, colorB);
    478    else
    479        tcuTextureUtil.fillWithGrid3D(access, cellSize, colorA, colorB);
    480 };
    481 
    482 /** tcuTextureUtil.fillWithGrid1D
    483 * @const @param {tcuTexture.PixelBufferAccess} access
    484 * @param {number} cellSize
    485 * @param {Array<number>} colorA
    486 * @param {Array<number>} colorB
    487 */
    488 tcuTextureUtil.fillWithGrid1D = function(access, cellSize, colorA, colorB) {
    489    for (var x = 0; x < access.getWidth(); x++) {
    490        var mx = Math.floor(x / cellSize) % 2;
    491 
    492        if (mx)
    493            access.setPixel(colorB, x, 0);
    494        else
    495            access.setPixel(colorA, x, 0);
    496    }
    497 };
    498 
    499 /** tcuTextureUtil.fillWithGrid2D
    500 * @const @param {tcuTexture.PixelBufferAccess} access
    501 * @param {number} cellSize
    502 * @param {Array<number>} colorA
    503 * @param {Array<number>} colorB
    504 */
    505 tcuTextureUtil.fillWithGrid2D = function(access, cellSize, colorA, colorB) {
    506    for (var y = 0; y < access.getHeight(); y++)
    507        for (var x = 0; x < access.getWidth(); x++) {
    508            var mx = Math.floor(x / cellSize) % 2;
    509            var my = Math.floor(y / cellSize) % 2;
    510 
    511            if (mx ^ my)
    512                access.setPixel(colorB, x, y);
    513            else
    514                access.setPixel(colorA, x, y);
    515        }
    516 };
    517 
    518 /** tcuTextureUtil.fillWithGrid3D
    519 * @const @param {tcuTexture.PixelBufferAccess} access
    520 * @param {number} cellSize
    521 * @param {Array<number>} colorA
    522 * @param {Array<number>} colorB
    523 */
    524 tcuTextureUtil.fillWithGrid3D = function(access, cellSize, colorA, colorB) {
    525    for (var z = 0; z < access.getDepth(); z++)
    526        for (var y = 0; y < access.getHeight(); y++)
    527            for (var x = 0; x < access.getWidth(); x++) {
    528                var mx = Math.floor(x / cellSize) % 2;
    529                var my = Math.floor(y / cellSize) % 2;
    530                var mz = Math.floor(z / cellSize) % 2;
    531 
    532                if (mx ^ my ^ mz)
    533                    access.setPixel(colorB, x, y, z);
    534                else
    535                    access.setPixel(colorA, x, y, z);
    536            }
    537 };
    538 
    539 /**
    540 * @const @param {tcuTexture.TextureFormat} format
    541 * @return {Array<number>}
    542 */
    543 tcuTextureUtil.getTextureFormatMantissaBitDepth = function(format) {
    544    /** @type {Array<number>} */ var chnBits = tcuTextureUtil.getChannelMantissaBitDepth(format.type);
    545    /** @type {Array<boolean>} */ var chnMask = [false, false, false, false];
    546    /** @type {Array<number>} */ var chnSwz = [0, 1, 2, 3];
    547 
    548    switch (format.order) {
    549        case tcuTexture.ChannelOrder.R: chnMask = [true, false, false, false]; break;
    550        case tcuTexture.ChannelOrder.A: chnMask = [false, false, false, true]; break;
    551        case tcuTexture.ChannelOrder.RA: chnMask = [true, false, false, true]; break;
    552        case tcuTexture.ChannelOrder.L: chnMask = [true, true, true, false]; break;
    553        case tcuTexture.ChannelOrder.I: chnMask = [true, true, true, true]; break;
    554        case tcuTexture.ChannelOrder.LA: chnMask = [true, true, true, true]; break;
    555        case tcuTexture.ChannelOrder.RG: chnMask = [true, true, false, false]; break;
    556        case tcuTexture.ChannelOrder.RGB: chnMask = [true, true, true, false]; break;
    557        case tcuTexture.ChannelOrder.RGBA: chnMask = [true, true, true, true]; break;
    558        case tcuTexture.ChannelOrder.BGRA: chnMask = [true, true, true, true]; chnSwz = [2, 1, 0, 3]; break;
    559        case tcuTexture.ChannelOrder.ARGB: chnMask = [true, true, true, true]; chnSwz = [1, 2, 3, 0]; break;
    560        case tcuTexture.ChannelOrder.sRGB: chnMask = [true, true, true, false]; break;
    561        case tcuTexture.ChannelOrder.sRGBA: chnMask = [true, true, true, true]; break;
    562        case tcuTexture.ChannelOrder.D: chnMask = [true, false, false, false]; break;
    563        case tcuTexture.ChannelOrder.DS: chnMask = [true, false, false, true]; break;
    564        case tcuTexture.ChannelOrder.S: chnMask = [false, false, false, true]; break;
    565        default:
    566            DE_ASSERT(false);
    567    }
    568    return tcuTextureUtil.select(deMath.swizzle(chnBits, [chnSwz[0], chnSwz[1], chnSwz[2], chnSwz[3]]), [0, 0, 0, 0], chnMask);
    569 };
    570 
    571 /**
    572 * @param {?tcuTexture.ChannelType} channelType
    573 * @return {Array<number>}
    574 */
    575 tcuTextureUtil.getChannelMantissaBitDepth = function(channelType) {
    576    switch (channelType) {
    577        case tcuTexture.ChannelType.SNORM_INT8:
    578        case tcuTexture.ChannelType.SNORM_INT16:
    579        case tcuTexture.ChannelType.SNORM_INT32:
    580        case tcuTexture.ChannelType.UNORM_INT8:
    581        case tcuTexture.ChannelType.UNORM_INT16:
    582        case tcuTexture.ChannelType.UNORM_INT32:
    583        case tcuTexture.ChannelType.UNORM_SHORT_565:
    584        case tcuTexture.ChannelType.UNORM_SHORT_4444:
    585        case tcuTexture.ChannelType.UNORM_SHORT_555:
    586        case tcuTexture.ChannelType.UNORM_SHORT_5551:
    587        case tcuTexture.ChannelType.UNORM_INT_101010:
    588        case tcuTexture.ChannelType.UNORM_INT_1010102_REV:
    589        case tcuTexture.ChannelType.SIGNED_INT8:
    590        case tcuTexture.ChannelType.SIGNED_INT16:
    591        case tcuTexture.ChannelType.SIGNED_INT32:
    592        case tcuTexture.ChannelType.UNSIGNED_INT8:
    593        case tcuTexture.ChannelType.UNSIGNED_INT16:
    594        case tcuTexture.ChannelType.UNSIGNED_INT32:
    595        case tcuTexture.ChannelType.UNSIGNED_INT_1010102_REV:
    596        case tcuTexture.ChannelType.UNSIGNED_INT_24_8:
    597        case tcuTexture.ChannelType.UNSIGNED_INT_999_E5_REV:
    598            return tcuTextureUtil.getChannelBitDepth(channelType);
    599        case tcuTexture.ChannelType.HALF_FLOAT: return [10, 10, 10, 10];
    600        case tcuTexture.ChannelType.FLOAT: return [23, 23, 23, 23];
    601        case tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV: return [6, 6, 5, 0];
    602        case tcuTexture.ChannelType.FLOAT_UNSIGNED_INT_24_8_REV: return [23, 0, 0, 8];
    603        default:
    604            throw new Error('Invalid channelType: ' + channelType);
    605    }
    606 };
    607 
    608 /**
    609 * @param {tcuTexture.PixelBufferAccess} dst
    610 * @param {tcuTexture.ConstPixelBufferAccess} src
    611 */
    612 tcuTextureUtil.copy = function(dst, src) {
    613    var width = dst.getWidth();
    614    var height = dst.getHeight();
    615    var depth = dst.getDepth();
    616 
    617    DE_ASSERT(src.getWidth() == width && src.getHeight() == height && src.getDepth() == depth);
    618 
    619    if (src.getFormat().isEqual(dst.getFormat())) {
    620        var srcData = src.getDataPtr();
    621        var dstData = dst.getDataPtr();
    622 
    623        if (srcData.length == dstData.length) {
    624            dstData.set(srcData);
    625            return;
    626        }
    627    }
    628    var srcClass = tcuTexture.getTextureChannelClass(src.getFormat().type);
    629    var dstClass = tcuTexture.getTextureChannelClass(dst.getFormat().type);
    630    var srcIsInt = srcClass == tcuTexture.TextureChannelClass.SIGNED_INTEGER || srcClass == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER;
    631    var dstIsInt = dstClass == tcuTexture.TextureChannelClass.SIGNED_INTEGER || dstClass == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER;
    632 
    633    if (srcIsInt && dstIsInt) {
    634        for (var z = 0; z < depth; z++)
    635        for (var y = 0; y < height; y++)
    636        for (var x = 0; x < width; x++)
    637            dst.setPixelInt(src.getPixelInt(x, y, z), x, y, z);
    638    } else {
    639        for (var z = 0; z < depth; z++)
    640        for (var y = 0; y < height; y++)
    641        for (var x = 0; x < width; x++)
    642            dst.setPixel(src.getPixel(x, y, z), x, y, z);
    643    }
    644 };
    645 
    646 /**
    647 * @param {tcuTexture.ConstPixelBufferAccess} access
    648 */
    649 tcuTextureUtil.estimatePixelValueRange = function(access) {
    650    var format = access.getFormat();
    651 
    652    switch (format.type) {
    653        case tcuTexture.ChannelType.UNORM_INT8:
    654        case tcuTexture.ChannelType.UNORM_INT16:
    655            // Normalized unsigned formats.
    656            return [
    657                [0, 0, 0, 0],
    658                [1, 1, 1, 1]
    659            ];
    660 
    661        case tcuTexture.ChannelType.SNORM_INT8:
    662        case tcuTexture.ChannelType.SNORM_INT16:
    663            // Normalized signed formats.
    664            return [
    665                [-1, -1, -1, -1],
    666                [1, 1, 1, 1]
    667            ];
    668 
    669        default:
    670            // \note Samples every 4/8th pixel.
    671            var minVal = [Infinity, Infinity, Infinity, Infinity];
    672            var maxVal = [-Infinity, -Infinity, -Infinity, -Infinity];
    673 
    674            for (var z = 0; z < access.getDepth(); z += 2) {
    675                for (var y = 0; y < access.getHeight(); y += 2) {
    676                    for (var x = 0; x < access.getWidth(); x += 2) {
    677                        var p = access.getPixel(x, y, z);
    678 
    679                        minVal[0] = Math.min(minVal[0], p[0]);
    680                        minVal[1] = Math.min(minVal[1], p[1]);
    681                        minVal[2] = Math.min(minVal[2], p[2]);
    682                        minVal[3] = Math.min(minVal[3], p[3]);
    683 
    684                        maxVal[0] = Math.max(maxVal[0], p[0]);
    685                        maxVal[1] = Math.max(maxVal[1], p[1]);
    686                        maxVal[2] = Math.max(maxVal[2], p[2]);
    687                        maxVal[3] = Math.max(maxVal[3], p[3]);
    688                    }
    689                }
    690            }
    691            return [minVal, maxVal];
    692    }
    693 };
    694 
    695 /**
    696 * @param {tcuTexture.ConstPixelBufferAccess} access
    697 * @return {{scale: Array<number>, bias: Array<number>}}
    698 */
    699 tcuTextureUtil.computePixelScaleBias = function(access) {
    700    var limits = tcuTextureUtil.estimatePixelValueRange(access);
    701    var minVal = limits[0];
    702    var maxVal = limits[1];
    703 
    704    var scale = [1, 1, 1, 1];
    705    var bias = [0, 0, 0, 0];
    706 
    707    var eps = 0.0001;
    708 
    709    for (var c = 0; c < 4; c++) {
    710        if (maxVal[c] - minVal[c] < eps) {
    711            scale[c] = (maxVal[c] < eps) ? 1 : (1 / maxVal[c]);
    712            bias[c] = (c == 3) ? (1 - maxVal[c] * scale[c]) : (0 - minVal[c] * scale[c]);
    713        } else {
    714            scale[c] = 1 / (maxVal[c] - minVal[c]);
    715            bias[c] = 0 - minVal[c] * scale[c];
    716        }
    717    }
    718 
    719    return {
    720        scale: scale,
    721        bias: bias
    722    };
    723 };
    724 
    725 });