-
Notifications
You must be signed in to change notification settings - Fork 513
Expand file tree
/
Copy pathdouble-buffer.html
More file actions
726 lines (672 loc) · 51.8 KB
/
double-buffer.html
File metadata and controls
726 lines (672 loc) · 51.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>Double Buffer · Sequencing Patterns · Game Programming Patterns</title>
<!-- Tell mobile browsers we're optimized for them and they don't need to crop
the viewport. -->
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="stylesheet" type="text/css" href="style.css" />
<link href="https://fonts.googleapis.com/css?family=Merriweather:400,400italic,700,700italic|Source+Code+Pro|Source+Sans+Pro:200,300,400,600,400italic,600italic|Rock+Salt" rel="stylesheet" type="text/css">
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-42804721-1', 'gameprogrammingpatterns.com');
ga('send', 'pageview');
</script>
<script src="jquery-3.6.0.min.js"></script>
<script src="script.js"></script>
</head>
<body id="top">
<div class="page sidebar">
<span class="theme-toggler" title="dark theme" onclick="toggleTheme()"></span>
<div class="content">
<nav class="top">
<span class="prev">← <a href="sequencing-patterns.html">Previous Chapter</a></span>
<span class="next"><a href="game-loop.html">Next Chapter</a> →</span>
<span class="toc">≡ <a href="/">The Book</a></span>
</nav>
<h1>Double Buffer</h1>
<h1 class="book"><a href="/">Game Programming Patterns</a><span class="section"><a href="sequencing-patterns.html">Sequencing Patterns</a></span></h1>
<h2><a href="#intent" name="intent">Intent</a></h2>
<p><em>Cause a series of sequential operations to appear instantaneous or
simultaneous.</em></p>
<h2><a href="#motivation" name="motivation">Motivation</a></h2>
<p>In their hearts, computers are <span name="sequential">sequential</span> beasts.
Their power comes from being able to break down the largest tasks into tiny
steps that can be performed one after another. Often, though, our users need to
see things occur in a single instantaneous step or see multiple tasks performed
simultaneously.</p>
<aside name="sequential">
<p>With threading and multi-core architectures this is becoming less true, but
even with several cores, only a few operations are running concurrently.</p>
</aside>
<p>A typical example, and one that every game engine must address, is rendering.
When the game draws the world the users see, it does so one piece at a time — the
mountains in the distance, the rolling hills, the trees, each in its turn. If
the user <em>watched</em> the view draw incrementally like that, the illusion of a
coherent world would be shattered. The scene must update smoothly and quickly,
displaying a series of complete frames, each appearing instantly.</p>
<p>Double buffering solves this problem, but to understand how, we first need to
review how a computer displays graphics.</p>
<h3><a href="#how-computer-graphics-work-(briefly)" name="how-computer-graphics-work-(briefly)">How computer graphics work (briefly)</a></h3>
<p>A <span name="scan">video</span> display like a computer monitor draws one pixel
at a time. It sweeps across each row of pixels from left to right and then
moves down to the next row. When it reaches the bottom right corner, it scans
back up to the top left and starts all over again. It does this so fast —
around sixty times a second — that our eyes can’t see the scanning. To us, it’s
a single static field of colored pixels — an image.</p>
<aside name="scan">
<p>This explanation is, err, “simplified”. If you’re a low-level hardware person
and you’re cringing right now, feel free to skip to the next section. You
already know enough to understand the rest of the chapter. If you <em>aren’t</em> that
person, my goal here is to give you just enough context to understand the
pattern we’ll discuss later.</p>
</aside>
<p>You can think of this process like a tiny hose that pipes pixels to the display.
Individual colors go into the back of the hose, and it sprays them out across
the display, one bit of color to each pixel in its turn. So how does the hose
know what colors go where?</p>
<p>In most computers, the answer is that it pulls them from a <em>framebuffer</em>. A
framebuffer is an array of pixels in memory, a chunk of RAM where each couple of
<span name="color">bytes</span> represents the color of a single pixel. As the
hose sprays across the display, it reads in the color values from this array,
one byte at a time.</p>
<aside name="color">
<p>The specific mapping between byte values and colors is described by the <em>pixel
format</em> and the <em>color depth</em> of the system. In most gaming consoles today, each
pixel gets 32 bits: eight each for the red, green, and blue channels, and another
eight left over for various other purposes.</p>
</aside>
<p>Ultimately, in order to get our game to appear on screen, all we do is write to
that array. All of the crazy advanced graphics algorithms we have boil down to
just that: setting byte values in the framebuffer. But there’s a little problem.</p>
<p>Earlier, I said computers are sequential. If the machine is executing a chunk of
our rendering code, we don’t expect it to be doing anything else at the same
time. That’s mostly accurate, but a couple of things <em>do</em> happen in the middle
of our program running. One of those is that the video display will be reading
from the framebuffer <em>constantly</em> while our game runs. This can cause a problem
for us.</p>
<p>Let’s say we want a happy face to appear on screen. Our program starts looping
through the framebuffer, coloring pixels. What we don’t realize is that the
video driver is pulling from the framebuffer right as we’re writing to it. As it
scans across the pixels we’ve written, our face starts to appear, but then it
outpaces us and moves into pixels we haven’t written yet. The result is
<em>tearing</em>, a hideous visual bug where you see half of something drawn on screen.</p>
<p><span name="tearing"></span></p>
<p><img src="images/double-buffer-tearing.png" alt="A series of images of an in-progress frame being rendered. A pointer writes pixels while another reads them. The reader outpaces the writer until it starts reading pixels that haven't been rendered yet." /></p>
<aside name="tearing">
<p>We start drawing pixels just as the video driver starts reading from the
framebuffer (Fig. 1). The video driver eventually catches up to the renderer and
then races past it to pixels we haven’t written yet (Fig. 2). We finish drawing
(Fig. 3), but the driver doesn’t catch those new pixels.</p>
<p>The result (Fig. 4) is that the user sees half of the drawing. The name
“tearing” comes from the fact that it looks like the bottom half was torn off.</p>
</aside>
<p>This is why we need this pattern. Our program renders the pixels one at a time,
but we need the display driver to see them all at once — in one frame the face
isn’t there, and in the next one it is. Double buffering solves this. I’ll explain how
by analogy.</p>
<h3><a href="#act-1,-scene-1" name="act-1,-scene-1">Act 1, Scene 1</a></h3>
<p>Imagine our users are watching a play produced by ourselves. As scene one ends
and scene two starts, we need to change the stage setting. If we have the
stagehands run on after the scene and start dragging props around, the illusion
of a coherent place will be broken. We could dim the lights while we do that
(which, of course, is what real theaters do), but the audience still knows
<em>something</em> is going on. We want there to be no gap in time between scenes.</p>
<p>With a bit of real estate, we come up with this clever solution: we build
<span name="stage"><em>two</em></span> stages set up so the audience can see both. Each
has its own set of lights. We’ll call them stage A and stage B. Scene one is shown on
stage A. Meanwhile, stage B is dark as the stagehands are setting up scene two. As soon as scene one ends, we cut the lights on stage A and bring them
up on stage B. The audience looks to the new stage and scene two begins
immediately.</p>
<p>At the same time, our stagehands are over on the now darkened stage <em>A</em>,
striking scene one and setting up scene <em>three</em>. As soon as scene two ends, we
switch the lights back to stage A again. We continue this process for the entire
play, using the darkened stage as a work area where we can set up the next
scene. Every scene transition, we just toggle the lights between the two stages.
Our audience gets a continuous performance with no delay between scenes. They
never see a stagehand.</p>
<aside name="stage">
<p>Using a half-silvered mirror and some very smart layout, you could actually
build this so that the two stages would appear to the audience in the same <em>place</em>. As
soon as the lights switch, they would be looking at a different stage, but they would
never have to change where they look. Building this is left as an exercise for
the reader.</p>
</aside>
<h3><a href="#back-to-the-graphics" name="back-to-the-graphics">Back to the graphics</a></h3>
<p>That is <span name="sync">exactly</span> how double buffering works, and this
process underlies the rendering system of just about every game you’ve ever
seen. Instead of a single framebuffer, we have <em>two</em>. One of them represents the
current frame, stage A in our analogy. It’s the one the video hardware is
reading from. The GPU can scan through it as much as it wants whenever it wants.</p>
<aside name="sync">
<p>Not <em>all</em> games and consoles do this, though. Older and simpler consoles where
memory is limited carefully sync their drawing to the video refresh
instead. It’s tricky.</p>
</aside>
<p>Meanwhile, our rendering code is writing to the <em>other</em> framebuffer. This is our
darkened stage B. When our rendering code is done drawing the scene, it switches
the lights by <em>swapping</em> the buffers. This tells the video hardware to start
reading from the second buffer now instead of the first one. As long as it times
that switch at the end of a refresh, we won’t get any tearing, and the entire
scene will appear all at once.</p>
<p>Meanwhile, the old framebuffer is now available for use. We start rendering the
next frame onto it. Voilà!</p>
<h2><a href="#the-pattern" name="the-pattern">The Pattern</a></h2>
<p>A <strong>buffered class</strong> encapsulates a <strong>buffer</strong>: a piece of state that can be
modified. This buffer is edited incrementally, but we want all outside code to
see the edit as a single atomic change. To do this, the class keeps <em>two</em>
instances of the buffer: a <strong>next buffer</strong> and a <strong>current buffer</strong>.</p>
<p>When information is read <em>from</em> a buffer, it is always from the <em>current</em>
buffer. When information is written <em>to</em> a buffer, it occurs on the <em>next</em>
buffer. When the changes are complete, a <strong>swap</strong> operation swaps the next and
current buffers instantly so that the new buffer is now publicly visible. The
old current buffer is now available to be reused as the new next buffer.</p>
<h2><a href="#when-to-use-it" name="when-to-use-it">When to Use It</a></h2>
<p>This pattern is one of those ones where you’ll know when you need it. If you
have a system that lacks double buffering, it will probably look visibly wrong
(tearing, etc.) or will behave incorrectly. But saying, “you’ll know when you
need it” doesn’t give you much to go on. More specifically, this pattern is
appropriate when all of these are true:</p>
<ul>
<li>
<p>We have some state that is being modified incrementally.</p>
</li>
<li>
<p>That same state may be accessed in the middle of modification.</p>
</li>
<li>
<p>We want to prevent the code that’s accessing the state from
seeing the work in progress.</p>
</li>
<li>
<p>We want to be able to read the state and we don’t want to have to
wait while it’s being written.</p>
</li>
</ul>
<h2><a href="#keep-in-mind" name="keep-in-mind">Keep in Mind</a></h2>
<p>Unlike larger architectural patterns, double buffering exists at a lower
implementation level. Because of this, it has fewer consequences for the rest of
the codebase — most of the game won’t even be aware of the difference. There
are a couple of caveats, though.</p>
<h3><a href="#the-swap-itself-takes-time" name="the-swap-itself-takes-time">The swap itself takes time</a></h3>
<p>Double-buffering requires a <em>swap</em> step once the state is done being modified.
That operation must be atomic — no code can access <em>either</em> state while they
are being swapped. Often, this is as quick as assigning a pointer, but if it
takes longer to swap than it does to modify the state to begin with, then we haven’t
helped ourselves at all.</p>
<h3><a href="#we-have-to-have-two-buffers" name="we-have-to-have-two-buffers">We have to have two buffers</a></h3>
<p>The other consequence of this pattern is increased memory usage. As its name implies, the
pattern requires you to keep <em>two</em> copies of your state in memory at all times.
On memory-constrained devices, this can be a heavy price to pay. If you can’t
afford two buffers, you may have to look into other ways to ensure your state
isn’t being accessed during modification.</p>
<h2><a href="#sample-code" name="sample-code">Sample Code</a></h2>
<p>Now that we’ve got the theory, let’s see how it works in practice. We’ll write a
very bare-bones graphics system that lets us draw pixels on a framebuffer. In
most consoles and PCs, the video driver provides this low-level part of the
graphics system, but implementing it by hand here will let us see what’s going on.
First up is the buffer itself:</p>
<div class="codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Framebuffer</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="n">Framebuffer</span><span class="p">()</span> <span class="p">{</span> <span class="n">clear</span><span class="p">();</span> <span class="p">}</span>
<span class="kt">void</span> <span class="n">clear</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">WIDTH</span> <span class="o">*</span> <span class="n">HEIGHT</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">pixels_</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">WHITE</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">draw</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">pixels_</span><span class="p">[(</span><span class="n">WIDTH</span> <span class="o">*</span> <span class="n">y</span><span class="p">)</span> <span class="o">+</span> <span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">BLACK</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">getPixels</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="n">pixels_</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="k">static</span> <span class="k">const</span> <span class="kt">int</span> <span class="n">WIDTH</span> <span class="o">=</span> <span class="mi">160</span><span class="p">;</span>
<span class="k">static</span> <span class="k">const</span> <span class="kt">int</span> <span class="n">HEIGHT</span> <span class="o">=</span> <span class="mi">120</span><span class="p">;</span>
<span class="kt">char</span> <span class="n">pixels_</span><span class="p">[</span><span class="n">WIDTH</span> <span class="o">*</span> <span class="n">HEIGHT</span><span class="p">];</span>
<span class="p">};</span>
</code></pre></div>
<p>It has basic operations for clearing the entire buffer to a default color and
setting the color of an individual pixel. It also has a function, <code>getPixels()</code>,
to expose the raw array of memory holding the pixel data. We won’t see this in
the example, but the video driver will call that function frequently to stream
memory from the buffer onto the screen.</p>
<p>We wrap this raw buffer in a <code>Scene</code> class. It’s job here is to render something
by making a bunch of <code>draw()</code> calls on its buffer:</p>
<p><span name="draw"></span></p>
<div class="codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Scene</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="kt">void</span> <span class="n">draw</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">Framebuffer</span><span class="o">&</span> <span class="n">getBuffer</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">buffer_</span><span class="p">;</span> <span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="n">Framebuffer</span> <span class="n">buffer_</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div>
<aside name="draw">
<p>Specifically, it draws this artistic masterpiece:</p>
<p><img src="images/double-buffer-face.png" width="240" alt="A pixellated smiley face." /></p>
</aside>
<p>Every frame, the game tells the scene to draw. The scene clears the buffer and
then draws a bunch of pixels, one at a time. It also provides access to the
internal buffer through <code>getBuffer()</code> so that the video driver can get to it.</p>
<p>This seems pretty straightforward, but if we leave it like this, we’ll run into
problems. The trouble is that the video driver can call <code>getPixels()</code> on the
buffer at <em>any</em> point in time, even here:</p>
<div class="codehilite"><pre><span></span><code><span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="c1">// <- Video driver reads pixels here!</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
<span class="n">buffer_</span><span class="p">.</span><span class="n">draw</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>
</code></pre></div>
<p>When that happens, the user will see the eyes of the face, but the mouth will
disappear for a single frame. In the next frame, it could get interrupted at some
other point. The end result is horribly flickering graphics. We’ll fix this with
double buffering:</p>
<div class="codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Scene</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="n">Scene</span><span class="p">()</span>
<span class="o">:</span> <span class="n">current_</span><span class="p">(</span><span class="o">&</span><span class="n">buffers_</span><span class="p">[</span><span class="mi">0</span><span class="p">]),</span>
<span class="n">next_</span><span class="p">(</span><span class="o">&</span><span class="n">buffers_</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="p">{}</span>
<span class="kt">void</span> <span class="n">draw</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">next_</span><span class="o">-></span><span class="n">clear</span><span class="p">();</span>
<span class="n">next_</span><span class="o">-></span><span class="n">draw</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="c1">// ...</span>
<span class="n">next_</span><span class="o">-></span><span class="n">draw</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>
<span class="n">swap</span><span class="p">();</span>
<span class="p">}</span>
<span class="n">Framebuffer</span><span class="o">&</span> <span class="n">getBuffer</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="o">*</span><span class="n">current_</span><span class="p">;</span> <span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="kt">void</span> <span class="n">swap</span><span class="p">()</span>
<span class="p">{</span>
<span class="c1">// Just switch the pointers.</span>
<span class="n">Framebuffer</span><span class="o">*</span> <span class="n">temp</span> <span class="o">=</span> <span class="n">current_</span><span class="p">;</span>
<span class="n">current_</span> <span class="o">=</span> <span class="n">next_</span><span class="p">;</span>
<span class="n">next_</span> <span class="o">=</span> <span class="n">temp</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">Framebuffer</span> <span class="n">buffers_</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="n">Framebuffer</span><span class="o">*</span> <span class="n">current_</span><span class="p">;</span>
<span class="n">Framebuffer</span><span class="o">*</span> <span class="n">next_</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div>
<p>Now <code>Scene</code> has two buffers, stored in the <code>buffers_</code> array. We don’t directly
reference them from the array. Instead, there are two members, <code>next_</code> and
<code>current_</code>, that point into the array. When we draw, we draw onto the next
buffer, referenced by <code>next_</code>. When the video driver needs to get the pixels,
it always accesses the <em>other</em> buffer through <code>current_</code>.</p>
<p>This way, the video driver never sees the buffer that we’re working on. The only
remaining piece of the puzzle is the call to <code>swap()</code> when the scene is done
drawing the frame. That swaps the two buffers by simply switching the <code>next_</code>
and <code>current_</code> references. The next time the video driver calls <code>getBuffer()</code>,
it will get the new buffer we just finished drawing and put our recently
drawn buffer on screen. No more tearing or unsightly glitches.</p>
<h3><a href="#not-just-for-graphics" name="not-just-for-graphics">Not just for graphics</a></h3>
<p>The core problem that double buffering solves is state being accessed while it’s
being modified. There are two common causes of this. We’ve covered the first one
with our graphics example — the state is directly accessed from code on another
thread or interrupt.</p>
<p>There is another equally common cause, though: when the code <em>doing the
modification</em> is accessing the same state that it’s modifying. This can manifest
in a variety of places, especially physics and AI where you have entities
interacting with each other. Double-buffering is often helpful here too.</p>
<h3><a href="#artificial-unintelligence" name="artificial-unintelligence">Artificial unintelligence</a></h3>
<p>Let’s say we’re building the behavioral system for, of all things, a game based
on slapstick comedy. The game has a stage containing a bunch of actors that run
around and get up to various hijinks and shenanigans. Here’s our base actor:</p>
<div class="codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Actor</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="n">Actor</span><span class="p">()</span> <span class="o">:</span> <span class="n">slapped_</span><span class="p">(</span><span class="nb">false</span><span class="p">)</span> <span class="p">{}</span>
<span class="k">virtual</span> <span class="o">~</span><span class="n">Actor</span><span class="p">()</span> <span class="p">{}</span>
<span class="k">virtual</span> <span class="kt">void</span> <span class="n">update</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">reset</span><span class="p">()</span> <span class="p">{</span> <span class="n">slapped_</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span>
<span class="kt">void</span> <span class="nf">slap</span><span class="p">()</span> <span class="p">{</span> <span class="n">slapped_</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span>
<span class="kt">bool</span> <span class="nf">wasSlapped</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">slapped_</span><span class="p">;</span> <span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="kt">bool</span> <span class="n">slapped_</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div>
<p>Every frame, the game is responsible for calling <span
name="update"><code>update()</code></span> on the actor so that it has a chance to do some
processing. Critically, from the user’s perspective, <em>all actors should appear
to update simultaneously</em>.</p>
<aside name="update">
<p>This is an example of the <a class="pattern" href="update-method.html">Update
Method</a> pattern.</p>
</aside>
<p>Actors can also interact with each other, if by “interacting”, we mean “they can
slap each other around”. When updating, the actor can call <code>slap()</code> on another
actor to slap it and call <code>wasSlapped()</code> to determine if it has been slapped.</p>
<p>The actors need a stage where they can interact, so let’s build that:</p>
<div class="codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Stage</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="kt">void</span> <span class="n">add</span><span class="p">(</span><span class="n">Actor</span><span class="o">*</span> <span class="n">actor</span><span class="p">,</span> <span class="kt">int</span> <span class="n">index</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">actors_</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="n">actor</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">update</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">NUM_ACTORS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">actors_</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-></span><span class="n">update</span><span class="p">();</span>
<span class="n">actors_</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-></span><span class="n">reset</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="k">static</span> <span class="k">const</span> <span class="kt">int</span> <span class="n">NUM_ACTORS</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
<span class="n">Actor</span><span class="o">*</span> <span class="n">actors_</span><span class="p">[</span><span class="n">NUM_ACTORS</span><span class="p">];</span>
<span class="p">};</span>
</code></pre></div>
<p><code>Stage</code> lets us add actors, and provides a single <code>update()</code> call that updates each
actor. To the user, actors appear to move simultaneously, but internally,
they are updated one at a time.</p>
<p>The only other point to note is that each actor’s “slapped” state is cleared
immediately after updating. This is so that an actor only responds to a given
slap once.</p>
<p>To get things going, let’s define a concrete actor subclass. Our comedian here
is pretty simple. He faces a single actor. Whenever he gets slapped — by
anyone — he responds by slapping the actor he faces.</p>
<div class="codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Comedian</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Actor</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="kt">void</span> <span class="n">face</span><span class="p">(</span><span class="n">Actor</span><span class="o">*</span> <span class="n">actor</span><span class="p">)</span> <span class="p">{</span> <span class="n">facing_</span> <span class="o">=</span> <span class="n">actor</span><span class="p">;</span> <span class="p">}</span>
<span class="k">virtual</span> <span class="kt">void</span> <span class="n">update</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">wasSlapped</span><span class="p">())</span> <span class="n">facing_</span><span class="o">-></span><span class="n">slap</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="n">Actor</span><span class="o">*</span> <span class="n">facing_</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div>
<p>Now, let’s throw some comedians on a stage and see what happens. We’ll set up
three comedians, each facing the next. The last one will face the first, in a
big circle:</p>
<div class="codehilite"><pre><span></span><code><span class="n">Stage</span> <span class="n">stage</span><span class="p">;</span>
<span class="n">Comedian</span><span class="o">*</span> <span class="n">harry</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Comedian</span><span class="p">();</span>
<span class="n">Comedian</span><span class="o">*</span> <span class="n">baldy</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Comedian</span><span class="p">();</span>
<span class="n">Comedian</span><span class="o">*</span> <span class="n">chump</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Comedian</span><span class="p">();</span>
<span class="n">harry</span><span class="o">-></span><span class="n">face</span><span class="p">(</span><span class="n">baldy</span><span class="p">);</span>
<span class="n">baldy</span><span class="o">-></span><span class="n">face</span><span class="p">(</span><span class="n">chump</span><span class="p">);</span>
<span class="n">chump</span><span class="o">-></span><span class="n">face</span><span class="p">(</span><span class="n">harry</span><span class="p">);</span>
<span class="n">stage</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">harry</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="n">stage</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">baldy</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">stage</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">chump</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
</code></pre></div>
<p>The resulting stage is set up as shown in the following image. The arrows
show who the actors are facing, and the numbers show their index in the stage’s array.</p>
<p><img src="images/double-buffer-slaps-1.png" alt="Boxes for Harry, Baldy, and Chump, in that order. Harry has an arrow pointing to Baldy, who has an arrow pointing to Chump, who has an arrow pointing back to Harry." /></p>
<p>We’ll slap Harry to get things going and see what happens when we start
processing:</p>
<div class="codehilite"><pre><span></span><code><span class="n">harry</span><span class="o">-></span><span class="n">slap</span><span class="p">();</span>
<span class="n">stage</span><span class="p">.</span><span class="n">update</span><span class="p">();</span>
</code></pre></div>
<p>Remember that the <code>update()</code> function in <code>Stage</code> updates each actor in turn, so if
we step through the code, we’ll find that the following occurs:</p>
<div class="codehilite"><pre><span></span><code>Stage updates actor 0 (Harry)
Harry was slapped, so he slaps Baldy
Stage updates actor 1 (Baldy)
Baldy was slapped, so he slaps Chump
Stage updates actor 2 (Chump)
Chump was slapped, so he slaps Harry
Stage update ends
</code></pre></div>
<p>In a single frame, our initial slap on Harry has propagated through all of
the comedians. Now, to mix things up a bit, let’s say we reorder the comedians
within the stage’s array but leave them facing each other the same way.</p>
<p><img src="images/double-buffer-slaps-2.png" alt="The same boxes as before with the same arrows, but now they are ordered Chump, Baldy, Harry." /></p>
<p>We’ll leave the rest of the stage setup alone, but we’ll replace the chunk of code
where we add the actors to the stage with this:</p>
<div class="codehilite"><pre><span></span><code><span class="n">stage</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">harry</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="n">stage</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">baldy</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="n">stage</span><span class="p">.</span><span class="n">add</span><span class="p">(</span><span class="n">chump</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</code></pre></div>
<p>Let’s see what happens when we run our experiment again:</p>
<div class="codehilite"><pre><span></span><code>Stage updates actor 0 (Chump)
Chump was not slapped, so he does nothing
Stage updates actor 1 (Baldy)
Baldy was not slapped, so he does nothing
Stage updates actor 2 (Harry)
Harry was slapped, so he slaps Baldy
Stage update ends
</code></pre></div>
<p>Uh, oh. Totally different. The problem is straightforward. When we
update the actors, we modify their “slapped” states, the exact same
state we also <em>read</em> during the update. Because of this, changes to
that state early in the update affect <span name="cascade">later</span> parts of that <em>same</em>
update step.</p>
<aside name="cascade">
<p>If you continue to update the stage, you’ll see the slaps gradually
cascade through the actors, one per frame. In the first frame, Harry
slaps Baldy. In the next frame, Baldy slaps Chump, and so on.</p>
</aside>
<p>The ultimate result is that an actor may respond to being slapped in
either the <em>same</em> frame as the slap or in the <em>next</em> frame based
entirely on how the two actors happen to be ordered on the stage. This
violates our requirement that actors need to appear to run in
parallel — the order that they update within a single frame shouldn’t
matter.</p>
<h3><a href="#buffered-slaps" name="buffered-slaps">Buffered slaps</a></h3>
<p>Fortunately, our Double Buffer pattern can help. This time, instead of
having two copies of a monolithic “buffer” object, we’ll be buffering
at a much finer granularity: each actor’s “slapped” state:</p>
<div class="codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Actor</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="n">Actor</span><span class="p">()</span> <span class="o">:</span> <span class="n">currentSlapped_</span><span class="p">(</span><span class="nb">false</span><span class="p">)</span> <span class="p">{}</span>
<span class="k">virtual</span> <span class="o">~</span><span class="n">Actor</span><span class="p">()</span> <span class="p">{}</span>
<span class="k">virtual</span> <span class="kt">void</span> <span class="n">update</span><span class="p">()</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">swap</span><span class="p">()</span>
<span class="p">{</span>
<span class="c1">// Swap the buffer.</span>
<span class="n">currentSlapped_</span> <span class="o">=</span> <span class="n">nextSlapped_</span><span class="p">;</span>
<span class="c1">// Clear the new "next" buffer.</span>
<span class="n">nextSlapped_</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">slap</span><span class="p">()</span> <span class="p">{</span> <span class="n">nextSlapped_</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span>
<span class="kt">bool</span> <span class="nf">wasSlapped</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">currentSlapped_</span><span class="p">;</span> <span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="kt">bool</span> <span class="n">currentSlapped_</span><span class="p">;</span>
<span class="kt">bool</span> <span class="n">nextSlapped_</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div>
<p>Instead of a single <code>slapped_</code> state, each actor now has two. Just
like the previous graphics example, the current state is used for
reading, and the next state is used for writing.</p>
<p>The <code>reset()</code> function has been replaced with <code>swap()</code>. Now, right
before clearing the swap state, it copies the next state into the
current one, making it the new current state. This also requires a
small change in <code>Stage</code>:</p>
<div class="codehilite"><pre><span></span><code><span class="kt">void</span> <span class="nf">Stage::update</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">NUM_ACTORS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">actors_</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-></span><span class="n">update</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">NUM_ACTORS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">actors_</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">-></span><span class="n">swap</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>The <code>update()</code> function now updates all of the actors and <em>then</em> swaps
all of their states. The end result of this is that an actor will only see a
slap in the frame <em>after</em> it was actually slapped. This way, the actors will
behave the same no matter their order in the stage’s array. As far as the user
or any outside code can tell, all of the actors update simultaneously within a
frame.</p>
<h2><a href="#design-decisions" name="design-decisions">Design Decisions</a></h2>
<p>Double Buffer is pretty straightforward, and the examples we’ve seen so far
cover most of the variations you’re likely to encounter. There are two main
decisions that come up when implementing this pattern.</p>
<h3><a href="#how-are-the-buffers-swapped" name="how-are-the-buffers-swapped">How are the buffers swapped?</a></h3>
<p>The swap operation is the most critical step of the process since we
must lock out all reading and modification of both buffers while it’s
occurring. To get the best performance, we want this to happen as
quickly as possible.</p>
<ul>
<li>
<p><strong>Swap pointers or references to the buffer:</strong></p>
<p>This is how our graphics example works, and it’s the most common
solution for double-buffering graphics.</p>
<ul>
<li>
<p><em>It’s fast.</em> Regardless of how big the buffer is, the swap is simply a
couple of pointer assignments. It’s hard to beat that for speed and
simplicity.</p>
</li>
<li>
<p><em>Outside code cannot store persistent pointers to the buffer.</em> This is
the main limitation. Since we don’t actually move the <em>data</em>, what we’re
essentially doing is periodically telling the rest of the codebase to
look somewhere else for the buffer, like in our original stage analogy.
This means that the rest of the codebase can’t store pointers directly
to data within the buffer — they may be pointing at the wrong one a
moment later.</p>
<p>This can be particularly troublesome on a system where the video driver
expects the framebuffer to always be at a fixed location in memory. In
that case, we won’t be able to use this option.</p>
</li>
<li>
<p><em>Existing data on the buffer will be from two frames ago, not the last
frame.</em> Successive frames are drawn on alternating buffers with no data
copied between them, like so:</p>
<div class="codehilite"><pre><span></span><code>Frame 1 drawn on buffer A
Frame 2 drawn on buffer B
Frame 3 drawn on buffer A
...
</code></pre></div>
<p>You’ll note that when we go to draw the third frame, the data already on
the buffer is from frame <em>one</em>, not the more recent second frame. In
most cases, this isn’t an issue — we usually clear the whole
buffer right before drawing. But if we intend to <span
name="blur">reuse</span> some of the existing data on the buffer, it’s
important to take into account that that data will be a frame older than
we might expect.</p>
<aside name="blur">
<p>One classic use of old framebuffer data is simulating motion blur. The
current frame is blended with a bit of the previously rendered frame to
make a resulting image that looks more like what a real camera captures.</p>
</aside>
</li>
</ul>
</li>
<li>
<p><strong>Copy the data between the buffers:</strong></p>
<p>If we can’t repoint users to the other buffer, the only other option is
to actually copy the data from the next frame to the current frame. This is
how our slapstick comedians work. In that case, we chose this method because
the state — a single Boolean flag — doesn’t take any longer to copy than a
pointer to the buffer would.</p>
<ul>
<li>
<p><em>Data on the next buffer is only a single frame old.</em> This is the nice
thing about copying the data as opposed to ping-ponging back and forth
between the two buffers. If we need access to previous buffer data, this
will give us more up-to-date data to work with.</p>
</li>
<li>
<p><em>Swapping can take more time.</em> This, of course, is the big negative
point. Our swap operation now means copying the entire buffer in memory.
If the buffer is large, like an entire framebuffer, it can take a
significant chunk of time to do this. Since nothing can read or write to
<em>either</em> buffer while this is happening, that’s a big limitation.</p>
</li>
</ul>
</li>
</ul>
<h3><a href="#what-is-the-granularity-of-the-buffer" name="what-is-the-granularity-of-the-buffer">What is the granularity of the buffer?</a></h3>
<p>The other question is how the buffer itself is organized — is it a single monolithic
chunk of data or distributed among a collection of objects? Our graphics
example uses the former, and the actors use the latter.</p>
<p>Most of the time, the nature of what you’re buffering will lead to the answer,
but there’s some flexibility. For example, our actors all could have stored
their messages in a single message block that they all reference into by their
index.</p>
<ul>
<li>
<p><strong>If the buffer is monolithic:</strong></p>
<ul>
<li><p><em>Swapping is simpler.</em> Since there is only one pair of buffers, a
single swap does it. If you can swap by changing pointers, then you can
swap the entire buffer, regardless of size, with just a couple of
assignments.</p></li>
</ul>
</li>
<li>
<p><strong>If many objects have a piece of data:</strong></p>
<ul>
<li>
<p><em>Swapping is slower.</em> In order to swap, we need to iterate through the
entire collection of objects and tell each one to swap.</p>
<p>In our comedian example, that was OK since we needed to clear the next
slap state anyway — every piece of buffered state needed to be touched
each frame. If we don’t need to otherwise touch the old buffer, there’s
a simple optimization we can do to get the same performance of a
monolithic buffer while distributing the buffer across multiple objects.</p>
<p>The idea is to get the “current” and “next” pointer concept and apply it
to each of our objects by turning them into object-relative <em>offsets</em>.
Like so:</p>
<div class="codehilite"><pre><span></span><code><span class="k">class</span> <span class="nc">Actor</span>
<span class="p">{</span>
<span class="k">public</span><span class="o">:</span>
<span class="k">static</span> <span class="kt">void</span> <span class="n">init</span><span class="p">()</span> <span class="p">{</span> <span class="n">current_</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span>
<span class="k">static</span> <span class="kt">void</span> <span class="n">swap</span><span class="p">()</span> <span class="p">{</span> <span class="n">current_</span> <span class="o">=</span> <span class="n">next</span><span class="p">();</span> <span class="p">}</span>
<span class="kt">void</span> <span class="n">slap</span><span class="p">()</span> <span class="p">{</span> <span class="n">slapped_</span><span class="p">[</span><span class="n">next</span><span class="p">()]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span>
<span class="kt">bool</span> <span class="n">wasSlapped</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">slapped_</span><span class="p">[</span><span class="n">current_</span><span class="p">];</span> <span class="p">}</span>
<span class="k">private</span><span class="o">:</span>
<span class="k">static</span> <span class="kt">int</span> <span class="n">current_</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">int</span> <span class="nf">next</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">current_</span><span class="p">;</span> <span class="p">}</span>
<span class="kt">bool</span> <span class="n">slapped_</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
<span class="p">};</span>
</code></pre></div>
<p>Actors access their current slap state by using <code>current_</code> to index into
the state array. The next state is always the other index in the array,
so we can calculate that with <code>next()</code>. Swapping the state simply
alternates the <code>current_</code> index. The clever bit is that <code>swap()</code> is now
a <em>static</em> function — it only needs to be called once, and <em>every</em>
actor’s state will be swapped.</p>
</li>
</ul>
</li>
</ul>
<h2><a href="#see-also" name="see-also">See Also</a></h2>
<ul>
<li><p>You can find the Double Buffer pattern in use in almost every graphics
API out there. For example, OpenGL has <code>swapBuffers()</code>, Direct3D has “swap
chains”, and Microsoft’s XNA framework swaps the framebuffers within its
<code>endDraw()</code> method.</p></li>
</ul>
<nav>
<span class="prev">← <a href="sequencing-patterns.html">Previous Chapter</a></span>
<span class="next"><a href="game-loop.html">Next Chapter</a> →</span>
<span class="toc">≡ <a href="/">The Book</a></span>
</nav>
</div>
</div>
<footer>© 2009-2021 Robert Nystrom</footer>
</body>
</html>