simvx.graphics.render2d.item_list

Column layout

============= ============ ==================================================== column dtype meaning (design §2.1) ============= ============ ==================================================== layer int16 ordering band (CanvasLayer / coarse band) z int32 absolute_z_index within the band seq uint32 structure-derived, frame-stable order key (§2.2) pipeline uint8 :class:PipelineKind {FILL, LINE, GLYPH, TEXTURED} clip_scope int32 index into the :class:ClipScopeTable (§2.5) blend uint8 :class:BlendMode {alpha, add, multiply} transform int32 row index into the per-item LOCAL transform column geometry int32 handle into the retained geometry store texture int32 bindless texture slot (-1 = none) flags uint8 :class:ItemFlags bitfield (is_msdf, lit, …) item_id int64 stable retention key across frames ============= ============ ====================================================

The global draw-order sort is (layer, seq)NOT (layer, z, seq) (design §2.2 / P0 gate 9). z is inherited (absolute_z_index), so a global lexsort on it reproduces the walk only 12/300 trials: a child must draw adjacent to its parent regardless of how its inherited z compares to other subtrees. The fix the design mandates is that the walk folds per-sibling-group local-z into seq (it emits siblings in resolved-z order, assigning monotonic seq), so the global sort is “seq alone” within a band. The z column is retained as data (banding, the z-dirty re-walk decision, debugging), never as a global sort input. (layer, seq) is packed into one uint64 so the sort is a single vectorised argsort.

The render Item as a flat struct-of-arrays (design §2.1, §2.4 design D-A).

A render Item is the unit produced by the collection pass and consumed by sort/batch/submit. It is not baked geometry; it is a reference (geometry + transform + texture handles) plus a key ((layer, z, seq)). This module stores the items as parallel typed numpy columns – the SoA layout the design mandates because the columns are GPU-uploadable, so later GPU-side sort/batch land additively on the same data (§2.4 “GPU-future-proof”).

Nothing here walks a scene tree, touches the GPU, or imports the live render path; that is the point of increment 1. The ItemBuilder walk seam, retention, and submit arrive in later increments and consume these columns.

Module Contents

Classes

PipelineKind

The pipeline class an item draws through (design §2.1).

BlendMode

Per-item blend mode (design §2.1; legacy draw2d_ops.BLEND_MODES).

ItemFlags

The flags column bitfield (design §2.1, §7.4/§7.5).

ItemView

A single render Item read back out of the SoA columns (design §2.1).

ItemList

A growable flat struct-of-arrays of render Items (design §2.1, §2.4).

Functions

pack_sort_key

Pack (layer, seq) columns into one order-preserving uint64.

unpack_sort_key

Inverse of :func:pack_sort_key -> (layer, seq) columns.

Data

API

simvx.graphics.render2d.item_list.__all__

[‘BlendMode’, ‘ItemFlags’, ‘ItemList’, ‘ItemView’, ‘PipelineKind’, ‘pack_sort_key’, ‘unpack_sort_key…

class simvx.graphics.render2d.item_list.PipelineKind[source]

Bases: enum.IntEnum

The pipeline class an item draws through (design §2.1).

Compatible with the legacy draw2d_ops.OpKind values (FILL=0, LINE=1, GLYPH/TEXT=2, TEXTURED/TEX=3); the design renames TEXT->GLYPH and TEX->TEXTURED but keeps the integer codes so the two paths agree.

Initialization

Initialize self. See help(type(self)) for accurate signature.

FILL

0

LINE

1

GLYPH

2

TEXTURED

3

__abs__()
__add__()
__and__()
__bool__()
__ceil__()
__delattr__()
__dir__()
__divmod__()
__eq__()
__float__()
__floor__()
__floordiv__()
__format__()
__ge__()
__getattribute__()
__getnewargs__()
__getstate__()
__gt__()
__hash__()
__index__()
__int__()
__invert__()
__le__()
__lshift__()
__lt__()
__mod__()
__mul__()
__ne__()
__neg__()
__new__()
__or__()
__pos__()
__pow__()
__radd__()
__rand__()
__rdivmod__()
__reduce__()
__reduce_ex__()
__repr__()
__rfloordiv__()
__rlshift__()
__rmod__()
__rmul__()
__ror__()
__round__()
__rpow__()
__rrshift__()
__rshift__()
__rsub__()
__rtruediv__()
__rxor__()
__setattr__()
__sizeof__()
__str__()
__sub__()
__subclasshook__()
__truediv__()
__trunc__()
__xor__()
as_integer_ratio()
bit_count()
bit_length()
conjugate()
class denominator
class imag
is_integer()
class numerator
class real
to_bytes()
__deepcopy__(memo)
__copy__()
name()
value()
class simvx.graphics.render2d.item_list.BlendMode[source]

Bases: enum.IntEnum

Per-item blend mode (design §2.1; legacy draw2d_ops.BLEND_MODES).

Initialization

Initialize self. See help(type(self)) for accurate signature.

ALPHA

0

ADD

1

MULTIPLY

2

__abs__()
__add__()
__and__()
__bool__()
__ceil__()
__delattr__()
__dir__()
__divmod__()
__eq__()
__float__()
__floor__()
__floordiv__()
__format__()
__ge__()
__getattribute__()
__getnewargs__()
__getstate__()
__gt__()
__hash__()
__index__()
__int__()
__invert__()
__le__()
__lshift__()
__lt__()
__mod__()
__mul__()
__ne__()
__neg__()
__new__()
__or__()
__pos__()
__pow__()
__radd__()
__rand__()
__rdivmod__()
__reduce__()
__reduce_ex__()
__repr__()
__rfloordiv__()
__rlshift__()
__rmod__()
__rmul__()
__ror__()
__round__()
__rpow__()
__rrshift__()
__rshift__()
__rsub__()
__rtruediv__()
__rxor__()
__setattr__()
__sizeof__()
__str__()
__sub__()
__subclasshook__()
__truediv__()
__trunc__()
__xor__()
as_integer_ratio()
bit_count()
bit_length()
conjugate()
class denominator
class imag
is_integer()
class numerator
class real
to_bytes()
__deepcopy__(memo)
__copy__()
name()
value()
class simvx.graphics.render2d.item_list.ItemFlags[source]

Bases: enum.IntFlag

The flags column bitfield (design §2.1, §7.4/§7.5).

Initialization

Initialize self. See help(type(self)) for accurate signature.

NONE

0

IS_MSDF

None

LIT

None

SCREEN_SPACE

None

HDR_OPT_IN

None

HDR_OPT_OUT

None

__abs__()
__add__()
__and__()
__bool__()
__ceil__()
__delattr__()
__dir__()
__divmod__()
__eq__()
__float__()
__floor__()
__floordiv__()
__format__()
__ge__()
__getattribute__()
__getnewargs__()
__getstate__()
__gt__()
__hash__()
__index__()
__int__()
__invert__()
__le__()
__lshift__()
__lt__()
__mod__()
__mul__()
__ne__()
__neg__()
__new__()
__or__()
__pos__()
__pow__()
__radd__()
__rand__()
__rdivmod__()
__reduce__()
__reduce_ex__()
__repr__()
__rfloordiv__()
__rlshift__()
__rmod__()
__rmul__()
__ror__()
__round__()
__rpow__()
__rrshift__()
__rshift__()
__rsub__()
__rtruediv__()
__rxor__()
__setattr__()
__sizeof__()
__str__()
__sub__()
__subclasshook__()
__truediv__()
__trunc__()
__xor__()
as_integer_ratio()
bit_count()
bit_length()
conjugate()
class denominator
class imag
is_integer()
class numerator
class real
to_bytes()
__deepcopy__(memo)
__copy__()
name()
value()
__contains__(other)
__iter__()
__len__()
simvx.graphics.render2d.item_list.SEQ_MAX

None

simvx.graphics.render2d.item_list.pack_sort_key(layer: numpy.ndarray, seq: numpy.ndarray) numpy.ndarray[source]

Pack (layer, seq) columns into one order-preserving uint64.

Ascending unsigned order of the result equals ascending lexicographic (layer, seq) – the §2.2 back-to-front ordering law with z already folded into seq by the walk. layer is biased into an unsigned range so negative layers sort first.

simvx.graphics.render2d.item_list.unpack_sort_key(key: numpy.ndarray) tuple[numpy.ndarray, numpy.ndarray][source]

Inverse of :func:pack_sort_key -> (layer, seq) columns.

class simvx.graphics.render2d.item_list.ItemView[source]

Bases: typing.NamedTuple

A single render Item read back out of the SoA columns (design §2.1).

layer: int

None

z: int

None

seq: int

None

pipeline: simvx.graphics.render2d.item_list.PipelineKind

None

clip_scope: int

None

blend: simvx.graphics.render2d.item_list.BlendMode

None

transform: int

None

geometry: int

None

texture: int

None

flags: simvx.graphics.render2d.item_list.ItemFlags

None

item_id: int

None

class simvx.graphics.render2d.item_list.ItemList(capacity: int = 64)[source]

A growable flat struct-of-arrays of render Items (design §2.1, §2.4).

Stores each Item field as its own typed numpy column, all sharing one capacity. Provides :meth:add/:meth:remove/iteration and

Meth:

sorted_order – the vectorised stable sort into draw order. The columns grow geometrically (design §2.7 arena policy, applied here to the item array itself), never silently truncating like the legacy fixed MAX_TEX_VERTS buffers.

This is a data structure, not a renderer: it neither walks a tree nor issues GPU work. Items are added with explicit references/keys; producing those references is the later ItemBuilder’s job.

Initialization

__slots__

(‘_cols’, ‘_count’, ‘_capacity’)

__len__() int[source]
property capacity: int[source]
clear() None[source]

Drop all items (keeps allocated capacity for reuse).

column(name: str) numpy.ndarray[source]

Return a view of the live (length-len(self)) slice of a column.

add(*, layer: int, z: int, seq: int, pipeline: simvx.graphics.render2d.item_list.PipelineKind | int, clip_scope: int, blend: simvx.graphics.render2d.item_list.BlendMode | int = BlendMode.ALPHA, transform: int = -1, geometry: int = -1, texture: int = -1, flags: simvx.graphics.render2d.item_list.ItemFlags | int = ItemFlags.NONE, item_id: int) int[source]

Append one Item; return its current row index.

The row index is positional and unstable across :meth:remove; use item_id for the cross-frame stable identity (design §2.1).

maybe_grow(needed: int) bool[source]

Ensure capacity for needed items, growing geometrically if short.

The explicit arena-growth entry point (design §2.7): the item columns are a growable arena that doubles at a frame boundary, NEVER the legacy fixed MAX_TEX_VERTS cap that silently truncated (>59% of a 10k-sprite scene vanished, P0 gate 6). Returns True if a grow happened. :meth:add already grows on demand; this lets a collector reserve up front (one realloc for a known batch instead of log2(N) doublings).

set_appearance(index: int, *, pipeline: simvx.graphics.render2d.item_list.PipelineKind | int, blend: simvx.graphics.render2d.item_list.BlendMode | int, texture: int, flags: simvx.graphics.render2d.item_list.ItemFlags | int) None[source]

Overwrite the appearance columns of one row in place (P2 item-level patch).

Rewrites only what a colour/texture/blend/msdf change can affect (pipeline/blend/texture/flags); geometry/transform/ seq/layer/z/item_id stay put so the row’s stable retention identity is preserved (design §2.7 item granularity). Colour lives in the geometry verts, refreshed alongside via the geometry store.

remove(index: int) None[source]

Remove the item at index (swap-with-last; order is not preserved).

Positional removal does not preserve draw order – callers re-derive order via :meth:sorted_order from (layer, z, seq), so the physical column order is free to be a swap-remove for O(1) deletion.

get(index: int) simvx.graphics.render2d.item_list.ItemView[source]

Return the Item at the given physical row as an :class:ItemView.

__iter__() collections.abc.Iterator[simvx.graphics.render2d.item_list.ItemView][source]
sort_keys() numpy.ndarray[source]

Return the packed uint64 (layer, seq) key per live item.

sorted_order() numpy.ndarray[source]

Return physical row indices in ascending (layer, seq) order.

STABLE: ties on the (layer, seq) key keep insertion (= physical) order. seq is the structure-derived order key (design §2.2) into which the walk has folded per-sibling-group z, so this is the back-to-front draw order. The sort is not a global z lexsort (P0 gate 9). Vectorised: one argsort over the packed key. kind="stable" makes the tie policy explicit even though the packed key normally makes ties impossible (distinct items get distinct seq within a band).

iter_sorted() collections.abc.Iterator[simvx.graphics.render2d.item_list.ItemView][source]

Iterate items in materialised draw order (design §2.1 “draw order”).