diff --git a/examples/07-callback/callback.cpp b/examples/07-callback/callback.cpp index 483918ce..fb48fc28 100644 --- a/examples/07-callback/callback.cpp +++ b/examples/07-callback/callback.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "fpumath.h" #include "aviwriter.h" @@ -311,14 +312,50 @@ struct BgfxCallback : public bgfx::CallbackI AviWriter* m_writer; }; +class BgfxAllocator : public bx::ReallocatorI +{ +public: + BgfxAllocator() + { + } + + virtual ~BgfxAllocator() + { + } + + virtual void* alloc(size_t _size, const char* _file, uint32_t _line) BX_OVERRIDE + { + BX_UNUSED(_file, _line); + void* ptr = ::malloc(_size); + BX_TRACE("ALLOC %p of %d byte(s) at %s line %d.", ptr, _size, _file, _line); + return ptr; + } + + virtual void free(void* _ptr, const char* _file, uint32_t _line) BX_OVERRIDE + { + BX_TRACE("FREE %p at %s line %d.", ptr, _file, _line); + BX_UNUSED(_file, _line); + ::free(_ptr); + } + + virtual void* realloc(void* _ptr, size_t _size, const char* _file, uint32_t _line) BX_OVERRIDE + { + BX_UNUSED(_file, _line); + void* ptr = ::realloc(_ptr, _size); + BX_TRACE("REALLOC %p (old %p) of %d byte(s) at %s line %d.", ptr, _ptr, _size, _file, _line); + return ptr; + } +}; + int _main_(int /*_argc*/, char** /*_argv*/) { BgfxCallback callback; + BgfxAllocator allocator; uint32_t width = 1280; uint32_t height = 720; - bgfx::init(&callback); + bgfx::init(&callback, &allocator); bgfx::reset(width, height, BGFX_RESET_CAPTURE); // Enable debug text. diff --git a/include/bgfx.h b/include/bgfx.h index fa9f1637..2d093a3b 100644 --- a/include/bgfx.h +++ b/include/bgfx.h @@ -230,6 +230,8 @@ #define BGFX_HANDLE(_name) struct _name { uint16_t idx; } #define BGFX_INVALID_HANDLE { bgfx::invalidHandle } +namespace bx { struct ReallocatorI; } + /// BGFX namespace bgfx { @@ -365,9 +367,6 @@ namespace bgfx BGFX_HANDLE(VertexDeclHandle); BGFX_HANDLE(VertexShaderHandle); - typedef void* (*ReallocFn)(void* _ptr, size_t _size); - typedef void (*FreeFn)(void* _ptr); - /// Callback interface to implement application specific behavior. /// Cached items are currently used only for OpenGL binary shaders. /// @@ -549,15 +548,11 @@ namespace bgfx /// @param _callback Provide application specific callback interface. /// See: CallbackI /// - /// @param _realloc Custom realloc function. - /// @param _free Custom free function. - /// - /// NOTE: In order to properly set custom allocator realloc and free, - /// both functions must be provided. When custom allocator is not + /// @param _reallocator Custom allocator. When custom allocator is not /// specified, library uses default CRT allocator. The library assumes /// custom allocator is thread safe. /// - void init(CallbackI* _callback = NULL, ReallocFn _realloc = NULL, FreeFn _free = NULL); + void init(CallbackI* _callback = NULL, bx::ReallocatorI* _reallocator = NULL); /// Shutdown bgfx library. void shutdown(); diff --git a/src/bgfx.cpp b/src/bgfx.cpp index 8e9d21f5..eaa5f04c 100755 --- a/src/bgfx.cpp +++ b/src/bgfx.cpp @@ -10,12 +10,12 @@ namespace tinystl { void* bgfx_allocator::static_allocate(size_t _bytes) { - return bgfx::g_realloc(NULL, _bytes); + return BX_ALLOC(g_allocator, _bytes); } void bgfx_allocator::static_deallocate(void* _ptr, size_t /*_bytes*/) { - bgfx::g_free(_ptr); + BX_FREE(g_allocator, _ptr); } } // namespace tinystl @@ -115,24 +115,10 @@ namespace bgfx }; static CallbackStub s_callbackStub; - - static void* reallocStub(void* _ptr, size_t _size) - { - void* ptr = ::realloc(_ptr, _size); - BX_CHECK(NULL != ptr, "Out of memory!"); - // BX_TRACE("alloc %d, %p", _size, ptr); - return ptr; - } - - static void freeStub(void* _ptr) - { - // BX_TRACE("free %p", _ptr); - ::free(_ptr); - } + static bx::CrtAllocator s_allocatorStub; CallbackI* g_callback = &s_callbackStub; - ReallocFn g_realloc = reallocStub; - FreeFn g_free = freeStub; + bx::ReallocatorI* g_allocator = &s_allocatorStub; static BX_THREAD uint32_t s_threadIndex = 0; static Context s_ctx; @@ -576,18 +562,16 @@ namespace bgfx #endif // BGFX_CONFIG_RENDERER_ } - void init(CallbackI* _callback, ReallocFn _realloc, FreeFn _free) + void init(CallbackI* _callback, bx::ReallocatorI* _allocator) { if (NULL != _callback) { g_callback = _callback; } - if (NULL != _realloc - && NULL != _free) + if (NULL != _allocator) { - g_realloc = _realloc; - g_free = _free; + g_allocator = _allocator; } s_threadIndex = BGFX_MAIN_THREAD_MAGIC; @@ -603,8 +587,7 @@ namespace bgfx s_threadIndex = 0; g_callback = &s_callbackStub; - g_realloc = reallocStub; - g_free = freeStub; + g_allocator = &s_allocatorStub; } void reset(uint32_t _width, uint32_t _height, uint32_t _flags) @@ -780,7 +763,7 @@ namespace bgfx const Memory* alloc(uint32_t _size) { - Memory* mem = (Memory*)g_realloc(NULL, sizeof(Memory) + _size); + Memory* mem = (Memory*)BX_ALLOC(g_allocator, sizeof(Memory) + _size); mem->size = _size; mem->data = (uint8_t*)mem + sizeof(Memory); return mem; @@ -788,7 +771,7 @@ namespace bgfx const Memory* makeRef(const void* _data, uint32_t _size) { - Memory* mem = (Memory*)g_realloc(NULL, sizeof(Memory) ); + Memory* mem = (Memory*)BX_ALLOC(g_allocator, sizeof(Memory) ); mem->size = _size; mem->data = (uint8_t*)_data; return mem; @@ -797,7 +780,7 @@ namespace bgfx void release(const Memory* _mem) { BX_CHECK(NULL != _mem, "_mem can't be NULL"); - g_free(const_cast(_mem) ); + BX_FREE(g_allocator, const_cast(_mem) ); } void setDebug(uint32_t _debug) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 11edeb56..8280fe30 100755 --- a/src/bgfx_p.h +++ b/src/bgfx_p.h @@ -48,6 +48,7 @@ namespace bgfx # define BX_TRACE _BX_TRACE # define BX_WARN _BX_WARN # define BX_CHECK _BX_CHECK +# define BX_CONFIG_ALLOCATOR_DEBUG 1 #endif // BGFX_CONFIG_DEBUG #define BGFX_FATAL(_condition, _err, _format, ...) \ @@ -226,8 +227,7 @@ namespace bgfx extern const uint32_t g_uniformTypeSize[UniformType::Count+1]; extern CallbackI* g_callback; - extern ReallocFn g_realloc; - extern FreeFn g_free; + extern bx::ReallocatorI* g_allocator; void release(const Memory* _mem); const char* getAttribName(Attrib::Enum _attr); @@ -308,7 +308,7 @@ namespace bgfx ~TextVideoMem() { - g_free(m_mem); + BX_FREE(g_allocator, m_mem); } void resize(bool _small = false, uint16_t _width = BGFX_DEFAULT_WIDTH, uint16_t _height = BGFX_DEFAULT_HEIGHT) @@ -328,7 +328,7 @@ namespace bgfx uint32_t size = m_size; m_size = m_width * m_height * 2; - m_mem = (uint8_t*)g_realloc(m_mem, m_size); + m_mem = (uint8_t*)BX_REALLOC(g_allocator, m_mem, m_size); if (size < m_size) { @@ -734,14 +734,14 @@ namespace bgfx static ConstantBuffer* create(uint32_t _size) { uint32_t size = BX_ALIGN_16(bx::uint32_max(_size, sizeof(ConstantBuffer) ) ); - void* data = g_realloc(NULL, size); + void* data = BX_ALLOC(g_allocator, size); return ::new(data) ConstantBuffer(_size); } static void destroy(ConstantBuffer* _constantBuffer) { _constantBuffer->~ConstantBuffer(); - g_free(_constantBuffer); + BX_FREE(g_allocator, _constantBuffer); } static uint32_t encodeOpcode(UniformType::Enum _type, uint16_t _loc, uint16_t _num, uint16_t _copy) @@ -1132,7 +1132,7 @@ namespace bgfx m_state.m_instanceDataStride = _idb->stride; m_state.m_numInstances = bx::uint16_min( (uint16_t)_idb->num, _num); m_state.m_instanceDataBuffer = _idb->handle; - g_free(const_cast(_idb) ); + BX_FREE(g_allocator, const_cast(_idb) ); } void setProgram(ProgramHandle _handle) @@ -1846,7 +1846,7 @@ namespace bgfx cmdbuf.write(handle); cmdbuf.write(_size); - ib = (TransientIndexBuffer*)g_realloc(NULL, sizeof(TransientIndexBuffer)+_size); + ib = (TransientIndexBuffer*)BX_ALLOC(g_allocator, sizeof(TransientIndexBuffer)+_size); ib->data = (uint8_t*)&ib[1]; ib->size = _size; ib->handle = handle; @@ -1861,7 +1861,7 @@ namespace bgfx cmdbuf.write(_ib->handle); m_submit->free(_ib->handle); - g_free(const_cast(_ib) ); + BX_FREE(g_allocator, const_cast(_ib) ); } void allocTransientIndexBuffer(TransientIndexBuffer* _tib, uint32_t _num) @@ -1900,7 +1900,7 @@ namespace bgfx cmdbuf.write(handle); cmdbuf.write(_size); - vb = (TransientVertexBuffer*)g_realloc(NULL, sizeof(TransientVertexBuffer)+_size); + vb = (TransientVertexBuffer*)BX_ALLOC(g_allocator, sizeof(TransientVertexBuffer)+_size); vb->data = (uint8_t*)&vb[1]; vb->size = _size; vb->startVertex = 0; @@ -1918,7 +1918,7 @@ namespace bgfx cmdbuf.write(_vb->handle); m_submit->free(_vb->handle); - g_free(const_cast(_vb) ); + BX_FREE(g_allocator, const_cast(_vb) ); } void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, const VertexDecl& _decl) @@ -1953,7 +1953,7 @@ namespace bgfx uint32_t offset = m_submit->allocTransientVertexBuffer(_num, stride); TransientVertexBuffer& dvb = *m_submit->m_transientVb; - InstanceDataBuffer* idb = (InstanceDataBuffer*)g_realloc(NULL, sizeof(InstanceDataBuffer) ); + InstanceDataBuffer* idb = (InstanceDataBuffer*)BX_ALLOC(g_allocator, sizeof(InstanceDataBuffer) ); idb->data = &dvb.data[offset]; idb->size = _num * stride; idb->offset = offset; diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index af90e0dc..49617170 100644 --- a/src/renderer_d3d11.cpp +++ b/src/renderer_d3d11.cpp @@ -1696,7 +1696,7 @@ namespace bgfx if (convert) { - uint8_t* temp = (uint8_t*)g_realloc(NULL, mip.m_width*mip.m_height*bpp/8); + uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, mip.m_width*mip.m_height*bpp/8); imageDecodeToBgra8(temp, mip.m_data, mip.m_width, mip.m_height, mip.m_format); srd[kk].pSysMem = temp; @@ -1792,7 +1792,7 @@ namespace bgfx { for (uint32_t lod = 0, num = imageContainer.m_numMips; lod < num; ++lod) { - g_free(const_cast(srd[kk].pSysMem) ); + BX_FREE(g_allocator, const_cast(srd[kk].pSysMem) ); ++kk; } } @@ -1840,7 +1840,7 @@ namespace bgfx if (convert) { - uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*_rect.m_height); + uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, srcpitch*_rect.m_height); imageDecodeToBgra8(temp, data, _rect.m_width, _rect.m_height, m_requestedFormat); data = temp; } @@ -1849,7 +1849,7 @@ namespace bgfx if (NULL != temp) { - g_free(temp); + BX_FREE(g_allocator, temp); } } @@ -1928,7 +1928,7 @@ namespace bgfx uint32_t size = BX_ALIGN_16(g_uniformTypeSize[_type]*_num); if (_alloc) { - m_data = g_realloc(NULL, size); + m_data = BX_ALLOC(g_allocator, size); memset(m_data, 0, size); } @@ -1946,7 +1946,7 @@ namespace bgfx { if (NULL != m_data) { - g_free(m_data); + BX_FREE(g_allocator, m_data); m_data = NULL; } diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index 896b3bb7..4202148a 100644 --- a/src/renderer_d3d9.cpp +++ b/src/renderer_d3d9.cpp @@ -1591,7 +1591,7 @@ namespace bgfx { uint32_t srcpitch = mipWidth*bpp/8; - uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*mipHeight); + uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, srcpitch*mipHeight); imageDecodeToBgra8(temp, mip.m_data, mip.m_width, mip.m_height, mip.m_format); uint32_t dstpitch = pitch; @@ -1602,7 +1602,7 @@ namespace bgfx memcpy(dst, src, dstpitch); } - g_free(temp); + BX_FREE(g_allocator, temp); } else { @@ -1650,7 +1650,7 @@ namespace bgfx if (convert) { - uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*_rect.m_height); + uint8_t* temp = (uint8_t*)BX_ALLOC(g_allocator, srcpitch*_rect.m_height); imageDecodeToBgra8(temp, data, _rect.m_width, _rect.m_height, m_requestedFormat); data = temp; } @@ -1671,7 +1671,7 @@ namespace bgfx if (NULL != temp) { - g_free(temp); + BX_FREE(g_allocator, temp); } if (0 == _mip) @@ -2127,7 +2127,7 @@ namespace bgfx void Context::rendererCreateUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) { uint32_t size = BX_ALIGN_16(g_uniformTypeSize[_type]*_num); - void* data = g_realloc(NULL, size); + void* data = BX_ALLOC(g_allocator, size); memset(data, 0, size); s_renderCtx.m_uniforms[_handle.idx] = data; s_renderCtx.m_uniformReg.add(_name, s_renderCtx.m_uniforms[_handle.idx]); @@ -2135,7 +2135,7 @@ namespace bgfx void Context::rendererDestroyUniform(UniformHandle _handle) { - g_free(s_renderCtx.m_uniforms[_handle.idx]); + BX_FREE(g_allocator, s_renderCtx.m_uniforms[_handle.idx]); } void Context::rendererSaveScreenShot(const char* _filePath) diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 9bfe8339..8426fc6f 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -735,7 +735,7 @@ namespace bgfx if (m_resolution.m_flags&BGFX_RESET_CAPTURE) { m_captureSize = m_resolution.m_width*m_resolution.m_height*4; - m_capture = g_realloc(m_capture, m_captureSize); + m_capture = BX_REALLOC(g_allocator, m_capture, m_captureSize); g_callback->captureBegin(m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, TextureFormat::BGRA8, true); } else @@ -743,7 +743,7 @@ namespace bgfx if (NULL != m_capture) { g_callback->captureEnd(); - g_free(m_capture); + BX_FREE(g_allocator, m_capture); m_capture = NULL; m_captureSize = 0; } @@ -770,7 +770,7 @@ namespace bgfx void saveScreenShot(const char* _filePath) { uint32_t length = m_resolution.m_width*m_resolution.m_height*4; - uint8_t* data = (uint8_t*)g_realloc(NULL, length); + uint8_t* data = (uint8_t*)BX_ALLOC(g_allocator, length); uint32_t width = m_resolution.m_width; uint32_t height = m_resolution.m_height; @@ -797,7 +797,7 @@ namespace bgfx , length , true ); - g_free(data); + BX_FREE(g_allocator, data); } void init() @@ -1038,7 +1038,7 @@ namespace bgfx if (cached) { - void* data = g_realloc(NULL, length); + void* data = BX_ALLOC(g_allocator, length); if (g_callback->cacheRead(id, data, length) ) { bx::MemoryReader reader(data, length); @@ -1049,7 +1049,7 @@ namespace bgfx GL_CHECK(glProgramBinary(m_id, format, reader.getDataPtr(), (GLsizei)reader.remaining() ) ); } - g_free(data); + BX_FREE(g_allocator, data); } #if BGFX_CONFIG_RENDERER_OPENGL @@ -1087,13 +1087,13 @@ namespace bgfx if (0 < programLength) { uint32_t length = programLength + 4; - uint8_t* data = (uint8_t*)g_realloc(NULL, length); + uint8_t* data = (uint8_t*)BX_ALLOC(g_allocator, length); GL_CHECK(glGetProgramBinary(m_id, programLength, NULL, &format, &data[4]) ); *(uint32_t*)data = format; g_callback->cacheWrite(id, data, length); - g_free(data); + BX_FREE(g_allocator, data); } } } @@ -1122,7 +1122,7 @@ namespace bgfx GL_CHECK(glGetProgramiv(m_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max1) ); GLint maxLength = bx::uint32_max(max0, max1); - char* name = (char*)g_realloc(NULL, maxLength + 1); + char* name = (char*)BX_ALLOC(g_allocator, maxLength + 1); BX_TRACE("Program %d", m_id); BX_TRACE("Attributes:"); @@ -1207,7 +1207,7 @@ namespace bgfx m_constantBuffer->finish(); - g_free(name); + BX_FREE(g_allocator, name); memset(m_attributes, 0xff, sizeof(m_attributes) ); uint32_t used = 0; @@ -1458,7 +1458,7 @@ namespace bgfx uint8_t* temp = NULL; if (convert || swizzle) { - temp = (uint8_t*)g_realloc(NULL, imageContainer.m_width*imageContainer.m_height*4); + temp = (uint8_t*)BX_ALLOC(g_allocator, imageContainer.m_width*imageContainer.m_height*4); } for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side) @@ -1562,7 +1562,7 @@ namespace bgfx if (NULL != temp) { - g_free(temp); + BX_FREE(g_allocator, temp); } } @@ -1670,7 +1670,7 @@ namespace bgfx uint8_t* temp = NULL; if (convert || swizzle) { - temp = (uint8_t*)g_realloc(NULL, width*height*4); + temp = (uint8_t*)BX_ALLOC(g_allocator, width*height*4); } if (compressed) @@ -1720,7 +1720,7 @@ namespace bgfx if (NULL != temp) { - g_free(temp); + BX_FREE(g_allocator, temp); } } @@ -2681,7 +2681,7 @@ namespace bgfx void Context::rendererCreateUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name) { uint32_t size = g_uniformTypeSize[_type]*_num; - void* data = g_realloc(NULL, size); + void* data = BX_ALLOC(g_allocator, size); memset(data, 0, size); s_renderCtx.m_uniforms[_handle.idx] = data; s_renderCtx.m_uniformReg.add(_name, s_renderCtx.m_uniforms[_handle.idx]); @@ -2689,7 +2689,7 @@ namespace bgfx void Context::rendererDestroyUniform(UniformHandle _handle) { - g_free(s_renderCtx.m_uniforms[_handle.idx]); + BX_FREE(g_allocator, s_renderCtx.m_uniforms[_handle.idx]); } void Context::rendererSaveScreenShot(const char* _filePath)