Dual buffering (double buffer) principle and use

Source: Internet
Author: User

One, double buffering effect

Double buffering and even multi-buffering are useful in many cases. In general, the use of double buffers is due to inconsistent supply and demand between "producer" and "consumer". Such a situation may occur in many places, and using multi-buffering can be a good solution. Let me cite a few common examples:
Example 1. When data is received during network transmission, it is sometimes possible for the data to come too quickly to receive data loss. This is due to the "sender" and "receiver" speed inconsistency, between them to arrange one or more buffers to hold too late to receive the data, so that the slower "receiver" can slowly take the data to avoid loss.
Example 2.Again, the level three cache structure in the computer: external memory (hard disk), memory, cache (between CPU and memory, possibly by multi-level). From left to right, their storage capacity is shrinking, but the speed is increasing, and of course the price is getting more expensive. As the "producer" of the CPU processing speed, and memory access speed relative to the CPU is slow, if directly in memory access to data, their speed inconsistent will cause the CPU capacity degradation. Hence the increased cache between them as a buffer to balance the difference in speed.
Example 3. In the graphic image display process, the computer from the display buffer to take the data and then display, many graphics operations are complex requires a lot of computation, it is difficult to access the display buffer to write the full graphics data to be displayed, often need to access the display buffer, each access to write the latest computed graphics data. The result is a graph that requires complex calculations, and the effects you see may be partially displayed, causing a large flicker discontinuity. Using double buffering allows you to first store the computed intermediate result in another buffer, but all of the calculations end, the buffer has already stored the full shape, and then the graphics data of the buffer is copied to the display buffer at once.
Example 1 uses double buffering to prevent data loss, and Example 2 uses double buffering to improve CPU processing efficiency, while example 3 uses double buffering to prevent undesirable experiences such as flicker delay when displaying graphics.
second, double buffering principle
Here, the main use of double buffering in the graphic image display of the application to do. The main principle of double buffering is mentioned in example 3 above, which is understood again through a diagram:
Figure 1 double buffering
Note, the display buffer is in conjunction with the monitor, and the display is only responsible for displaying the data from the display buffer. What we usually say is to draw a line on the monitor, which is actually writing the data to the display buffer. The display is constantly refreshed (fetching data from the display buffer) so that changes to the data in the display buffer are reflected on the monitor in a timely manner.
This is also the cause of flicker when displaying complex graphics, such as you are now showing a cluster of rays that are emitted from the center of the screen, and you begin to write code that starts with a loop from 0 degrees to 360 degrees, drawing a straight line from the center of the circle at every angle. Every time you draw a line is actually to the display buffer to write data, if you have not finished painting, the display from the display buffer data display graphics, when you see an incomplete graphics, and then you continue to draw lines, wait until the display buffer data display again, the graph is more complete than the last time, Go down until the full graphic is displayed. You see that the graphic is not displayed completely at once, but is displayed one at a time, causing flicker.
Understand the principle, look at the demo will know how to use. The following first describes how the Win32 API and C # in the use of double buffering, the other environment because it is not used so did not write, and so used to add, but in other circumstancesThe process is basically similar.
three, double buffer use (Win32 version) [CPP]View Plaincopyprint?
  1. LRESULT CALLBACK WndProc (hwnd hwnd, UINT message, WPARAM WPARAM, LPARAM LPARAM)
  2. {
  3. HDC hdc, HDCMEM;
  4. hbitmap Hbmpmem, hprebmp;
  5. switch (message)
  6. {
  7. Case WM_PAINT:
  8. HDC = BeginPaint (hWnd, &ps);
  9. / * Create a double buffer * /
  10. //Create a memory DC that is compatible with the current DC
  11. Hdcmem = CreateCompatibleDC (HDC);
  12. //Create a bitmap of a specified size
  13. Hbmpmem = CreateCompatibleBitmap (HDC, Rect.right, Rect.bottom);
  14. //The bitmap is selected into the memory DC and is All Black by default
  15. Hprebmp = SelectObject (Hdcmem, hmembmp);
  16. / * Draw in double buffering * /
  17. //Load background bitmap
  18. Hbkbmp = LoadBitmap (HInst, Makeintresource (IDB_BITMAP1));
  19. Hbrush = CreatePatternBrush (hbkbmp);
  20. GetClientRect (HWnd, &rect);
  21. FillRect (Hdcmem, &rect, hbrush);
  22. DeleteObject (Hbrush);
  23. / * Copy the double buffer image to the display buffer * /
  24. BitBlt (HDC, 0, 0, rect.right, Rect.bottom, Hdcmem, 0, 0, srccopy);
  25. / * Release resources * /
  26. SelectObject (Hdcmem, hprebmp);
  27. DeleteObject (hmembmp);
  28. DeleteDC (HDCMEM);
  29. EndPaint (HWnd, &ps);
  30. Break ;
  31. }
  32. }
[CPP]View Plaincopy print?
  1. LRESULT CALLBACK WndProc (hwnd hwnd, UINT message, WPARAM WPARAM, LPARAM LPARAM)
  2. {
  3. HDC hdc, HDCMEM;
  4. hbitmap Hbmpmem, hprebmp;
  5. switch (message)
  6. {
  7. Case WM_PAINT:
  8. HDC = BeginPaint (hWnd, &ps);
  9. / * Create a double buffer * /
  10. //Create a memory DC that is compatible with the current DC
  11. Hdcmem = CreateCompatibleDC (HDC);
  12. //Create a bitmap of a specified size
  13. Hbmpmem = CreateCompatibleBitmap (HDC, Rect.right, Rect.bottom);
  14. //The bitmap is selected into the memory DC and is All Black by default
  15. Hprebmp = SelectObject (Hdcmem, hmembmp);
  16. / * Draw in double buffering * /
  17. //Load background bitmap
  18. Hbkbmp = LoadBitmap (HInst, Makeintresource (IDB_BITMAP1));
  19. Hbrush = CreatePatternBrush (hbkbmp);
  20. GetClientRect (HWnd, &rect);
  21. FillRect (Hdcmem, &rect, hbrush);
  22. DeleteObject (Hbrush);
  23. / * Copy the double buffer image to the display buffer * /
  24. BitBlt (HDC, 0, 0, rect.right, Rect.bottom, Hdcmem, 0, 0, srccopy);
  25. / * Release resources * /
  26. SelectObject (Hdcmem, hprebmp);
  27. DeleteObject (hmembmp);
  28. DeleteDC (HDCMEM);
  29. EndPaint (HWnd, &ps);
  30. Break ;
  31. }
  32. }

When you use the Win32 version, be aware of freeing resources, and the order of release is the opposite of creation. I accidentally omitted a sentence in the use of the above "DeleteObject (hmembmp);" Causes graphics to be stuck after a period of time, view memory usage discover that memory has soared over time, and with the above code, there is no problem. It also reminds us once again how important it is to release resources, and how important it is to become a habit of programming.

Figure 2 memory change diagram after processing several WM_PAINT messages
In the process of use, if you want to update the area using the double buffer display, you can use InvalidateRect (hWnd, &rect,FALSE);  , it is important to note that the third parameter must be set to FALSE, and the third parameter indicates whether to erase the background when the region specified by the second parameter is updated, since the entire buffer data is copied directly to the display buffer when using the double buffering technique, so the third parameter is set to a FALSE helps improve new energy. The main reason is that if you erase the original buffer, it will cause the middle of the moment the display buffer is emptied (shown as the default background color), and then wait until the data of the double buffer is copied and then display the new image, which will cause flicker! This is contrary to the intention of using double buffering, so be aware of this.
Quad-Buffered use (C # version)
[CSharp]View Plaincopyprint?
  1. Public void Show (System.Windows.Forms.Control Control)
  2. {
  3. Graphics GC = control. CreateGraphics ();
  4. //Create buffered graphics context (similar to CreateCompatibleDC in Win32)
  5. BufferedGraphicsContext DC = new BufferedGraphicsContext ();
  6. //Create a specified size buffer (similar to CreateCompatibleBitmap in Win32)
  7. BufferedGraphics BackBuffer = DC. Allocate (GC, new Rectangle (new Point (0, 0), control.       Size));
  8. / * Like drawing with a normal graphics * /
  9. Pen pen = New Pen (Color.gray);
  10. foreach (Step s in m_steps)
  11. {
  12. Gc. DrawLine (pen, S.start, s.end);
  13. }
  14. //Render a graphic in a double buffer to the specified canvas (similar to Win32) BitBlt
  15. Backbuffer.render (Control. CreateGraphics ());
  16. }
[CSharp]View Plaincopy print?
  1. Public void Show (System.Windows.Forms.Control Control)
  2. {
  3. Graphics GC = control. CreateGraphics ();
  4. //Create buffered graphics context (similar to CreateCompatibleDC in Win32)
  5. BufferedGraphicsContext DC = new BufferedGraphicsContext ();
  6. //Create a specified size buffer (similar to CreateCompatibleBitmap in Win32)
  7. BufferedGraphics BackBuffer = DC. Allocate (GC, new Rectangle (new Point (0, 0), control.       Size));
  8. / * Like drawing with a normal graphics * /
  9. Pen pen = New Pen (Color.gray);
  10. foreach (Step s in m_steps)
  11. {
  12. Gc. DrawLine (pen, S.start, s.end);
  13. }
  14. //Render a graphic in a double buffer to the specified canvas (similar to Win32) BitBlt
  15. Backbuffer.render (Control. CreateGraphics ());
  16. }

Other versions are later used to supplement.

Dual buffering (double buffer) principle and use

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.