Skip to content

Commit

Permalink
blender: Explicitly tear down/free c-ray & fix small leak
Browse files Browse the repository at this point in the history
The destructor for the PyCapsule was never being called, despite me
deleting it in Python, so an explicit teardown function is now expected
to be called.
I don't know if it's specific to my system, but Blender seems to leak
quite a bit of memory, even while using Cycles. I fixed a small leak in
c-ray, but the rest seems to all be in Blender code.
  • Loading branch information
vkoskiv committed Dec 30, 2023
1 parent 7c414bb commit c1b75f3
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 14 deletions.
4 changes: 3 additions & 1 deletion bindings/blender_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,15 @@ class CrayRender(bpy.types.RenderEngine):
bl_label = "c-ray for Blender"
bl_use_preview = True
bl_use_shading_nodes_custom = False
cr_renderer = None

def __init__(self):
print("c-ray initialized")
self.cr_renderer = None
self.cr_scene = None

def __del__(self):
if self.cr_renderer:
self.cr_renderer.close()
print("c-ray deleted")

def sync_scene(self, depsgraph):
Expand Down
1 change: 1 addition & 0 deletions bindings/c_ray.py
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,7 @@ def __init__(self, path = None):
_lib.load_json(self.obj_ptr, path)

def close(self):
_lib.renderer_destroy(self.obj_ptr)
del(self.obj_ptr)

def stop(self):
Expand Down
23 changes: 13 additions & 10 deletions bindings/cray_wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,26 @@ static PyObject *py_cr_get_git_hash(PyObject *self, PyObject *args) {
return PyUnicode_FromString(cr_get_git_hash());
}

void py_internal_destroy_renderer(PyObject *capsule) {
struct cr_renderer *renderer = PyCapsule_GetPointer(capsule, "cray.cr_renderer");
cr_destroy_renderer(renderer);
}

static PyObject *py_cr_new_renderer(PyObject *self, PyObject *args) {
(void)self; (void)args;
struct cr_renderer *new = cr_new_renderer();
if (!new) {
PyErr_SetString(PyExc_MemoryError, "Failed to allocate renderer");
return NULL;
}
return PyCapsule_New(new, "cray.cr_renderer", py_internal_destroy_renderer);
return PyCapsule_New(new, "cray.cr_renderer", NULL);
}

// TODO: Not sure if we want to keep this explicit teardown func, or trust the destructor above
// static PyObject *py_cr_destroy_renderer(PyObject *self, PyObject *args) {
// return NULL;
// }
static PyObject *py_cr_destroy_renderer(PyObject *self, PyObject *args) {
(void)self;
PyObject *r_ext;
if (!PyArg_ParseTuple(args, "O", &r_ext)) {
return NULL;
}
struct cr_renderer *r = PyCapsule_GetPointer(r_ext, "cray.cr_renderer");
cr_destroy_renderer(r);
Py_RETURN_NONE;
}

static PyObject *py_cr_renderer_set_num_pref(PyObject *self, PyObject *args) {
(void)self; (void)args;
Expand Down Expand Up @@ -365,6 +366,7 @@ static PyObject *py_cr_mesh_bind_faces(PyObject *self, PyObject *args) {

struct cr_scene *s = PyCapsule_GetPointer(s_ext, "cray.cr_scene");
cr_mesh_bind_faces(s, mesh, faces, face_count);
free(faces);
Py_RETURN_NONE;
}

Expand Down Expand Up @@ -609,6 +611,7 @@ static PyObject *py_debug_dump_state(PyObject *self, PyObject *args) {
static PyMethodDef cray_methods[] = {
{ "get_version", py_cr_get_version, METH_NOARGS, "" },
{ "get_git_hash", py_cr_get_git_hash, METH_NOARGS, "" },
{ "renderer_destroy", py_cr_destroy_renderer, METH_VARARGS, "" },
{ "new_renderer", py_cr_new_renderer, METH_NOARGS, "" },
// { "destroy_renderer", py_cr_destroy_renderer, METH_VARARGS, "" },
{ "renderer_set_num_pref", py_cr_renderer_set_num_pref, METH_VARARGS, "" },
Expand Down
2 changes: 0 additions & 2 deletions include/c-ray/c-ray.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,6 @@ struct cr_bitmap {
size_t height;
};

// TODO: Maybe redo this to have this update an internal render buffer,
// and another func to get a ptr to that? No need for awkward free() then
CR_EXPORT void cr_renderer_render(struct cr_renderer *r);
CR_EXPORT struct cr_bitmap *cr_renderer_get_result(struct cr_renderer *r);

Expand Down
2 changes: 1 addition & 1 deletion src/lib/renderer/renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ struct renderer *renderer_new() {
r->scene->storage.node_table = newHashtable(compareNodes, &r->scene->storage.node_pool);
return r;
}

void renderer_destroy(struct renderer *r) {
if (!r) return;
scene_destroy(r->scene);
Expand Down

0 comments on commit c1b75f3

Please sign in to comment.