###Doublebuffer Double cache simply says: When a cache is read, it is written to another cache, so alternately the pattern has two cache instances, one is current buffer and the next buffer reads from current buffer To the next buffer to write the information. Swap operation for two-buff identity Switching # # # # when to use1states that require incremental modification2access is required during the modification process3when accessing data, it is not found that the data is being written4read operations do not wait for write operations to complete # # # Notes1swap operation is time consuming2must have two buffer, memory consumption becomes larger # # # # code### #一个帧缓存的例子 ' 'classframebuffer{ Public: Framebuffer () {clear ();} voidClear () { for(inti =0; I < WIDTH * HEIGHT; i++) {Pixels_[i]=White ; } } voidDrawintXinty) {pixels_[(WIDTH* y) + x] =BLACK; } Const Char*Getpixels () {returnPixels_; }Private: Static Const intWIDTH = the; Static Const intHEIGHT = -; CharPixels_[width *HEIGHT];};//Issue versionclassscene{ Public: //each frame executes voidDraw () {buffer_.clear (); Buffer_.draw (1,1); Buffer_.draw (4,1); //the problem! Video driver can read pixels at any time and may read illegal valuesBuffer_.draw (1,3); Buffer_.draw (2,4); Buffer_.draw (3,4); Buffer_.draw (4,3); } Framebuffer& GetBuffer () {returnBuffer_;}Private: Framebuffer buffer_; voidswap () {//Just Switch the pointers.framebuffer* temp =Current_; Current_=Next_; Next_=temp; } };//use double bufferclassscene{ Public: Scene (): Current_ (&buffers_[0]), Next_ (&buffers_[1]) {} //video driver will only get pixel from current voidDraw () {Next_-Clear (); Next_->draw (1,1); // ...Next_->draw (4,3); Swap (); } Framebuffer& GetBuffer () {return*Current_;}Private: voidswap () {//Just Switch the pointers.framebuffer* temp =Current_; Current_=Next_; Next_=temp; } Framebuffer buffers_[2]; Framebuffer*Current_; Framebuffer*Next_;}; "' ##### Artificial unintelligence 'classactor{ Public: Actor (): Slapped_ (false) {} Virtual~Actor () {}Virtual voidUpdate () =0; voidReset () {slapped_ =false; } voidSlap () {slapped_ =true; } BOOLWasslapped () {returnslapped_;}Private: BOOLslapped_;};//each frame calls the actor's update, and all actors need to be updated at the same time .//actors can interact with each other, such as hittingclassstage{ Public: voidAdd (actor* Actor,intindex) {Actors_[index]=actor; } voidUpdate () { for(inti =0; i < num_actors; i++) {Actors_[i]-update (); Actors_[i]-Reset (); } }Private: Static Const intNum_actors =3; Actor*actors_[num_actors];};//at the same time, there will only be one actor performing the updateclassComedian: Publicactor{ Public: voidFace (actor* Actor) {facing_ =actor;} Virtual voidUpdate () {if(wasslapped ()) facing_->slap (); }Private: Actor*facing_;};//face SB .Harry------> Balay------>Chump^ | | -------------------------------v stage stage; Comedian* Harry =Newcomedian (); Comedian* Baldy =Newcomedian (); Comedian* Chump =Newcomedian (); Harry.-Face (Baldy); Baldy-Face (chump); Chump-Face (Harry); Stage.add (Harry,0); Stage.add (Baldy,1); Stage.add (Chump,2); Harry-slap (); Stage.update ();//SlapHarry---Slap---> balay--slap---->Chump^ | | ----------------Slap---------------v The correct result #如果把三人的执行顺序换一下, the result will be incorrect #stage.add (Harry,2); Stage.add (Baldy,1); Stage.add (Chump,0); only Harry slap baldybuffered slaps.//record The slap in buffer .classactor{ Public: Actor (): Currentslapped_ (false) {} Virtual~Actor () {}Virtual voidUpdate () =0; voidswap () {//Swap the buffer.Currentslapped_ =Nextslapped_; //Clear The new "next" buffer.Nextslapped_ =false; } voidSlap () {nextslapped_ =true; } BOOLWasslapped () {returncurrentslapped_;}Private: BOOLCurrentslapped_; BOOLnextslapped_;};voidstage::update () { for(inti =0; i < num_actors; i++) {Actors_[i]-update (); } for(inti =0; i < num_actors; i++) {Actors_[i]-swap (); }} "# # # # # # # # Two buffer required to be locked, required to be as light and fast as possible1Exchange Pointer Reference1. Fast2. External code cannot save buffer pointer3The current data, which is the data before two frames (the data is written to next while reading2copy data between buffer if the swap is not possible, copy the next data to current if the number is small, it will be fine if the large amount of time "" When a lot of objects have to swap operation, will be very slow the following example, not swap, but s The lap changed the value of next .classactor{ Public: Static voidInit () {Current_ =0; } Static voidSwap () {Current_ =next ();} voidSlap () {slapped_[next ()] =true; } BOOLWasslapped () {returnSlapped_[current_];}Private: Static intCurrent_; Static intNext () {return 1-Current_;} BOOLslapped_[2];}; "' # # # # # alsoDoubleThe buffer mode is widely used in graphics programming. You can find the Double buffer patterninchUseinchAlmost every graphics API outthere. For example, OpenGL have Swapbuffers (), Direct3D has "swap chains", and Microsoft ' s XNA framework swaps the framebuffers WI Thin its EndDraw () method.
The dual-cache mode in 7_doublebuffer game programming