| function checkCanvasRect(buf, x, y, width, height, color, tolerance, bufWidth, retVal) |
| { |
| for (var px = x; px < x + width; px++) { |
| for (var py = y; py < y + height; py++) { |
| var offset = (py * bufWidth + px) * 4; |
| for (var j = 0; j < color.length; j++) { |
| if (Math.abs(buf[offset + j] - color[j]) > tolerance) { |
| retVal.testPassed = false; |
| return; |
| } |
| } |
| } |
| } |
| } |
| |
| function runOneIteration(useTexSubImage2D, bindingTarget, program, bitmap, flipY, premultiplyAlpha, retVal, colorSpace = 'empty') |
| { |
| gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| // Enable writes to the RGBA channels |
| gl.colorMask(1, 1, 1, 0); |
| var texture = gl.createTexture(); |
| // Bind the texture to texture unit 0 |
| gl.bindTexture(bindingTarget, texture); |
| // Set up texture parameters |
| gl.texParameteri(bindingTarget, gl.TEXTURE_MIN_FILTER, gl.NEAREST); |
| gl.texParameteri(bindingTarget, gl.TEXTURE_MAG_FILTER, gl.NEAREST); |
| |
| var targets = [gl.TEXTURE_2D]; |
| if (bindingTarget == gl.TEXTURE_CUBE_MAP) { |
| targets = [gl.TEXTURE_CUBE_MAP_POSITIVE_X, |
| gl.TEXTURE_CUBE_MAP_NEGATIVE_X, |
| gl.TEXTURE_CUBE_MAP_POSITIVE_Y, |
| gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, |
| gl.TEXTURE_CUBE_MAP_POSITIVE_Z, |
| gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]; |
| } |
| // Upload the image into the texture |
| for (var tt = 0; tt < targets.length; ++tt) { |
| if (useTexSubImage2D) { |
| // Initialize the texture to black first |
| gl.texImage2D(targets[tt], 0, gl[internalFormat], bitmap.width, bitmap.height, 0, |
| gl[pixelFormat], gl[pixelType], null); |
| gl.texSubImage2D(targets[tt], 0, 0, 0, gl[pixelFormat], gl[pixelType], bitmap); |
| } else { |
| gl.texImage2D(targets[tt], 0, gl[internalFormat], gl[pixelFormat], gl[pixelType], bitmap); |
| } |
| } |
| |
| var width = gl.canvas.width; |
| var halfWidth = Math.floor(width / 2); |
| var quaterWidth = Math.floor(halfWidth / 2); |
| var height = gl.canvas.height; |
| var halfHeight = Math.floor(height / 2); |
| var quaterHeight = Math.floor(halfHeight / 2); |
| |
| var top = flipY ? quaterHeight : (height - halfHeight + quaterHeight); |
| var bottom = flipY ? (height - halfHeight + quaterHeight) : quaterHeight; |
| |
| var tl = redColor; |
| var tr = premultiplyAlpha ? ((retVal.alpha == 0.5) ? darkRed : (retVal.alpha == 1) ? redColor : blackColor) : redColor; |
| var bl = greenColor; |
| var br = premultiplyAlpha ? ((retVal.alpha == 0.5) ? darkGreen : (retVal.alpha == 1) ? greenColor : blackColor) : greenColor; |
| |
| var blueColor = [0, 0, 255]; |
| if (colorSpace == 'none') { |
| tl = tr = bl = br = blueColor; |
| } else if (colorSpace == 'default' || colorSpace == 'notprovided') { |
| tl = tr = bl = br = redColor; |
| } |
| |
| var loc; |
| if (bindingTarget == gl.TEXTURE_CUBE_MAP) { |
| loc = gl.getUniformLocation(program, "face"); |
| } |
| |
| var tolerance = (retVal.alpha == 0) ? 0 : 2; |
| if (colorSpace == 'default' || colorSpace == 'none' || colorSpace == 'notprovided') |
| tolerance = 13; // For linux and win, the tolerance can be 8. |
| for (var tt = 0; tt < targets.length; ++tt) { |
| if (bindingTarget == gl.TEXTURE_CUBE_MAP) { |
| gl.uniform1i(loc, targets[tt]); |
| } |
| // Draw the triangles |
| gl.clearColor(0, 0, 0, 1); |
| gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); |
| gl.drawArrays(gl.TRIANGLES, 0, 6); |
| |
| // Check the top pixel and bottom pixel and make sure they have |
| // the right color. |
| var buf = new Uint8Array(width * height * 4); |
| gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf); |
| checkCanvasRect(buf, quaterWidth, bottom, 2, 2, tl, tolerance, width, retVal); |
| checkCanvasRect(buf, halfWidth + quaterWidth, bottom, 2, 2, tr, tolerance, width, retVal); |
| checkCanvasRect(buf, quaterWidth, top, 2, 2, bl, tolerance, width, retVal); |
| checkCanvasRect(buf, halfWidth + quaterWidth, top, 2, 2, br, tolerance, width, retVal); |
| } |
| } |
| |
| function runTestOnBindingTarget(bindingTarget, program, bitmaps, retVal) { |
| var cases = [ |
| { sub: false, bitmap: bitmaps.defaultOption, flipY: false, premultiply: true, colorSpace: 'empty' }, |
| { sub: true, bitmap: bitmaps.defaultOption, flipY: false, premultiply: true, colorSpace: 'empty' }, |
| { sub: false, bitmap: bitmaps.noFlipYPremul, flipY: false, premultiply: true, colorSpace: 'empty' }, |
| { sub: true, bitmap: bitmaps.noFlipYPremul, flipY: false, premultiply: true, colorSpace: 'empty' }, |
| { sub: false, bitmap: bitmaps.noFlipYDefault, flipY: false, premultiply: true, colorSpace: 'empty' }, |
| { sub: true, bitmap: bitmaps.noFlipYDefault, flipY: false, premultiply: true, colorSpace: 'empty' }, |
| { sub: false, bitmap: bitmaps.noFlipYUnpremul, flipY: false, premultiply: false, colorSpace: 'empty' }, |
| { sub: true, bitmap: bitmaps.noFlipYUnpremul, flipY: false, premultiply: false, colorSpace: 'empty' }, |
| { sub: false, bitmap: bitmaps.flipYPremul, flipY: true, premultiply: true, colorSpace: 'empty' }, |
| { sub: true, bitmap: bitmaps.flipYPremul, flipY: true, premultiply: true, colorSpace: 'empty' }, |
| { sub: false, bitmap: bitmaps.flipYDefault, flipY: true, premultiply: true, colorSpace: 'empty' }, |
| { sub: true, bitmap: bitmaps.flipYDefault, flipY: true, premultiply: true, colorSpace: 'empty' }, |
| { sub: false, bitmap: bitmaps.flipYUnpremul, flipY: true, premultiply: false, colorSpace: 'empty' }, |
| { sub: true, bitmap: bitmaps.flipYUnpremul, flipY: true, premultiply: false, colorSpace: 'empty' }, |
| { sub: false, bitmap: bitmaps.colorSpaceDef, flipY: false, premultiply: true, colorSpace: retVal.colorSpaceEffect ? 'notprovided' : 'empty' }, |
| { sub: true, bitmap: bitmaps.colorSpaceDef, flipY: false, premultiply: true, colorSpace: retVal.colorSpaceEffect ? 'notprovided' : 'empty' }, |
| { sub: false, bitmap: bitmaps.colorSpaceNone, flipY: false, premultiply: true, colorSpace: retVal.colorSpaceEffect ? 'none' : 'empty' }, |
| { sub: true, bitmap: bitmaps.colorSpaceNone, flipY: false, premultiply: true, colorSpace: retVal.colorSpaceEffect ? 'none' : 'empty' }, |
| { sub: false, bitmap: bitmaps.colorSpaceDefault, flipY: false, premultiply: true, colorSpace: retVal.colorSpaceEffect ? 'default' : 'empty' }, |
| { sub: true, bitmap: bitmaps.colorSpaceDefault, flipY: false, premultiply: true, colorSpace: retVal.colorSpaceEffect ? 'default' : 'empty' }, |
| ]; |
| |
| for (var i in cases) { |
| runOneIteration(cases[i].sub, bindingTarget, program, cases[i].bitmap, cases[i].flipY, |
| cases[i].premultiply, retVal, cases[i].colorSpace); |
| } |
| } |
| |
| function runTest(bitmaps, alphaVal, colorSpaceEffective) |
| { |
| var retVal = {testPassed: true, alpha: alphaVal, colorSpaceEffect: colorSpaceEffective}; |
| var program = tiu.setupTexturedQuad(gl, internalFormat); |
| runTestOnBindingTarget(gl.TEXTURE_2D, program, bitmaps, retVal); |
| program = tiu.setupTexturedQuadWithCubeMap(gl, internalFormat); |
| runTestOnBindingTarget(gl.TEXTURE_CUBE_MAP, program, bitmaps, retVal); |
| return retVal.testPassed; |
| } |