NanoVG: Added ability to pass custom allocator.

This commit is contained in:
Branimir Karadžić 2016-02-07 18:58:17 -08:00
parent a42cba815c
commit 728a8ee4e5
3 changed files with 36 additions and 27 deletions

View file

@ -468,7 +468,7 @@ struct Imgui
IMGUI_create(_data, _size, _fontSize, m_allocator); IMGUI_create(_data, _size, _fontSize, m_allocator);
m_nvg = nvgCreate(1, m_view); m_nvg = nvgCreate(1, m_view, m_allocator);
nvgCreateFontMem(m_nvg, "default", (unsigned char*)_data, INT32_MAX, 0); nvgCreateFontMem(m_nvg, "default", (unsigned char*)_data, INT32_MAX, 0);
nvgFontSize(m_nvg, _fontSize); nvgFontSize(m_nvg, _fontSize);
nvgFontFace(m_nvg, "default"); nvgFontFace(m_nvg, "default");

View file

@ -598,8 +598,10 @@ struct NVGparams {
}; };
typedef struct NVGparams NVGparams; typedef struct NVGparams NVGparams;
NVGcontext* nvgCreate(int edgeaa, unsigned char viewid); namespace bx { struct AllocatorI; }
void nvgViewId(struct NVGcontext* ctx, unsigned char viewid);
NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId, bx::AllocatorI* _allocator = NULL);
void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId);
void nvgDelete(struct NVGcontext* ctx); void nvgDelete(struct NVGcontext* ctx);
// Constructor and destructor, called by the render back-end. // Constructor and destructor, called by the render back-end.

View file

@ -23,14 +23,13 @@
#define NVG_ANTIALIAS 1 #define NVG_ANTIALIAS 1
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h> #include <math.h>
#include "nanovg.h" #include "nanovg.h"
#include <bgfx/bgfx.h> #include <bgfx/bgfx.h>
#include <bx/bx.h> #include <bx/bx.h>
#include <bx/allocator.h>
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4244); // warning C4244: '=' : conversion from '' to '', possible loss of data BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4244); // warning C4244: '=' : conversion from '' to '', possible loss of data
@ -113,6 +112,8 @@ namespace
struct GLNVGcontext struct GLNVGcontext
{ {
bx::AllocatorI* m_allocator;
bgfx::ProgramHandle prog; bgfx::ProgramHandle prog;
bgfx::UniformHandle u_scissorMat; bgfx::UniformHandle u_scissorMat;
bgfx::UniformHandle u_paintMat; bgfx::UniformHandle u_paintMat;
@ -131,7 +132,7 @@ namespace
bgfx::TextureHandle texMissing; bgfx::TextureHandle texMissing;
bgfx::TransientVertexBuffer tvb; bgfx::TransientVertexBuffer tvb;
uint8_t viewid; uint8_t m_viewId;
struct GLNVGtexture* textures; struct GLNVGtexture* textures;
float view[2]; float view[2];
@ -177,7 +178,7 @@ namespace
{ {
int old = gl->ctextures; int old = gl->ctextures;
gl->ctextures = (gl->ctextures == 0) ? 2 : gl->ctextures*2; gl->ctextures = (gl->ctextures == 0) ? 2 : gl->ctextures*2;
gl->textures = (struct GLNVGtexture*)realloc(gl->textures, sizeof(struct GLNVGtexture)*gl->ctextures); gl->textures = (struct GLNVGtexture*)BX_REALLOC(gl->m_allocator, gl->textures, sizeof(struct GLNVGtexture)*gl->ctextures);
memset(&gl->textures[old], 0xff, (gl->ctextures-old)*sizeof(struct GLNVGtexture) ); memset(&gl->textures[old], 0xff, (gl->ctextures-old)*sizeof(struct GLNVGtexture) );
if (gl->textures == NULL) if (gl->textures == NULL)
@ -548,7 +549,7 @@ namespace
struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr; struct GLNVGcontext* gl = (struct GLNVGcontext*)_userPtr;
gl->view[0] = (float)width; gl->view[0] = (float)width;
gl->view[1] = (float)height; gl->view[1] = (float)height;
bgfx::setViewRect(gl->viewid, 0, 0, width, height); bgfx::setViewRect(gl->m_viewId, 0, 0, width, height);
} }
static void fan(uint32_t _start, uint32_t _count) static void fan(uint32_t _start, uint32_t _count)
@ -596,7 +597,7 @@ namespace
bgfx::setVertexBuffer(&gl->tvb); bgfx::setVertexBuffer(&gl->tvb);
bgfx::setTexture(0, gl->s_tex, gl->th); bgfx::setTexture(0, gl->s_tex, gl->th);
fan(paths[i].fillOffset, paths[i].fillCount); fan(paths[i].fillOffset, paths[i].fillCount);
bgfx::submit(gl->viewid, gl->prog); bgfx::submit(gl->m_viewId, gl->prog);
} }
} }
@ -620,7 +621,7 @@ namespace
); );
bgfx::setVertexBuffer(&gl->tvb, paths[i].strokeOffset, paths[i].strokeCount); bgfx::setVertexBuffer(&gl->tvb, paths[i].strokeOffset, paths[i].strokeCount);
bgfx::setTexture(0, gl->s_tex, gl->th); bgfx::setTexture(0, gl->s_tex, gl->th);
bgfx::submit(gl->viewid, gl->prog); bgfx::submit(gl->m_viewId, gl->prog);
} }
} }
@ -635,7 +636,7 @@ namespace
| BGFX_STENCIL_OP_FAIL_Z_ZERO | BGFX_STENCIL_OP_FAIL_Z_ZERO
| BGFX_STENCIL_OP_PASS_Z_ZERO | BGFX_STENCIL_OP_PASS_Z_ZERO
); );
bgfx::submit(gl->viewid, gl->prog); bgfx::submit(gl->m_viewId, gl->prog);
} }
static void glnvg__convexFill(struct GLNVGcontext* gl, struct GLNVGcall* call) static void glnvg__convexFill(struct GLNVGcontext* gl, struct GLNVGcall* call)
@ -652,7 +653,7 @@ namespace
bgfx::setVertexBuffer(&gl->tvb); bgfx::setVertexBuffer(&gl->tvb);
bgfx::setTexture(0, gl->s_tex, gl->th); bgfx::setTexture(0, gl->s_tex, gl->th);
fan(paths[i].fillOffset, paths[i].fillCount); fan(paths[i].fillOffset, paths[i].fillCount);
bgfx::submit(gl->viewid, gl->prog); bgfx::submit(gl->m_viewId, gl->prog);
} }
if (gl->edgeAntiAlias) if (gl->edgeAntiAlias)
@ -665,7 +666,7 @@ namespace
); );
bgfx::setVertexBuffer(&gl->tvb, paths[i].strokeOffset, paths[i].strokeCount); bgfx::setVertexBuffer(&gl->tvb, paths[i].strokeOffset, paths[i].strokeCount);
bgfx::setTexture(0, gl->s_tex, gl->th); bgfx::setTexture(0, gl->s_tex, gl->th);
bgfx::submit(gl->viewid, gl->prog); bgfx::submit(gl->m_viewId, gl->prog);
} }
} }
} }
@ -685,7 +686,7 @@ namespace
); );
bgfx::setVertexBuffer(&gl->tvb, paths[i].strokeOffset, paths[i].strokeCount); bgfx::setVertexBuffer(&gl->tvb, paths[i].strokeOffset, paths[i].strokeCount);
bgfx::setTexture(0, gl->s_tex, gl->th); bgfx::setTexture(0, gl->s_tex, gl->th);
bgfx::submit(gl->viewid, gl->prog); bgfx::submit(gl->m_viewId, gl->prog);
} }
} }
@ -698,7 +699,7 @@ namespace
bgfx::setState(gl->state); bgfx::setState(gl->state);
bgfx::setVertexBuffer(&gl->tvb, call->vertexOffset, call->vertexCount); bgfx::setVertexBuffer(&gl->tvb, call->vertexOffset, call->vertexCount);
bgfx::setTexture(0, gl->s_tex, gl->th); bgfx::setTexture(0, gl->s_tex, gl->th);
bgfx::submit(gl->viewid, gl->prog); bgfx::submit(gl->m_viewId, gl->prog);
} }
} }
@ -791,7 +792,7 @@ namespace
if (gl->ncalls+1 > gl->ccalls) if (gl->ncalls+1 > gl->ccalls)
{ {
gl->ccalls = gl->ccalls == 0 ? 32 : gl->ccalls * 2; gl->ccalls = gl->ccalls == 0 ? 32 : gl->ccalls * 2;
gl->calls = (struct GLNVGcall*)realloc(gl->calls, sizeof(struct GLNVGcall) * gl->ccalls); gl->calls = (struct GLNVGcall*)BX_REALLOC(gl->m_allocator, gl->calls, sizeof(struct GLNVGcall) * gl->ccalls);
} }
ret = &gl->calls[gl->ncalls++]; ret = &gl->calls[gl->ncalls++];
memset(ret, 0, sizeof(struct GLNVGcall) ); memset(ret, 0, sizeof(struct GLNVGcall) );
@ -804,7 +805,7 @@ namespace
if (gl->npaths + n > gl->cpaths) { if (gl->npaths + n > gl->cpaths) {
GLNVGpath* paths; GLNVGpath* paths;
int cpaths = glnvg__maxi(gl->npaths + n, 128) + gl->cpaths / 2; // 1.5x Overallocate int cpaths = glnvg__maxi(gl->npaths + n, 128) + gl->cpaths / 2; // 1.5x Overallocate
paths = (GLNVGpath*)realloc(gl->paths, sizeof(GLNVGpath) * cpaths); paths = (GLNVGpath*)BX_REALLOC(gl->m_allocator, gl->paths, sizeof(GLNVGpath) * cpaths);
if (paths == NULL) return -1; if (paths == NULL) return -1;
gl->paths = paths; gl->paths = paths;
gl->cpaths = cpaths; gl->cpaths = cpaths;
@ -821,7 +822,7 @@ namespace
{ {
NVGvertex* verts; NVGvertex* verts;
int cverts = glnvg__maxi(gl->nverts + n, 4096) + gl->cverts/2; // 1.5x Overallocate int cverts = glnvg__maxi(gl->nverts + n, 4096) + gl->cverts/2; // 1.5x Overallocate
verts = (NVGvertex*)realloc(gl->verts, sizeof(NVGvertex) * cverts); verts = (NVGvertex*)BX_REALLOC(gl->m_allocator, gl->verts, sizeof(NVGvertex) * cverts);
if (verts == NULL) return -1; if (verts == NULL) return -1;
gl->verts = verts; gl->verts = verts;
gl->cverts = cverts; gl->cverts = cverts;
@ -837,7 +838,7 @@ namespace
if (gl->nuniforms+n > gl->cuniforms) if (gl->nuniforms+n > gl->cuniforms)
{ {
gl->cuniforms = gl->cuniforms == 0 ? glnvg__maxi(n, 32) : gl->cuniforms * 2; gl->cuniforms = gl->cuniforms == 0 ? glnvg__maxi(n, 32) : gl->cuniforms * 2;
gl->uniforms = (unsigned char*)realloc(gl->uniforms, gl->cuniforms * structSize); gl->uniforms = (unsigned char*)BX_REALLOC(gl->m_allocator, gl->uniforms, gl->cuniforms * structSize);
} }
ret = gl->nuniforms * structSize; ret = gl->nuniforms * structSize;
gl->nuniforms += n; gl->nuniforms += n;
@ -1023,18 +1024,23 @@ namespace
} }
} }
free(gl->textures); BX_FREE(gl->m_allocator, gl->textures);
BX_FREE(gl->m_allocator, gl);
free(gl);
} }
} // namespace } // namespace
NVGcontext* nvgCreate(int edgeaa, unsigned char viewid) NVGcontext* nvgCreate(int edgeaa, unsigned char _viewId, bx::AllocatorI* _allocator)
{ {
if (NULL == _allocator)
{
static bx::CrtAllocator allocator;
_allocator = &allocator;
}
struct NVGparams params; struct NVGparams params;
struct NVGcontext* ctx = NULL; struct NVGcontext* ctx = NULL;
struct GLNVGcontext* gl = (struct GLNVGcontext*)malloc(sizeof(struct GLNVGcontext) ); struct GLNVGcontext* gl = (struct GLNVGcontext*)BX_ALLOC(_allocator, sizeof(struct GLNVGcontext) );
if (gl == NULL) goto error; if (gl == NULL) goto error;
memset(gl, 0, sizeof(struct GLNVGcontext) ); memset(gl, 0, sizeof(struct GLNVGcontext) );
@ -1053,8 +1059,9 @@ NVGcontext* nvgCreate(int edgeaa, unsigned char viewid)
params.userPtr = gl; params.userPtr = gl;
params.edgeAntiAlias = edgeaa; params.edgeAntiAlias = edgeaa;
gl->m_allocator = _allocator;
gl->edgeAntiAlias = edgeaa; gl->edgeAntiAlias = edgeaa;
gl->viewid = uint8_t(viewid); gl->m_viewId = uint8_t(_viewId);
ctx = nvgCreateInternal(&params); ctx = nvgCreateInternal(&params);
if (ctx == NULL) goto error; if (ctx == NULL) goto error;
@ -1071,11 +1078,11 @@ error:
return NULL; return NULL;
} }
void nvgViewId(struct NVGcontext* ctx, unsigned char viewid) void nvgViewId(struct NVGcontext* ctx, unsigned char _viewId)
{ {
struct NVGparams* params = nvgInternalParams(ctx); struct NVGparams* params = nvgInternalParams(ctx);
struct GLNVGcontext* gl = (struct GLNVGcontext*)params->userPtr; struct GLNVGcontext* gl = (struct GLNVGcontext*)params->userPtr;
gl->viewid = uint8_t(viewid); gl->m_viewId = uint8_t(_viewId);
} }
void nvgDelete(struct NVGcontext* ctx) void nvgDelete(struct NVGcontext* ctx)