Generify tests for MPImage
PiperOrigin-RevId: 527611864
This commit is contained in:
parent
bc3434108e
commit
b457060c3a
|
@ -29,43 +29,64 @@ if (skip) {
|
||||||
/** The image types supported by MPImage. */
|
/** The image types supported by MPImage. */
|
||||||
type ImageType = ImageData|ImageBitmap|WebGLTexture;
|
type ImageType = ImageData|ImageBitmap|WebGLTexture;
|
||||||
|
|
||||||
async function createTestData(
|
const IMAGE_2_2 = [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255];
|
||||||
gl: WebGL2RenderingContext, data: number[], width: number,
|
const IMAGE_2_1 = [1, 0, 0, 255, 2, 0, 0, 255];
|
||||||
height: number): Promise<[ImageData, ImageBitmap, WebGLTexture]> {
|
const IMAGE_2_3 = [
|
||||||
const imageData = new ImageData(new Uint8ClampedArray(data), width, height);
|
1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255,
|
||||||
const imageBitmap = await createImageBitmap(imageData);
|
4, 0, 0, 255, 5, 0, 0, 255, 6, 0, 0, 255
|
||||||
const webGlTexture = gl.createTexture()!;
|
];
|
||||||
|
|
||||||
gl.bindTexture(gl.TEXTURE_2D, webGlTexture);
|
/** The test images and data to use for the unit tests below. */
|
||||||
gl.texImage2D(
|
class MPImageTestContext {
|
||||||
gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageBitmap);
|
canvas!: OffscreenCanvas;
|
||||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
gl!: WebGL2RenderingContext;
|
||||||
|
imageData!: ImageData;
|
||||||
|
imageBitmap!: ImageBitmap;
|
||||||
|
webGLTexture!: WebGLTexture;
|
||||||
|
|
||||||
return [imageData, imageBitmap, webGlTexture];
|
async init(pixels = IMAGE_2_2, width = WIDTH, height = HEIGHT):
|
||||||
|
Promise<void> {
|
||||||
|
// Initialize a canvas with default dimensions. Note that the canvas size
|
||||||
|
// can be different from the image size.
|
||||||
|
this.canvas = new OffscreenCanvas(WIDTH, HEIGHT);
|
||||||
|
this.gl = this.canvas.getContext('webgl2') as WebGL2RenderingContext;
|
||||||
|
|
||||||
|
const gl = this.gl;
|
||||||
|
this.imageData =
|
||||||
|
new ImageData(new Uint8ClampedArray(pixels), width, height);
|
||||||
|
this.imageBitmap = await createImageBitmap(this.imageData);
|
||||||
|
this.webGLTexture = gl.createTexture()!;
|
||||||
|
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, this.webGLTexture);
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.imageBitmap);
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
get(type: unknown) {
|
||||||
|
switch (type) {
|
||||||
|
case ImageData:
|
||||||
|
return this.imageData;
|
||||||
|
case ImageBitmap:
|
||||||
|
return this.imageBitmap;
|
||||||
|
case WebGLTexture:
|
||||||
|
return this.webGLTexture;
|
||||||
|
default:
|
||||||
|
throw new Error(`Unsupported type: ${type}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(): void {
|
||||||
|
this.gl.deleteTexture(this.webGLTexture);
|
||||||
|
this.imageBitmap.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(skip ? xdescribe : describe)('MPImage', () => {
|
(skip ? xdescribe : describe)('MPImage', () => {
|
||||||
let canvas: OffscreenCanvas;
|
const context = new MPImageTestContext();
|
||||||
let gl: WebGL2RenderingContext;
|
|
||||||
let imageData: ImageData;
|
|
||||||
let imageBitmap: ImageBitmap;
|
|
||||||
let webGlTexture: WebGLTexture;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
canvas = new OffscreenCanvas(WIDTH, HEIGHT);
|
|
||||||
gl = canvas.getContext('webgl2') as WebGL2RenderingContext;
|
|
||||||
|
|
||||||
const images = await createTestData(
|
|
||||||
gl, [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255], WIDTH,
|
|
||||||
HEIGHT);
|
|
||||||
imageData = images[0];
|
|
||||||
imageBitmap = images[1];
|
|
||||||
webGlTexture = images[2];
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
gl.deleteTexture(webGlTexture);
|
context.close();
|
||||||
imageBitmap.close();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function readPixelsFromImageBitmap(imageBitmap: ImageBitmap): ImageData {
|
function readPixelsFromImageBitmap(imageBitmap: ImageBitmap): ImageData {
|
||||||
|
@ -78,6 +99,7 @@ async function createTestData(
|
||||||
function readPixelsFromWebGLTexture(texture: WebGLTexture): Uint8Array {
|
function readPixelsFromWebGLTexture(texture: WebGLTexture): Uint8Array {
|
||||||
const pixels = new Uint8Array(WIDTH * WIDTH * 4);
|
const pixels = new Uint8Array(WIDTH * WIDTH * 4);
|
||||||
|
|
||||||
|
const gl = context.gl;
|
||||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||||
|
|
||||||
const framebuffer = gl.createFramebuffer()!;
|
const framebuffer = gl.createFramebuffer()!;
|
||||||
|
@ -113,8 +135,8 @@ async function createTestData(
|
||||||
height: number): MPImage {
|
height: number): MPImage {
|
||||||
return new MPImage(
|
return new MPImage(
|
||||||
[input],
|
[input],
|
||||||
/* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas,
|
/* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false,
|
||||||
shaderContext, width, height);
|
context.canvas, shaderContext, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
function runConversionTest(
|
function runConversionTest(
|
||||||
|
@ -136,105 +158,67 @@ async function createTestData(
|
||||||
shaderContext.close();
|
shaderContext.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
it(`converts from ImageData to ImageData`, () => {
|
const sources = skip ? [] : [ImageData, ImageBitmap, WebGLTexture];
|
||||||
runConversionTest(imageData, imageData);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`converts from ImageData to ImageBitmap`, () => {
|
for (let i = 0; i < sources.length; i++) {
|
||||||
runConversionTest(imageData, imageBitmap);
|
for (let j = 0; j < sources.length; j++) {
|
||||||
});
|
it(`converts from ${sources[i].name} to ${sources[j].name}`, async () => {
|
||||||
|
await context.init();
|
||||||
|
runConversionTest(context.get(sources[i]), context.get(sources[j]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
it(`converts from ImageData to WebGLTexture`, () => {
|
for (let i = 0; i < sources.length; i++) {
|
||||||
runConversionTest(imageData, webGlTexture);
|
it(`clones ${sources[i].name}`, async () => {
|
||||||
});
|
await context.init();
|
||||||
|
runCloneTest(context.get(sources[i]));
|
||||||
it(`converts from ImageBitmap to ImageData`, () => {
|
});
|
||||||
runConversionTest(imageBitmap, imageData);
|
}
|
||||||
});
|
|
||||||
|
|
||||||
it(`converts from ImageBitmap to ImageBitmap`, () => {
|
|
||||||
runConversionTest(imageBitmap, imageBitmap);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`converts from ImageBitmap to WebGLTexture`, () => {
|
|
||||||
runConversionTest(imageBitmap, webGlTexture);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`converts from WebGLTexture to ImageData`, () => {
|
|
||||||
runConversionTest(webGlTexture, imageData);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`converts from WebGLTexture to ImageBitmap`, () => {
|
|
||||||
runConversionTest(webGlTexture, imageBitmap);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`converts from WebGLTexture to WebGLTexture`, () => {
|
|
||||||
runConversionTest(webGlTexture, webGlTexture);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`clones ImageData`, () => {
|
|
||||||
runCloneTest(imageData);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`clones ImageBitmap`, () => {
|
|
||||||
runCloneTest(imageBitmap);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`clones WebGLTextures`, () => {
|
|
||||||
runCloneTest(webGlTexture);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`does not flip textures twice`, async () => {
|
it(`does not flip textures twice`, async () => {
|
||||||
const [imageData, , webGlTexture] = await createTestData(
|
await context.init();
|
||||||
gl, [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255], WIDTH,
|
|
||||||
HEIGHT);
|
|
||||||
|
|
||||||
const shaderContext = new MPImageShaderContext();
|
const shaderContext = new MPImageShaderContext();
|
||||||
const image = new MPImage(
|
const image = new MPImage(
|
||||||
[webGlTexture],
|
[context.webGLTexture],
|
||||||
/* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas,
|
/* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false,
|
||||||
shaderContext, WIDTH, HEIGHT);
|
context.canvas, shaderContext, WIDTH, HEIGHT);
|
||||||
|
|
||||||
const result = image.clone().getImage(MPImageStorageType.IMAGE_DATA);
|
const result = image.clone().getImage(MPImageStorageType.IMAGE_DATA);
|
||||||
expect(result).toEqual(imageData);
|
expect(result).toEqual(context.imageData);
|
||||||
|
|
||||||
gl.deleteTexture(webGlTexture);
|
|
||||||
shaderContext.close();
|
shaderContext.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`can clone and get image`, async () => {
|
it(`can clone and get image`, async () => {
|
||||||
const [imageData, , webGlTexture] = await createTestData(
|
await context.init();
|
||||||
gl, [1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255, 4, 0, 0, 255], WIDTH,
|
|
||||||
HEIGHT);
|
|
||||||
|
|
||||||
const shaderContext = new MPImageShaderContext();
|
const shaderContext = new MPImageShaderContext();
|
||||||
const image = new MPImage(
|
const image = new MPImage(
|
||||||
[webGlTexture],
|
[context.webGLTexture],
|
||||||
/* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false, canvas,
|
/* ownsImageBitmap= */ false, /* ownsWebGLTexture= */ false,
|
||||||
shaderContext, WIDTH, HEIGHT);
|
context.canvas, shaderContext, WIDTH, HEIGHT);
|
||||||
|
|
||||||
// Verify that we can mix the different shader modes by running them out of
|
// Verify that we can mix the different shader modes by running them out of
|
||||||
// order.
|
// order.
|
||||||
let result = image.getImage(MPImageStorageType.IMAGE_DATA);
|
let result = image.getImage(MPImageStorageType.IMAGE_DATA);
|
||||||
expect(result).toEqual(imageData);
|
expect(result).toEqual(context.imageData);
|
||||||
|
|
||||||
result = image.clone().getImage(MPImageStorageType.IMAGE_DATA);
|
result = image.clone().getImage(MPImageStorageType.IMAGE_DATA);
|
||||||
expect(result).toEqual(imageData);
|
expect(result).toEqual(context.imageData);
|
||||||
|
|
||||||
result = image.getImage(MPImageStorageType.IMAGE_DATA);
|
result = image.getImage(MPImageStorageType.IMAGE_DATA);
|
||||||
expect(result).toEqual(imageData);
|
expect(result).toEqual(context.imageData);
|
||||||
|
|
||||||
gl.deleteTexture(webGlTexture);
|
|
||||||
shaderContext.close();
|
shaderContext.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports hasType()', async () => {
|
it('supports hasType()', async () => {
|
||||||
const shaderContext = new MPImageShaderContext();
|
await context.init();
|
||||||
const image = createImage(shaderContext, imageData, WIDTH, HEIGHT);
|
|
||||||
|
|
||||||
expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true);
|
const shaderContext = new MPImageShaderContext();
|
||||||
expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(false);
|
const image = createImage(shaderContext, context.imageData, WIDTH, HEIGHT);
|
||||||
expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false);
|
|
||||||
|
|
||||||
image.getImage(MPImageStorageType.WEBGL_TEXTURE);
|
image.getImage(MPImageStorageType.WEBGL_TEXTURE);
|
||||||
|
|
||||||
|
@ -242,7 +226,7 @@ async function createTestData(
|
||||||
expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true);
|
expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true);
|
||||||
expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false);
|
expect(image.hasType(MPImageStorageType.IMAGE_BITMAP)).toBe(false);
|
||||||
|
|
||||||
await image.getImage(MPImageStorageType.IMAGE_BITMAP);
|
image.getImage(MPImageStorageType.IMAGE_BITMAP);
|
||||||
|
|
||||||
expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true);
|
expect(image.hasType(MPImageStorageType.IMAGE_DATA)).toBe(true);
|
||||||
expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true);
|
expect(image.hasType(MPImageStorageType.WEBGL_TEXTURE)).toBe(true);
|
||||||
|
@ -253,33 +237,32 @@ async function createTestData(
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports image that is smaller than the canvas', async () => {
|
it('supports image that is smaller than the canvas', async () => {
|
||||||
const [imageData, imageBitmap, webGlTexture] = await createTestData(
|
await context.init(IMAGE_2_1, /* width= */ 2, /* height= */ 1);
|
||||||
gl, [1, 0, 0, 255, 2, 0, 0, 255], /* width= */ 2, /* height= */ 1);
|
|
||||||
|
|
||||||
runConversionTest(imageData, webGlTexture, /* width= */ 2, /* height= */ 1);
|
|
||||||
runConversionTest(
|
runConversionTest(
|
||||||
webGlTexture, imageBitmap, /* width= */ 2, /* height= */ 1);
|
context.imageData, context.webGLTexture, /* width= */ 2,
|
||||||
runConversionTest(imageBitmap, imageData, /* width= */ 2, /* height= */ 1);
|
/* height= */ 1);
|
||||||
|
runConversionTest(
|
||||||
|
context.webGLTexture, context.imageBitmap, /* width= */ 2,
|
||||||
|
/* height= */ 1);
|
||||||
|
runConversionTest(
|
||||||
|
context.imageBitmap, context.imageData, /* width= */ 2,
|
||||||
|
/* height= */ 1);
|
||||||
|
|
||||||
gl.deleteTexture(webGlTexture);
|
context.close();
|
||||||
imageBitmap.close();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports image that is larger than the canvas', async () => {
|
it('supports image that is larger than the canvas', async () => {
|
||||||
const [imageData, imageBitmap, webGlTexture] = await createTestData(
|
await context.init(IMAGE_2_3, /* width= */ 2, /* height= */ 3);
|
||||||
gl,
|
|
||||||
[
|
|
||||||
1, 0, 0, 255, 2, 0, 0, 255, 3, 0, 0, 255,
|
|
||||||
4, 0, 0, 255, 5, 0, 0, 255, 6, 0, 0, 255
|
|
||||||
],
|
|
||||||
/* width= */ 2, /* height= */ 3);
|
|
||||||
|
|
||||||
runConversionTest(imageData, webGlTexture, /* width= */ 2, /* height= */ 3);
|
|
||||||
runConversionTest(
|
runConversionTest(
|
||||||
webGlTexture, imageBitmap, /* width= */ 2, /* height= */ 3);
|
context.imageData, context.webGLTexture, /* width= */ 2,
|
||||||
runConversionTest(imageBitmap, imageData, /* width= */ 2, /* height= */ 3);
|
/* height= */ 3);
|
||||||
|
runConversionTest(
|
||||||
gl.deleteTexture(webGlTexture);
|
context.webGLTexture, context.imageBitmap, /* width= */ 2,
|
||||||
imageBitmap.close();
|
/* height= */ 3);
|
||||||
|
runConversionTest(
|
||||||
|
context.imageBitmap, context.imageData, /* width= */ 2,
|
||||||
|
/* height= */ 3);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user