Skip to content

Commit 4b1c165

Browse files
DrJKLwebfilteredgithub-actions
authored
Cleanup/Perf: Float32Array/Float64Array removal (#5877)
## Summary Redoing #5567, without the link rendering changes. ## Changes - **What**: Standardizing the Point/Size/Rect logic around numeric tuples instead of typed arrays. ## Review Focus Cutting here and going to continue in a second PR. Do the simpler types make sense? Do we want to keep the behavior of Rectangle as it is now? ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5877-WIP-Float32Array-Float64Array-removal-27f6d73d36508169a39eff1e4a87a61c) by [Unito](https://www.unito.io) --------- Co-authored-by: filtered <[email protected]> Co-authored-by: github-actions <[email protected]>
1 parent 720de8c commit 4b1c165

File tree

24 files changed

+167
-219
lines changed

24 files changed

+167
-219
lines changed

browser_tests/fixtures/utils/litegraphUtils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ class NodeSlotReference {
151151
const convertedPos =
152152
window['app'].canvas.ds.convertOffsetToCanvas(rawPos)
153153

154-
// Debug logging - convert Float32Arrays to regular arrays for visibility
154+
// Debug logging - convert Float64Arrays to regular arrays for visibility
155+
// eslint-disable-next-line no-console
155156
console.log(
156157
`NodeSlotReference debug for ${type} slot ${index} on node ${id}:`,
157158
{
-58 Bytes
Loading
-76 Bytes
Loading

src/lib/litegraph/src/LGraphCanvas.ts

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { toString } from 'es-toolkit/compat'
22

33
import { PREFIX, SEPARATOR } from '@/constants/groupNodeConstants'
4-
import { LinkConnector } from '@/lib/litegraph/src/canvas/LinkConnector'
54
import {
65
type LinkRenderContext,
76
LitegraphLinkAdapter
@@ -17,6 +16,7 @@ import { LGraphGroup } from './LGraphGroup'
1716
import { LGraphNode, type NodeId, type NodeProperty } from './LGraphNode'
1817
import { LLink, type LinkId } from './LLink'
1918
import { Reroute, type RerouteId } from './Reroute'
19+
import { LinkConnector } from './canvas/LinkConnector'
2020
import { isOverNodeInput, isOverNodeOutput } from './canvas/measureSlots'
2121
import { strokeShape } from './draw'
2222
import type {
@@ -25,6 +25,7 @@ import type {
2525
} from './infrastructure/CustomEventTarget'
2626
import type { LGraphCanvasEventMap } from './infrastructure/LGraphCanvasEventMap'
2727
import { NullGraphError } from './infrastructure/NullGraphError'
28+
import { Rectangle } from './infrastructure/Rectangle'
2829
import type {
2930
CanvasColour,
3031
ColorOption,
@@ -47,12 +48,11 @@ import type {
4748
NullableProperties,
4849
Point,
4950
Positionable,
50-
ReadOnlyPoint,
5151
ReadOnlyRect,
5252
Rect,
5353
Size
5454
} from './interfaces'
55-
import { LiteGraph, Rectangle, SubgraphNode, createUuidv4 } from './litegraph'
55+
import { LiteGraph } from './litegraph'
5656
import {
5757
containsRect,
5858
createBounds,
@@ -67,6 +67,7 @@ import { NodeInputSlot } from './node/NodeInputSlot'
6767
import type { Subgraph } from './subgraph/Subgraph'
6868
import { SubgraphIONodeBase } from './subgraph/SubgraphIONodeBase'
6969
import type { SubgraphInputNode } from './subgraph/SubgraphInputNode'
70+
import { SubgraphNode } from './subgraph/SubgraphNode'
7071
import type { SubgraphOutputNode } from './subgraph/SubgraphOutputNode'
7172
import type {
7273
CanvasPointerEvent,
@@ -88,6 +89,7 @@ import type { IBaseWidget } from './types/widgets'
8889
import { alignNodes, distributeNodes, getBoundaryNodes } from './utils/arrange'
8990
import { findFirstNode, getAllNestedItems } from './utils/collections'
9091
import { resolveConnectingLinkColor } from './utils/linkColors'
92+
import { createUuidv4 } from './utils/uuid'
9193
import type { UUID } from './utils/uuid'
9294
import { BaseWidget } from './widgets/BaseWidget'
9395
import { toConcreteWidget } from './widgets/widgetMap'
@@ -228,20 +230,19 @@ const cursors = {
228230
NW: 'nwse-resize'
229231
} as const
230232

233+
// Optimised buffers used during rendering
234+
const temp = new Rectangle()
235+
const temp_vec2: Point = [0, 0]
236+
const tmp_area = new Rectangle()
237+
const margin_area = new Rectangle()
238+
const link_bounding = new Rectangle()
231239
/**
232240
* This class is in charge of rendering one graph inside a canvas. And provides all the interaction required.
233241
* Valid callbacks are: onNodeSelected, onNodeDeselected, onShowNodePanel, onNodeDblClicked
234242
*/
235243
export class LGraphCanvas
236244
implements CustomEventDispatcher<LGraphCanvasEventMap>
237245
{
238-
// Optimised buffers used during rendering
239-
static #temp = new Float32Array(4)
240-
static #temp_vec2 = new Float32Array(2)
241-
static #tmp_area = new Float32Array(4)
242-
static #margin_area = new Float32Array(4)
243-
static #link_bounding = new Float32Array(4)
244-
245246
static DEFAULT_BACKGROUND_IMAGE =
246247
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQBJREFUeNrs1rEKwjAUhlETUkj3vP9rdmr1Ysammk2w5wdxuLgcMHyptfawuZX4pJSWZTnfnu/lnIe/jNNxHHGNn//HNbbv+4dr6V+11uF527arU7+u63qfa/bnmh8sWLBgwYJlqRf8MEptXPBXJXa37BSl3ixYsGDBMliwFLyCV/DeLIMFCxYsWLBMwSt4Be/NggXLYMGCBUvBK3iNruC9WbBgwYJlsGApeAWv4L1ZBgsWLFiwYJmCV/AK3psFC5bBggULloJX8BpdwXuzYMGCBctgwVLwCl7Be7MMFixYsGDBsu8FH1FaSmExVfAxBa/gvVmwYMGCZbBg/W4vAQYA5tRF9QYlv/QAAAAASUVORK5CYII='
247248

@@ -628,7 +629,7 @@ export class LGraphCanvas
628629
dirty_area?: Rect | null
629630
/** @deprecated Unused */
630631
node_in_panel?: LGraphNode | null
631-
last_mouse: ReadOnlyPoint = [0, 0]
632+
last_mouse: Readonly<Point> = [0, 0]
632633
last_mouseclick: number = 0
633634
graph: LGraph | Subgraph | null
634635
get _graph(): LGraph | Subgraph {
@@ -2634,7 +2635,7 @@ export class LGraphCanvas
26342635
pointer: CanvasPointer,
26352636
node?: LGraphNode | undefined
26362637
): void {
2637-
const dragRect = new Float32Array(4)
2638+
const dragRect: Rect = [0, 0, 0, 0]
26382639

26392640
dragRect[0] = e.canvasX
26402641
dragRect[1] = e.canvasY
@@ -3174,7 +3175,7 @@ export class LGraphCanvas
31743175

31753176
LGraphCanvas.active_canvas = this
31763177
this.adjustMouseEvent(e)
3177-
const mouse: ReadOnlyPoint = [e.clientX, e.clientY]
3178+
const mouse: Readonly<Point> = [e.clientX, e.clientY]
31783179
this.mouse[0] = mouse[0]
31793180
this.mouse[1] = mouse[1]
31803181
const delta = [mouse[0] - this.last_mouse[0], mouse[1] - this.last_mouse[1]]
@@ -4077,7 +4078,7 @@ export class LGraphCanvas
40774078
this.setDirty(true)
40784079
}
40794080

4080-
#handleMultiSelect(e: CanvasPointerEvent, dragRect: Float32Array) {
4081+
#handleMultiSelect(e: CanvasPointerEvent, dragRect: Rect) {
40814082
// Process drag
40824083
// Convert Point pair (pos, offset) to Rect
40834084
const { graph, selectedItems, subgraph } = this
@@ -4848,7 +4849,7 @@ export class LGraphCanvas
48484849
}
48494850

48504851
/** Get the target snap / highlight point in graph space */
4851-
#getHighlightPosition(): ReadOnlyPoint {
4852+
#getHighlightPosition(): Readonly<Point> {
48524853
return LiteGraph.snaps_for_comfy
48534854
? this.linkConnector.state.snapLinksPos ??
48544855
this._highlight_pos ??
@@ -4863,7 +4864,7 @@ export class LGraphCanvas
48634864
*/
48644865
#renderSnapHighlight(
48654866
ctx: CanvasRenderingContext2D,
4866-
highlightPos: ReadOnlyPoint
4867+
highlightPos: Readonly<Point>
48674868
): void {
48684869
const linkConnectorSnap = !!this.linkConnector.state.snapLinksPos
48694870
if (!this._highlight_pos && !linkConnectorSnap) return
@@ -5204,8 +5205,9 @@ export class LGraphCanvas
52045205

52055206
// clip if required (mask)
52065207
const shape = node._shape || RenderShape.BOX
5207-
const size = LGraphCanvas.#temp_vec2
5208-
size.set(node.renderingSize)
5208+
const size = temp_vec2
5209+
size[0] = node.renderingSize[0]
5210+
size[1] = node.renderingSize[1]
52095211

52105212
if (node.collapsed) {
52115213
ctx.font = this.inner_text_font
@@ -5399,7 +5401,7 @@ export class LGraphCanvas
53995401
: true
54005402

54015403
// Normalised node dimensions
5402-
const area = LGraphCanvas.#tmp_area
5404+
const area = tmp_area
54035405
area.set(node.boundingRect)
54045406
area[0] -= node.pos[0]
54055407
area[1] -= node.pos[1]
@@ -5501,7 +5503,7 @@ export class LGraphCanvas
55015503
item: Positionable,
55025504
shape = RenderShape.ROUND
55035505
) {
5504-
const snapGuide = LGraphCanvas.#temp
5506+
const snapGuide = temp
55055507
snapGuide.set(item.boundingRect)
55065508

55075509
// Not all items have pos equal to top-left of bounds
@@ -5548,10 +5550,10 @@ export class LGraphCanvas
55485550

55495551
const now = LiteGraph.getTime()
55505552
const { visible_area } = this
5551-
LGraphCanvas.#margin_area[0] = visible_area[0] - 20
5552-
LGraphCanvas.#margin_area[1] = visible_area[1] - 20
5553-
LGraphCanvas.#margin_area[2] = visible_area[2] + 40
5554-
LGraphCanvas.#margin_area[3] = visible_area[3] + 40
5553+
margin_area[0] = visible_area[0] - 20
5554+
margin_area[1] = visible_area[1] - 20
5555+
margin_area[2] = visible_area[2] + 40
5556+
margin_area[3] = visible_area[3] + 40
55555557

55565558
// draw connections
55575559
ctx.lineWidth = this.connections_width
@@ -5772,18 +5774,13 @@ export class LGraphCanvas
57725774
// Bounding box of all points (bezier overshoot on long links will be cut)
57735775
const pointsX = points.map((x) => x[0])
57745776
const pointsY = points.map((x) => x[1])
5775-
LGraphCanvas.#link_bounding[0] = Math.min(...pointsX)
5776-
LGraphCanvas.#link_bounding[1] = Math.min(...pointsY)
5777-
LGraphCanvas.#link_bounding[2] =
5778-
Math.max(...pointsX) - LGraphCanvas.#link_bounding[0]
5779-
LGraphCanvas.#link_bounding[3] =
5780-
Math.max(...pointsY) - LGraphCanvas.#link_bounding[1]
5777+
link_bounding[0] = Math.min(...pointsX)
5778+
link_bounding[1] = Math.min(...pointsY)
5779+
link_bounding[2] = Math.max(...pointsX) - link_bounding[0]
5780+
link_bounding[3] = Math.max(...pointsY) - link_bounding[1]
57815781

57825782
// skip links outside of the visible area of the canvas
5783-
if (
5784-
!overlapBounding(LGraphCanvas.#link_bounding, LGraphCanvas.#margin_area)
5785-
)
5786-
return
5783+
if (!overlapBounding(link_bounding, margin_area)) return
57875784

57885785
const start_dir = startDirection || LinkDirection.RIGHT
57895786
const end_dir = endDirection || LinkDirection.LEFT
@@ -5942,8 +5939,8 @@ export class LGraphCanvas
59425939
*/
59435940
renderLink(
59445941
ctx: CanvasRenderingContext2D,
5945-
a: ReadOnlyPoint,
5946-
b: ReadOnlyPoint,
5942+
a: Readonly<Point>,
5943+
b: Readonly<Point>,
59475944
link: LLink | null,
59485945
skip_border: boolean,
59495946
flow: number | null,
@@ -5960,9 +5957,9 @@ export class LGraphCanvas
59605957
/** When defined, render data will be saved to this reroute instead of the {@link link}. */
59615958
reroute?: Reroute
59625959
/** Offset of the bezier curve control point from {@link a point a} (output side) */
5963-
startControl?: ReadOnlyPoint
5960+
startControl?: Readonly<Point>
59645961
/** Offset of the bezier curve control point from {@link b point b} (input side) */
5965-
endControl?: ReadOnlyPoint
5962+
endControl?: Readonly<Point>
59665963
/** Number of sublines (useful to represent vec3 or rgb) @todo If implemented, refactor calculations out of the loop */
59675964
num_sublines?: number
59685965
/** Whether this is a floating link segment */

src/lib/litegraph/src/LGraphGroup.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import type {
1313
Positionable,
1414
Size
1515
} from './interfaces'
16-
import { LiteGraph } from './litegraph'
16+
import { LiteGraph, Rectangle } from './litegraph'
1717
import {
1818
containsCentre,
1919
containsRect,
@@ -40,15 +40,10 @@ export class LGraphGroup implements Positionable, IPinnable, IColorable {
4040
title: string
4141
font?: string
4242
font_size: number = LiteGraph.DEFAULT_GROUP_FONT || 24
43-
_bounding: Float32Array = new Float32Array([
44-
10,
45-
10,
46-
LGraphGroup.minWidth,
47-
LGraphGroup.minHeight
48-
])
49-
50-
_pos: Point = this._bounding.subarray(0, 2)
51-
_size: Size = this._bounding.subarray(2, 4)
43+
_bounding = new Rectangle(10, 10, LGraphGroup.minWidth, LGraphGroup.minHeight)
44+
45+
_pos: Point = this._bounding.pos
46+
_size: Size = this._bounding.size
5247
/** @deprecated See {@link _children} */
5348
_nodes: LGraphNode[] = []
5449
_children: Set<Positionable> = new Set()

src/lib/litegraph/src/LGraphNode.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ import type {
3737
ISlotType,
3838
Point,
3939
Positionable,
40-
ReadOnlyPoint,
4140
ReadOnlyRect,
4241
Rect,
4342
Size
@@ -413,7 +412,7 @@ export class LGraphNode
413412
}
414413

415414
/** @inheritdoc {@link renderArea} */
416-
#renderArea: Float32Array = new Float32Array(4)
415+
#renderArea = new Rectangle()
417416
/**
418417
* Rect describing the node area, including shadows and any protrusions.
419418
* Determines if the node is visible. Calculated once at the start of every frame.
@@ -434,18 +433,18 @@ export class LGraphNode
434433
}
435434

436435
/** The offset from {@link pos} to the top-left of {@link boundingRect}. */
437-
get boundingOffset(): ReadOnlyPoint {
436+
get boundingOffset(): Readonly<Point> {
438437
const {
439438
pos: [posX, posY],
440439
boundingRect: [bX, bY]
441440
} = this
442441
return [posX - bX, posY - bY]
443442
}
444443

445-
/** {@link pos} and {@link size} values are backed by this {@link Rect}. */
446-
_posSize: Float32Array = new Float32Array(4)
447-
_pos: Point = this._posSize.subarray(0, 2)
448-
_size: Size = this._posSize.subarray(2, 4)
444+
/** {@link pos} and {@link size} values are backed by this {@link Rectangle}. */
445+
_posSize = new Rectangle()
446+
_pos: Point = this._posSize.pos
447+
_size: Size = this._posSize.size
449448

450449
public get pos() {
451450
return this._pos
@@ -1653,7 +1652,7 @@ export class LGraphNode
16531652
inputs ? inputs.filter((input) => !isWidgetInputSlot(input)).length : 1,
16541653
outputs ? outputs.length : 1
16551654
)
1656-
const size = out || new Float32Array([0, 0])
1655+
const size = out ?? [0, 0]
16571656
rows = Math.max(rows, 1)
16581657
// although it should be graphcanvas.inner_text_font size
16591658
const font_size = LiteGraph.NODE_TEXT_SIZE
@@ -2004,13 +2003,13 @@ export class LGraphNode
20042003

20052004
/**
20062005
* returns the bounding of the object, used for rendering purposes
2007-
* @param out {Float32Array[4]?} [optional] a place to store the output, to free garbage
2006+
* @param out {Rect?} [optional] a place to store the output, to free garbage
20082007
* @param includeExternal {boolean?} [optional] set to true to
20092008
* include the shadow and connection points in the bounding calculation
20102009
* @returns the bounding box in format of [topleft_cornerx, topleft_cornery, width, height]
20112010
*/
20122011
getBounding(out?: Rect, includeExternal?: boolean): Rect {
2013-
out ||= new Float32Array(4)
2012+
out ||= [0, 0, 0, 0]
20142013

20152014
const rect = includeExternal ? this.renderArea : this.boundingRect
20162015
out[0] = rect[0]
@@ -3169,7 +3168,7 @@ export class LGraphNode
31693168
* @returns the position
31703169
*/
31713170
getConnectionPos(is_input: boolean, slot_number: number, out?: Point): Point {
3172-
out ||= new Float32Array(2)
3171+
out ||= [0, 0]
31733172

31743173
const {
31753174
pos: [nodeX, nodeY],

src/lib/litegraph/src/LLink.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
ISlotType,
1515
LinkNetwork,
1616
LinkSegment,
17+
Point,
1718
ReadonlyLinkNetwork
1819
} from './interfaces'
1920
import type {
@@ -109,7 +110,7 @@ export class LLink implements LinkSegment, Serialisable<SerialisableLLink> {
109110
data?: number | string | boolean | { toToolTip?(): string }
110111
_data?: unknown
111112
/** Centre point of the link, calculated during render only - can be inaccurate */
112-
_pos: Float32Array
113+
_pos: Point
113114
/** @todo Clean up - never implemented in comfy. */
114115
_last_time?: number
115116
/** The last canvas 2D path that was used to render this link */
@@ -171,7 +172,7 @@ export class LLink implements LinkSegment, Serialisable<SerialisableLLink> {
171172

172173
this._data = null
173174
// center
174-
this._pos = new Float32Array(2)
175+
this._pos = [0, 0]
175176
}
176177

177178
/** @deprecated Use {@link LLink.create} */

0 commit comments

Comments
 (0)