mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-04 07:01:04 +01:00 
			
		
		
		
	Tables: Fixed unaligned accesses when using TableSetBgColor(ImGuiTableBgTarget_CellBg). (#3872)
ImSpanAllocator: Support for alignment.
This commit is contained in:
		@@ -214,6 +214,7 @@ namespace ImStb
 | 
			
		||||
#define IM_NEWLINE                      "\n"
 | 
			
		||||
#endif
 | 
			
		||||
#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_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
 | 
			
		||||
@@ -545,20 +546,22 @@ struct ImSpan
 | 
			
		||||
 | 
			
		||||
// Helper: ImSpanAllocator<>
 | 
			
		||||
// 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>
 | 
			
		||||
struct ImSpanAllocator
 | 
			
		||||
{
 | 
			
		||||
    char*   BasePtr;
 | 
			
		||||
    int     TotalSize;
 | 
			
		||||
    int     CurrSpan;
 | 
			
		||||
    int     CurrOff;
 | 
			
		||||
    int     CurrIdx;
 | 
			
		||||
    int     Offsets[CHUNKS];
 | 
			
		||||
    int     Sizes[CHUNKS];
 | 
			
		||||
 | 
			
		||||
    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 int   GetArenaSizeInBytes()              { return TotalSize; }
 | 
			
		||||
    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 CurrOff; }
 | 
			
		||||
    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* GetSpanPtrEnd(int n)               { IM_ASSERT(n >= 0 && n < CHUNKS && CurrSpan == CHUNKS); return (n + 1 < CHUNKS) ? BasePtr + Offsets[n + 1] : (void*)(BasePtr + TotalSize); }
 | 
			
		||||
    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 && CurrIdx == CHUNKS); return (void*)(BasePtr + Offsets[n] + Sizes[n]); }
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    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<>
 | 
			
		||||
// Build and iterate a contiguous stream of variable-sized structures.
 | 
			
		||||
// 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.
 | 
			
		||||
template<typename T>
 | 
			
		||||
struct IMGUI_API ImChunkStream
 | 
			
		||||
@@ -602,7 +605,7 @@ struct IMGUI_API ImChunkStream
 | 
			
		||||
    void    clear()                     { Buf.clear(); }
 | 
			
		||||
    bool    empty() const               { return Buf.Size == 0; }
 | 
			
		||||
    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*      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]; }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user