Skip to content

Commit

Permalink
Performance updates (#409)
Browse files Browse the repository at this point in the history
Stash of small performance updates:
* Removal of lots of redundant `const` creations
* Introduced a Texture Type to avoid more expensive `instanceof` checks
* Small refactor on `flipY` detection with RTT
* Reduced immediate GC pressure on node destroy by setting values to
`undefined` over explicit `delete`
* Skip sanitizing custom `data` on node creation if inspector is
disabled

Performance changes:
```
create: 60.24ms ±17.30 ->  50.07ms ±8.84
update: 30.66ms ±1.50 -> 28.87ms ±9.51
skipNth: 24.32ms ±7.00  -> 22.81ms ±5.22
select: 27.72ms ±12.20  -> 26.44ms ±15.72
swap: 28.14ms ±14.80 -> 24.16ms ±12.71
remove: 25.72ms ±5.20 -> 22.83ms ±5.25
createLots: 303.16ms ±141.40  -> 258.30ms ±50.86
append: 282.90ms ±36.70 -> 283.57ms ±191.68
clear: 14.76ms ±1.50 -> 14.59ms ±5.86
```
  • Loading branch information
wouterlucas authored Oct 15, 2024
2 parents 0fccd9b + 4b74c19 commit 76c563d
Show file tree
Hide file tree
Showing 13 changed files with 210 additions and 204 deletions.
93 changes: 38 additions & 55 deletions src/core/CoreNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -759,10 +759,11 @@ export class CoreNode extends EventEmitter {
this.src = props.src;
this.rtt = props.rtt;

this.updateScaleRotateTransform();

this.setUpdateType(
UpdateType.Local | UpdateType.RenderBounds | UpdateType.RenderState,
UpdateType.ScaleRotate |
UpdateType.Local |
UpdateType.RenderBounds |
UpdateType.RenderState,
);
}

Expand Down Expand Up @@ -797,7 +798,7 @@ export class CoreNode extends EventEmitter {
}

unloadTexture(): void {
if (this.texture) {
if (this.texture !== null) {
this.texture.off('loaded', this.onTextureLoaded);
this.texture.off('failed', this.onTextureFailed);
this.texture.off('freed', this.onTextureFreed);
Expand Down Expand Up @@ -1459,24 +1460,23 @@ export class CoreNode extends EventEmitter {
this.unloadTexture();

this.clippingRect.valid = false;

this.isRenderable = false;

delete this.renderCoords;
delete this.renderBound;
delete this.strictBound;
delete this.preloadBound;
delete this.globalTransform;
delete this.scaleRotateTransform;
delete this.localTransform;
this.renderCoords = undefined;
this.renderBound = undefined;
this.strictBound = undefined;
this.preloadBound = undefined;
this.globalTransform = undefined;
this.scaleRotateTransform = undefined;
this.localTransform = undefined;

this.props.texture = null;
this.props.shader = this.stage.defShaderCtr;

const children = [...this.children];
for (let i = 0, length = children.length; i < length; i++) {
children[i]!.destroy();
while (this.children.length > 0) {
this.children[0]?.destroy();
}

// This very action will also remove the node from the parent's children array
this.parent = null;

Expand All @@ -1488,8 +1488,6 @@ export class CoreNode extends EventEmitter {
}

renderQuads(renderer: CoreRenderer): void {
const { texture, width, height, textureOptions, rtt, shader } = this.props;

// Prevent quad rendering if parent has a render texture
// and renderer is not currently rendering to a texture
if (this.parentHasRenderTexture) {
Expand All @@ -1502,47 +1500,32 @@ export class CoreNode extends EventEmitter {
}
}

const {
premultipliedColorTl,
premultipliedColorTr,
premultipliedColorBl,
premultipliedColorBr,
} = this;

const {
zIndex,
worldAlpha,
globalTransform: gt,
clippingRect,
renderCoords,
} = this;

assertTruthy(gt);
assertTruthy(renderCoords);
assertTruthy(this.globalTransform);
assertTruthy(this.renderCoords);

// add to list of renderables to be sorted before rendering
renderer.addQuad({
width,
height,
colorTl: premultipliedColorTl,
colorTr: premultipliedColorTr,
colorBl: premultipliedColorBl,
colorBr: premultipliedColorBr,
texture,
textureOptions,
zIndex,
shader: shader.shader,
shaderProps: shader.getResolvedProps(),
alpha: worldAlpha,
clippingRect,
tx: gt.tx,
ty: gt.ty,
ta: gt.ta,
tb: gt.tb,
tc: gt.tc,
td: gt.td,
renderCoords,
rtt,
width: this.props.width,
height: this.props.height,
colorTl: this.premultipliedColorTl,
colorTr: this.premultipliedColorTr,
colorBl: this.premultipliedColorBl,
colorBr: this.premultipliedColorBr,
texture: this.texture,
textureOptions: this.textureOptions,
zIndex: this.zIndex,
shader: this.shader.shader,
shaderProps: this.shader.getResolvedProps(),
alpha: this.worldAlpha,
clippingRect: this.clippingRect,
tx: this.globalTransform.tx,
ty: this.globalTransform.ty,
ta: this.globalTransform.ta,
tb: this.globalTransform.tb,
tc: this.globalTransform.tc,
td: this.globalTransform.td,
renderCoords: this.renderCoords,
rtt: this.rtt,
parentHasRenderTexture: this.parentHasRenderTexture,
framebufferDimensions: this.framebufferDimensions,
});
Expand Down
7 changes: 6 additions & 1 deletion src/core/Stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export interface StageOptions {
eventBus: EventEmitter;
quadBufferSize: number;
fontEngines: (typeof CanvasTextRenderer | typeof SdfTextRenderer)[];
inspector: boolean;
}

export type StageFpsUpdateHandler = (
Expand Down Expand Up @@ -580,7 +581,11 @@ export class Stage {
props.colorBl ?? props.colorBottom ?? props.colorLeft ?? color;
const colorBr =
props.colorBr ?? props.colorBottom ?? props.colorRight ?? color;
const data = santizeCustomDataMap(props.data ?? {});

let data = {};
if (this.options.inspector === true) {
data = santizeCustomDataMap(props.data ?? {});
}

return {
x: props.x ?? 0,
Expand Down
17 changes: 13 additions & 4 deletions src/core/renderers/webgl/WebGlCoreRenderOp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,25 @@ export class WebGlCoreRenderOp extends CoreRenderOp {

addTexture(texture: WebGlCoreCtxTexture): number {
const { textures, maxTextures } = this;
const existingIdx = textures.findIndex((t) => t === texture);
let existingIdx = -1;
const texturesLength = textures.length;
for (let i = 0; i < texturesLength; i++) {
const t = textures[i];
if (t === texture) {
existingIdx = i;
break;
}
}

if (existingIdx !== -1) {
return existingIdx;
}
const newIdx = textures.length;
if (newIdx >= maxTextures) {

if (texturesLength >= maxTextures) {
return 0xffffffff;
}
this.textures.push(texture);
return newIdx;
return texturesLength;
}

draw() {
Expand Down
Loading

0 comments on commit 76c563d

Please sign in to comment.