mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-28 00:39:02 +08:00
Tables: Fixed unaligned accesses when using TableSetBgColor(ImGuiTableBgTarget_CellBg). (#3872)
ImSpanAllocator: Support for alignment.
This commit is contained in:
parent
1ddaff83d8
commit
d8c88bd943
@ -51,6 +51,7 @@ Other Changes:
|
|||||||
- Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible
|
- Window: Shrink close button hit-testing region when it covers an abnormally high portion of the window visible
|
||||||
area (e.g. when window is collapsed + moved in a corner) to facilitate moving the window away. (#3825)
|
area (e.g. when window is collapsed + moved in a corner) to facilitate moving the window away. (#3825)
|
||||||
- Window, Nav: Fixed crash when calling SetWindowFocus(NULL) as the time a new window appears. (#3865) [@nem0]
|
- Window, Nav: Fixed crash when calling SetWindowFocus(NULL) as the time a new window appears. (#3865) [@nem0]
|
||||||
|
- Tables: Fixed unaligned accesses when using TableSetBgColor(ImGuiTableBgTarget_CellBg). (#3872)
|
||||||
- Added GetAllocatorFunctions() to facilitate sharing allocators accross DLL boundaries. (#3836)
|
- Added GetAllocatorFunctions() to facilitate sharing allocators accross DLL boundaries. (#3836)
|
||||||
- ImFontAtlas: Added 'bool TexPixelsUseColors' output to help backend decide of underlying texture format. (#3369)
|
- ImFontAtlas: Added 'bool TexPixelsUseColors' output to help backend decide of underlying texture format. (#3369)
|
||||||
This can currently only ever be set by the Freetype renderer.
|
This can currently only ever be set by the Freetype renderer.
|
||||||
|
@ -214,6 +214,7 @@ namespace ImStb
|
|||||||
#define IM_NEWLINE "\n"
|
#define IM_NEWLINE "\n"
|
||||||
#endif
|
#endif
|
||||||
#define IM_TABSIZE (4)
|
#define IM_TABSIZE (4)
|
||||||
|
#define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + (_ALIGN - 1)) & ~(_ALIGN - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8
|
||||||
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
|
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
|
||||||
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
|
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
|
||||||
#define IM_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds
|
#define IM_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds
|
||||||
@ -545,20 +546,22 @@ struct ImSpan
|
|||||||
|
|
||||||
// Helper: ImSpanAllocator<>
|
// Helper: ImSpanAllocator<>
|
||||||
// Facilitate storing multiple chunks into a single large block (the "arena")
|
// Facilitate storing multiple chunks into a single large block (the "arena")
|
||||||
|
// - Usage: call Reserve() N times, allocate GetArenaSizeInBytes() worth, pass it to SetArenaBasePtr(), call GetSpan() N times to retrieve the aligned ranges.
|
||||||
template<int CHUNKS>
|
template<int CHUNKS>
|
||||||
struct ImSpanAllocator
|
struct ImSpanAllocator
|
||||||
{
|
{
|
||||||
char* BasePtr;
|
char* BasePtr;
|
||||||
int TotalSize;
|
int CurrOff;
|
||||||
int CurrSpan;
|
int CurrIdx;
|
||||||
int Offsets[CHUNKS];
|
int Offsets[CHUNKS];
|
||||||
|
int Sizes[CHUNKS];
|
||||||
|
|
||||||
ImSpanAllocator() { memset(this, 0, sizeof(*this)); }
|
ImSpanAllocator() { memset(this, 0, sizeof(*this)); }
|
||||||
inline void ReserveBytes(int n, size_t sz) { IM_ASSERT(n == CurrSpan && n < CHUNKS); IM_UNUSED(n); Offsets[CurrSpan++] = TotalSize; TotalSize += (int)sz; }
|
inline void Reserve(int n, size_t sz, int a=4) { IM_ASSERT(n == CurrIdx && n < CHUNKS); CurrOff = IM_MEMALIGN(CurrOff, a); Offsets[n] = CurrOff; Sizes[n] = (int)sz; CurrIdx++; CurrOff += (int)sz; }
|
||||||
inline int GetArenaSizeInBytes() { return TotalSize; }
|
inline int GetArenaSizeInBytes() { return CurrOff; }
|
||||||
inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; }
|
inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; }
|
||||||
inline void* GetSpanPtrBegin(int n) { IM_ASSERT(n >= 0 && n < CHUNKS && CurrSpan == CHUNKS); return (void*)(BasePtr + Offsets[n]); }
|
inline void* GetSpanPtrBegin(int n) { IM_ASSERT(n >= 0 && n < CHUNKS && CurrIdx == CHUNKS); return (void*)(BasePtr + Offsets[n]); }
|
||||||
inline void* GetSpanPtrEnd(int n) { IM_ASSERT(n >= 0 && n < CHUNKS && CurrSpan == CHUNKS); return (n + 1 < CHUNKS) ? BasePtr + Offsets[n + 1] : (void*)(BasePtr + TotalSize); }
|
inline void* GetSpanPtrEnd(int n) { IM_ASSERT(n >= 0 && n < CHUNKS && CurrIdx == CHUNKS); return (void*)(BasePtr + Offsets[n] + Sizes[n]); }
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void GetSpan(int n, ImSpan<T>* span) { span->set((T*)GetSpanPtrBegin(n), (T*)GetSpanPtrEnd(n)); }
|
inline void GetSpan(int n, ImSpan<T>* span) { span->set((T*)GetSpanPtrBegin(n), (T*)GetSpanPtrEnd(n)); }
|
||||||
};
|
};
|
||||||
@ -592,7 +595,7 @@ struct IMGUI_API ImPool
|
|||||||
// Helper: ImChunkStream<>
|
// Helper: ImChunkStream<>
|
||||||
// Build and iterate a contiguous stream of variable-sized structures.
|
// Build and iterate a contiguous stream of variable-sized structures.
|
||||||
// This is used by Settings to store persistent data while reducing allocation count.
|
// This is used by Settings to store persistent data while reducing allocation count.
|
||||||
// We store the chunk size first, and align the final size on 4 bytes boundaries (this what the '(X + 3) & ~3' statement is for)
|
// We store the chunk size first, and align the final size on 4 bytes boundaries.
|
||||||
// The tedious/zealous amount of casting is to avoid -Wcast-align warnings.
|
// The tedious/zealous amount of casting is to avoid -Wcast-align warnings.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct IMGUI_API ImChunkStream
|
struct IMGUI_API ImChunkStream
|
||||||
@ -602,7 +605,7 @@ struct IMGUI_API ImChunkStream
|
|||||||
void clear() { Buf.clear(); }
|
void clear() { Buf.clear(); }
|
||||||
bool empty() const { return Buf.Size == 0; }
|
bool empty() const { return Buf.Size == 0; }
|
||||||
int size() const { return Buf.Size; }
|
int size() const { return Buf.Size; }
|
||||||
T* alloc_chunk(size_t sz) { size_t HDR_SZ = 4; sz = ((HDR_SZ + sz) + 3u) & ~3u; int off = Buf.Size; Buf.resize(off + (int)sz); ((int*)(void*)(Buf.Data + off))[0] = (int)sz; return (T*)(void*)(Buf.Data + off + (int)HDR_SZ); }
|
T* alloc_chunk(size_t sz) { size_t HDR_SZ = 4; sz = IM_MEMALIGN(HDR_SZ + sz, 4u); int off = Buf.Size; Buf.resize(off + (int)sz); ((int*)(void*)(Buf.Data + off))[0] = (int)sz; return (T*)(void*)(Buf.Data + off + (int)HDR_SZ); }
|
||||||
T* begin() { size_t HDR_SZ = 4; if (!Buf.Data) return NULL; return (T*)(void*)(Buf.Data + HDR_SZ); }
|
T* begin() { size_t HDR_SZ = 4; if (!Buf.Data) return NULL; return (T*)(void*)(Buf.Data + HDR_SZ); }
|
||||||
T* next_chunk(T* p) { size_t HDR_SZ = 4; IM_ASSERT(p >= begin() && p < end()); p = (T*)(void*)((char*)(void*)p + chunk_size(p)); if (p == (T*)(void*)((char*)end() + HDR_SZ)) return (T*)0; IM_ASSERT(p < end()); return p; }
|
T* next_chunk(T* p) { size_t HDR_SZ = 4; IM_ASSERT(p >= begin() && p < end()); p = (T*)(void*)((char*)(void*)p + chunk_size(p)); if (p == (T*)(void*)((char*)end() + HDR_SZ)) return (T*)0; IM_ASSERT(p < end()); return p; }
|
||||||
int chunk_size(const T* p) { return ((const int*)p)[-1]; }
|
int chunk_size(const T* p) { return ((const int*)p)[-1]; }
|
||||||
|
@ -538,9 +538,9 @@ void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count)
|
|||||||
{
|
{
|
||||||
// Allocate single buffer for our arrays
|
// Allocate single buffer for our arrays
|
||||||
ImSpanAllocator<3> span_allocator;
|
ImSpanAllocator<3> span_allocator;
|
||||||
span_allocator.ReserveBytes(0, columns_count * sizeof(ImGuiTableColumn));
|
span_allocator.Reserve(0, columns_count * sizeof(ImGuiTableColumn));
|
||||||
span_allocator.ReserveBytes(1, columns_count * sizeof(ImGuiTableColumnIdx));
|
span_allocator.Reserve(1, columns_count * sizeof(ImGuiTableColumnIdx));
|
||||||
span_allocator.ReserveBytes(2, columns_count * sizeof(ImGuiTableCellData));
|
span_allocator.Reserve(2, columns_count * sizeof(ImGuiTableCellData), 4);
|
||||||
table->RawData = IM_ALLOC(span_allocator.GetArenaSizeInBytes());
|
table->RawData = IM_ALLOC(span_allocator.GetArenaSizeInBytes());
|
||||||
memset(table->RawData, 0, span_allocator.GetArenaSizeInBytes());
|
memset(table->RawData, 0, span_allocator.GetArenaSizeInBytes());
|
||||||
span_allocator.SetArenaBasePtr(table->RawData);
|
span_allocator.SetArenaBasePtr(table->RawData);
|
||||||
|
Loading…
Reference in New Issue
Block a user