Members

(static, constant) TEXTURE_BUFFER_ROWS

Rows kept loaded on each side of the visible rows (see viewport.rowWindow).

Default Value
  • 2

(static, constant) TEXTURE_BUFFER_THRESHOLD

Maximum items a row can have before horizontal buffer logic kicks in. Rows at or below this count skip the horizontal buffer: all items stay loaded when on screen because they fit comfortably in texture memory.

Default Value
  • 20

Methods

(static) activateTextureManager(contentRoot) → {void}

Activates texture management after initial content load or on onScreenShown. Transitions state from "init" or "hidden" to "active", enabling buffer-based texture management. Callers should update loadedRowRange before calling this.

Parameters:
NameTypeDescription
contentRootobject

the RowList's root ContentNode (m.top.content)

Returns:
Type: 
void

(static) calculateTextureItemSpacing(rowItemSpacing) → {integer}

Extracts horizontal item spacing from the RowList rowItemSpacing field.

Parameters:
NameTypeDescription
rowItemSpacingdynamic

flat [x,y] or nested [[x,y]]

Returns:

horizontal spacing in pixels

Type: 
integer

(static) calculateTextureVisibleItemCount(visibleWidth, slotWidth, itemSpacing) → {integer}

How many item slots of one row are visible at once. A partly visible slot at the right edge counts, because it renders.

Parameters:
NameTypeDescription
visibleWidthinteger

usable row width, from calculateTextureVisibleWidth

slotWidthinteger

the row's item width (the cell's own width)

itemSpacinginteger

horizontal gap between items, from calculateTextureItemSpacing

Returns:

visible slot count; 0 when the slot width cannot be used

Type: 
integer

(static) calculateTextureVisibleWidth(itemSize, focusXOffset) → {integer}

Calculates the usable row width for determining how many items fit on screen.

Parameters:
NameTypeDescription
itemSizedynamic

RowList itemSize field ([containerWidth, containerHeight])

focusXOffsetdynamic

RowList focusXOffset field (array like [96] or empty [])

Returns:

usable pixel width

Type: 
integer

(static) destroyTextureManager(contentRoot) → {void}

Destroys texture management during component teardown. All cells force-unload unconditionally: no guards, no buffer checks.

Parameters:
NameTypeDescription
contentRootobject

the RowList's root ContentNode (m.top.content)

Returns:
Type: 
void

(static) hideTextureManager(contentRoot) → {void}

Hides texture management when the screen is no longer visible. Freezes all cells in their current state: textures stay loaded so returning is instant. renderTracking changes are ignored while hidden.

Parameters:
NameTypeDescription
contentRootobject

the RowList's root ContentNode (m.top.content)

Returns:
Type: 
void

(static) initTextureManager(contentRoot, itemSize, focusXOffset, rowItemSpacing) → {void}

Adds texture management fields to a RowList content root node. Sets initial state to "init", so cells will not unload during layout changes.

Parameters:
NameTypeDescription
contentRootobject

the RowList's root ContentNode (m.top.content)

itemSizedynamic

RowList itemSize field ([containerWidth, containerHeight])

focusXOffsetdynamic

RowList focusXOffset field (array like [96] or empty [])

rowItemSpacingdynamic

RowList rowItemSpacing field (flat [x,y] or nested [[x,y]])

Returns:
Type: 
void

(static) isColumnInTextureWindow(colIndex, focusedCol, totalItems, numVisible) → {boolean}

Whether one column of a long RowList row belongs to the horizontal texture window.

The window keeps TEXTURE_BUFFER_THRESHOLD textures loaded: the visible slots plus the remaining budget split around them, the odd item going to the right. It wraps, because Home's rows use fixedFocusWrap: at column 0 the left half sits at the row's TAIL, which is the item drawn in the focusXOffset gap and one Left press away.

Pure so the geometry can be pinned by unit tests. The column sets those tests assert were read off a Stick 4K with an RTA cell census (32- and 100-item portrait rows), so a change here that moves the window fails a test rather than needing a device to notice.

Parameters:
NameTypeDescription
colIndexinteger

the column being asked about

focusedColinteger

the row's focused column

totalItemsinteger

item count of the row

numVisibleinteger

from calculateTextureVisibleItemCount

Returns:

true when the column's texture should stay loaded

Type: 
boolean

(static) setLoadedRowRange(contentRoot, range) → {void}

Writes range to loadedRowRange only when it differs, so cells observing the field are not woken by a focus move that leaves the window where it was.

Parameters:
NameTypeDescription
contentRootobject
rangeobject
Returns:
Type: 
void

(static) shouldReloadTexture(isTextureUnloaded, cachedUri) → {boolean}

Decides whether a cell scrolling back into range should re-issue its image load.

THREE paths leave a cell's poster at "" with the real URL still cached, and they do not all want the same thing:

  • unloadTexture() : the manager evicted a resident texture to free memory.
  • deferTextureLoad() : the cell bound while off screen, so no request was ever issued.
  • showPlaceholder() : the image FAILED, and the URI was cleared to reveal the type glyph underneath. The first two want the load; the third does not, because re-requesting a known-broken image wipes the glyph off a cell that is sitting still and then fails again. Deciding on currentUri <> cachedUri cannot separate them: all three look identical from there. isTextureUnloaded can: the first two set it, showPlaceholder does not.

Worth knowing before "fixing" the missing retry: a failed image does not retry while its cell stays in range, only at the next unload or rebind. That is deliberate, and the measurement behind it is recorded as failed-poster-no-scroll-retry in docs/decisions.md.

Parameters:
NameTypeDescription
isTextureUnloadedboolean
cachedUristring
Returns:
Type: 
boolean

(static) updateGridTextureBufferRange(contentRoot, focusedIndex, numColumns, numVisibleRows) → {void}

Calculates and sets the loaded row range for a MarkupGrid based on current focus. Unlike updateTextureBufferRange() which works with hierarchical RowList content (children = rows), this works with flat MarkupGrid content (children = items) and derives row indices from the flat item index and column count.

Parameters:
NameTypeDescription
contentRootobject

the MarkupGrid's root ContentNode (m.data / m.itemGrid.content)

focusedIndexdynamic

flat index of the focused item (itemGrid.itemFocused)

numColumnsinteger

number of columns in the grid (itemGrid.numColumns)

numVisibleRowsinteger

number of rows visible on screen (itemGrid.numRows)

Returns:
Type: 
void

(static) updateTextureBufferRange(contentRoot, focusedRow, focusedColumn, numVisibleRows) → {void}

Calculates and sets the loaded row range and focused column based on current focus. The vertical range includes all visible rows plus a 2-row buffer above and below.

Parameters:
NameTypeDescription
contentRootobject

the RowList's root ContentNode (m.top.content)

focusedRowdynamic

index of the currently focused row (rowItemFocused[0])

focusedColumndynamic

index of the currently focused column (rowItemFocused[1])

numVisibleRowsinteger

number of rows visible on screen (RowList.numRows)

Returns:
Type: 
void