Skip to content

Commit

Permalink
Simplify ImageWorkerManager initialization (#460)
Browse files Browse the repository at this point in the history
Instead of using an additional postMessage init flow, directly set the
variables in the JS Blob before instantiating the worker.

Note:
CI will fail because of a race condition with 2 tests where the
createImageBitmap detection is still happening and an image request is
already being made, this will need to be addressed with texture
throttling instead of trying to jump through hoops with the current
texture source download + ctxCoreContext construction.
  • Loading branch information
wouterlucas authored Nov 28, 2024
2 parents b0685a4 + 081a1b0 commit 857c8e9
Showing 2 changed files with 18 additions and 27 deletions.
13 changes: 4 additions & 9 deletions src/core/CoreTextureManager.ts
Original file line number Diff line number Diff line change
@@ -209,21 +209,16 @@ export class CoreTextureManager extends EventEmitter {
this.hasWorker &&
numImageWorkers > 0
) {
const imageWorkers = new ImageWorkerManager(numImageWorkers, result);

// wait for the image worker manager to be initialized
imageWorkers.once('initialized', () => {
// enable image worker manager
this.imageWorkerManager = imageWorkers;
});
this.imageWorkerManager = new ImageWorkerManager(
numImageWorkers,
result,
);
} else {
console.warn(
'[Lightning] Imageworker is 0 or not supported on this browser. Image loading will be slower.',
);
}

// Do an early init event, we don't need to wait for the image worker manager to be initialized.
// Loading textures will be done on the main thread from this point on until the image worker manager is ready.
this.emit('initialized');
})
.catch((e) => {
32 changes: 14 additions & 18 deletions src/core/lib/ImageWorker.ts
Original file line number Diff line number Diff line change
@@ -17,7 +17,6 @@
* limitations under the License.
*/

import { EventEmitter } from '../../common/EventEmitter.js';
import type { CreateImageBitmapSupport } from '../CoreTextureManager.js';
import { type TextureData } from '../textures/Texture.js';

@@ -138,14 +137,6 @@ function createImageWorker() {
}

self.onmessage = (event) => {
if (event.data.type === 'init') {
// Store support level sent from the main thread
supportsOptionsCreateImageBitmap = event.data.support.config;
supportsFullCreateImageBitmap = event.data.support.full;
self.postMessage({ initialized: true });
return;
}

var src = event.data.src;
var id = event.data.id;
var premultiplyAlpha = event.data.premultiplyAlpha;
@@ -165,7 +156,7 @@ function createImageWorker() {
}
/* eslint-enable */

export class ImageWorkerManager extends EventEmitter {
export class ImageWorkerManager {
imageWorkersEnabled = true;
messageManager: Record<number, MessageCallback> = {};
workers: Worker[] = [];
@@ -176,7 +167,6 @@ export class ImageWorkerManager extends EventEmitter {
numImageWorkers: number,
createImageBitmapSupport: CreateImageBitmapSupport,
) {
super();
this.workers = this.createWorkers(
numImageWorkers,
createImageBitmapSupport,
@@ -187,12 +177,6 @@ export class ImageWorkerManager extends EventEmitter {
}

private handleMessage(event: MessageEvent) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (event.data?.initialized) {
this.emit('initialized');
return;
}

const { id, data, error } = event.data as ImageWorkerMessage;
const msg = this.messageManager[id];
if (msg) {
@@ -210,7 +194,19 @@ export class ImageWorkerManager extends EventEmitter {
numWorkers = 1,
createImageBitmapSupport: CreateImageBitmapSupport,
): Worker[] {
const workerCode = `(${createImageWorker.toString()})()`;
let workerCode = `(${createImageWorker.toString()})()`;

// Replace placeholders with actual initialization values
const supportsOptions = createImageBitmapSupport.options ? 'true' : 'false';
const supportsFull = createImageBitmapSupport.full ? 'true' : 'false';
workerCode = workerCode.replace(
'var supportsOptionsCreateImageBitmap = false;',
`var supportsOptionsCreateImageBitmap = ${supportsOptions};`,
);
workerCode = workerCode.replace(
'var supportsFullCreateImageBitmap = false;',
`var supportsFullCreateImageBitmap = ${supportsFull};`,
);

const blob: Blob = new Blob([workerCode.replace('"use strict";', '')], {
type: 'application/javascript',

0 comments on commit 857c8e9

Please sign in to comment.