diff options
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuBilinearImageCompare.js')
-rw-r--r-- | dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuBilinearImageCompare.js | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuBilinearImageCompare.js b/dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuBilinearImageCompare.js new file mode 100644 index 0000000000..bc23104c09 --- /dev/null +++ b/dom/canvas/test/webgl-conf/checkout/deqp/framework/common/tcuBilinearImageCompare.js @@ -0,0 +1,272 @@ +/*------------------------------------------------------------------------- + * drawElements Quality Program OpenGL ES Utilities + * ------------------------------------------------ + * + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +'use strict'; +goog.provide('framework.common.tcuBilinearImageCompare'); +goog.require('framework.common.tcuRGBA'); +goog.require('framework.common.tcuTexture'); +goog.require('framework.delibs.debase.deMath'); + +goog.scope(function() { + + var tcuBilinearImageCompare = framework.common.tcuBilinearImageCompare; + var deMath = framework.delibs.debase.deMath; + var tcuTexture = framework.common.tcuTexture; + var tcuRGBA = framework.common.tcuRGBA; + + var DE_ASSERT = function(x) { + if (!x) + throw new Error('Assert failed'); + }; + + // for bilinear interpolation + /** @const {number} */ tcuBilinearImageCompare.NUM_SUBPIXEL_BITS = 8; + + // Algorithm assumes that colors are packed to 32-bit values as dictated by + // tcu::RGBA::*_SHIFT values. + + function UintRGBA8_R(color) { + return (color >> 24) & 0xff; + } + function UintRGBA8_G(color) { + return (color >> 16) & 0xff; + } + function UintRGBA8_B(color) { + return (color >> 8) & 0xff; + } + function UintRGBA8_A(color) { + return color & 0xff; + } + + /** + * @param {number} fx1 deUint32 + * @param {number} fy1 deUint32 + * @param {number} p00 deUint8 + * @param {number} p01 deUint8 + * @param {number} p10 deUint8 + * @param {number} p11 deUint8 + * @return {number} deUint8 + */ + tcuBilinearImageCompare.interpolateChannel = function(fx1, fy1, p00, p01, p10, p11) { + /** @const {number} */ var fx0 = (1 << tcuBilinearImageCompare.NUM_SUBPIXEL_BITS) - fx1; + /** @const {number} */ var fy0 = (1 << tcuBilinearImageCompare.NUM_SUBPIXEL_BITS) - fy1; + /** @const {number} */ + var half = 1 << (tcuBilinearImageCompare.NUM_SUBPIXEL_BITS * 2 - 1); + /** @const {number} */ var sum = + (fx0 * fy0 * p00) + + (fx1 * fy0 * p10) + + (fx0 * fy1 * p01) + + (fx1 * fy1 * p11); + /** @const {number} */ + var rounded = (sum + half) >> (tcuBilinearImageCompare.NUM_SUBPIXEL_BITS * 2); + + DE_ASSERT(deMath.deInRange32(rounded, 0, 0xff)); + return rounded; + }; + + tcuBilinearImageCompare.compareUintRGBA8Threshold = function(a, b, thr) { + if (a == b) + return true; + + return (Math.abs(UintRGBA8_R(a) - UintRGBA8_R(b)) <= thr.getRed() && + Math.abs(UintRGBA8_G(a) - UintRGBA8_G(b)) <= thr.getGreen() && + Math.abs(UintRGBA8_B(a) - UintRGBA8_B(b)) <= thr.getBlue() && + Math.abs(UintRGBA8_A(a) - UintRGBA8_A(b)) <= thr.getAlpha()); + }; + + /** + * @param {tcuTexture.RGBA8View} view + * @param {number} u + * @param {number} v + * @return {number} + */ + tcuBilinearImageCompare.bilinearSampleUintRGBA8 = function(view, u, v) { + /** @type {number} */ var x0 = u >> tcuBilinearImageCompare.NUM_SUBPIXEL_BITS; + /** @type {number} */ var y0 = v >> tcuBilinearImageCompare.NUM_SUBPIXEL_BITS; + /** @type {number} */ var x1 = x0 + 1; + /** @type {number} */ var y1 = y0 + 1; + + DE_ASSERT(x1 < view.getWidth()); + DE_ASSERT(y1 < view.getHeight()); + + /** @type {number} */ var fx1 = u - (x0 << tcuBilinearImageCompare.NUM_SUBPIXEL_BITS); + /** @type {number} */ var fy1 = v - (y0 << tcuBilinearImageCompare.NUM_SUBPIXEL_BITS); + + /** @type {Array<number>} */ var channelsP00 = view.readUintRGBA8(x0, y0); + /** @type {Array<number>} */ var channelsP10 = view.readUintRGBA8(x1, y0); + /** @type {Array<number>} */ var channelsP01 = view.readUintRGBA8(x0, y1); + /** @type {Array<number>} */ var channelsP11 = view.readUintRGBA8(x1, y1); + + /** @type {number} */ var res = 0; + + res = (tcuBilinearImageCompare.interpolateChannel(fx1, fy1, UintRGBA8_R(channelsP00), + UintRGBA8_R(channelsP01), UintRGBA8_R(channelsP10), UintRGBA8_R(channelsP11)) & 0xff) << 24; + res += (tcuBilinearImageCompare.interpolateChannel(fx1, fy1, UintRGBA8_G(channelsP00), + UintRGBA8_G(channelsP01), UintRGBA8_G(channelsP10), UintRGBA8_G(channelsP11)) & 0xff) << 16; + res += (tcuBilinearImageCompare.interpolateChannel(fx1, fy1, UintRGBA8_B(channelsP00), + UintRGBA8_B(channelsP01), UintRGBA8_B(channelsP10), UintRGBA8_B(channelsP11)) & 0xff) << 8; + res += tcuBilinearImageCompare.interpolateChannel(fx1, fy1, UintRGBA8_A(channelsP00), + UintRGBA8_A(channelsP01), UintRGBA8_A(channelsP10), UintRGBA8_A(channelsP11)) & 0xff; + + return res; + }; + + /** + * @param {tcuTexture.RGBA8View} reference + * @param {tcuTexture.RGBA8View} result + * @param {tcuRGBA.RGBA} threshold + * @param {number} x + * @param {number} y + * @return {boolean} + */ + tcuBilinearImageCompare.comparePixelRGBA8 = function(reference, result, threshold, x, y) { + /** @const {tcuRGBA.RGBA} */ var resPix = result.readUintRGBA8(x, y); + + // Step 1: Compare result pixel to 3x3 neighborhood pixels in reference. + /** @const {number} */ var x0 = Math.max(x - 1, 0); + /** @const {number} */ var x1 = x; + /** @const {number} */ + var x2 = Math.min(x + 1, reference.getWidth() - 1); + /** @const {number} */ var y0 = Math.max(y - 1, 0); + /** @const {number} */ var y1 = y; + /** @const {number} */ + var y2 = Math.min(y + 1, reference.getHeight() - 1); + + //tcuBilinearImageCompare.readRGBA8List (reference, x0, y0, x2, y2); + + if (tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, reference.readUintRGBA8(x1, y1), threshold) || + tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, reference.readUintRGBA8(x0, y1), threshold) || + tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, reference.readUintRGBA8(x2, y1), threshold) || + tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, reference.readUintRGBA8(x0, y0), threshold) || + tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, reference.readUintRGBA8(x1, y0), threshold) || + tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, reference.readUintRGBA8(x2, y0), threshold) || + tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, reference.readUintRGBA8(x0, y2), threshold) || + tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, reference.readUintRGBA8(x1, y2), threshold) || + tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, reference.readUintRGBA8(x2, y2), threshold)) + return true; + + // Step 2: Compare using bilinear sampling. + // \todo [pyry] Optimize sample positions! + /** @const {Array<Array<number>>} */ var s_offsets = [ + [226, 186], + [335, 235], + [279, 334], + [178, 272], + [112, 202], + [306, 117], + [396, 299], + [206, 382], + [146, 96], + [423, 155], + [361, 412], + [84, 339], + [48, 130], + [367, 43], + [455, 367], + [105, 439], + [83, 46], + [217, 24], + [461, 71], + [450, 459], + [239, 469], + [67, 267], + [459, 255], + [13, 416], + [10, 192], + [141, 502], + [503, 304], + [380, 506] + ]; + + for (var sampleNdx = 0; sampleNdx < s_offsets.length; sampleNdx++) { + /** @const {number} */ + var u = ((x - 1) << tcuBilinearImageCompare.NUM_SUBPIXEL_BITS) + s_offsets[sampleNdx][0]; + /** @const {number} */ + var v = ((y - 1) << tcuBilinearImageCompare.NUM_SUBPIXEL_BITS) + s_offsets[sampleNdx][1]; + + if (!deMath.deInBounds32(u, 0, (reference.getWidth() - 1) << tcuBilinearImageCompare.NUM_SUBPIXEL_BITS) || + !deMath.deInBounds32(v, 0, (reference.getHeight() - 1) << tcuBilinearImageCompare.NUM_SUBPIXEL_BITS)) + continue; + + if (tcuBilinearImageCompare.compareUintRGBA8Threshold(resPix, tcuBilinearImageCompare.bilinearSampleUintRGBA8(reference, u, v), threshold)) + return true; + } + + return false; + }; + + /** + * @param {tcuTexture.RGBA8View} reference + * @param {tcuTexture.RGBA8View} result + * @param {tcuTexture.PixelBufferAccess} errorMask + * @param {tcuRGBA.RGBA} threshold + * @return {boolean} + */ + tcuBilinearImageCompare.bilinearCompareRGBA8 = function(reference, result, errorMask, threshold) { + DE_ASSERT(reference.getFormat().isEqual(new tcuTexture.TextureFormat( + tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8))); + DE_ASSERT(result.getFormat().isEqual(new tcuTexture.TextureFormat( + tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8))); + + // Clear error mask first to green (faster this way). + errorMask.clear([0.0, 1.0, 0.0, 1.0]); + + /** @type {boolean} */ var allOk = true; + + for (var y = 0; y < reference.getHeight(); y++) { + for (var x = 0; x < reference.getWidth(); x++) { + if (!tcuBilinearImageCompare.comparePixelRGBA8(reference, result, threshold, x, y) && + !tcuBilinearImageCompare.comparePixelRGBA8(result, reference, threshold, x, y)) { + allOk = false; + errorMask.setPixel([1.0, 0.0, 0.0, 1.0], x, y); + } + } + } + + return allOk; + }; + + /** + * @param {tcuTexture.ConstPixelBufferAccess} reference + * @param {tcuTexture.ConstPixelBufferAccess} result + * @param {tcuTexture.PixelBufferAccess} errorMask + * @param {tcuRGBA.RGBA} threshold + * @return {boolean} + */ + tcuBilinearImageCompare.bilinearCompare = function(reference, result, errorMask, threshold) { + assertMsgOptions(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight() && result.getDepth() == reference.getDepth(), + 'Reference and result images have different dimensions', false, true); + + assertMsgOptions(errorMask.getWidth() == reference.getWidth() && errorMask.getHeight() == reference.getHeight() && errorMask.getDepth() == reference.getDepth(), + 'Reference and error mask images have different dimensions', false, true); + + /** @type {boolean} */ var isEqual = reference.getFormat().isEqual( + new tcuTexture.TextureFormat( + tcuTexture.ChannelOrder.RGBA, + tcuTexture.ChannelType.UNORM_INT8)); + if (isEqual) { + /** @type {tcuTexture.RGBA8View} */ var refView = new tcuTexture.RGBA8View(reference); + /** @type {tcuTexture.RGBA8View} */ var resView = new tcuTexture.RGBA8View(result); + return tcuBilinearImageCompare.bilinearCompareRGBA8(refView, resView, errorMask, threshold); + } else + throw new Error('Unsupported format for bilinear comparison'); + }; + +}); |