From 76b967a91b7b0f3db40e2216964ddd4d63eee7d4 Mon Sep 17 00:00:00 2001 From: wouterlucas Date: Tue, 21 Jan 2025 22:23:07 +0100 Subject: [PATCH 1/6] refactor: streamline texture loading and freeing logic in CoreNode and Texture classes --- src/core/CoreNode.ts | 2 +- src/core/textures/Texture.ts | 44 ++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/core/CoreNode.ts b/src/core/CoreNode.ts index ca6038ad..a80f3127 100644 --- a/src/core/CoreNode.ts +++ b/src/core/CoreNode.ts @@ -2284,7 +2284,7 @@ export class CoreNode extends EventEmitter { this.props.texture = value; if (value !== null) { - value.setRenderableOwner(this, this.isRenderable); // WVB TODO: check if this is correct + value.setRenderableOwner(this, this.isRenderable); this.loadTexture(); } diff --git a/src/core/textures/Texture.ts b/src/core/textures/Texture.ts index 627819af..d354f721 100644 --- a/src/core/textures/Texture.ts +++ b/src/core/textures/Texture.ts @@ -212,11 +212,7 @@ export abstract class Texture extends EventEmitter { (this.renderable as boolean) = true; (this.lastRenderableChangeTime as number) = this.txManager.frameTime; this.onChangeIsRenderable?.(true); - - // Check if the texture needs to be added to the loading queue - if (this.state === 'freed' || this.state === 'initial') { - this.txManager.loadTexture(this); - } + this.load(); } } else { this.renderableOwners.delete(owner); @@ -229,6 +225,16 @@ export abstract class Texture extends EventEmitter { } } + load(): void { + if (this.sourceState === 'loaded' && this.coreCtxState === 'freed') { + // we need to load the texture data to the gpu + this.txManager.enqueueUploadTexture(this); + return; + } + + this.txManager.loadTexture(this); + } + /** * Event called when the Texture becomes renderable or unrenderable. * @@ -262,10 +268,18 @@ export abstract class Texture extends EventEmitter { */ free(): void { this.ctxTexture?.free(); - if (this.textureData !== null) { - this.textureData = null; - this.setSourceState('freed'); - } + } + + /** + * Free the source texture data for this Texture. + * + * @remarks + * The texture data is the source data that is used to populate the CoreContextTexture. + * e.g. ImageData that is downloaded from a URL. + */ + freeTextureData(): void { + this.textureData = null; + this.setSourceState('freed'); } private setState( @@ -338,12 +352,12 @@ export abstract class Texture extends EventEmitter { } else if (sourceState === 'loaded' && ctxState === 'loaded') { newState = 'loaded'; payload = this.dimensions; // Dimensions set by the source - } else if ( - (sourceState === 'loaded' && ctxState === 'freed') || - (ctxState === 'loaded' && sourceState === 'freed') - ) { - // If one is loaded and the other is freed, then we are in a loading state - newState = 'loading'; + // } else if ( + // (sourceState === 'loaded' && ctxState === 'freed') || + // (ctxState === 'loaded' && sourceState === 'freed') + // ) { + // // If one is loaded and the other is freed, then we are in a loading state + // newState = 'loading'; } else { newState = 'freed'; } From 732a0968eeeae8acfc17fa6f3a9314e724e5cdeb Mon Sep 17 00:00:00 2001 From: wouterlucas Date: Wed, 22 Jan 2025 10:57:30 +0100 Subject: [PATCH 2/6] fix: prevent multiple texture loading attempts in Texture class --- src/core/textures/Texture.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/textures/Texture.ts b/src/core/textures/Texture.ts index d354f721..f7397af5 100644 --- a/src/core/textures/Texture.ts +++ b/src/core/textures/Texture.ts @@ -232,6 +232,10 @@ export abstract class Texture extends EventEmitter { return; } + if (this.state === 'loading' || this.state === 'loaded') { + return; + } + this.txManager.loadTexture(this); } From 99bc34f3675d1c0b99770c453b77fb91a74bc888 Mon Sep 17 00:00:00 2001 From: wouterlucas Date: Wed, 22 Jan 2025 21:07:35 +0100 Subject: [PATCH 3/6] feat: Add texture reload test example --- examples/tests/texture-reload.ts | 182 +++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 examples/tests/texture-reload.ts diff --git a/examples/tests/texture-reload.ts b/examples/tests/texture-reload.ts new file mode 100644 index 00000000..0c32f1c1 --- /dev/null +++ b/examples/tests/texture-reload.ts @@ -0,0 +1,182 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2023 Comcast Cable Communications Management, LLC. + * + * 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. + */ + +import type { INode, RendererMainSettings } from '@lightningjs/renderer'; +import type { ExampleSettings } from '../common/ExampleSettings.js'; + +export function customSettings(): Partial { + return { + textureMemory: { + cleanupInterval: 5000, + debugLogging: true, + }, + }; +} + +const COLORS = [ + 0xff0000ff, // Red + 0x00ff00ff, // Green + 0x0000ffff, // Blue + 0xffff00ff, // Yellow + 0xff00ffff, // Magenta + 0x00ffffff, // Cyan + 0xffffffff, // White +]; + +/** + * Function that chooses a random color from the `COLORS` array + */ +function randomColor() { + return COLORS[Math.floor(Math.random() * COLORS.length)]; +} + +function delay(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +export default async function ({ renderer, testRoot }: ExampleSettings) { + const screenWidth = renderer.settings.appWidth; + const screenHeight = renderer.settings.appHeight; + const nodeSize = 128; // Each node will be 128x128 pixels + const memoryThreshold = 125 * 1024 * 1024; // 50 MB + const textureSize = nodeSize * nodeSize * 3; // RGBA bytes per pixel + const maxNodes = Math.ceil(memoryThreshold / textureSize); + const nodes: INode[] = []; + + const header = renderer.createTextNode({ + fontFamily: 'Ubuntu', + text: `Texture Reload Test`, + fontSize: 45, + parent: testRoot, + x: 900, + y: 50, + }); + + const status = renderer.createTextNode({ + fontFamily: 'Ubuntu', + text: `Creating nodes...`, + fontSize: 30, + parent: testRoot, + color: 0xffff00ff, + x: 900, + y: 150, + }); + + // Create nodes with unique noise textures until the memory threshold is reached + for (let i = 0; i < maxNodes; i++) { + const x = (i % 27) * 10; + const y = ~~(i / 27) * 10; + + const node = renderer.createNode({ + x, + y, + width: nodeSize, + height: nodeSize, + parent: testRoot, + color: randomColor(), + texture: renderer.createTexture('NoiseTexture', { + width: nodeSize, + height: nodeSize, + cacheId: i, + }), + }); + nodes.push(node); + } + + console.log(`Created ${nodes.length} nodes. Memory threshold reached.`); + status.text = `Created ${nodes.length} nodes. Memory threshold reached.`; + + // Choose a node to move offscreen + function getNode() { + const testNode = nodes[0]; + if (!testNode) { + throw new Error('Test failed: No node found to move offscreen.'); + } + return testNode; + } + + let textureFreed = false; + let textureLoaded = false; + + const testNode = getNode(); + testNode.on('freed', () => { + console.log('Texture freed event received.'); + textureFreed = true; + textureLoaded = false; + }); + + testNode.on('loaded', () => { + console.log('Texture loaded event received.'); + textureLoaded = true; + textureFreed = false; + }); + + // Wait for the texture to be freed + console.log('Waiting for texture to be loaded...'); + status.text = `Waiting for texture to be loaded...`; + while (!textureLoaded) { + await delay(100); + } + + // Move the node offscreen + console.log('Moving node offscreen...'); + status.text = `Moving node offscreen...`; + // Move the node out of bounds + testNode.x = -screenWidth * 2; + testNode.y = -screenHeight * 2; + + // Wait for the texture to be freed + console.log('Waiting for texture to be freed...'); + status.text = `Waiting for texture to be freed...`; + while (!textureFreed) { + await delay(100); + } + + // Move the node back into bounds + console.log('Moving node back into view...'); + status.text = `Moving node back into view...`; + testNode.x = 0; + testNode.y = 0; + + // Wait for the texture to be reloaded + console.log('Waiting for texture to be reloaded...'); + status.text = `Waiting for texture to be reloaded...`; + while (!textureLoaded) { + await delay(100); + } + + if (textureLoaded) { + console.log('Test passed: Texture was freed and reloaded successfully.'); + status.text = `Test passed: Texture was freed and reloaded successfully.`; + status.color = 0x00ff00ff; + + // make texture really big in the center of the screen to display it to the user + testNode.x = screenWidth / 2 - nodeSize / 2; + testNode.y = screenHeight / 2 - nodeSize / 2; + testNode.width = nodeSize * 4; + testNode.height = nodeSize * 4; + } else { + console.error('Test failed: Texture was not freed or reloaded correctly.'); + status.text = `Test failed: Texture was not freed or reloaded correctly.`; + status.color = 0xff0000ff; + throw new Error( + 'Test failed: Texture was not freed or reloaded correctly.', + ); + } +} From 8a6dfdf5488ed6a6908d401d9411f716f0d6d611 Mon Sep 17 00:00:00 2001 From: wouterlucas Date: Wed, 22 Jan 2025 22:39:29 +0100 Subject: [PATCH 4/6] feat: Enhance texture reload test with additional cases --- examples/tests/texture-reload.ts | 298 +++++++++++++++++++++++-------- 1 file changed, 226 insertions(+), 72 deletions(-) diff --git a/examples/tests/texture-reload.ts b/examples/tests/texture-reload.ts index 0c32f1c1..974dc410 100644 --- a/examples/tests/texture-reload.ts +++ b/examples/tests/texture-reload.ts @@ -20,6 +20,8 @@ import type { INode, RendererMainSettings } from '@lightningjs/renderer'; import type { ExampleSettings } from '../common/ExampleSettings.js'; +import rockoPng from '../assets/rocko.png'; + export function customSettings(): Partial { return { textureMemory: { @@ -54,7 +56,7 @@ export default async function ({ renderer, testRoot }: ExampleSettings) { const screenWidth = renderer.settings.appWidth; const screenHeight = renderer.settings.appHeight; const nodeSize = 128; // Each node will be 128x128 pixels - const memoryThreshold = 125 * 1024 * 1024; // 50 MB + const memoryThreshold = 130 * 1024 * 1024; // 130 MB const textureSize = nodeSize * nodeSize * 3; // RGBA bytes per pixel const maxNodes = Math.ceil(memoryThreshold / textureSize); const nodes: INode[] = []; @@ -64,18 +66,18 @@ export default async function ({ renderer, testRoot }: ExampleSettings) { text: `Texture Reload Test`, fontSize: 45, parent: testRoot, - x: 900, + x: 500, y: 50, }); - const status = renderer.createTextNode({ + const finalStatus = renderer.createTextNode({ fontFamily: 'Ubuntu', - text: `Creating nodes...`, + text: `Running...`, fontSize: 30, parent: testRoot, color: 0xffff00ff, - x: 900, - y: 150, + x: 500, + y: 100, }); // Create nodes with unique noise textures until the memory threshold is reached @@ -100,83 +102,235 @@ export default async function ({ renderer, testRoot }: ExampleSettings) { } console.log(`Created ${nodes.length} nodes. Memory threshold reached.`); - status.text = `Created ${nodes.length} nodes. Memory threshold reached.`; - // Choose a node to move offscreen - function getNode() { - const testNode = nodes[0]; - if (!testNode) { - throw new Error('Test failed: No node found to move offscreen.'); + const testNode = async function (testNode: INode) { + let textureFreed = false; + let textureLoaded = false; + let timedOut = false; + let timeOutTimer: NodeJS.Timeout | null = null; + + function resetTimeout() { + if (timeOutTimer) { + clearTimeout(timeOutTimer); + } + + timeOutTimer = setTimeout(() => { + timedOut = true; + }, 10000); } - return testNode; - } - let textureFreed = false; - let textureLoaded = false; + testNode.on('freed', () => { + console.log('Texture freed event received.'); + textureFreed = true; + textureLoaded = false; + }); - const testNode = getNode(); - testNode.on('freed', () => { - console.log('Texture freed event received.'); - textureFreed = true; - textureLoaded = false; - }); + testNode.on('loaded', () => { + console.log('Texture loaded event received.'); + textureLoaded = true; + textureFreed = false; + }); + + // Wait for the texture to be freed + console.log('Waiting for texture to be loaded...'); + while (!textureLoaded && !timedOut) { + await delay(100); + } + + if (timedOut) { + console.error('Texture failed to load within 10 seconds.'); + return false; + } + + resetTimeout(); + + // Move the node offscreen + console.log('Moving node offscreen...'); + // Move the node out of bounds + queueMicrotask(() => { + testNode.x = -screenWidth * 2; + testNode.y = -screenHeight * 2; + }); + + // Wait for the texture to be freed + console.log('Waiting for texture to be freed...'); + while (!textureFreed && !timedOut) { + renderer.rerender(); + await delay(100); + } + + if (timedOut) { + console.error('Texture failed to free within 10 seconds.'); + return false; + } + + resetTimeout(); - testNode.on('loaded', () => { - console.log('Texture loaded event received.'); - textureLoaded = true; - textureFreed = false; + // Move the node back into bounds + console.log('Moving node back into view...'); + testNode.x = 0; + testNode.y = 0; + + // Wait for the texture to be reloaded + console.log('Waiting for texture to be reloaded...'); + while (!textureLoaded && !timedOut) { + await delay(100); + } + + if (timedOut) { + console.error('Texture failed to reload within 10 seconds.'); + return false; + } + + if (timeOutTimer) { + clearTimeout(timeOutTimer); + } + + if (textureLoaded) { + return true; + } else { + return false; + } + }; + + const image = renderer.createTexture('ImageTexture', { + src: rockoPng, }); - // Wait for the texture to be freed - console.log('Waiting for texture to be loaded...'); - status.text = `Waiting for texture to be loaded...`; - while (!textureLoaded) { - await delay(100); - } + const nodeSpawnX = 1100; + const nodeSpawnY = 30; - // Move the node offscreen - console.log('Moving node offscreen...'); - status.text = `Moving node offscreen...`; - // Move the node out of bounds - testNode.x = -screenWidth * 2; - testNode.y = -screenHeight * 2; - - // Wait for the texture to be freed - console.log('Waiting for texture to be freed...'); - status.text = `Waiting for texture to be freed...`; - while (!textureFreed) { - await delay(100); - } + const testCases: Record INode> = { + 'Noise Texture': () => + renderer.createNode({ + texture: renderer.createTexture('NoiseTexture', { + width: nodeSize, + height: nodeSize, + cacheId: Math.random(), + }), + x: nodeSpawnX, + y: nodeSpawnY, + width: nodeSize, + height: nodeSize, + parent: testRoot, + }), + 'Image Texture': () => + renderer.createNode({ + x: nodeSpawnX, + y: nodeSpawnY, + width: nodeSize, + height: nodeSize, + src: rockoPng, + parent: testRoot, + }), + // No need to test color textures, they all sample from the same 1x1 pixel texture + // and are not subject to the same memory constraints as other textures + // "Color Texture": () => renderer.createNode({ + // color: 0xff00ff, // Magenta + // x: nodeSpawnX, + // y: nodeSpawnY, + // width: nodeSize, + // height: nodeSize, + // parent: testRoot, + // }), + SubTexture: () => + renderer.createNode({ + texture: renderer.createTexture('SubTexture', { + texture: image, + x: 30, + y: 0, + width: 50, + height: 50, + }), + x: nodeSpawnX, + y: nodeSpawnY, + width: nodeSize, + height: nodeSize, + parent: testRoot, + }), + 'RTT Node': () => { + const rtt = renderer.createNode({ + rtt: true, + x: nodeSpawnX, + y: nodeSpawnY, + width: nodeSize, + height: nodeSize, + parent: testRoot, + }); - // Move the node back into bounds - console.log('Moving node back into view...'); - status.text = `Moving node back into view...`; - testNode.x = 0; - testNode.y = 0; - - // Wait for the texture to be reloaded - console.log('Waiting for texture to be reloaded...'); - status.text = `Waiting for texture to be reloaded...`; - while (!textureLoaded) { - await delay(100); - } + const child = renderer.createNode({ + x: 0, + y: 0, + width: 100, + height: 100, + color: 0xff0000ff, + parent: rtt, + }); + + const child2 = renderer.createNode({ + x: 0, + y: 20, + width: 100, + height: 100, + src: rockoPng, + parent: rtt, + }); + + return rtt; + }, + }; + + // Run all tests + let allTestsPassed = true; + let lastStatusOffSet = 30; + let testIdx = 1; + + for (const [name, createNode] of Object.entries(testCases)) { + console.log(`${testIdx}. Running test for: ${name}`); + finalStatus.text = `${testIdx}. Running test for: ${name}`; + + const testNodeInstance = createNode(); // Create the test node dynamically + + const result = await testNode(testNodeInstance); + + if (!result) { + console.error(`${testIdx}. Test failed for: ${name}`); + finalStatus.text = `Test failed for: ${name}`; + finalStatus.color = 0xff0000ff; + allTestsPassed = false; + } - if (textureLoaded) { - console.log('Test passed: Texture was freed and reloaded successfully.'); - status.text = `Test passed: Texture was freed and reloaded successfully.`; - status.color = 0x00ff00ff; + console.log(`${testIdx}. Test passed for: ${name}`); + + testNodeInstance.x = 500; + testNodeInstance.y = lastStatusOffSet + 128; + testNodeInstance.width = 128; + testNodeInstance.height = 128; + + const status = result ? 'passed' : 'failed'; + + renderer.createTextNode({ + fontFamily: 'Ubuntu', + text: `${testIdx}. Test ${status} for: ${name}`, + fontSize: 30, + parent: testRoot, + color: result ? 0x00ff00ff : 0xff0000ff, + x: 630, + y: lastStatusOffSet + 128 + 128 / 2, + }); + + lastStatusOffSet += 130; + testIdx++; + } - // make texture really big in the center of the screen to display it to the user - testNode.x = screenWidth / 2 - nodeSize / 2; - testNode.y = screenHeight / 2 - nodeSize / 2; - testNode.width = nodeSize * 4; - testNode.height = nodeSize * 4; + if (allTestsPassed) { + console.log('All tests passed successfully!'); + finalStatus.text = `All tests passed successfully!`; + finalStatus.color = 0x00ff00ff; } else { - console.error('Test failed: Texture was not freed or reloaded correctly.'); - status.text = `Test failed: Texture was not freed or reloaded correctly.`; - status.color = 0xff0000ff; - throw new Error( - 'Test failed: Texture was not freed or reloaded correctly.', - ); + console.error('One or more tests failed.'); + finalStatus.text = `One or more tests failed.`; + finalStatus.color = 0xff0000ff; + throw new Error('Test suite failed.'); } } From d2838b3519d8320ffc9f32884b2c484adc96d49b Mon Sep 17 00:00:00 2001 From: wouterlucas Date: Thu, 23 Jan 2025 14:53:08 +0100 Subject: [PATCH 5/6] feat: SubTexture forward parent texture Freed events --- examples/tests/texture-reload.ts | 38 +++++++++++++++++++------------- src/core/textures/SubTexture.ts | 9 ++++++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/examples/tests/texture-reload.ts b/examples/tests/texture-reload.ts index 974dc410..67932e45 100644 --- a/examples/tests/texture-reload.ts +++ b/examples/tests/texture-reload.ts @@ -52,7 +52,7 @@ function delay(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); } -export default async function ({ renderer, testRoot }: ExampleSettings) { +export default async function test({ renderer, testRoot }: ExampleSettings) { const screenWidth = renderer.settings.appWidth; const screenHeight = renderer.settings.appHeight; const nodeSize = 128; // Each node will be 128x128 pixels @@ -197,6 +197,14 @@ export default async function ({ renderer, testRoot }: ExampleSettings) { src: rockoPng, }); + image.on('loaded', () => { + console.warn('Parent Image texture loaded.'); + }); + + image.on('freed', () => { + console.warn('Parent Image texture freed.'); + }); + const nodeSpawnX = 1100; const nodeSpawnY = 30; @@ -214,15 +222,6 @@ export default async function ({ renderer, testRoot }: ExampleSettings) { height: nodeSize, parent: testRoot, }), - 'Image Texture': () => - renderer.createNode({ - x: nodeSpawnX, - y: nodeSpawnY, - width: nodeSize, - height: nodeSize, - src: rockoPng, - parent: testRoot, - }), // No need to test color textures, they all sample from the same 1x1 pixel texture // and are not subject to the same memory constraints as other textures // "Color Texture": () => renderer.createNode({ @@ -248,6 +247,15 @@ export default async function ({ renderer, testRoot }: ExampleSettings) { height: nodeSize, parent: testRoot, }), + 'Image Texture': () => + renderer.createNode({ + x: nodeSpawnX, + y: nodeSpawnY, + width: nodeSize, + height: nodeSize, + src: rockoPng, + parent: testRoot, + }), 'RTT Node': () => { const rtt = renderer.createNode({ rtt: true, @@ -294,21 +302,19 @@ export default async function ({ renderer, testRoot }: ExampleSettings) { const result = await testNode(testNodeInstance); if (!result) { - console.error(`${testIdx}. Test failed for: ${name}`); finalStatus.text = `Test failed for: ${name}`; finalStatus.color = 0xff0000ff; allTestsPassed = false; } - console.log(`${testIdx}. Test passed for: ${name}`); + const status = result ? 'passed' : 'failed'; + console.log(`${testIdx}. Test ${result} for: ${name}`); testNodeInstance.x = 500; testNodeInstance.y = lastStatusOffSet + 128; testNodeInstance.width = 128; testNodeInstance.height = 128; - const status = result ? 'passed' : 'failed'; - renderer.createTextNode({ fontFamily: 'Ubuntu', text: `${testIdx}. Test ${status} for: ${name}`, @@ -327,10 +333,12 @@ export default async function ({ renderer, testRoot }: ExampleSettings) { console.log('All tests passed successfully!'); finalStatus.text = `All tests passed successfully!`; finalStatus.color = 0x00ff00ff; + + return true; } else { console.error('One or more tests failed.'); finalStatus.text = `One or more tests failed.`; finalStatus.color = 0xff0000ff; - throw new Error('Test suite failed.'); + return false; } } diff --git a/src/core/textures/SubTexture.ts b/src/core/textures/SubTexture.ts index c28ef98d..01533301 100644 --- a/src/core/textures/SubTexture.ts +++ b/src/core/textures/SubTexture.ts @@ -111,9 +111,13 @@ export class SubTexture extends Texture { this.onParentTxLoaded(parentTx, parentTx.dimensions!); } else if (parentTx.state === 'failed') { this.onParentTxFailed(parentTx, parentTx.error!); + } else if (parentTx.state === 'freed') { + this.onParentTxFreed(); } + parentTx.on('loaded', this.onParentTxLoaded); parentTx.on('failed', this.onParentTxFailed); + parentTx.on('freed', this.onParentTxFreed); }); } @@ -138,6 +142,11 @@ export class SubTexture extends Texture { this.setSourceState('failed', error); }; + private onParentTxFreed = () => { + console.log('Parent texture freed, freeing sub-texture'); + this.setSourceState('freed'); + }; + override onChangeIsRenderable(isRenderable: boolean): void { // Propagate the renderable owner change to the parent texture this.parentTexture.setRenderableOwner(this, isRenderable); From 86fd1a477579002848f522712534e279c1cc0154 Mon Sep 17 00:00:00 2001 From: wouterlucas Date: Thu, 23 Jan 2025 16:04:01 +0100 Subject: [PATCH 6/6] chore: cleanup --- src/core/textures/SubTexture.ts | 1 - src/core/textures/Texture.ts | 6 ------ 2 files changed, 7 deletions(-) diff --git a/src/core/textures/SubTexture.ts b/src/core/textures/SubTexture.ts index 01533301..6ee552d4 100644 --- a/src/core/textures/SubTexture.ts +++ b/src/core/textures/SubTexture.ts @@ -143,7 +143,6 @@ export class SubTexture extends Texture { }; private onParentTxFreed = () => { - console.log('Parent texture freed, freeing sub-texture'); this.setSourceState('freed'); }; diff --git a/src/core/textures/Texture.ts b/src/core/textures/Texture.ts index f7397af5..2ce86947 100644 --- a/src/core/textures/Texture.ts +++ b/src/core/textures/Texture.ts @@ -356,12 +356,6 @@ export abstract class Texture extends EventEmitter { } else if (sourceState === 'loaded' && ctxState === 'loaded') { newState = 'loaded'; payload = this.dimensions; // Dimensions set by the source - // } else if ( - // (sourceState === 'loaded' && ctxState === 'freed') || - // (ctxState === 'loaded' && sourceState === 'freed') - // ) { - // // If one is loaded and the other is freed, then we are in a loading state - // newState = 'loading'; } else { newState = 'freed'; }