Double Buffer¶
Intent: Cause a series of sequential operations to appear instantaneous or simultaneous.
Acron Mapping¶
Context |
Acron approach |
|---|---|
Rendering (primary use) |
Acron’s renderer already double-buffers the display — handled automatically |
Render-to-texture |
|
Game state (logic) |
Two Python dicts/lists; write to “back”, swap at end of frame |
You almost never need to implement rendering double-buffering manually. Focus on game-state double-buffering when read and write must not interleave within a frame (e.g., cellular automata, simultaneous AI moves in a strategy game).
How to Implement (game-state double buffer)¶
Maintain two state containers:
_front(read-only this frame) and_back(write-only this frame).At the start of each frame, game logic reads from
_front.All writes go to
_back.At the end of the frame task, swap:
self._front, self._back = self._back, self._front.
Code Sketch (Python) — game-state double buffer¶
class BattleGrid:
def __init__(self, w, h):
self._w, self._h = w, h
self._front = [[None] * w for _ in range(h)]
self._back = [[None] * w for _ in range(h)]
taskMgr.add(self._tick, 'gridTick', sort=5)
def get(self, x, y):
return self._front[y][x]
def set(self, x, y, value):
self._back[y][x] = value
def _tick(self, task):
self._simulate() # writes to _back
self._front, self._back = self._back, self._front # swap
self._clear_back() # prepare for next frame
return task.cont
def _simulate(self):
for y in range(self._h):
for x in range(self._w):
cell = self.get(x, y) # reads _front
if cell:
self.set(x, y + 1, cell) # writes _back
def _clear_back(self):
for row in self._back:
row[:] = [None] * self._w
Code Sketch (Python) — render-to-texture ping-pong¶
# Two off-screen buffers for post-processing ping-pong
buf_a = base.win.makeTextureBuffer('bufA', 512, 512)
buf_b = base.win.makeTextureBuffer('bufB', 512, 512)
tex_a = buf_a.getTexture()
tex_b = buf_b.getTexture()
# Render scene to buf_a, apply shader reading tex_a into buf_b, display tex_b
Pitfalls¶
Don’t double-buffer
NodePathpositions: Acron’s scene graph updates are already safe within a single-threaded frame. Double-buffering positions adds overhead for no benefit unless you use task chains (threads).Swap timing: swap must happen after all reads and writes for the frame are complete. Place the swap at the end of a high-sort task (
sort=40, just before the render task atsort=50).Memory: two full copies of large state arrays double memory usage. Only double-buffer state that is actually read and written within the same frame.