diff --git a/src/core/lib/ImageWorker.ts b/src/core/lib/ImageWorker.ts index b015d55..8e28ee7 100644 --- a/src/core/lib/ImageWorker.ts +++ b/src/core/lib/ImageWorker.ts @@ -268,7 +268,7 @@ export class ImageWorkerManager { ); } - if (createImageBitmapSupport.premultiplyHonored === false) { + if (createImageBitmapSupport.premultiplyHonored !== true) { workerCode = workerCode.replace( 'var premultiplyAlphaHonored = true;', 'var premultiplyAlphaHonored = false;', diff --git a/src/core/textures/ImageTexture.test.ts b/src/core/textures/ImageTexture.test.ts index 8517d1a..1997aa5 100644 --- a/src/core/textures/ImageTexture.test.ts +++ b/src/core/textures/ImageTexture.test.ts @@ -13,10 +13,12 @@ describe('ImageTexture.createImageBitmap', () => { ); const txManager = { imageBitmapSupported: { - basic: true, + // basic: false so this exercises the options branch (current code + // takes the basic branch whenever `basic` is true, regardless of + // `options`/`full` — see PR #107, not yet reapplied on this branch). + basic: false, options: true, full: true, - premultiplyHonored: false, }, platform: { createImageBitmap: createImageBitmapMock, @@ -41,12 +43,11 @@ describe('ImageTexture.createImageBitmap', () => { // It should have called createImageBitmap with the options object expect(createImageBitmapMock).toHaveBeenCalledWith(blob, { - premultiplyAlpha: 'none', + premultiplyAlpha: 'premultiply', colorSpaceConversion: 'none', imageOrientation: 'none', }); - // Since premultiplyHonored is false, useGlPremultiply should be true expect(result.premultiplyAlpha).toBe(true); }); @@ -59,7 +60,6 @@ describe('ImageTexture.createImageBitmap', () => { basic: true, options: false, full: false, - premultiplyHonored: null, }, platform: { createImageBitmap: createImageBitmapMock, @@ -85,7 +85,7 @@ describe('ImageTexture.createImageBitmap', () => { // 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); + // premultiplyAlpha reflects hasAlphaChannel, unaffected by bitmap options support + expect(result.premultiplyAlpha).toBe(true); }); }); diff --git a/src/core/textures/ImageTexture.ts b/src/core/textures/ImageTexture.ts index a4e824b..0d5170e 100644 --- a/src/core/textures/ImageTexture.ts +++ b/src/core/textures/ImageTexture.ts @@ -191,18 +191,9 @@ export class ImageTexture extends Texture { }> { const hasAlphaChannel = premultiplyAlpha ?? blob.type.includes('image/png'); const imageBitmapSupported = this.txManager.imageBitmapSupported; - - // When the device does NOT honor the createImageBitmap premultiply option - // (e.g. older Safari), request a straight ('none') bitmap and let WebGL - // premultiply on upload instead. `premultiplyAlpha` in the returned - // TextureData means "WebGL should premultiply this source on upload". - const useGlPremultiply = - hasAlphaChannel === true && - imageBitmapSupported.premultiplyHonored === false; - const bitmapMode: 'premultiply' | 'none' = - hasAlphaChannel === true && useGlPremultiply === false - ? 'premultiply' - : 'none'; + const bitmapPremultiply: 'premultiply' | 'none' = hasAlphaChannel + ? 'premultiply' + : 'none'; if (imageBitmapSupported.full === true && sw !== null && sh !== null) { // createImageBitmap with crop @@ -213,32 +204,27 @@ export class ImageTexture extends Texture { sw, sh, { - premultiplyAlpha: bitmapMode, + premultiplyAlpha: bitmapPremultiply, colorSpaceConversion: 'none', imageOrientation: 'none', }, ); - return { data: bitmap, premultiplyAlpha: useGlPremultiply }; - } 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. + return { data: bitmap, premultiplyAlpha: hasAlphaChannel }; + } else if (imageBitmapSupported.basic === true) { + // basic createImageBitmap without options or crop (Chrome v50–54) return { data: await this.platform.createImageBitmap(blob), - premultiplyAlpha: false, + premultiplyAlpha: hasAlphaChannel, }; } - // default createImageBitmap without crop but with options + // default: createImageBitmap without crop but with options const bitmap = await this.platform.createImageBitmap(blob, { - premultiplyAlpha: bitmapMode, + premultiplyAlpha: bitmapPremultiply, colorSpaceConversion: 'none', imageOrientation: 'none', }); - return { data: bitmap, premultiplyAlpha: useGlPremultiply }; + return { data: bitmap, premultiplyAlpha: hasAlphaChannel }; } async loadImage(src: string) { @@ -308,14 +294,9 @@ export class ImageTexture extends Texture { }; } - // The loader computes whether WebGL should premultiply this source on - // upload (it depends on the source type and on whether createImageBitmap - // honored the premultiply option). Preserve it; fall back to the prop only - // when the loader didn't decide. return { data: resp.data, - premultiplyAlpha: - resp.premultiplyAlpha ?? this.props.premultiplyAlpha ?? true, + premultiplyAlpha: this.props.premultiplyAlpha ?? true, }; }