Skip to content

Commit

Permalink
graphics: batch deletion of framebuffers/renderbuffers/buffers in one…
Browse files Browse the repository at this point in the history
… call, using python array module and cython array pointers. Need cython 0.17 minimum, and full recompilation.
  • Loading branch information
tito committed Apr 19, 2013
1 parent 903767f commit c84e051
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 30 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ build:
force:
$(PYTHON) setup.py build_ext --inplace -f

debug:
$(PYTHON) setup.py build_ext --inplace -f -g

mesabuild:
/usr/bin/env USE_MESAGL=1 $(PYTHON) setup.py build_ext --inplace

Expand Down
7 changes: 4 additions & 3 deletions kivy/graphics/context.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ cdef class Context:
cdef list l_shader
cdef list l_fbo

cdef list lr_texture
cdef object lr_texture
cdef list lr_canvas
cdef list lr_vbo
cdef list lr_fbo
cdef object lr_vbo
cdef object lr_fbo_rb
cdef object lr_fbo_fb

cdef void register_texture(self, Texture texture)
cdef void register_canvas(self, Canvas canvas)
Expand Down
64 changes: 41 additions & 23 deletions kivy/graphics/context.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ You can read more about it at :doc:`api-kivy.graphics`

include "config.pxi"

from cpython.array cimport array
import gc
from os import environ
from weakref import ref
Expand Down Expand Up @@ -44,10 +45,11 @@ cdef class Context:
self.trigger_gl_dealloc = Clock.create_trigger(self.gl_dealloc, 0)

cdef void flush(self):
self.lr_texture = []
self.lr_texture = array('i')
self.lr_canvas = []
self.lr_vbo = []
self.lr_fbo = []
self.lr_vbo = array('i')
self.lr_fbo_rb = array('i')
self.lr_fbo_fb = array('i')

cdef void register_texture(self, Texture texture):
self.l_texture.append(ref(texture))
Expand All @@ -68,20 +70,26 @@ cdef class Context:
self.l_fbo.append(ref(fbo))

cdef void dealloc_texture(self, Texture texture):
cdef array arr
if texture._nofree or texture.__class__ is TextureRegion:
return
if texture.id > 0:
self.lr_texture.append(texture.id)
arr = self.lr_texture
arr.append(texture.id)
self.trigger_gl_dealloc()

cdef void dealloc_vbo(self, VBO vbo):
cdef array arr
if vbo.have_id():
self.lr_vbo.append(vbo.id)
arr = self.lr_vbo
arr.append(vbo.id)
self.trigger_gl_dealloc()

cdef void dealloc_vertexbatch(self, VertexBatch batch):
cdef array arr
if batch.have_id():
self.lr_vbo.append(batch.id)
arr = self.lr_vbo
arr.append(batch.id)
self.trigger_gl_dealloc()

cdef void dealloc_shader(self, Shader shader):
Expand All @@ -94,9 +102,16 @@ cdef class Context:
glDeleteProgram(shader.program)

cdef void dealloc_fbo(self, Fbo fbo):
if fbo.buffer_id != -1:
self.lr_fbo.append((fbo.buffer_id, fbo.depthbuffer_id))
cdef array arr_fb
cdef array arr_rb
if fbo.buffer_id != 0:
arr_fb = self.lr_fbo_fb
arr_fb.append(fbo.buffer_id)
self.trigger_gl_dealloc()
if fbo.depthbuffer_id != 0:
arr_rb = self.lr_fbo_rb
arr_rb.append(fbo.depthbuffer_id)
# no need to trigger, depthbuffer required absolutely a buffer.

def add_reload_observer(self, callback, before=False):
'''Add a callback to be called after the whole graphics context have
Expand Down Expand Up @@ -168,7 +183,6 @@ cdef class Context:
Logger.info('Context: Reloading graphics data...')
Logger.debug('Context: Collect and flush all garbage')
self.gc()
gc.collect()
self.flush()

# First step, prevent double loading by setting everything to -1
Expand Down Expand Up @@ -256,34 +270,38 @@ cdef class Context:
self.l_canvas = [x for x in self.l_canvas if x() is not None]
self.l_vbo = [x for x in self.l_vbo if x() is not None]
self.l_vertexbatch = [x for x in self.l_vertexbatch if x() is not None]
gc.collect()

def gl_dealloc(self, *largs):
# dealloc all gl resources asynchronously
cdef GLuint i, j
cdef array arr

# FIXME we are doing gc for each time we dealloc things. But if you have
# "big" apps, this might just slow it down.
self.gc()

if len(self.lr_vbo):
Logger.trace('Context: releasing %d vbos' % len(self.lr_vbo))
while len(self.lr_vbo):
i = self.lr_vbo.pop()
glDeleteBuffers(1, &i)
arr = self.lr_vbo
glDeleteBuffers(len(self.lr_vbo), arr.data.as_uints)
del self.lr_vbo[:]
if len(self.lr_texture):
Logger.trace('Context: releasing %d textures: %r' % (
len(self.lr_texture), self.lr_texture))
while len(self.lr_texture):
i = self.lr_texture.pop()
glDeleteTextures(1, &i)
if len(self.lr_fbo):
Logger.trace('Context: releasing %d fbos' % len(self.lr_fbo))
while len(self.lr_fbo):
i, j = self.lr_fbo.pop()
if i != -1:
glDeleteFramebuffers(1, &i)
if j != -1:
glDeleteRenderbuffers(1, &j)
arr = self.lr_texture
glDeleteTextures(len(self.lr_texture), arr.data.as_uints)
del self.lr_texture[:]
if len(self.lr_fbo_fb):
Logger.trace('Context: releasing %d framebuffer fbos' % len(self.lr_fbo_fb))
arr = self.lr_fbo_fb
glDeleteFramebuffers(len(self.lr_fbo_fb), arr.data.as_uints)
del self.lr_fbo_fb[:]
if len(self.lr_fbo_rb):
Logger.trace('Context: releasing %d renderbuffer fbos' % len(self.lr_fbo_fb))
arr = self.lr_fbo_rb
glDeleteRenderbuffers(len(self.lr_fbo_rb), arr.data.as_uints)
del self.lr_fbo_rb[:]


cpdef Context get_context():
Expand Down
8 changes: 4 additions & 4 deletions kivy/graphics/fbo.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ cdef class Fbo(RenderContext):
if 'texture' not in kwargs:
kwargs['texture'] = None

self.buffer_id = -1
self.depthbuffer_id = -1
self.buffer_id = 0
self.depthbuffer_id = 0
self._width, self._height = kwargs['size']
self.clear_color = kwargs['clear_color']
self._depthbuffer_attached = int(kwargs['with_depthbuffer'])
Expand All @@ -167,8 +167,8 @@ cdef class Fbo(RenderContext):
cdef void delete_fbo(self):
self._texture = None
get_context().dealloc_fbo(self)
self.buffer_id = -1
self.depthbuffer_id = -1
self.buffer_id = 0
self.depthbuffer_id = 0

cdef void create_fbo(self):
cdef GLuint f_id = 0
Expand Down

0 comments on commit c84e051

Please sign in to comment.