yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
arena.h
Go to the documentation of this file.
1#ifndef YAZE_APP_GFX_ARENA_H
2#define YAZE_APP_GFX_ARENA_H
3
4#include <array>
5#include <cstdint>
6#include <functional>
7#include <list>
8#include <memory>
9#include <mutex>
10#include <string>
11#include <tuple>
12#include <unordered_map>
13#include <vector>
14
15#include "app/gfx/core/bitmap.h"
17#include "util/sdl_deleter.h"
18
19namespace yaze {
20namespace gfx {
21
47class Arena {
48 public:
49 static Arena& Get();
50
51 void Initialize(IRenderer* renderer);
52 ~Arena();
53
54 // --- New Deferred Command System ---
58 Bitmap* bitmap; // The bitmap that needs a texture operation
59 uint32_t generation; // Generation at queue time for staleness detection
60 };
61
64 const Bitmap* bitmap) const;
65 void ProcessTextureQueue(IRenderer* renderer);
66 void ClearTextureQueue();
67
76 void RetireBitmap(Bitmap& bitmap);
77
86 size_t DrainRetiredBitmaps(IRenderer* renderer);
87
92 bool HasPendingTextures() const { return !texture_command_queue_.empty(); }
93
99 bool ProcessSingleTexture(IRenderer* renderer);
100
116 bool ProcessTextureQueueWithBudget(IRenderer* renderer, float budget_ms);
117
122 size_t textures_processed = 0; // Total textures processed this session
123 size_t frames_with_work = 0; // Frames that did texture work
124 float total_time_ms = 0.0f; // Total time spent processing
125 float max_frame_time_ms = 0.0f; // Maximum time spent in a single call
126 float avg_texture_time_ms = 0.0f; // Average time per texture
127
128 void Reset() {
131 total_time_ms = 0.0f;
132 max_frame_time_ms = 0.0f;
133 avg_texture_time_ms = 0.0f;
134 }
135 };
136
144
149
150 // --- Surface Management (unchanged) ---
151 SDL_Surface* AllocateSurface(int width, int height, int depth, int format);
152 void FreeSurface(SDL_Surface* surface);
153
154 void Shutdown();
155
156 // Resource tracking for debugging
157 size_t GetTextureCount() const { return textures_.size(); }
158 size_t GetSurfaceCount() const { return surfaces_.size(); }
159 size_t GetPooledTextureCount() const {
161 }
162 size_t GetPooledSurfaceCount() const {
164 }
166 return texture_command_queue_.size();
167 }
169 return retired_texture_handles_.size();
170 }
171
172 // Graphics sheet access (223 total sheets in YAZE)
177 using GraphicsSheets = std::array<gfx::Bitmap, 223>;
179
185 auto gfx_sheet(int i) {
186 if (i < 0 || i >= 223)
187 return gfx::Bitmap{};
188 return gfx_sheets()[i];
189 }
190
196 auto mutable_gfx_sheet(int i) {
197 if (i < 0 || i >= 223)
198 return static_cast<gfx::Bitmap*>(nullptr);
199 return &gfx_sheets()[i];
200 }
201
207
208 // Select stable session-owned display storage. The caller retains it through
209 // rendering and retires its bitmaps before destruction. Null selects the
210 // standalone storage; switching never copies pixels or replaces textures.
211 void BindGraphicsSheets(GraphicsSheets* sheets, const void* owner);
212
213 // Legacy standalone/test ownership marker. Session code must bind storage
214 // and ownership together through BindGraphicsSheets().
215 void set_gfx_sheets_owner(const void* owner) { gfx_sheets_owner_ = owner; }
216 const void* gfx_sheets_owner() const { return gfx_sheets_owner_; }
217
223 void NotifySheetModified(int sheet_index);
224
225 // ========== Palette Change Notification System ==========
226
231 std::function<void(const std::string& group_name, int palette_index)>;
232
239 void NotifyPaletteModified(const std::string& group_name,
240 int palette_index = -1);
241
248
253 void UnregisterPaletteListener(int listener_id);
254
255 // Background buffer access for SNES layer rendering
260 auto& bg1() { return bg1_; }
261
266 auto& bg2() { return bg2_; }
267
268 // ========== LRU Sheet Texture Cache ==========
269
277 void TouchSheet(int sheet_index);
278
290 Bitmap* GetSheetWithCache(int sheet_index);
291
299 void SetSheetCacheSize(size_t max_size);
300
305 size_t GetSheetCacheSize() const { return sheet_cache_max_size_; }
306
311 size_t GetCachedSheetCount() const { return sheet_lru_map_.size(); }
312
320 size_t EvictLRUSheets(size_t count = 0);
321
328 void ClearSheetCache();
329
334 size_t hits = 0; // Sheet accessed and already had texture
335 size_t misses = 0; // Sheet accessed but needed texture creation
336 size_t evictions = 0; // Textures evicted due to cache pressure
337 size_t current_size = 0; // Current number of cached textures
338
339 void Reset() {
340 hits = 0;
341 misses = 0;
342 evictions = 0;
343 current_size = 0;
344 }
345
346 float HitRate() const {
347 size_t total = hits + misses;
348 return total > 0 ? static_cast<float>(hits) / total : 0.0f;
349 }
350 };
351
357 return sheet_cache_stats_;
358 }
359
364
365 private:
366 Arena();
367
370
371 static constexpr int kTilesPerRow = 64;
372 static constexpr int kTilesPerColumn = 64;
373 static constexpr int kTotalTiles = kTilesPerRow * kTilesPerColumn;
374
375 std::array<uint16_t, kTotalTiles> layer1_buffer_;
376 std::array<uint16_t, kTotalTiles> layer2_buffer_;
377
380 const void* gfx_sheets_owner_ = nullptr;
381
382 std::unordered_map<TextureHandle,
383 std::unique_ptr<SDL_Texture, util::SDL_Texture_Deleter>>
385
386 std::unordered_map<SDL_Surface*,
387 std::unique_ptr<SDL_Surface, util::SDL_Surface_Deleter>>
389
390 // Resource pooling for efficient memory management
391 struct TexturePool {
392 std::vector<TextureHandle> available_textures_;
393 std::unordered_map<TextureHandle, std::pair<int, int>> texture_sizes_;
394 static constexpr size_t MAX_POOL_SIZE = 100;
396
397 struct SurfacePool {
398 std::vector<SDL_Surface*> available_surfaces_;
399 std::unordered_map<SDL_Surface*, std::tuple<int, int, int, int>>
401 static constexpr size_t MAX_POOL_SIZE = 100;
403
404 std::vector<TextureCommand> texture_command_queue_;
405 std::vector<TextureHandle> retired_texture_handles_;
407 bool is_shutdown_ = false;
409
410 // Palette change notification system
411 std::unordered_map<int, PaletteChangeCallback> palette_listeners_;
413
414 // LRU sheet texture cache
415 // List stores sheet indices in access order (front = most recent)
416 std::list<int> sheet_lru_list_;
417 // Map from sheet index to iterator in lru_list for O(1) access
418 std::unordered_map<int, std::list<int>::iterator> sheet_lru_map_;
419 size_t sheet_cache_max_size_ = 64; // Default: cache 64 sheet textures
421};
422
423} // namespace gfx
424} // namespace yaze
425
426#endif // YAZE_APP_GFX_ARENA_H
Resource management arena for efficient graphics memory handling.
Definition arena.h:47
IRenderer * renderer_
Definition arena.h:406
size_t sheet_cache_max_size_
Definition arena.h:419
const void * gfx_sheets_owner_
Definition arena.h:380
size_t GetSurfaceCount() const
Definition arena.h:158
std::unordered_map< SDL_Surface *, std::unique_ptr< SDL_Surface, util::SDL_Surface_Deleter > > surfaces_
Definition arena.h:388
void Initialize(IRenderer *renderer)
Definition arena.cc:17
struct yaze::gfx::Arena::TexturePool texture_pool_
bool ProcessTextureQueueWithBudget(IRenderer *renderer, float budget_ms)
Process texture queue with a time budget.
Definition arena.cc:372
size_t retired_texture_handle_count() const
Definition arena.h:168
SDL_Surface * AllocateSurface(int width, int height, int depth, int format)
Definition arena.cc:443
GraphicsSheets gfx_sheets_
Definition arena.h:378
std::unordered_map< TextureHandle, std::unique_ptr< SDL_Texture, util::SDL_Texture_Deleter > > textures_
Definition arena.h:384
BackgroundBuffer bg2_
Definition arena.h:369
std::array< gfx::Bitmap, 223 > GraphicsSheets
Get reference to all graphics sheets.
Definition arena.h:177
size_t GetPooledSurfaceCount() const
Definition arena.h:162
bool HasPendingTextures() const
Check if there are pending textures to process.
Definition arena.h:92
auto gfx_sheet(int i)
Get a specific graphics sheet by index.
Definition arena.h:185
static constexpr int kTotalTiles
Definition arena.h:373
void ClearTextureQueue()
Definition arena.cc:59
Bitmap * GetSheetWithCache(int sheet_index)
Get a sheet with automatic LRU tracking and texture creation.
Definition arena.cc:615
size_t GetTextureCount() const
Definition arena.h:157
void set_gfx_sheets_owner(const void *owner)
Definition arena.h:215
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
Definition arena.cc:39
int RegisterPaletteListener(PaletteChangeCallback callback)
Register a callback for palette change notifications.
Definition arena.cc:580
const void * gfx_sheets_owner() const
Definition arena.h:216
GraphicsSheets * active_gfx_sheets_
Definition arena.h:379
std::array< uint16_t, kTotalTiles > layer2_buffer_
Definition arena.h:376
static constexpr int kTilesPerColumn
Definition arena.h:372
bool HasPendingTextureCommand(TextureCommandType type, const Bitmap *bitmap) const
Definition arena.cc:45
size_t GetPooledTextureCount() const
Definition arena.h:159
static constexpr int kTilesPerRow
Definition arena.h:371
void RetireBitmap(Bitmap &bitmap)
Explicitly retire resources owned by a bitmap that is being erased.
Definition arena.cc:63
auto mutable_gfx_sheets()
Get mutable reference to all graphics sheets.
Definition arena.h:206
const SheetCacheStats & GetSheetCacheStats() const
Get sheet cache statistics.
Definition arena.h:356
size_t DrainRetiredBitmaps(IRenderer *renderer)
Destroy texture handles retired earlier in the frame.
Definition arena.cc:91
GraphicsSheets & gfx_sheets()
Definition arena.h:178
void ResetTextureQueueStats()
Reset texture queue statistics.
Definition arena.h:148
SheetCacheStats sheet_cache_stats_
Definition arena.h:420
std::function< void(const std::string &group_name, int palette_index)> PaletteChangeCallback
Definition arena.h:230
void FreeSurface(SDL_Surface *surface)
Definition arena.cc:475
auto mutable_gfx_sheet(int i)
Get mutable reference to a specific graphics sheet.
Definition arena.h:196
BackgroundBuffer bg1_
Definition arena.h:368
void ProcessTextureQueue(IRenderer *renderer)
Definition arena.cc:211
void BindGraphicsSheets(GraphicsSheets *sheets, const void *owner)
Definition arena.cc:522
bool ProcessSingleTexture(IRenderer *renderer)
Process a single texture command for frame-budget-aware loading.
Definition arena.cc:112
auto & bg2()
Get reference to background layer 2 buffer.
Definition arena.h:266
std::unordered_map< int, std::list< int >::iterator > sheet_lru_map_
Definition arena.h:418
std::unordered_map< int, PaletteChangeCallback > palette_listeners_
Definition arena.h:411
std::vector< TextureHandle > retired_texture_handles_
Definition arena.h:405
std::vector< TextureCommand > texture_command_queue_
Definition arena.h:404
std::array< uint16_t, kTotalTiles > layer1_buffer_
Definition arena.h:375
bool is_shutdown_
Definition arena.h:407
void NotifySheetModified(int sheet_index)
Notify Arena that a graphics sheet has been modified.
Definition arena.cc:532
auto & bg1()
Get reference to background layer 1 buffer.
Definition arena.h:260
struct yaze::gfx::Arena::SurfacePool surface_pool_
void ResetSheetCacheStats()
Reset sheet cache statistics.
Definition arena.h:363
void UnregisterPaletteListener(int listener_id)
Unregister a palette change listener.
Definition arena.cc:587
TextureQueueStats texture_queue_stats_
Definition arena.h:408
size_t texture_command_queue_size() const
Definition arena.h:165
void Shutdown()
Definition arena.cc:489
void SetSheetCacheSize(size_t max_size)
Set the maximum number of sheet textures to keep cached.
Definition arena.cc:648
static Arena & Get()
Definition arena.cc:24
size_t EvictLRUSheets(size_t count=0)
Evict least recently used sheet textures.
Definition arena.cc:660
size_t GetSheetCacheSize() const
Get current sheet cache size limit.
Definition arena.h:305
std::list< int > sheet_lru_list_
Definition arena.h:416
size_t GetCachedSheetCount() const
Get number of sheets currently with textures.
Definition arena.h:311
int next_palette_listener_id_
Definition arena.h:412
void NotifyPaletteModified(const std::string &group_name, int palette_index=-1)
Notify all listeners that a palette has been modified.
Definition arena.cc:562
const TextureQueueStats & GetTextureQueueStats() const
Get texture queue processing statistics.
Definition arena.h:141
void ClearSheetCache()
Clear all sheet texture cache tracking.
Definition arena.cc:697
void TouchSheet(int sheet_index)
Mark a graphics sheet as recently accessed.
Definition arena.cc:597
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:70
Defines an abstract interface for all rendering operations.
Definition irenderer.h:60
void * TextureHandle
An abstract handle representing a texture.
Definition irenderer.h:47
Statistics for sheet cache performance.
Definition arena.h:333
static constexpr size_t MAX_POOL_SIZE
Definition arena.h:401
std::vector< SDL_Surface * > available_surfaces_
Definition arena.h:398
std::unordered_map< SDL_Surface *, std::tuple< int, int, int, int > > surface_info_
Definition arena.h:400
TextureCommandType type
Definition arena.h:57
static constexpr size_t MAX_POOL_SIZE
Definition arena.h:394
std::vector< TextureHandle > available_textures_
Definition arena.h:392
std::unordered_map< TextureHandle, std::pair< int, int > > texture_sizes_
Definition arena.h:393
Statistics for texture queue processing.
Definition arena.h:121