TachyonUI 0.1.0
High-performance UI for building tools.
Loading...
Searching...
No Matches
gui_gradient_manager.h
Go to the documentation of this file.
1#pragma once
2
5
6#include <stdint.h>
7#include <vector>
8#include <span>
9#include <unordered_map>
10
11namespace tachyon
12{
15
16 class Image;
17 class GraphicsContext;
18
26 {
27 uint32_t value = 0;
28
29 constexpr GradientHandle() = default;
30 constexpr explicit GradientHandle(uint32_t v) : value(v) {}
31
33 constexpr bool IsValid() const { return value != 0; }
34 constexpr uint32_t SlotIndex() const { return value >> 8; }
35 constexpr uint8_t Generation() const { return value & 0xFF; }
36
37 constexpr bool operator==(const GradientHandle&) const noexcept = default;
38
39 static constexpr GradientHandle Invalid() { return GradientHandle(0); }
41 static constexpr GradientHandle Make(uint32_t slotIndex1Based, uint8_t generation)
42 {
43 return GradientHandle((slotIndex1Based << 8) | uint32_t(generation));
44 }
45 };
46
49 {
50 uint16_t col = 0;
51 uint16_t row = 0;
52 uint16_t width = 0;
53 uint8_t page = 0;
54 };
55
64 {
65 public:
68 static constexpr uint32_t kMaxPageHeight = 8192;
69
71 static constexpr int32_t kUnregisteredPage = -1;
72
73 public:
75 GradientManager(size_t width = 256);
76
79 void ReleaseAll(GraphicsContext* graphicsContext);
80
88
91
92 GradientHandle AcquireColors(const color4b& c0, const color4b& c1, const color4b& c2);
93 GradientHandle AcquireColors(const color4f& c0, const color4f& c1, const color4f& c2);
94
95 GradientHandle AcquireColors(const color4b& c0, const color4b& c1, const color4b& c2, const color4b& c3);
96 GradientHandle AcquireColors(const color4f& c0, const color4f& c1, const color4f& c2, const color4f& c3);
97
100
102 void AddRef(GradientHandle handle);
105
108
110 bool IsValid(GradientHandle handle) const;
111
113 uint16_t GetRefcount(GradientHandle handle) const;
114
116 inline size_t Width() const noexcept { return m_width; }
117
119 inline uint32_t PageCount() const noexcept { return static_cast<uint32_t>(m_pages.size()); }
120
122 size_t PageHeight(uint32_t pageIndex) const noexcept;
123
125 std::span<const color4b> PageTextureData(uint32_t pageIndex) const noexcept;
126
128 std::span<color4b> PageTextureData(uint32_t pageIndex) noexcept;
130 void MarkPageModified(uint32_t pageIndex) noexcept;
131
138 int32_t GetPagePhysicalImageIndex(uint32_t pageIndex) const noexcept;
139 void SetPagePhysicalImageIndex(uint32_t pageIndex, int32_t shaderSlotZeroBased) noexcept;
140 bool HasPageTableChanged() const noexcept { return m_pageTableDirty; }
141 void ClearPageTableChanged() noexcept { m_pageTableDirty = false; }
143
146 void ClearAll() noexcept;
147
150 tachyon::Image* GetGradientImage(GraphicsContext* graphicsContext, uint32_t pageIndex = 0);
151
152 private:
153 struct Slot
154 {
155 uint64_t contentHash = 0;
156 uint16_t refcount = 0;
157 uint16_t row = 0;
158 uint16_t col = 0;
159 uint16_t width = 0;
160 uint8_t page = 0;
161 uint8_t generation = 0;
162 bool inUse = false;
163 };
164
165 struct Page
166 {
167 uint32_t width = 0;
168 uint32_t height = 0;
169 uint32_t rowsUsed = 0;
170 std::vector<color4b> data;
171 Image* image = nullptr;
172 bool modified = true;
173
176 int32_t smallRow = -1;
177 int32_t smallCursor = 0;
178
179 int32_t physicalImageIndex = kUnregisteredPage;
180 };
181
182 // --- helpers ---
183 GradientHandle AcquireSmall(uint16_t width, uint64_t contentHash,
184 const color4b* colors);
185 GradientHandle AcquireRow(uint64_t contentHash,
186 std::span<const color4b> rowPixels);
187
189 int32_t AllocateSmallSlot(uint16_t width);
190 int32_t AllocateRowSlot();
191
192 uint32_t AllocateSlotStorage(); // returns slot index (into m_slots)
193 void FreeSlotStorage(uint32_t slotIdx);
194
195 bool GrowOrAddPage(uint32_t& outPageIdx, uint32_t& outRow); // for full-row allocs
196 bool EnsureSmallRowAvailable(uint32_t& outPageIdx, uint16_t width);
197
198 Slot* GetSlot(GradientHandle handle);
199 const Slot* GetSlot(GradientHandle handle) const;
200
201 void ReleaseSlot(uint32_t slotIdx);
202
203 static uint64_t HashGradient(const Gradient& g);
204 static uint64_t HashSmall(uint16_t width, const color4b* colors);
205
206 size_t m_width;
207 std::vector<Page> m_pages;
208 std::vector<Slot> m_slots;
209 std::vector<uint32_t> m_freeSlotStorage;
210
214 static constexpr uint32_t kFreeListCount = 6;
215 std::vector<uint32_t> m_freeLists[kFreeListCount];
216
218 std::unordered_map<uint64_t, uint32_t> m_contentDedup;
219
220 bool m_pageTableDirty = true;
221 };
222
223}
void MarkPageModified(uint32_t pageIndex) noexcept
Makes the next GetGradientImage re-upload the page.
void AddRef(GradientHandle handle)
Raises the refcount of a live handle; pair with one Release.
size_t Width() const noexcept
Page width in texels, the same for every page.
Definition gui_gradient_manager.h:116
void ClearAll() noexcept
Releases every slot; every outstanding GradientHandle becomes stale, so holders (StyleManager,...
static constexpr uint32_t kMaxPageHeight
Page height cap; a full page gets a new page instead of growing.
Definition gui_gradient_manager.h:68
int32_t GetPagePhysicalImageIndex(uint32_t pageIndex) const noexcept
GradientHandle AcquireColors(const color4f &c0, const color4f &c1, const color4f &c2)
GradientHandle AcquireColors(const color4b &c0, const color4b &c1)
GradientHandle AcquireSolidColor(const color4f &color)
bool Release(GradientHandle handle)
Lowers the refcount; true when it reached zero and the slot was reclaimed.
GradientHandle AcquireColors(const color4b &c0, const color4b &c1, const color4b &c2, const color4b &c3)
GradientManager(size_t width=256)
An empty atlas whose pages are width texels wide.
bool IsValid(GradientHandle handle) const
True if the handle is live (slot occupied and generation matches).
std::span< const color4b > PageTextureData(uint32_t pageIndex) const noexcept
CPU texels of a page, PageHeight x Width.
void ClearPageTableChanged() noexcept
Definition gui_gradient_manager.h:141
GradientHandle AcquireColors(const color4f &c0, const color4f &c1)
GradientHandle AcquireGradient(const Gradient &g)
GradientHandle AcquireSolidColor(const color4b &color)
void SetPagePhysicalImageIndex(uint32_t pageIndex, int32_t shaderSlotZeroBased) noexcept
tachyon::Image * GetGradientImage(GraphicsContext *graphicsContext, uint32_t pageIndex=0)
The GPU image of a page, created or re-uploaded as needed; nullptr when pageIndex is out of range.
void ReleaseAll(GraphicsContext *graphicsContext)
Destroys every GPU image of the atlas (deferred through graphicsContext).
bool HasPageTableChanged() const noexcept
Definition gui_gradient_manager.h:140
size_t PageHeight(uint32_t pageIndex) const noexcept
Allocated height of a page in rows; the rows in use are at most this.
uint16_t GetRefcount(GradientHandle handle) const
Refcount of a live handle; 0 for an invalid or stale handle.
uint32_t PageCount() const noexcept
Number of pages allocated.
Definition gui_gradient_manager.h:119
std::span< color4b > PageTextureData(uint32_t pageIndex) noexcept
Writable CPU texels of a page; call MarkPageModified after writing.
GradientHandle AcquireColors(const color4f &c0, const color4f &c1, const color4f &c2, const color4f &c3)
AtlasLocation GetLocation(GradientHandle handle) const
The atlas position of a handle; all zero for an invalid or stale handle.
GradientHandle AcquireColors(const color4b &c0, const color4b &c1, const color4b &c2)
static constexpr int32_t kUnregisteredPage
GetPagePhysicalImageIndex of a page the renderer hasn't registered.
Definition gui_gradient_manager.h:71
A graphics backend: the device, the window contexts that render the GUI's windows,...
Definition gui_graphics_context.h:60
An image made by GraphicsContext::CreateImage; the backend defines its contents.
Definition gui_image.h:40
Definition gui_logging.h:24
Where a handle's texels are in the atlas.
Definition gui_gradient_manager.h:49
uint8_t page
logical page index (0..PageCount()-1)
Definition gui_gradient_manager.h:53
uint16_t width
number of columns (1..page.width)
Definition gui_gradient_manager.h:52
uint16_t col
starting column within the row (0..page.width-1)
Definition gui_gradient_manager.h:50
uint16_t row
row index within the page (0..page.height-1)
Definition gui_gradient_manager.h:51
Handle to a reference-counted GradientManager atlas slot.
Definition gui_gradient_manager.h:26
constexpr uint8_t Generation() const
wraps around
Definition gui_gradient_manager.h:35
static constexpr GradientHandle Invalid()
the invalid handle
Definition gui_gradient_manager.h:39
constexpr uint32_t SlotIndex() const
1-based; 0 = invalid
Definition gui_gradient_manager.h:34
constexpr bool IsValid() const
Not the invalid handle; GradientManager::IsValid also checks it's still live.
Definition gui_gradient_manager.h:33
constexpr bool operator==(const GradientHandle &) const noexcept=default
constexpr GradientHandle(uint32_t v)
Definition gui_gradient_manager.h:30
uint32_t value
encoded slot index and generation
Definition gui_gradient_manager.h:27
static constexpr GradientHandle Make(uint32_t slotIndex1Based, uint8_t generation)
Encodes a slot index (1-based) and generation.
Definition gui_gradient_manager.h:41
constexpr GradientHandle()=default
Up to kMaxStops color stops plus an angle and interpolation color space.
Definition gui_style_gradient.h:91
Definition gui_base_types.h:384
Definition gui_base_types.h:395