Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
atlas_inventory.hpp
Go to the documentation of this file.
1#pragma once
2
3// atlas_inventory.hpp — read-only GPU texture-atlas inventory.
4//
5// The render layer owns several shelf-packed texture atlases — the
6// glyph atlas (SDF text), the image atlas, the gradient ramp atlas,
7// and the path atlas (texture_atlas.hpp). Each one is a GPU texture
8// page that small bitmaps are packed into; when an atlas fills up,
9// rendering either thrashes (evict + re-pack churn) or spills to a
10// fresh page. "Is my SDF atlas thrashing?" is a real perf question.
11//
12// `AtlasInventory` is the answer surface: a small, render-layer-owned
13// collection of `AtlasInfo` snapshots that the inspector overlay's
14// atlas viewer renders. It deliberately holds *value snapshots*, not
15// pointers to live atlases — the inspector reads it on the UI thread
16// while the render thread keeps mutating the real atlases, so a
17// snapshot taken at a known point is the safe contract.
18//
19// What it surfaces is exactly what the Pulp-owned atlas classes can
20// honestly report: per-atlas pixel dimensions, a shelf-packer
21// occupancy estimate, the live entry (packed-region) count, and a
22// page count. Skia manages its own internal SkStrike glyph cache
23// separately and does not expose page-level introspection through a
24// stable public API; this inventory does NOT fabricate numbers for
25// it — it reports the atlases Pulp itself packs.
26
28
29#include <algorithm>
30#include <cstddef>
31#include <string>
32#include <vector>
33
34namespace pulp::render {
35
45
48inline const char* atlas_kind_name(AtlasKind kind) {
49 switch (kind) {
50 case AtlasKind::glyph: return "glyph";
51 case AtlasKind::image: return "image";
52 case AtlasKind::gradient: return "gradient";
53 case AtlasKind::path: return "path";
54 }
55 return "unknown";
56}
57
61struct AtlasInfo {
63 std::string label;
64 int width = 0;
65 int height = 0;
66 int pages = 1;
67 std::size_t entries = 0;
68 float occupancy = 0.0f;
69
71 std::size_t texel_capacity() const {
72 const int safe_width = width < 0 ? 0 : width;
73 const int safe_height = height < 0 ? 0 : height;
74 return static_cast<std::size_t>(safe_width) *
75 static_cast<std::size_t>(safe_height) *
76 static_cast<std::size_t>(pages < 1 ? 1 : pages);
77 }
78
81 int occupancy_percent() const {
82 float clamped = occupancy;
83 if (clamped < 0.0f) clamped = 0.0f;
84 if (clamped > 1.0f) clamped = 1.0f;
85 return static_cast<int>(clamped * 100.0f + 0.5f);
86 }
87};
88
97public:
103 template <typename Atlas>
104 static AtlasInfo snapshot(const Atlas& atlas, AtlasKind kind,
105 std::string label = {}, int pages = 1) {
107 info.kind = kind;
108 info.label = label.empty() ? atlas_kind_name(kind)
109 : std::move(label);
110 info.width = atlas.width();
111 info.height = atlas.height();
112 info.pages = pages < 1 ? 1 : pages;
113 info.entries = atlas.entry_count();
114 info.occupancy = atlas.occupancy();
115 return info;
116 }
117
123 std::string label = {},
124 int ramp_width = 256) {
127 info.label = label.empty() ? atlas_kind_name(AtlasKind::gradient)
128 : std::move(label);
129 info.width = ramp_width < 0 ? 0 : ramp_width;
130 info.height = atlas.row_capacity();
131 info.pages = 1;
132 info.entries = atlas.entry_count();
133 info.occupancy = atlas.occupancy();
134 return info;
135 }
136
138 void add(AtlasInfo info) { atlases_.push_back(std::move(info)); }
139
142 template <typename Atlas>
143 void add_atlas(const Atlas& atlas, AtlasKind kind,
144 std::string label = {}, int pages = 1) {
145 atlases_.push_back(snapshot(atlas, kind, std::move(label), pages));
146 }
147
149 void add_gradient(const GradientAtlas& atlas, std::string label = {},
150 int ramp_width = 256) {
151 atlases_.push_back(
152 snapshot_gradient(atlas, std::move(label), ramp_width));
153 }
154
157 void clear() { atlases_.clear(); }
158
160 const std::vector<AtlasInfo>& atlases() const { return atlases_; }
161
163 std::size_t size() const { return atlases_.size(); }
164
167 bool empty() const { return atlases_.empty(); }
168
170 int total_pages() const {
171 int total = 0;
172 for (const auto& a : atlases_)
173 total += (a.pages < 1 ? 1 : a.pages);
174 return total;
175 }
176
179 std::size_t total_entries() const {
180 std::size_t total = 0;
181 for (const auto& a : atlases_) total += a.entries;
182 return total;
183 }
184
186 float average_occupancy() const {
187 if (atlases_.empty()) return 0.0f;
188 float sum = 0.0f;
189 for (const auto& a : atlases_) {
190 float o = a.occupancy;
191 if (o < 0.0f) o = 0.0f;
192 if (o > 1.0f) o = 1.0f;
193 sum += o;
194 }
195 return sum / static_cast<float>(atlases_.size());
196 }
197
198private:
199 std::vector<AtlasInfo> atlases_;
200};
201
202} // namespace pulp::render
A read-only collection of atlas snapshots for the inspector.
Definition atlas_inventory.hpp:96
int total_pages() const
Total GPU texture pages across every registered atlas.
Definition atlas_inventory.hpp:170
void add_atlas(const Atlas &atlas, AtlasKind kind, std::string label={}, int pages=1)
Snapshot any width/height/occupancy atlas straight into the inventory.
Definition atlas_inventory.hpp:143
const std::vector< AtlasInfo > & atlases() const
All atlas snapshots, in insertion order.
Definition atlas_inventory.hpp:160
bool empty() const
True when no atlas has been registered — the inspector renders the "GPU atlas unavailable" empty stat...
Definition atlas_inventory.hpp:167
float average_occupancy() const
Mean occupancy across all atlases, in [0, 1]; 0 when empty.
Definition atlas_inventory.hpp:186
std::size_t size() const
Number of atlas snapshots held.
Definition atlas_inventory.hpp:163
void add_gradient(const GradientAtlas &atlas, std::string label={}, int ramp_width=256)
Snapshot a GradientAtlas straight into the inventory.
Definition atlas_inventory.hpp:149
static AtlasInfo snapshot_gradient(const GradientAtlas &atlas, std::string label={}, int ramp_width=256)
GradientAtlas is row-packed (no width/height) — give it an explicit dedicated snapshot.
Definition atlas_inventory.hpp:122
static AtlasInfo snapshot(const Atlas &atlas, AtlasKind kind, std::string label={}, int pages=1)
Capture a snapshot of an ImageAtlas / GlyphAtlas / PathAtlas — any atlas type exposing width()/height...
Definition atlas_inventory.hpp:104
std::size_t total_entries() const
Total live packed regions (glyphs / images / ramps / paths) across every atlas.
Definition atlas_inventory.hpp:179
void add(AtlasInfo info)
Append a pre-built AtlasInfo snapshot.
Definition atlas_inventory.hpp:138
void clear()
Drop every snapshot — call before re-populating each frame the inspector refreshes.
Definition atlas_inventory.hpp:157
Gradient atlas — caches evaluated gradient ramps as GPU textures.
Definition texture_atlas.hpp:105
size_t entry_count() const
Definition texture_atlas.hpp:120
float occupancy() const
Definition texture_atlas.hpp:128
int row_capacity() const
Read-only introspection for the inspector's atlas viewer.
Definition texture_atlas.hpp:126
Definition gpu_fwd.hpp:31
const char * atlas_kind_name(AtlasKind kind)
Human-readable name for an AtlasKind — used by the inspector panel and by tests.
Definition atlas_inventory.hpp:48
@ info
Definition gpu_diagnostics.hpp:56
AtlasKind
Which kind of atlas an AtlasInfo describes.
Definition atlas_inventory.hpp:39
@ image
ImageAtlas — packed small images.
Definition atlas_inventory.hpp:41
@ glyph
GlyphAtlas — SDF / custom-text glyph cache.
Definition atlas_inventory.hpp:40
@ path
PathAtlas — rasterized vector paths.
Definition atlas_inventory.hpp:43
@ gradient
GradientAtlas — evaluated gradient ramps (row-packed).
Definition atlas_inventory.hpp:42
STL namespace.
A value-snapshot of one texture atlas's state, taken at a known point.
Definition atlas_inventory.hpp:61
AtlasKind kind
Definition atlas_inventory.hpp:62
int pages
Number of GPU texture pages.
Definition atlas_inventory.hpp:66
float occupancy
Shelf-packer fill fraction, [0, 1].
Definition atlas_inventory.hpp:68
std::string label
Display label (defaults to the kind name).
Definition atlas_inventory.hpp:63
std::size_t entries
Live packed regions (glyphs/images/etc).
Definition atlas_inventory.hpp:67
int occupancy_percent() const
Occupancy clamped to [0, 1] and expressed as a 0-100 percentage, rounded to the nearest integer — the...
Definition atlas_inventory.hpp:81
int width
Atlas page width in texels.
Definition atlas_inventory.hpp:64
int height
Atlas page height in texels.
Definition atlas_inventory.hpp:65
std::size_t texel_capacity() const
Total addressable texels across every page.
Definition atlas_inventory.hpp:71