blob: 6c9d9df6e8628964b76ef524a9ee1eb7bb8fa55c [file] [log] [blame]
var wtu = WebGLTestUtils;
var tiu = TexImageUtils;
var gl = null;
var internalFormat = "RGBA";
var pixelFormat = "RGBA";
var pixelType = "UNSIGNED_BYTE";
var pixelsBuffer = [];
var resizeQualities = ["pixelated", "low", "medium", "high"];
function runOneIteration(useTexSubImage2D, bindingTarget, program, bitmap,
flipY, premultiplyAlpha, retVal, colorSpace,
testOptions)
{
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Enable writes to the RGBA channels
gl.colorMask(1, 1, 1, 1);
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 height = gl.canvas.height;
var loc;
if (bindingTarget == gl.TEXTURE_CUBE_MAP) {
loc = gl.getUniformLocation(program, "face");
}
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);
var buf = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
pixelsBuffer.unshift({quality: testOptions.resizeQuality, flip: flipY,
premul: premultiplyAlpha, buffer: buf});
}
}
function runTestOnBindingTarget(bindingTarget, program, bitmaps, retVal,
testOptions) {
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 = 0; i < cases.length; i++) {
runOneIteration(cases[i].sub, bindingTarget, program, cases[i].bitmap,
cases[i].flipY, cases[i].premultiply, retVal, cases[i].colorSpace,
testOptions);
}
}
// createImageBitmap resize code has two separate code paths for premul and
// unpremul image sources when the resize quality is set to high.
function runTest(bitmaps, alphaVal, colorSpaceEffective, testOptions)
{
var retVal = {testPassed: true, alpha: alphaVal,
colorSpaceEffect: colorSpaceEffective};
var program = tiu.setupTexturedQuad(gl, internalFormat);
runTestOnBindingTarget(gl.TEXTURE_2D, program, bitmaps, retVal,
testOptions);
program = tiu.setupTexturedQuadWithCubeMap(gl, internalFormat);
runTestOnBindingTarget(gl.TEXTURE_CUBE_MAP, program, bitmaps, retVal,
testOptions);
return retVal.testPassed;
}
function prepareResizedImageBitmapsAndRuntTest(testOptions) {
var bitmaps = [];
var imageSource= testOptions.imageSource;
var options = {resizeWidth: testOptions.resizeWidth,
resizeHeight: testOptions.resizeHeight,
resizeQuality: testOptions.resizeQuality};
var p1 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.defaultOption = imageBitmap });
options.imageOrientation = "none";
options.premultiplyAlpha = "premultiply";
var p2 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.noFlipYPremul = imageBitmap });
options.premultiplyAlpha = "default";
var p3 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.noFlipYDefault = imageBitmap });
options.premultiplyAlpha = "none";
var p4 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.noFlipYUnpremul = imageBitmap });
options.imageOrientation = "flipY";
options.premultiplyAlpha = "premultiply";
var p5 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.flipYPremul = imageBitmap });
options.premultiplyAlpha = "default";
var p6 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.flipYDefault = imageBitmap });
options.premultiplyAlpha = "none";
var p7 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.flipYUnpremul = imageBitmap });
options = {resizeWidth: testOptions.resizeWidth,
resizeHeight: testOptions.resizeHeight,
resizeQuality: testOptions.resizeQuality};
var p8 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.colorSpaceDef = imageBitmap });
options.colorSpaceConversion = "none";
var p9 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.colorSpaceNone = imageBitmap });
options.colorSpaceConversion = "default";
var p10 = createImageBitmap(imageSource, options).then(
function(imageBitmap) { bitmaps.colorSpaceDefault = imageBitmap });
return Promise.all([p1, p2, p3, p4, p5, p6, p7, p8, p9, p10]).then(
function() {
var alphaVal = 0.5;
runTest(bitmaps, alphaVal, false, testOptions);
});
}
function prepareResizedImageBitmapsAndRuntTests(testOptions) {
testOptions.resizeQuality = resizeQualities[0];
var p1 = prepareResizedImageBitmapsAndRuntTest(testOptions);
testOptions.resizeQuality = resizeQualities[1];
var p2 = prepareResizedImageBitmapsAndRuntTest(testOptions);
testOptions.resizeQuality = resizeQualities[2];
var p3 = prepareResizedImageBitmapsAndRuntTest(testOptions);
testOptions.resizeQuality = resizeQualities[3];
var p4 = prepareResizedImageBitmapsAndRuntTest(testOptions);
return Promise.all([p1, p2, p3, p4]).then(function() {
DrawResultsOnCanvas(testOptions);
});
}
function prepareWebGLContext(testOptions) {
var glcanvas = document.createElement('canvas');
glcanvas.width = testOptions.resizeWidth;
glcanvas.height = testOptions.resizeHeight;
glcanvas.style.display="none";
document.body.appendChild(glcanvas);
gl = glcanvas.getContext("webgl");
gl.clearColor(0,0,0,1);
gl.clearDepth(1);
}
function PrintTileInfoForDebug(x, y, quality, premul, flip) {
var tileLog = "x: " + x + ", y: " + y + ", quality: " + quality +
", premul: " + premul + ", flip: " + flip;
console.log(tileLog);
}
function DrawResultsOnCanvas(testOptions) {
var resultsCanvas = testOptions.resultsCanvas;
var numTiles = Math.ceil(Math.sqrt(pixelsBuffer.length));
var width = numTiles * testOptions.resizeWidth;
var hieght = numTiles * testOptions.resizeWidth;
var resultsCtx = resultsCanvas.getContext("2d");
// Sweep for resize qualities one by one.
var tileCounter = 0;
for (var i = 0; i < resizeQualities.length; i++) {
// Loop in reverse order and use splice to remove the buffer after
// drawing to the canvas
for (var j = pixelsBuffer.length - 1; j >= 0; j--) {
if (pixelsBuffer[j].quality == resizeQualities[i]) {
var buffer = pixelsBuffer[j].buffer;
// Find the proper location for buffer
var x = (tileCounter * testOptions.resizeWidth) % width;
var y = Math.floor(tileCounter / numTiles) *
testOptions.resizeHeight;
if (testOptions.printDebugInfoToConsole)
PrintTileInfoForDebug(x, y, pixelsBuffer[j].quality,
pixelsBuffer[j].premultiply, pixelsBuffer[j].flip);
tileCounter++;
var imageData = new ImageData(Uint8ClampedArray.from(buffer),
testOptions.resizeWidth, testOptions.resizeHeight);
resultsCtx.putImageData(imageData, x, y);
if (i != resizeQualities.length - 1)
pixelsBuffer.splice(j, 1);
}
}
}
if (window.testRunner)
testRunner.notifyDone();
}