Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions src/core/textures/ImageTexture.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { ImageTexture } from './ImageTexture.js';
import type { CoreTextureManager } from '../CoreTextureManager.js';

describe('ImageTexture.createImageBitmap', () => {
beforeEach(() => {
vi.stubGlobal('ImageBitmap', class {});
});

it('passes options to createImageBitmap when no crop is requested and options/full are supported', async () => {
const createImageBitmapMock = vi.fn(() =>
Promise.resolve({ close: () => {} }),
);
const txManager = {
imageBitmapSupported: {
basic: true,
options: true,
full: true,
premultiplyHonored: false,
},
platform: {
createImageBitmap: createImageBitmapMock,
},
} as unknown as CoreTextureManager;

const props = ImageTexture.resolveDefaults({
src: 'test.png',
premultiplyAlpha: true,
});
const texture = new ImageTexture(txManager, props);

const blob = new Blob([], { type: 'image/png' });
const result = await texture.createImageBitmap(
blob,
true,
null,
null,
null,
null,
);

// It should have called createImageBitmap with the options object
expect(createImageBitmapMock).toHaveBeenCalledWith(blob, {
premultiplyAlpha: 'none',
colorSpaceConversion: 'none',
imageOrientation: 'none',
});

// Since premultiplyHonored is false, useGlPremultiply should be true
expect(result.premultiplyAlpha).toBe(true);
});

it('falls back to basic createImageBitmap when options are not supported', async () => {
const createImageBitmapMock = vi.fn(() =>
Promise.resolve({ close: () => {} }),
);
const txManager = {
imageBitmapSupported: {
basic: true,
options: false,
full: false,
premultiplyHonored: null,
},
platform: {
createImageBitmap: createImageBitmapMock,
},
} as unknown as CoreTextureManager;

const props = ImageTexture.resolveDefaults({
src: 'test.png',
premultiplyAlpha: true,
});
const texture = new ImageTexture(txManager, props);

const blob = new Blob([], { type: 'image/png' });
const result = await texture.createImageBitmap(
blob,
true,
null,
null,
null,
null,
);

// It should have called basic createImageBitmap without options
expect(createImageBitmapMock).toHaveBeenCalledWith(blob);

// And premultiplyAlpha should be false (browser default is assumed to premultiply)
expect(result.premultiplyAlpha).toBe(false);
});
});
5 changes: 4 additions & 1 deletion src/core/textures/ImageTexture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,10 @@ export class ImageTexture extends Texture {
},
);
return { data: bitmap, premultiplyAlpha: useGlPremultiply };
} else if (imageBitmapSupported.basic === true) {
} else if (
imageBitmapSupported.options === false &&
imageBitmapSupported.full === false
) {
// basic createImageBitmap without options or crop
// this is supported for Chrome v50 to v52/54 that doesn't support options.
// The browser default premultiplies, so WebGL must not premultiply again.
Expand Down
Loading