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.
| Name | Type | Description |
|---|---|---|
contentRoot | object | the RowList's root ContentNode (m.top.content) |
- Type:
- void
(static) calculateTextureItemSpacing(rowItemSpacing) → {integer}
Extracts horizontal item spacing from the RowList rowItemSpacing field.
| Name | Type | Description |
|---|---|---|
rowItemSpacing | dynamic | flat [x,y] or nested [[x,y]] |
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.
| Name | Type | Description |
|---|---|---|
visibleWidth | integer | usable row width, from calculateTextureVisibleWidth |
slotWidth | integer | the row's item width (the cell's own |
itemSpacing | integer | horizontal gap between items, from calculateTextureItemSpacing |
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.
| Name | Type | Description |
|---|---|---|
itemSize | dynamic | RowList itemSize field ([containerWidth, containerHeight]) |
focusXOffset | dynamic | RowList focusXOffset field (array like [96] or empty []) |
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.
| Name | Type | Description |
|---|---|---|
contentRoot | object | the RowList's root ContentNode (m.top.content) |
- 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.
| Name | Type | Description |
|---|---|---|
contentRoot | object | the RowList's root ContentNode (m.top.content) |
- 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.
| Name | Type | Description |
|---|---|---|
contentRoot | object | the RowList's root ContentNode (m.top.content) |
itemSize | dynamic | RowList itemSize field ([containerWidth, containerHeight]) |
focusXOffset | dynamic | RowList focusXOffset field (array like [96] or empty []) |
rowItemSpacing | dynamic | RowList rowItemSpacing field (flat [x,y] or nested [[x,y]]) |
- 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.
| Name | Type | Description |
|---|---|---|
colIndex | integer | the column being asked about |
focusedCol | integer | the row's focused column |
totalItems | integer | item count of the row |
numVisible | integer | from calculateTextureVisibleItemCount |
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.
| Name | Type | Description |
|---|---|---|
contentRoot | object | |
range | object |
- 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 <> cachedUricannot separate them: all three look identical from there.isTextureUnloadedcan: 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.
| Name | Type | Description |
|---|---|---|
isTextureUnloaded | boolean | |
cachedUri | string |
- 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.
| Name | Type | Description |
|---|---|---|
contentRoot | object | the MarkupGrid's root ContentNode (m.data / m.itemGrid.content) |
focusedIndex | dynamic | flat index of the focused item (itemGrid.itemFocused) |
numColumns | integer | number of columns in the grid (itemGrid.numColumns) |
numVisibleRows | integer | number of rows visible on screen (itemGrid.numRows) |
- 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.
| Name | Type | Description |
|---|---|---|
contentRoot | object | the RowList's root ContentNode (m.top.content) |
focusedRow | dynamic | index of the currently focused row (rowItemFocused[0]) |
focusedColumn | dynamic | index of the currently focused column (rowItemFocused[1]) |
numVisibleRows | integer | number of rows visible on screen (RowList.numRows) |
- Type:
- void