summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsLifetimeTests.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsLifetimeTests.js1118
1 files changed, 1118 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsLifetimeTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsLifetimeTests.js
new file mode 100644
index 0000000000..427a3a4fce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/modules/shared/glsLifetimeTests.js
@@ -0,0 +1,1118 @@
+/*-------------------------------------------------------------------------
+ * 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('modules.shared.glsLifetimeTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuStringTemplate');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('modules.shared.glsTextureTestUtil');
+
+goog.scope(function() {
+var glsLifetimeTests = modules.shared.glsLifetimeTests;
+var tcuStringTemplate = framework.common.tcuStringTemplate;
+var tcuSurface = framework.common.tcuSurface;
+var deRandom = framework.delibs.debase.deRandom;
+var glsTextureTestUtil = modules.shared.glsTextureTestUtil;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var tcuTestCase = framework.common.tcuTestCase;
+var tcuImageCompare = framework.common.tcuImageCompare;
+
+/** @const */ var VIEWPORT_SIZE = 128;
+/** @const */ var FRAMEBUFFER_SIZE = 128;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/** @const */ var s_vertexShaderSrc =
+ '#version 100\n' +
+ 'attribute vec2 pos;\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = vec4(pos.xy, 0.0, 1.0);\n' +
+ '}\n';
+
+/** @const */ var s_fragmentShaderSrc =
+ '#version 100\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_FragColor = vec4(1.0);\n' +
+ '}\n';
+
+/**
+ * @constructor
+ * @extends {gluShaderProgram.Shader}
+ * @param {gluShaderProgram.shaderType} type
+ * @param {string} src
+ */
+glsLifetimeTests.CheckedShader = function(type, src) {
+ gluShaderProgram.Shader.call(this, gl, type);
+ this.setSources(src);
+ this.compile();
+ assertMsgOptions(this.getCompileStatus() === true, 'Failed to compile shader', false, true);
+};
+
+setParentClass(glsLifetimeTests.CheckedShader, gluShaderProgram.Shader);
+
+/**
+ * @constructor
+ * @extends {gluShaderProgram.Program}
+ * @param {WebGLShader} vtxShader
+ * @param {WebGLShader} fragShader
+ */
+glsLifetimeTests.CheckedProgram = function(vtxShader, fragShader) {
+ gluShaderProgram.Program.call(this, gl);
+ this.attachShader(vtxShader);
+ this.attachShader(fragShader);
+ this.link();
+ assertMsgOptions(this.info.linkOk === true, 'Failed to link program', false, true);
+};
+
+setParentClass(glsLifetimeTests.CheckedProgram, gluShaderProgram.Program);
+
+/**
+ * @constructor
+ */
+glsLifetimeTests.Binder = function() {
+};
+
+/**
+ * @param {WebGLObject} obj
+ */
+glsLifetimeTests.Binder.prototype.bind = function(obj) { throw new Error('Virtual function'); };
+
+/**
+ * @return {WebGLObject}
+ */
+glsLifetimeTests.Binder.prototype.getBinding = function() { throw new Error('Virtual function'); };
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Binder}
+ * @param {?function(number, ?)} bindFunc
+ * @param {number} bindTarget
+ * @param {number} bindingParam
+ */
+glsLifetimeTests.SimpleBinder = function(bindFunc, bindTarget, bindingParam) {
+ glsLifetimeTests.Binder.call(this);
+ this.m_bindFunc = bindFunc;
+ this.m_bindTarget = bindTarget;
+ this.m_bindingParam = bindingParam;
+};
+
+setParentClass(glsLifetimeTests.SimpleBinder, glsLifetimeTests.Binder);
+
+glsLifetimeTests.SimpleBinder.prototype.bind = function(obj) {
+ this.m_bindFunc.call(gl, this.m_bindTarget, obj);
+};
+
+glsLifetimeTests.SimpleBinder.prototype.getBinding = function() {
+ return /** @type {WebGLObject} */ (gl.getParameter(this.m_bindingParam));
+};
+
+/**
+ * @constructor
+ */
+glsLifetimeTests.Type = function() {
+};
+
+/**
+ * Create a type
+ * @return {WebGLObject}
+ */
+glsLifetimeTests.Type.prototype.gen = function() { throw new Error('Virtual function'); };
+
+/**
+ * Destroy a type
+ * @param {WebGLObject} obj
+ */
+glsLifetimeTests.Type.prototype.release = function(obj) { throw new Error('Virtual function'); };
+
+/**
+ * Is object valid
+ * @param {WebGLObject} obj
+ */
+glsLifetimeTests.Type.prototype.exists = function(obj) { throw new Error('Virtual function'); };
+
+/**
+ * Is object flagged for deletion
+ * @param {WebGLObject} obj
+ */
+glsLifetimeTests.Type.prototype.isDeleteFlagged = function(obj) { return false; };
+
+/**
+ * @return {glsLifetimeTests.Binder}
+ */
+glsLifetimeTests.Type.prototype.binder = function() { return null; };
+
+/**
+ * @return {string}
+ */
+glsLifetimeTests.Type.prototype.getName = function() { throw new Error('Virtual function'); };
+
+/**
+ * Is the object unbound automatically when it is deleted?
+ * @return {boolean}
+ */
+glsLifetimeTests.Type.prototype.nameLingers = function() { return false; };
+
+/**
+ * Does 'create' creates the object fully?
+ * If not, the object is created at bound time
+ * @return {boolean}
+ */
+glsLifetimeTests.Type.prototype.genCreates = function() { return false; };
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Type}
+ * @param {string} name
+ * @param {function(): WebGLObject} genFunc
+ * @param {function(?)} deleteFunc
+ * @param {function(?): boolean} existsFunc
+ * @param {glsLifetimeTests.Binder} binder
+ * @param {boolean=} genCreates
+ */
+glsLifetimeTests.SimpleType = function(name, genFunc, deleteFunc, existsFunc, binder, genCreates) {
+ glsLifetimeTests.Type.call(this);
+ this.m_getName = name;
+ this.m_genFunc = genFunc;
+ this.m_deleteFunc = deleteFunc;
+ this.m_existsFunc = existsFunc;
+ this.m_binder = binder;
+ this.m_genCreates = genCreates || false;
+};
+
+setParentClass(glsLifetimeTests.SimpleType, glsLifetimeTests.Type);
+
+glsLifetimeTests.SimpleType.prototype.gen = function() { return this.m_genFunc.call(gl); };
+
+glsLifetimeTests.SimpleType.prototype.release = function(obj) { return this.m_deleteFunc.call(gl, obj); };
+
+glsLifetimeTests.SimpleType.prototype.exists = function(obj) { return this.m_existsFunc.call(gl, obj); };
+
+glsLifetimeTests.SimpleType.prototype.binder = function() { return this.m_binder; };
+
+glsLifetimeTests.SimpleType.prototype.getName = function() { return this.m_getName; };
+
+glsLifetimeTests.SimpleType.prototype.genCreates = function() { return this.m_genCreates; };
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Type}
+ */
+glsLifetimeTests.ProgramType = function() {
+ glsLifetimeTests.Type.call(this);
+};
+
+setParentClass(glsLifetimeTests.ProgramType, glsLifetimeTests.Type);
+
+glsLifetimeTests.ProgramType.prototype.gen = function() { return gl.createProgram(); };
+
+glsLifetimeTests.ProgramType.prototype.release = function(obj) { return gl.deleteProgram(/** @type {WebGLProgram} */ (obj)); };
+
+glsLifetimeTests.ProgramType.prototype.exists = function(obj) { return gl.isProgram(/** @type {WebGLProgram} */ (obj)); };
+
+glsLifetimeTests.ProgramType.prototype.getName = function() { return 'program'; };
+
+glsLifetimeTests.ProgramType.prototype.genCreates = function() { return true; };
+
+glsLifetimeTests.ProgramType.prototype.nameLingers = function() { return true; };
+
+glsLifetimeTests.ProgramType.prototype.isDeleteFlagged = function(obj) { return gl.getProgramParameter(/** @type {WebGLProgram} */ (obj), gl.DELETE_STATUS); };
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Type}
+ */
+glsLifetimeTests.ShaderType = function() {
+ glsLifetimeTests.Type.call(this);
+};
+
+setParentClass(glsLifetimeTests.ShaderType, glsLifetimeTests.Type);
+
+glsLifetimeTests.ShaderType.prototype.gen = function() { return gl.createShader(gl.FRAGMENT_SHADER); };
+
+glsLifetimeTests.ShaderType.prototype.release = function(obj) { return gl.deleteShader(/** @type {WebGLShader} */ (obj)); };
+
+glsLifetimeTests.ShaderType.prototype.exists = function(obj) { return gl.isShader(/** @type {WebGLShader} */ (obj)); };
+
+glsLifetimeTests.ShaderType.prototype.getName = function() { return 'shader'; };
+
+glsLifetimeTests.ShaderType.prototype.genCreates = function() { return true; };
+
+glsLifetimeTests.ShaderType.prototype.nameLingers = function() { return true; };
+
+glsLifetimeTests.ShaderType.prototype.isDeleteFlagged = function(obj) { return gl.getShaderParameter(/** @type {WebGLShader} */ (obj), gl.DELETE_STATUS); };
+
+/**
+ * @constructor
+ * @param {glsLifetimeTests.Type} elementType
+ * @param {glsLifetimeTests.Type} containerType
+ */
+glsLifetimeTests.Attacher = function(elementType, containerType) {
+ this.m_elementType = elementType;
+ this.m_containerType = containerType;
+};
+
+/**
+ * @param {number} seed
+ * @param {WebGLObject} obj
+ */
+glsLifetimeTests.Attacher.prototype.initAttachment = function(seed, obj) { throw new Error('Virtual function'); };
+
+/**
+ * @param {WebGLObject} element
+ * @param {WebGLObject} target
+ */
+glsLifetimeTests.Attacher.prototype.attach = function(element, target) { throw new Error('Virtual function'); };
+
+/**
+ * @param {WebGLObject} element
+ * @param {WebGLObject} target
+ */
+glsLifetimeTests.Attacher.prototype.detach = function(element, target) { throw new Error('Virtual function'); };
+glsLifetimeTests.Attacher.prototype.canAttachDeleted = function() { return true; };
+
+/**
+ * @return {glsLifetimeTests.Type}
+ */
+glsLifetimeTests.Attacher.prototype.getElementType = function() { return this.m_elementType; };
+
+/**
+ * @return {glsLifetimeTests.Type}
+ */
+glsLifetimeTests.Attacher.prototype.getContainerType = function() { return this.m_containerType; };
+
+/**
+ * @constructor
+ */
+glsLifetimeTests.InputAttacher = function(attacher) {
+ this.m_attacher = attacher;
+};
+
+glsLifetimeTests.InputAttacher.prototype.getAttacher = function() { return this.m_attacher; };
+
+/**
+ * @param {WebGLObject} container
+ * @param {tcuSurface.Surface} dst
+ */
+glsLifetimeTests.InputAttacher.prototype.drawContainer = function(container, dst) { throw new Error('Virtual function'); };
+
+/**
+ * @constructor
+ */
+glsLifetimeTests.OutputAttacher = function(attacher) {
+ this.m_attacher = attacher;
+};
+
+glsLifetimeTests.OutputAttacher.prototype.getAttacher = function() { return this.m_attacher; };
+
+/**
+ * @param {number} seed
+ * @param {WebGLObject} container
+ */
+glsLifetimeTests.OutputAttacher.prototype.setupContainer = function(seed, container) { throw new Error('Virtual function'); };
+
+/**
+ * @param {WebGLObject} attachment
+ * @param {tcuSurface.Surface} dst
+ */
+glsLifetimeTests.OutputAttacher.prototype.drawAttachment = function(attachment, dst) { throw new Error('Virtual function'); };
+
+/**
+ * @constructor
+ */
+glsLifetimeTests.Types = function() {
+ /** @type {Array<glsLifetimeTests.Type>} */ this.m_types = [];
+ /** @type {Array<glsLifetimeTests.Attacher>} */ this.m_attachers = [];
+ /** @type {Array<glsLifetimeTests.InputAttacher>} */ this.m_inAttachers = [];
+ /** @type {Array<glsLifetimeTests.OutputAttacher>} */ this.m_outAttachers = [];
+};
+
+/**
+ * @return {glsLifetimeTests.ProgramType}
+ */
+glsLifetimeTests.Types.prototype.getProgramType = function() { throw new Error('Virtual function'); };
+
+glsLifetimeTests.Types.prototype.getTypes = function() { return this.m_types; };
+
+glsLifetimeTests.Types.prototype.getAttachers = function() { return this.m_attachers; };
+
+glsLifetimeTests.Types.prototype.getInputAttachers = function() { return this.m_inAttachers; };
+
+glsLifetimeTests.Types.prototype.getOutputAttachers = function() { return this.m_outAttachers; };
+
+/**
+ * @param {number} seed
+ * @param {WebGLFramebuffer} fbo
+ */
+glsLifetimeTests.setupFbo = function(seed, fbo) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ if (seed == 0) {
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ } else {
+ var rnd = new deRandom.Random(seed);
+ var width = rnd.getInt(0, FRAMEBUFFER_SIZE);
+ var height = rnd.getInt(0, FRAMEBUFFER_SIZE);
+ var x = rnd.getInt(0, FRAMEBUFFER_SIZE - width);
+ var y = rnd.getInt(0, FRAMEBUFFER_SIZE - height);
+ var r1 = rnd.getFloat();
+ var g1 = rnd.getFloat();
+ var b1 = rnd.getFloat();
+ var a1 = rnd.getFloat();
+ var r2 = rnd.getFloat();
+ var g2 = rnd.getFloat();
+ var b2 = rnd.getFloat();
+ var a2 = rnd.getFloat();
+
+ gl.clearColor(r1, g1, b1, a1);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.scissor(x, y, width, height);
+ gl.enable(gl.SCISSOR_TEST);
+ gl.clearColor(r2, g2, b2, a2);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.disable(gl.SCISSOR_TEST);
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+};
+
+/**
+ * @param {{x: number, y:number, width: number, height: number}} rect
+ * @param {tcuSurface.Surface} dst
+ */
+glsLifetimeTests.readRectangle = function(rect, dst) {
+ dst.readViewport(gl, rect);
+};
+
+/**
+ * @param {WebGLFramebuffer} fbo
+ * @param {tcuSurface.Surface} dst
+ */
+glsLifetimeTests.drawFbo = function(fbo, dst) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ dst.readViewport(gl, [0, 0, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE]);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Attacher}
+ */
+glsLifetimeTests.FboAttacher = function(elementType, containerType) {
+ glsLifetimeTests.Attacher.call(this, elementType, containerType);
+};
+
+setParentClass(glsLifetimeTests.FboAttacher, glsLifetimeTests.Attacher);
+
+glsLifetimeTests.FboAttacher.prototype.initStorage = function() { throw new Error('Virtual function'); };
+
+glsLifetimeTests.FboAttacher.prototype.initAttachment = function(seed, element) {
+ var binder = this.getElementType().binder();
+ var fbo = gl.createFramebuffer();
+
+ binder.bind(element);
+ this.initStorage();
+ binder.bind(null);
+
+ this.attach(element, fbo);
+ glsLifetimeTests.setupFbo(seed, fbo);
+ this.detach(element, fbo);
+
+ gl.deleteFramebuffer(fbo);
+
+ bufferedLogToConsole('Drew to ' + this.getElementType().getName() + ' ' + element + ' with seed ' + seed + '.');
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.InputAttacher}
+ */
+glsLifetimeTests.FboInputAttacher = function(attacher) {
+ glsLifetimeTests.InputAttacher.call(this, attacher);
+};
+
+setParentClass(glsLifetimeTests.FboInputAttacher, glsLifetimeTests.InputAttacher);
+
+glsLifetimeTests.FboInputAttacher.prototype.drawContainer = function(obj, dst) {
+ var fbo = /** @type {WebGLFramebuffer} */ (obj);
+ glsLifetimeTests.drawFbo(fbo, dst);
+ bufferedLogToConsole('Read pixels from framebuffer ' + fbo + ' to output image.');
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.OutputAttacher}
+ */
+glsLifetimeTests.FboOutputAttacher = function(attacher) {
+ glsLifetimeTests.OutputAttacher.call(this, attacher);
+};
+
+setParentClass(glsLifetimeTests.FboOutputAttacher, glsLifetimeTests.OutputAttacher);
+
+glsLifetimeTests.FboOutputAttacher.prototype.setupContainer = function(seed, fbo) {
+ glsLifetimeTests.setupFbo(seed, /** @type {WebGLFramebuffer} */ (fbo));
+ bufferedLogToConsole('Drew to framebuffer ' + fbo + ' with seed ' + seed + '.');
+};
+
+glsLifetimeTests.FboOutputAttacher.prototype.drawAttachment = function(element, dst) {
+ var fbo = gl.createFramebuffer();
+ this.m_attacher.attach(element, fbo);
+ glsLifetimeTests.drawFbo(fbo, dst);
+ this.m_attacher.detach(element, fbo);
+ gl.deleteFramebuffer(fbo);
+ bufferedLogToConsole('Read pixels from ' + this.m_attacher.getElementType().getName() + ' ' + element + ' to output image.');
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.FboAttacher}
+ */
+glsLifetimeTests.TextureFboAttacher = function(elementType, containerType) {
+ glsLifetimeTests.FboAttacher.call(this, elementType, containerType);
+};
+
+setParentClass(glsLifetimeTests.TextureFboAttacher, glsLifetimeTests.FboAttacher);
+
+glsLifetimeTests.TextureFboAttacher.prototype.initStorage = function() {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
+ gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, null);
+
+};
+
+glsLifetimeTests.TextureFboAttacher.prototype.attach = function(element, target) {
+ var texture = /** @type {WebGLTexture} */ (element);
+ var fbo = /** @type {WebGLFramebuffer} */ (target);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D, texture, 0);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+};
+
+glsLifetimeTests.TextureFboAttacher.prototype.detach = function(texture, target) {
+ var fbo = /** @type {WebGLFramebuffer} */ (target);
+ this.attach(null, fbo);
+};
+
+glsLifetimeTests.getFboAttachment = function(fbo, requiredType) {
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ var type = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ var name = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ var ret = type == requiredType ? name : null;
+ return ret;
+};
+
+glsLifetimeTests.TextureFboAttacher.prototype.getAttachment = function(fbo) {
+ return glsLifetimeTests.getFboAttachment(fbo, gl.TEXTURE);
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.FboAttacher}
+ */
+glsLifetimeTests.RboFboAttacher = function(elementType, containerType) {
+ glsLifetimeTests.FboAttacher.call(this, elementType, containerType);
+};
+
+setParentClass(glsLifetimeTests.RboFboAttacher, glsLifetimeTests.FboAttacher);
+
+glsLifetimeTests.RboFboAttacher.prototype.initStorage = function() {
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE);
+
+};
+
+glsLifetimeTests.RboFboAttacher.prototype.attach = function(element, target) {
+ var rbo = /** @type {WebGLRenderbuffer} */ (element);
+ var fbo = /** @type {WebGLFramebuffer} */ (target);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+};
+
+glsLifetimeTests.RboFboAttacher.prototype.detach = function(rbo, target) {
+ var fbo = /** @type {WebGLFramebuffer} */ (target);
+ this.attach(null, fbo);
+};
+
+glsLifetimeTests.RboFboAttacher.prototype.getAttachment = function(fbo) {
+ return glsLifetimeTests.getFboAttachment(fbo, gl.RENDERBUFFER);
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Attacher}
+ */
+glsLifetimeTests.ShaderProgramAttacher = function(elementType, containerType) {
+ glsLifetimeTests.Attacher.call(this, elementType, containerType);
+};
+
+setParentClass(glsLifetimeTests.ShaderProgramAttacher, glsLifetimeTests.Attacher);
+
+glsLifetimeTests.ShaderProgramAttacher.prototype.initAttachment = function(seed, obj) {
+ var shader = /** @type {WebGLShader} */ (obj);
+ var s_fragmentShaderTemplate =
+ '#version 100\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_FragColor = vec4(${RED}, ${GREEN}, ${BLUE}, 1.0);\n' +
+ '}';
+
+ var rnd = new deRandom.Random(seed);
+ var params = [];
+ params['RED'] = rnd.getFloat().toString(10);
+ params['GREEN'] = rnd.getFloat().toString(10);
+ params['BLUE'] = rnd.getFloat().toString(10);
+
+ var source = tcuStringTemplate.specialize(s_fragmentShaderTemplate, params);
+ gl.shaderSource(shader, source);
+ gl.compileShader(shader);
+ var compileStatus = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
+ assertMsgOptions(compileStatus === true, 'Failed to compile shader: ' + source, false, true);
+};
+
+glsLifetimeTests.ShaderProgramAttacher.prototype.attach = function(element, target) {
+ var shader = /** @type {WebGLShader} */ (element);
+ var program = /** @type {WebGLProgram} */ (target);
+ gl.attachShader(program, shader);
+};
+
+glsLifetimeTests.ShaderProgramAttacher.prototype.detach = function(element, target) {
+ var shader = /** @type {WebGLShader} */ (element);
+ var program = /** @type {WebGLProgram} */ (target);
+ gl.detachShader(program, shader);
+};
+
+glsLifetimeTests.ShaderProgramAttacher.prototype.getAttachment = function(program) {
+ var shaders = gl.getAttachedShaders(program);
+ for (var i = 0; i < shaders.length; i++) {
+ var shader = shaders[i];
+ var type = gl.getShaderParameter(shader, gl.SHADER_TYPE);
+ if (type === gl.FRAGMENT_SHADER)
+ return shader;
+ }
+ return null;
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.InputAttacher}
+ */
+glsLifetimeTests.ShaderProgramInputAttacher = function(attacher) {
+ glsLifetimeTests.InputAttacher.call(this, attacher);
+};
+
+setParentClass(glsLifetimeTests.ShaderProgramInputAttacher, glsLifetimeTests.InputAttacher);
+
+glsLifetimeTests.ShaderProgramInputAttacher.prototype.drawContainer = function(container, dst) {
+ var program = /** @type {WebGLProgram} */ (container);
+ var s_vertices = [-1.0, 0.0, 1.0, 1.0, 0.0, -1.0];
+ glsLifetimeTests.ShaderProgramInputAttacher.seed = glsLifetimeTests.ShaderProgramInputAttacher.seed || 0;
+ var vtxShader = new glsLifetimeTests.CheckedShader(gluShaderProgram.shaderType.VERTEX, s_vertexShaderSrc);
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), VIEWPORT_SIZE, VIEWPORT_SIZE, glsLifetimeTests.ShaderProgramInputAttacher.seed);
+
+ gl.attachShader(program, vtxShader.getShader());
+ gl.linkProgram(program);
+
+ var linkStatus = gl.getProgramParameter(program, gl.LINK_STATUS);
+ assertMsgOptions(linkStatus === true, 'Program link failed', false, true);
+
+ bufferedLogToConsole('Attached a temporary vertex shader and linked program ' + program);
+
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ bufferedLogToConsole('Positioned viewport randomly');
+
+ gl.useProgram(program);
+
+ var posLoc = gl.getAttribLocation(program, 'pos');
+ assertMsgOptions(posLoc >= 0, 'Could not find pos attribute', false, true);
+
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(s_vertices), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(posLoc);
+ gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ gl.clearColor(0, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ gl.disableVertexAttribArray(posLoc);
+ gl.deleteBuffer(buf);
+ bufferedLogToConsole('Drew a fixed triangle');
+
+ gl.useProgram(null);
+
+ glsLifetimeTests.readRectangle(viewport, dst);
+ bufferedLogToConsole('Copied viewport to output image');
+
+ gl.detachShader(program, vtxShader.getShader());
+ bufferedLogToConsole('Removed temporary vertex shader');
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Types}
+ */
+glsLifetimeTests.ES2Types = function() {
+ glsLifetimeTests.Types.call(this);
+ this.m_bufferBind = new glsLifetimeTests.SimpleBinder(gl.bindBuffer, gl.ARRAY_BUFFER, gl.ARRAY_BUFFER_BINDING);
+ this.m_bufferType = new glsLifetimeTests.SimpleType('buffer', gl.createBuffer, gl.deleteBuffer, gl.isBuffer, this.m_bufferBind);
+ this.m_textureBind = new glsLifetimeTests.SimpleBinder(gl.bindTexture, gl.TEXTURE_2D, gl.TEXTURE_BINDING_2D);
+ this.m_textureType = new glsLifetimeTests.SimpleType('texture', gl.createTexture, gl.deleteTexture, gl.isTexture, this.m_textureBind);
+ this.m_rboBind = new glsLifetimeTests.SimpleBinder(gl.bindRenderbuffer, gl.RENDERBUFFER, gl.RENDERBUFFER_BINDING);
+ this.m_rboType = new glsLifetimeTests.SimpleType('renderbuffer', gl.createRenderbuffer, gl.deleteRenderbuffer, gl.isRenderbuffer, this.m_rboBind);
+ this.m_fboBind = new glsLifetimeTests.SimpleBinder(gl.bindFramebuffer, gl.FRAMEBUFFER, gl.FRAMEBUFFER_BINDING);
+ this.m_fboType = new glsLifetimeTests.SimpleType('framebuffer', gl.createFramebuffer, gl.deleteFramebuffer, gl.isFramebuffer, this.m_fboBind);
+ this.m_shaderType = new glsLifetimeTests.ShaderType();
+ this.m_programType = new glsLifetimeTests.ProgramType();
+ this.m_texFboAtt = new glsLifetimeTests.TextureFboAttacher(this.m_textureType, this.m_fboType);
+ this.m_texFboInAtt = new glsLifetimeTests.FboInputAttacher(this.m_texFboAtt);
+ this.m_texFboOutAtt = new glsLifetimeTests.FboOutputAttacher(this.m_texFboAtt);
+ this.m_rboFboAtt = new glsLifetimeTests.RboFboAttacher(this.m_rboType, this.m_fboType);
+ this.m_rboFboInAtt = new glsLifetimeTests.FboInputAttacher(this.m_rboFboAtt);
+ this.m_rboFboOutAtt = new glsLifetimeTests.FboOutputAttacher(this.m_rboFboAtt);
+ this.m_shaderAtt = new glsLifetimeTests.ShaderProgramAttacher(this.m_shaderType, this.m_programType);
+ this.m_shaderInAtt = new glsLifetimeTests.ShaderProgramInputAttacher(this.m_shaderAtt);
+
+ this.m_types.push(this.m_bufferType, this.m_textureType, this.m_rboType, this.m_fboType, this.m_shaderType, this.m_programType);
+ this.m_attachers.push(this.m_texFboAtt, this.m_rboFboAtt, this.m_shaderAtt);
+ this.m_inAttachers.push(this.m_texFboInAtt, this.m_rboFboInAtt, this.m_shaderInAtt);
+ this.m_outAttachers.push(this.m_texFboOutAtt, this.m_rboFboOutAtt);
+};
+
+setParentClass(glsLifetimeTests.ES2Types, glsLifetimeTests.Types);
+
+glsLifetimeTests.ES2Types.prototype.getProgramType = function() { return this.m_programType; };
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {glsLifetimeTests.Type} type
+ * @param {function()} test
+ */
+glsLifetimeTests.LifeTest = function(name, description, type, test) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ this.m_type = type;
+ this.m_test = test;
+};
+
+setParentClass(glsLifetimeTests.LifeTest, tcuTestCase.DeqpTest);
+
+glsLifetimeTests.LifeTest.prototype.iterate = function() {
+ this.m_test();
+ return tcuTestCase.IterateResult.STOP;
+};
+
+/**
+ * @this {glsLifetimeTests.LifeTest}
+ */
+glsLifetimeTests.LifeTest.testGen = function() {
+ var obj = this.m_type.gen();
+ if (this.m_type.genCreates())
+ assertMsgOptions(this.m_type.exists(obj), "create* should have created an object, but didn't", false, true);
+ else
+ assertMsgOptions(!this.m_type.exists(obj), 'create* should not have created an object, but did', false, true);
+ this.m_type.release(obj);
+ testPassed();
+};
+
+/**
+ * @this {glsLifetimeTests.LifeTest}
+ */
+glsLifetimeTests.LifeTest.testDelete = function() {
+ var obj = this.m_type.gen();
+ this.m_type.release(obj);
+ assertMsgOptions(!this.m_type.exists(obj), 'Object still exists after deletion', false, true);
+ testPassed();
+};
+
+/**
+ * @this {glsLifetimeTests.LifeTest}
+ */
+glsLifetimeTests.LifeTest.testBind = function() {
+ var obj = this.m_type.gen();
+ this.m_type.binder().bind(obj);
+ var err = gl.getError();
+ assertMsgOptions(err == gl.NONE, 'Bind failed', false, true);
+ assertMsgOptions(this.m_type.exists(obj), 'Object does not exist after binding', false, true);
+ this.m_type.binder().bind(null);
+ this.m_type.release(obj);
+ testPassed();
+};
+
+/**
+ * @this {glsLifetimeTests.LifeTest}
+ */
+glsLifetimeTests.LifeTest.testDeleteBound = function() {
+ var obj = this.m_type.gen();
+ this.m_type.binder().bind(obj);
+ this.m_type.release(obj);
+ if (this.m_type.nameLingers()) {
+ assertMsgOptions(gl.getError() == gl.NONE, 'Deleting bound object failed', false, true);
+ assertMsgOptions(this.m_type.binder().getBinding() === obj, 'Deleting bound object did not retain binding', false, true);
+ assertMsgOptions(this.m_type.exists(obj), 'Deleting bound object made its name invalid', false, true);
+ assertMsgOptions(this.m_type.isDeleteFlagged(obj), 'Deleting bound object did not flag the object for deletion', false, true);
+ this.m_type.binder().bind(null);
+ } else {
+ assertMsgOptions(gl.getError() == gl.NONE, 'Deleting bound object failed', false, true);
+ assertMsgOptions(this.m_type.binder().getBinding() === null, 'Deleting bound object did not remove binding', false, true);
+ assertMsgOptions(!this.m_type.exists(obj), 'Deleting bound object did not make its name invalid', false, true);
+ }
+ assertMsgOptions(this.m_type.binder().getBinding() === null, "Unbinding didn't remove binding", false, true);
+ assertMsgOptions(!this.m_type.exists(obj), 'Name is still valid after deleting and unbinding', false, true);
+ testPassed();
+};
+
+/**
+ * @this {glsLifetimeTests.LifeTest}
+ */
+glsLifetimeTests.LifeTest.testDeleteUsed = function() {
+ var vtxShader = new glsLifetimeTests.CheckedShader(gluShaderProgram.shaderType.VERTEX, s_vertexShaderSrc);
+ var fragShader = new glsLifetimeTests.CheckedShader(gluShaderProgram.shaderType.FRAGMENT, s_fragmentShaderSrc);
+ var program = new glsLifetimeTests.CheckedProgram(vtxShader.getShader(), fragShader.getShader());
+ var programId = program.getProgram();
+ bufferedLogToConsole('Created and linked program ' + programId);
+ gl.useProgram(programId);
+
+ gl.deleteProgram(programId);
+ bufferedLogToConsole('Deleted program ' + programId);
+ assertMsgOptions(gl.isProgram(programId), 'Deleted current program', false, true);
+ var deleteFlagged = gl.getProgramParameter(programId, gl.DELETE_STATUS);
+ assertMsgOptions(deleteFlagged == true, 'Program object was not flagged as deleted', false, true);
+ gl.useProgram(null);
+ assertMsgOptions(!gl.isProgram(programId), 'Deleted program name still valid after being made non-current', false, true);
+ testPassed();
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {glsLifetimeTests.Attacher} attacher
+ * @param {function()} test
+ */
+glsLifetimeTests.AttachmentTest = function(name, description, attacher, test) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ this.m_attacher = attacher;
+ this.m_test = test;
+};
+
+setParentClass(glsLifetimeTests.AttachmentTest, tcuTestCase.DeqpTest);
+
+glsLifetimeTests.AttachmentTest.prototype.iterate = function() {
+ this.m_test();
+ return tcuTestCase.IterateResult.STOP;
+};
+
+/**
+ * @this {glsLifetimeTests.AttachmentTest}
+ */
+glsLifetimeTests.AttachmentTest.testDeletedNames = function() {
+ var getAttachment = function(attacher, container) {
+ var queriedAttachment = attacher.getAttachment(container);
+ bufferedLogToConsole('Result of query for ' + attacher.getElementType().getName() +
+ ' attached to ' + attacher.getContainerType().getName() + ' ' +
+ container + ': ' + queriedAttachment);
+ return queriedAttachment;
+ };
+
+ var elemType = this.m_attacher.getElementType();
+ var containerType = this.m_attacher.getContainerType();
+ var container = containerType.gen();
+
+ var element = elemType.gen();
+ this.m_attacher.initAttachment(0, element);
+ this.m_attacher.attach(element, container);
+ assertMsgOptions(getAttachment(this.m_attacher, container) == element,
+ 'Attachment not returned by query even before deletion.', false, true);
+
+ elemType.release(element);
+ // "Such a container or other context may continue using the object, and
+ // may still contain state identifying its name as being currently bound"
+ //
+ // We here interpret "may" to mean that whenever the container has a
+ // deleted object attached to it, a query will return that object's former
+ // name.
+ assertMsgOptions(getAttachment(this.m_attacher, container) == element,
+ 'Attachment name not returned by query after attachment was deleted.', false, true);
+
+ if (elemType.nameLingers())
+ assertMsgOptions(elemType.exists(element),
+ 'Attached object name no longer valid after deletion.', false, true);
+ else
+ assertMsgOptions(!elemType.exists(element),
+ 'Attached object name still valid after deletion.', false, true);
+
+ this.m_attacher.detach(element, container);
+ assertMsgOptions(getAttachment(this.m_attacher, container) == null,
+ 'Attachment name returned by query even after detachment.', false, true);
+ assertMsgOptions(!elemType.exists(element),
+ 'Deleted attached object name still usable after detachment.', false, true);
+ testPassed();
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {glsLifetimeTests.InputAttacher} attacher
+ */
+glsLifetimeTests.InputAttachmentTest = function(name, description, attacher) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ this.m_inputAttacher = attacher;
+};
+
+setParentClass(glsLifetimeTests.InputAttachmentTest, tcuTestCase.DeqpTest);
+
+glsLifetimeTests.InputAttachmentTest.prototype.iterate = function() {
+ var attacher = this.m_inputAttacher.getAttacher();
+ var containerType = attacher.getContainerType();
+ var elementType = attacher.getElementType();
+ var container = containerType.gen();
+
+ glsLifetimeTests.InputAttachmentTest.seed = glsLifetimeTests.InputAttachmentTest.seed || 0;
+ ++glsLifetimeTests.InputAttachmentTest.seed;
+ var rnd = new deRandom.Random(glsLifetimeTests.InputAttachmentTest.seed);
+ var refSeed = rnd.getInt();
+ var newSeed = rnd.getInt();
+
+ var refSurface = new tcuSurface.Surface(VIEWPORT_SIZE, VIEWPORT_SIZE); // Surface from drawing with refSeed-seeded attachment
+ var delSurface = new tcuSurface.Surface(VIEWPORT_SIZE, VIEWPORT_SIZE); // Surface from drawing with deleted refSeed attachment
+ var newSurface = new tcuSurface.Surface(VIEWPORT_SIZE, VIEWPORT_SIZE); // Surface from drawing with newSeed-seeded attachment
+
+ bufferedLogToConsole('Testing if writing to a newly created object modifies a deleted attachment');
+
+ bufferedLogToConsole('Writing to an original attachment');
+ var element = elementType.gen();
+
+ attacher.initAttachment(refSeed, element);
+ attacher.attach(element, container);
+ this.m_inputAttacher.drawContainer(container, refSurface);
+ // element gets deleted here
+ bufferedLogToConsole('Deleting attachment');
+ elementType.release(element);
+
+ bufferedLogToConsole('Writing to a new attachment after deleting the original');
+ var newElement = elementType.gen();
+
+ attacher.initAttachment(newSeed, newElement);
+
+ this.m_inputAttacher.drawContainer(container, delSurface);
+ attacher.detach(element, container);
+
+ attacher.attach(newElement, container);
+ this.m_inputAttacher.drawContainer(container, newSurface);
+ attacher.detach(newElement, container);
+ var surfacesMatch = tcuImageCompare.pixelThresholdCompare(
+ 'Reading from deleted',
+ 'Comparison result from reading from a container with a deleted attachment ' +
+ 'before and after writing to a fresh object.',
+ refSurface, delSurface, [0, 0, 0, 0]);
+
+ /* TODO: Add logging images */
+ // if (!surfacesMatch)
+ // log() << TestLog::Image("New attachment",
+ // "Container state after attached to the fresh object",
+ // newSurface);
+
+ assertMsgOptions(surfacesMatch,
+ 'Writing to a fresh object modified the container with a deleted attachment.', false, true);
+
+ testPassed();
+ return tcuTestCase.IterateResult.STOP;
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {glsLifetimeTests.OutputAttacher} attacher
+ */
+glsLifetimeTests.OutputAttachmentTest = function(name, description, attacher) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ this.m_outputAttacher = attacher;
+};
+
+setParentClass(glsLifetimeTests.OutputAttachmentTest, tcuTestCase.DeqpTest);
+
+glsLifetimeTests.OutputAttachmentTest.prototype.iterate = function() {
+ var attacher = this.m_outputAttacher.getAttacher();
+ var containerType = attacher.getContainerType();
+ var elementType = attacher.getElementType();
+ var container = containerType.gen();
+ glsLifetimeTests.InputAttachmentTest.seed = glsLifetimeTests.InputAttachmentTest.seed || 0;
+ ++glsLifetimeTests.InputAttachmentTest.seed;
+ var rnd = new deRandom.Random(glsLifetimeTests.InputAttachmentTest.seed);
+ var refSeed = rnd.getInt();
+ var newSeed = rnd.getInt();
+
+ var refSurface = new tcuSurface.Surface(VIEWPORT_SIZE, VIEWPORT_SIZE); // Surface from drawing with refSeed-seeded attachment
+ var delSurface = new tcuSurface.Surface(VIEWPORT_SIZE, VIEWPORT_SIZE); // Surface from drawing with deleted refSeed attachment
+ var newSurface = new tcuSurface.Surface(VIEWPORT_SIZE, VIEWPORT_SIZE); // Surface from drawing with newSeed-seeded attachment
+
+ bufferedLogToConsole('Testing if writing to a container with a deleted attachment ' +
+ 'modifies a newly created object');
+
+ bufferedLogToConsole('Writing to a container with an existing attachment');
+ var element = elementType.gen();
+
+ attacher.initAttachment(0, element);
+ attacher.attach(element, container);
+
+ // For reference purposes, make note of what refSeed looks like.
+ this.m_outputAttacher.setupContainer(refSeed, container);
+ // Since in WebGL, buffer bound to TRANSFORM_FEEDBACK_BUFFER can not be bound to other targets.
+ // Unfortunately, element will be bound again in drawAttachment() for drawing.
+ // Detach element from container before drawing, then reattach it after drawing.
+ attacher.detach(element, container);
+ this.m_outputAttacher.drawAttachment(element, refSurface);
+ attacher.attach(element, container);
+ elementType.release(element);
+
+ bufferedLogToConsole('Writing to a container after deletion of attachment');
+ var newElement = elementType.gen();
+ bufferedLogToConsole('Creating a new object ');
+
+ bufferedLogToConsole('Recording state of new object before writing to container');
+ attacher.initAttachment(newSeed, newElement);
+ this.m_outputAttacher.drawAttachment(newElement, newSurface);
+
+ bufferedLogToConsole('Writing to container');
+
+ // Now re-write refSeed to the container.
+ this.m_outputAttacher.setupContainer(refSeed, container);
+ // Does it affect the newly created attachment object?
+ this.m_outputAttacher.drawAttachment(newElement, delSurface);
+ attacher.detach(element, container);
+
+ var surfacesMatch = tcuImageCompare.pixelThresholdCompare(
+ 'Writing to deleted',
+ 'Comparison result from reading from a fresh object before and after ' +
+ 'writing to a container with a deleted attachment',
+ newSurface, delSurface, [0, 0, 0, 0]);
+
+ /* TODO: Add logging images */
+ // if (!surfacesMatch)
+ // log() << TestLog::Image(
+ // "Original attachment",
+ // "Result of container modification on original attachment before deletion.",
+ // refSurface);
+
+ assertMsgOptions(surfacesMatch,
+ 'Writing to container with deleted attachment modified a new object.', false, true);
+
+ testPassed();
+ return tcuTestCase.IterateResult.STOP;
+};
+
+glsLifetimeTests.createLifeTestGroup = function(spec, types) {
+ var group = tcuTestCase.newTest(spec.name, spec.name);
+
+ for (var i = 0; i < types.length; i++) {
+ var type = types[i];
+ var name = type.getName();
+ if (!spec.needBind || type.binder() != null)
+ group.addChild(new glsLifetimeTests.LifeTest(name, name, type, spec.func));
+ }
+
+ return group;
+};
+
+/**
+ * @param {tcuTestCase.DeqpTest} group
+ * @param {glsLifetimeTests.Types} types
+ */
+glsLifetimeTests.addTestCases = function(group, types) {
+ var attacherName = function(attacher) {
+ return attacher.getElementType().getName() + '_' + attacher.getContainerType().getName();
+ };
+
+ var s_lifeTests = [
+ /* Create */ { name: 'gen', func: glsLifetimeTests.LifeTest.testGen, needBind: false },
+ /* Delete */ { name: 'delete', func: glsLifetimeTests.LifeTest.testDelete, needBind: false },
+ /* Bind */ { name: 'bind', func: glsLifetimeTests.LifeTest.testBind, needBind: true },
+ /* Delete bound */ { name: 'delete_bound', func: glsLifetimeTests.LifeTest.testDeleteBound, needBind: true }
+ ];
+
+ s_lifeTests.forEach(function(spec) {
+ group.addChild(glsLifetimeTests.createLifeTestGroup(spec, types.getTypes()));
+ });
+
+ var delUsedGroup = tcuTestCase.newTest('delete_used', 'Delete current program');
+ group.addChild(delUsedGroup);
+
+ delUsedGroup.addChild(new glsLifetimeTests.LifeTest('program', 'program', types.getProgramType(),
+ glsLifetimeTests.LifeTest.testDeleteUsed));
+
+ var attGroup = tcuTestCase.newTest('attach', 'Attachment tests');
+ group.addChild(attGroup);
+
+ var nameGroup = tcuTestCase.newTest('deleted_name', 'Name of deleted attachment');
+ attGroup.addChild(nameGroup);
+
+ var atts = types.getAttachers();
+ for (var i = 0; i < atts.length; i++) {
+ var att = atts[i];
+ var name = attacherName(att);
+ nameGroup.addChild(new glsLifetimeTests.AttachmentTest(name, name, att,
+ glsLifetimeTests.AttachmentTest.testDeletedNames));
+ }
+
+ var inputGroup = tcuTestCase.newTest('deleted_input', 'Input from deleted attachment');
+ attGroup.addChild(inputGroup);
+
+ var inAtts = types.getInputAttachers();
+ for (var i = 0; i < inAtts.length; i++) {
+ var att = inAtts[i];
+ var name = attacherName(att.getAttacher());
+ inputGroup.addChild(new glsLifetimeTests.InputAttachmentTest(name, name, att));
+ }
+
+ var outputGroup = tcuTestCase.newTest('deleted_output', 'Output to deleted attachment');
+ attGroup.addChild(outputGroup);
+
+ var outAtts = types.getOutputAttachers();
+ for (var i = 0; i < outAtts.length; i++) {
+ var att = outAtts[i];
+ var name = attacherName(att.getAttacher());
+ outputGroup.addChild(new glsLifetimeTests.OutputAttachmentTest(name, name, att));
+ }
+
+};
+
+});