graphics.go RawHistoryFolder
1// Package graphics provides a renderer-neutral, bounded graphics scene.
2//
3// The package stores immutable encoded asset blobs and sparse placements. A
4// scene is mutated by its owner and publishes immutable snapshots for
5// consumers. It deliberately knows nothing about terminal protocols,
6// renderers, image formats, or text state.
7package graphics
8
9import "errors"
10
11var (
12 ErrInvalidRect = errors.New("invalid rectangle")
13 ErrInvalidAsset = errors.New("invalid asset")
14 ErrInvalidPlacement = errors.New("invalid placement")
15 ErrAssetNotFound = errors.New("asset not found")
16 ErrPlacementNotFound = errors.New("placement not found")
17 ErrAssetInUse = errors.New("asset is still in use")
18 ErrTooManyAssets = errors.New("asset quota exceeded")
19 ErrTooManyPlacements = errors.New("placement quota exceeded")
20 ErrEncodedBudget = errors.New("encoded byte budget exceeded")
21 ErrDecodedPixelBudget = errors.New("decoded pixel budget exceeded")
22 ErrGenerationOverflow = errors.New("generation overflow")
23 ErrIdentifierOverflow = errors.New("identifier overflow")
24 ErrInvalidOperation = errors.New("invalid graphics operation")
25 ErrInvalidSceneLimits = errors.New("invalid scene limits")
26)
27
28// AssetID identifies an asset in a scene. Its representation is deliberately
29// private: IDs are only meaningful to the scene that issued them and are not
30// interchangeable with placement IDs.
31type AssetID struct{ value uint64 }
32
33// PlacementID identifies a sparse placement in a scene.
34type PlacementID struct{ value uint64 }
35
36// Valid reports whether the ID was issued by a scene.
37func (id AssetID) Valid() bool { return id.value != 0 }
38
39// Valid reports whether the ID was issued by a scene.
40func (id PlacementID) Valid() bool { return id.value != 0 }
41
42// String returns a stable diagnostic form of the opaque ID.
43func (id AssetID) String() string { return formatID('a', id.value) }
44
45// String returns a stable diagnostic form of the opaque ID.
46func (id PlacementID) String() string { return formatID('p', id.value) }
47
48func formatID(prefix byte, value uint64) string {
49 if value == 0 {
50 return "<invalid>"
51 }
52 var buf [1 + 20]byte
53 buf[0] = prefix
54 i := len(buf)
55 for value != 0 {
56 i--
57 buf[i] = byte('0' + value%10)
58 value /= 10
59 }
60 return string(buf[0:1]) + string(buf[i:])
61}
62
63// Limits bounds live scene resources. Zero-valued limits use the package
64// defaults; this keeps a zero-value configuration bounded as well.
65type Limits struct {
66 MaxAssets uint64
67 MaxPlacements uint64
68 MaxEncodedBytes uint64
69 MaxDecodedPixels uint64
70 MaxEncodedBytesPerAsset uint64
71 MaxDecodedPixelsPerAsset uint64
72}
73
74// Config is an alternate name for Limits for callers that prefer constructor
75// configuration terminology.
76type Config = Limits
77
78// SceneConfig is a descriptive alias for Config.
79type SceneConfig = Limits
80
81// Generation is the monotonically increasing scene generation number.
82type Generation = uint64
83
84// SnapshotRef is an explicit name for an immutable snapshot reference.
85type SnapshotRef = Snapshot
86
87// AssetInput is an alternate name for an asset registration description.
88type AssetInput = AssetBlob
89
90const (
91 DefaultMaxAssets = uint64(1024)
92 DefaultMaxPlacements = uint64(65536)
93 DefaultMaxEncodedBytes = uint64(64 << 20)
94 DefaultMaxDecodedPixels = uint64(256 << 20)
95 DefaultMaxEncodedBytesPerAsset = uint64(16 << 20)
96 DefaultMaxDecodedPixelsPerAsset = uint64(128 << 20)
97)
98
99// AssetFormat identifies the encoded pixel layout supplied by an asset.
100type AssetFormat uint8
101
102const (
103 AssetFormatUnknown AssetFormat = iota
104 AssetFormatRGB
105 AssetFormatRGBA
106 AssetFormatPNG
107)
108
109// AssetBlob is the caller-owned description of one encoded asset. AddAsset
110// copies Encoded before returning, so later caller mutations cannot alter a
111// scene or any snapshot. Format preserves the encoded pixel layout for the
112// renderer. Width and Height describe the decoded pixel extent used for
113// clipping and quota accounting. DecodedPixels, when non-zero, must equal
114// Width*Height; accounting always uses the checked product. Scene.AddAssetOwned
115// and ReplaceAssetOwned instead take ownership of Encoded without copying it.
116type AssetBlob struct {
117 Encoded []byte
118 Format AssetFormat
119 Width, Height int64
120 DecodedPixels uint64
121}
122
123// AssetSpec is the conventional name for an asset input description.
124type AssetSpec = AssetBlob
125
126// PlacementSpec describes one sparse placement. Source defaults to the full
127// asset. Destination is a pixel rectangle. Cells optionally records the
128// cell-space extent associated with the same placement. HasCells and HasLayer
129// preserve explicit zero values when updating an existing placement.
130type PlacementSpec struct {
131 Asset AssetID
132 Source PixelRect
133 Destination PixelRect
134 Cells CellRect
135 HasCells bool
136 Layer int64
137 HasLayer bool
138}
139
140// Viewport can constrain visible fragments in pixel space, cell space, or
141// both. A zero-valued rectangle means that coordinate space is not supplied.
142type Viewport struct {
143 Pixels PixelRect
144 Cells CellRect
145}
146
147// VisibleFragment is the visible part of a placement. Source and Destination
148// are clipped together, preserving the placement's source-to-destination
149// mapping even when the destination is scaled. Cells is populated when the
150// placement and viewport carry cell geometry.
151type VisibleFragment struct {
152 PlacementID PlacementID
153 AssetID AssetID
154 Source PixelRect
155 Destination PixelRect
156 Cells CellRect
157}
158
159// Fragment is a short alias for VisibleFragment.
160type Fragment = VisibleFragment
161
162// Usage reports resources held by the current scene or an immutable snapshot.
163type Usage struct {
164 Assets uint64
165 Placements uint64
166 EncodedBytes uint64
167 DecodedPixels uint64
168}
169
170// OperationKind identifies one transactional scene operation.
171type OperationKind uint8
172
173const (
174 OperationAddAsset OperationKind = iota + 1
175 OperationRemoveAsset
176 OperationPlace
177 OperationUpdatePlacement
178 OperationRemovePlacement
179)
180
181// Operation is a sparse scene operation. Add-asset operations allocate an
182// opaque ID internally; use AddAsset directly when the ID is needed by the
183// caller for a subsequent placement.
184type Operation struct {
185 Kind OperationKind
186 Blob AssetBlob
187 Asset AssetID
188 Placement PlacementSpec
189 PlacementID PlacementID
190}
191
192// Operation aliases make operation construction readable without introducing
193// protocol-specific terminology.
194const (
195 AddAssetOperation = OperationAddAsset
196 RemoveAssetOperation = OperationRemoveAsset
197 PlaceOperation = OperationPlace
198 UpdatePlacementOperation = OperationUpdatePlacement
199 RemovePlacementOperation = OperationRemovePlacement
200)