Skip to content

Commit

Permalink
feat: For unique label renderer optimise redrawing when only position…
Browse files Browse the repository at this point in the history
… haschanged
  • Loading branch information
Imperger committed Apr 17, 2024
1 parent 260f804 commit 8219df2
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 19 deletions.
6 changes: 3 additions & 3 deletions src/lib/UI/UILabel/UILabel.vert
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ out vec3 v_color;
out vec2 v_glyph;

uniform mat4 u_viewProject;
uniform mat4 u_world;

void main()
{
gl_Position = u_viewProject * vec4(a_vertex, 1.0);
void main() {
gl_Position = u_viewProject * u_world * vec4(a_vertex, 1.0f);

v_color = a_color;
v_glyph = a_glyph;
Expand Down
49 changes: 33 additions & 16 deletions src/lib/UI/UILabel/UILabelRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
import { mat4 } from 'gl-matrix';
import { inject, injectable } from 'inversify';

import { UIObservablePositioningGroup } from '../UIObservablePositioningGroup';

import { UILabel } from './UILabel';
import FUILabel from './UILabel.frag';
import VUILabel from './UILabel.vert';
import { UIObservableLabel } from './UIObservableLabel';
import { UIObservableLabel, UpdatedProperty } from './UIObservableLabel';

import { AppSettings } from '@/app/AppSettings';
import { InjectionToken, UILabelRendererTargetName } from '@/app/InjectionToken';
import { Inversify } from '@/Inversify';
import { ArrayHelper } from '@/lib/ArrayHelper';
import { EnumSize } from "@/lib/EnumSize";
import { ExceptionTrap } from '@/lib/ExceptionTrap';
import { FontGlyphCollection, FontGlyphCollectionFactory, GlyphMeshBlueprint } from '@/lib/font/FontGlyphCollection';
import { MemoryPoolTracker } from '@/lib/MemoryPoolTracker';
import { Vec2 } from '@/lib/Primitives';
import { PrimitiveBuilder } from '@/lib/renderer/PrimitiveBuilder';
import { PrimitivesRenderer } from "@/lib/renderer/PrimitivesRenderer";
import { Mat4 } from '@/lib/renderer/ShaderProgram';
import { TypeSizeResolver } from "@/lib/renderer/TypeSizeResolver";
import { SelfBind } from '@/lib/SelfBind';


enum UILabelComponent { X, Y, Z, R, G, B, Ux, Uy };

type Offset = number;

interface SplitedLine {
Expand All @@ -44,6 +40,8 @@ export class UILabelRenderer extends PrimitivesRenderer {

private vertexAttributesTracker: MemoryPoolTracker;

public Unique = false;

constructor(
@inject(InjectionToken.WebGLRenderingContext) gl: WebGL2RenderingContext,
@inject(AppSettings) private settings: AppSettings,
Expand Down Expand Up @@ -72,6 +70,9 @@ export class UILabelRenderer extends PrimitivesRenderer {
}],
{ indicesPerPrimitive: 6, basePrimitiveType: gl.TRIANGLES });

this.shader.SetUniformMatrix4fv('u_world', mat4.create());


this.vertexAttributesTracker = new (class extends MemoryPoolTracker {
constructor(private renderer: UILabelRenderer) {
const initialCapacity = 256;
Expand Down Expand Up @@ -182,10 +183,14 @@ export class UILabelRenderer extends PrimitivesRenderer {
this.vertexAttributesTracker.Free(idx);
}

private UpdateAttributes(component: UIObservableLabel): void {
const fontGlyphCollection = this.fontGlyphCollectionFactory({ ASCIIRange: { Start: ' ', End: '~' }, Font: { Name: 'Roboto', Size: component.LineHeight } });
private OnlyPositionChanged(component: UIObservableLabel): boolean {
return component.ChangedProperties.every((x, n) => n === UpdatedProperty.Position ? x : !x);
}

private UpdateAttributes(component: UIObservableLabel): void {
let width = 0;
let { x, y } = { x: 0, y: 0 };
const fontGlyphCollection = this.fontGlyphCollectionFactory({ ASCIIRange: { Start: ' ', End: '~' }, Font: { Name: 'Roboto', Size: component.LineHeight } });
const lines = UILabelRenderer.SplitString(component.Text);

if (lines.length === 0) {
Expand All @@ -195,16 +200,28 @@ export class UILabelRenderer extends PrimitivesRenderer {

const minBaseOffset = UILabelRenderer.MinBaseOffset(lines[lines.length - 1].text, component, fontGlyphCollection);

let { x, y } = {
x: component.AbsolutePosition.x,
y: component.AbsolutePosition.y - minBaseOffset
};
if (this.Unique) {
const world = mat4.create();
const p = component.AbsolutePosition;
mat4.translate(world, world, [p.x, p.y, 0]);

this.shader.SetUniformMatrix4fv('u_world', world);

if (this.OnlyPositionChanged(component)) {
return;
}
} else {
x = component.AbsolutePosition.x;
y = component.AbsolutePosition.y - minBaseOffset;
}

const xOffset = this.Unique ? 0 : component.AbsolutePosition.x;

for (let n = lines.length - 1; n >= 0; --n) {
const line = lines[n];

if (line.text.length === 0) {
x = component.AbsolutePosition.x;
x = xOffset;
y += component.LineHeight * component.Scale;
continue;
}
Expand Down Expand Up @@ -241,10 +258,10 @@ export class UILabelRenderer extends PrimitivesRenderer {

x += glyphBlueprint.width * component.Scale;

width = Math.max(width, x - component.AbsolutePosition.x);
width = Math.max(width, x - xOffset);
}

x = component.AbsolutePosition.x;
x = xOffset;
y += component.LineHeight * component.Scale + minBaseOffset;
}

Expand Down Expand Up @@ -295,4 +312,4 @@ export class UILabelRenderer extends PrimitivesRenderer {

Inversify.bind(UILabelRenderer).toSelf().inSingletonScope().whenTargetIsDefault();
Inversify.bind(UILabelRenderer).toSelf().inSingletonScope().whenTargetNamed(UILabelRendererTargetName.Perspective);
Inversify.bind(UILabelRenderer).toSelf().inTransientScope().whenTargetNamed(UILabelRendererTargetName.Unique);
Inversify.bind(UILabelRenderer).toSelf().inTransientScope().whenTargetNamed(UILabelRendererTargetName.Unique).onActivation((ctx, instance) => (instance.Unique = true, instance));
23 changes: 23 additions & 0 deletions src/lib/UI/UILabel/UIObservableLabel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export interface GlyphAllocator {
Free: (idx: number) => void;
}

export enum UpdatedProperty { Position = 0, Style, Text, LineHeight, ZIndex, Scale };
type ComponentsToUpdate = [boolean, boolean, boolean, boolean, boolean, boolean];

export class UIObservableLabel implements UIComponent, UILabel {
public static readonly NonPrintableOffset = -1;

Expand All @@ -34,6 +37,8 @@ export class UIObservableLabel implements UIComponent, UILabel {

private updateNeeded = false;

private changedProperties: ComponentsToUpdate = [false, false, false, false, false, false];

constructor(
private position: Vec2,
private text: string,
Expand All @@ -55,6 +60,8 @@ export class UIObservableLabel implements UIComponent, UILabel {
this.symbolsStyle[n] = { ...style };
}

this.changedProperties[UpdatedProperty.Style] = true;

this.DeferredNotify();
}

Expand All @@ -73,6 +80,8 @@ export class UIObservableLabel implements UIComponent, UILabel {
set Position(position: Vec2) {
this.position = position;

this.changedProperties[UpdatedProperty.Position] = true;

this.DeferredNotify();
}

Expand All @@ -96,6 +105,8 @@ export class UIObservableLabel implements UIComponent, UILabel {
this.ResizeSymbolStyles();
this.AdjustPoolMemory();

this.changedProperties[UpdatedProperty.Text] = true;

this.DeferredNotify();
}

Expand All @@ -106,6 +117,8 @@ export class UIObservableLabel implements UIComponent, UILabel {
set LineHeight(lineHeight: number) {
this.lineHeight = lineHeight;

this.changedProperties[UpdatedProperty.LineHeight] = true;

this.DeferredNotify();
}

Expand All @@ -116,6 +129,8 @@ export class UIObservableLabel implements UIComponent, UILabel {
set ZIndex(zIndex: number) {
this.zIndex = zIndex;

this.changedProperties[UpdatedProperty.ZIndex] = true;

this.DeferredNotify();
}

Expand All @@ -126,6 +141,8 @@ export class UIObservableLabel implements UIComponent, UILabel {
set Scale(scale: number) {
this.scale = scale;

this.changedProperties[UpdatedProperty.Scale] = true;

this.DeferredNotify();
}

Expand All @@ -145,6 +162,10 @@ export class UIObservableLabel implements UIComponent, UILabel {
return this.observable;
}

get ChangedProperties(): ComponentsToUpdate {
return this.changedProperties;
}

private get PrintableTextLength(): number {
return this.text
.split('')
Expand Down Expand Up @@ -178,6 +199,8 @@ export class UIObservableLabel implements UIComponent, UILabel {
private Notify(): void {
this.observable.Notify(this);
this.updateNeeded = false;

this.changedProperties.fill(false);
}

private Uninitialize(): void {
Expand Down

0 comments on commit 8219df2

Please sign in to comment.