The engine's memory, in named regions.
More...
#include <deki/providers/Memory.h>
|
| static bool | Initialize () |
| | Returns false on failure.
|
| static void | Shutdown () |
| static void | SetBackend (IMemoryProvider *backend) |
| | Installs the memory provider and takes ownership of it.
|
| static bool | IsInitialized () |
| static void * | Allocate (size_t size, Memory::Region region, AllocContext ctx={}) |
| | Allocates size bytes in region, or returns nullptr.
|
| static void * | AllocateDma (size_t size, Memory::Region region, AllocContext ctx={}) |
| | Allocates memory a DMA engine can read, in region.
|
| static void * | AllocateInternal (size_t size, AllocContext ctx={}) |
| | Allocates size bytes in internal RAM only, never PSRAM, or returns nullptr.
|
| static void | FreeInternal (void *ptr) |
| | Frees memory from AllocateInternal.
|
| static void | Free (void *ptr, AllocContext ctx={}) |
| template<typename T> |
| static T * | AllocateArray (size_t count, Memory::Region region, AllocContext ctx={}) |
| | Allocates count T, or returns nullptr.
|
| static MemoryStats | GetStats () |
| static size_t | GetAvailableExternal () |
| | Free bytes in the External region, 0 when the target has none.
|
| static size_t | GetAvailableInternal () |
| | Free internal RAM in bytes, the figure a project is sized against.
|
| static size_t | GetRawAllocated () |
| | Live bytes on the raw (operator new) path: std::vector, std::string and scalar new.
|
| static void | LogStats (const char *label=nullptr) |
| | Logs what is allocated and what is left, in one line, with an optional label (such as "after level load").
|
| static bool | IsExternalAvailable () |
| | True when the target's provider serves the External region.
|
|
| static const Region | Internal { "internal" } |
| | Internal RAM: fast and scarce, a few hundred KB on an ESP32-S3.
|
| static const Region | External { "external" } |
| | External RAM (PSRAM) where the board has it: megabytes, but much slower because it is reached over SPI.
|
The engine's memory, in named regions.
Internal is the heap every target has; External is a second, larger, slower memory a target may offer (such as PSRAM on a microcontroller). What a region maps to on a target is up to that target's provider.
◆ Initialize()
| bool Deki::Memory::Initialize |
( |
| ) |
|
|
static |
Returns false on failure.
◆ Shutdown()
| void Deki::Memory::Shutdown |
( |
| ) |
|
|
static |
◆ SetBackend()
Installs the memory provider and takes ownership of it.
◆ IsInitialized()
| bool Deki::Memory::IsInitialized |
( |
| ) |
|
|
static |
◆ Allocate()
Allocates size bytes in region, or returns nullptr.
There is no fallback to another region; a region the board's provider does not serve returns nullptr and is named in the log. Leave ctx out: the compiler fills in the call site.
◆ AllocateDma()
Allocates memory a DMA engine can read, in region.
DMA reach is a requirement on top of the region (a framebuffer may live in internal RAM or PSRAM), and a separate entry point keeps it from being dropped. Where all memory is DMA-reachable this is the same as Allocate.
◆ AllocateInternal()
| void * Deki::Memory::AllocateInternal |
( |
size_t | size, |
|
|
AllocContext | ctx = {} ) |
|
static |
Allocates size bytes in internal RAM only, never PSRAM, or returns nullptr.
Leave ctx out: the compiler fills in the call site.
◆ FreeInternal()
| void Deki::Memory::FreeInternal |
( |
void * | ptr | ) |
|
|
static |
Frees memory from AllocateInternal.
◆ Free()
| void Deki::Memory::Free |
( |
void * | ptr, |
|
|
AllocContext | ctx = {} ) |
|
static |
◆ AllocateArray()
Allocates count T, or returns nullptr.
Use it instead of new T[count] for anything sized by a file, a scene or the screen.
new[] cannot fail gracefully on a device: ESP-IDF builds with exceptions off, so a failed allocation calls abort() and reboots the board, and std::nothrow does not help because libstdc++ implements it with the throwing form. A caller that checks for nullptr can carry on instead.
The size multiplication is checked: a count from a corrupt file and a 32-bit size_t would otherwise wrap to a small size.
For trivially copyable T only: nothing is constructed.
◆ GetStats()
◆ GetAvailableExternal()
| size_t Deki::Memory::GetAvailableExternal |
( |
| ) |
|
|
static |
Free bytes in the External region, 0 when the target has none.
◆ GetAvailableInternal()
| size_t Deki::Memory::GetAvailableInternal |
( |
| ) |
|
|
static |
Free internal RAM in bytes, the figure a project is sized against.
0 where the platform does not report it (the desktop provider, since the OS pages).
◆ GetRawAllocated()
| size_t Deki::Memory::GetRawAllocated |
( |
| ) |
|
|
static |
Live bytes on the raw (operator new) path: std::vector, std::string and scalar new.
Requires DEKI_MEMORY_TRACK_RAW and returns 0 without it. Counting needs the block size on free, which only the heap knows, and asking costs about 35% per allocation (on Windows, _msize takes a lock), so only a build that asks counts. Turn it on while hunting where memory went.
Approximate even then: allocations from static initialisers, before the backend exists, are freed through it later, so the total is clamped at zero. A diagnostic, not an invariant.
◆ LogStats()
| void Deki::Memory::LogStats |
( |
const char * | label = nullptr | ) |
|
|
static |
Logs what is allocated and what is left, in one line, with an optional label (such as "after level load").
Debug builds add the live and peak allocation counts.
◆ IsExternalAvailable()
| bool Deki::Memory::IsExternalAvailable |
( |
| ) |
|
|
static |
True when the target's provider serves the External region.
◆ Detail::RawAllocate
◆ Detail::RawFree
◆ Internal
Internal RAM: fast and scarce, a few hundred KB on an ESP32-S3.
◆ External
External RAM (PSRAM) where the board has it: megabytes, but much slower because it is reached over SPI.
Use it only for buffers whose latency does not matter, not for one read every frame.
The documentation for this class was generated from the following file:
- deki-engine/include/deki/providers/Memory.h