×
Namespaces

Variants
Actions
(Difference between revisions)

Avoid flickering with double buffering on Symbian

From Nokia Developer Wiki
Jump to: navigation, search
Forum Nokia KB (Talk | contribs)
lpvalente (Talk | contribs)
m (Lpvalente -)
 
(9 intermediate revisions by 4 users not shown)
Line 1: Line 1:
__NOTOC__
+
[[Category:Symbian C++]][[Category:Code Snippet]][[Category:Graphics]][[Category:Code Snippet]]
__NOEDITSECTION__
+
{{ArticleMetaData <!-- v1.2 -->
{{KBCS}}
+
|sourcecode= <!-- Link to example source code (e.g. [[Media:The Code Example ZIP.zip]]) -->
{|style="background:#eceff2" width="660px" border="1" cellpadding="5" cellspacing="0"
+
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.sis]]) -->
|-
+
|devices= Nokia N95
|'''ID''' ||CS001049
+
|sdk= <!-- SDK(s) built and tested against (e.g. [http://linktosdkdownload/ Nokia Qt SDK 1.1]) -->
|'''Creation date''' || July 1, 2008
+
|platform= S60 3rd Edition, MR
|-
+
|devicecompatability= <!-- Compatible devices (e.g.: All* (must have GPS) ) -->
|'''Platform''' || S60 3rd Edition, MR
+
|dependencies= <!-- Any other/external dependencies e.g.: Google Maps Api v1.0 -->
|'''Tested on devices''' || Nokia N95
+
|signing= <!-- Empty or one of Self-Signed, DevCert, Manufacturer -->
|-
+
|capabilities= <!-- Capabilities required by the article/code example (e.g. Location, NetworkServices. -->
|'''Category''' || Symbian C++
+
|keywords= double buffering, CFbsBitmapDevice, CFbsBitGc, CFbsBitmap
|'''Subcategory''' || Code Examples
+
|language= <!-- Language category code for non-English topics - e.g. Lang-Chinese -->
|-
+
|translated-by= <!-- [[User:XXXX]] -->
|}
+
|translated-from-title= <!-- Title only -->
 
+
|translated-from-id= <!-- Id of translated revision -->
 
+
|review-by= <!-- After re-review: [[User:username]] -->
{|style="background:#eceff2" width="660px" border="1" cellpadding="5" cellspacing="0"
+
|review-timestamp= <!-- After re-review: YYYYMMDD -->
|-
+
|update-by= <!-- After significant update: [[User:username]]-->
|'''Keywords (APIs, classes, methods, functions):''' double buffering, CFbsBitmapDevice, CFbsBitGc, CFbsBitmap
+
|update-timestamp= <!-- After significant update: YYYYMMDD -->
|}
+
|creationdate= 20080613
 +
|author= [[User:Tepaa]]
 +
<!-- The following are not in current metadata -->
 +
|subcategory= Graphics
 +
|id= CS001049
 +
}}
  
 
==Overview==
 
==Overview==
When drawing images directly on the screen and there exists some animation
+
{{Abstract|When images are drawn directly on the screen and there is an animation, the screen may flicker. A common technique to solve this is to draw images on an off-screen buffer, and then copy its contents to the screen when the drawing operations are finished.
can screen flicker.
+
A common technique to solve this is to draw images on an off-screen buffer,
+
and them copy its contents to the screen when the drawing operations are finished.
+
  
Following example shows how to implement this technique. There is neede two buffers,
+
The following example shows how to implement this technique. Two buffers are needed, hence the term "double buffering". This off-screen buffer has the same screen dimensions as the original one.}}
hence the term "double buffering". This off-screen buffer has the same dimensions of the screen than
+
the original one.
+
  
 
==MMP file==
 
==MMP file==
 
The following capabilities and libraries are required:
 
The following capabilities and libraries are required:
 
<code cpp>
 
<code cpp>
CAPABILITY       NONE
+
CAPABILITY NONE
LIBRARY           fbscli.lib
+
LIBRARY fbscli.lib
LIBRARY           bitgdi.lib
+
LIBRARY bitgdi.lib
 
</code>
 
</code>
  
 
==Header==
 
==Header==
Here is example header of CCoeControl componet where double buffering is enabled
+
Here is an example header of the CCoeControl component where double buffering is enabled.
 
<code cpp>
 
<code cpp>
 
#include <coecntrl.h>
 
#include <coecntrl.h>
Line 73: Line 73:
 
         CFbsBitmapDevice*              iBackBufferDevice;
 
         CFbsBitmapDevice*              iBackBufferDevice;
 
         CFbsBitGc*                      iBackBufferContext;
 
         CFbsBitGc*                      iBackBufferContext;
         TSize                           iBackBufferSize;
+
         TSize iBackBufferSize;
 
          
 
          
     // class other member variables if needed
+
     // other member variables of the class if needed
 
     private:
 
     private:
 
     };
 
     };
Line 81: Line 81:
  
 
==Source==
 
==Source==
There is source code only double buffering-related data
+
This source code is only for data related to double buffering:
 
<code cpp>
 
<code cpp>
 
void CMyContainer::SizeChanged()
 
void CMyContainer::SizeChanged()
Line 151: Line 151:
 
     CWindowGc& gc = SystemGc();
 
     CWindowGc& gc = SystemGc();
 
      
 
      
     // Copy backbuffer into the screen
+
     // Copy backbuffer to the screen
 
     gc.BitBlt(TPoint(0, 0), iBackBuffer);
 
     gc.BitBlt(TPoint(0, 0), iBackBuffer);
 
      
 
      
Line 164: Line 164:
  
 
==Using==
 
==Using==
Old way was
+
Previously this was done as follows:
 
<code cpp>
 
<code cpp>
 
iAppContainer->DrawNow();
 
iAppContainer->DrawNow();
 
</code>
 
</code>
  
and now with double buffering
+
and now with double buffering:
 
<code cpp>
 
<code cpp>
 
iAppContainer->DrawToBackBuffer();
 
iAppContainer->DrawToBackBuffer();
Line 176: Line 176:
  
 
==Postconditions==  
 
==Postconditions==  
No anymore flickering
+
The screen does not flicker any more.
  
 
==See also==
 
==See also==
Line 182: Line 182:
  
 
[http://en.wikipedia.org/wiki/Double_buffering Double buffering in Wikipedia]
 
[http://en.wikipedia.org/wiki/Double_buffering Double buffering in Wikipedia]
 
[[Category:Symbian C++]][[Category:Code Examples]]
 

Latest revision as of 16:06, 23 January 2013

Article Metadata
Tested with
Devices(s): Nokia N95
Compatibility
Platform(s): S60 3rd Edition, MR
Article
Keywords: double buffering, CFbsBitmapDevice, CFbsBitGc, CFbsBitmap
Created: tepaa (13 Jun 2008)
Last edited: lpvalente (23 Jan 2013)

Contents

[edit] Overview

When images are drawn directly on the screen and there is an animation, the screen may flicker. A common technique to solve this is to draw images on an off-screen buffer, and then copy its contents to the screen when the drawing operations are finished.

The following example shows how to implement this technique. Two buffers are needed, hence the term "double buffering". This off-screen buffer has the same screen dimensions as the original one.

[edit] MMP file

The following capabilities and libraries are required:

CAPABILITY NONE
LIBRARY fbscli.lib
LIBRARY bitgdi.lib

[edit] Header

Here is an example header of the CCoeControl component where double buffering is enabled.

#include <coecntrl.h>
#include <bitstd.h>
#include <bitdev.h>
 
class CMyContainer : public CCoeControl
{
public:
void NewL(const TRect& aRect)
void ConstructL(const TRect& aRect);
virtual ~CImageConverterContainer();
private:
void CMyContainer();
void SizeChanged();
void HandleResourceChange(TInt aType);
TInt CountComponentControls() const;
CCoeControl* ComponentControl(TInt aIndex) const;
void Draw(const TRect& aRect) const;
 
// for Double buffering
public:
void DrawToBackBuffer();
// for Double buffering
private:
void CreateBackBufferL();
void ReleaseBackBuffer();
 
// for Double buffering
private:
CFbsBitmap* iBackBuffer;
CFbsBitmapDevice* iBackBufferDevice;
CFbsBitGc* iBackBufferContext;
TSize iBackBufferSize;
 
// other member variables of the class if needed
private:
};

[edit] Source

This source code is only for data related to double buffering:

void CMyContainer::SizeChanged()
{
// Delete back buffer and create a new one with new size
ReleaseBackBuffer();
CreateBackBufferL();
DrawToBackBuffer();
}
 
void CMyContainer::CreateBackBufferL()
{
// Create back buffer bitmap
iBackBuffer = new (ELeave) CFbsBitmap;
 
User::LeaveIfError( iBackBuffer->Create(Size(),
iEikonEnv->DefaultDisplayMode()));
 
// Create back buffer graphics context
iBackBufferDevice = CFbsBitmapDevice::NewL(iBackBuffer);
User::LeaveIfError(iBackBufferDevice->CreateContext(iBackBufferContext));
iBackBufferContext->SetPenStyle(CGraphicsContext::ESolidPen);
 
iBackBufferSize = iBackBuffer->SizeInPixels();
}
 
void CMyContainer::ReleaseBackBuffer()
{
// Release double buffering classes
if (iBackBufferContext)
{
delete iBackBufferContext;
iBackBufferContext = NULL;
}
if (iBackBufferDevice)
{
delete iBackBufferDevice;
iBackBufferDevice = NULL;
}
if (iBackBuffer)
{
delete iBackBuffer;
iBackBuffer = NULL;
}
iBackBufferSize = TSize(0, 0);
}
 
void CMyContainer::DrawToBackBuffer()
{
if (!iBackBufferContext)
{
return;
}
 
iBackBufferContext->Clear();
 
// TODO: do your drawing there.
// Remember to draw to iBackBufferContext buffered graphic contex
 
// Example of drawing bitmap into iBackBufferContext
//if(iBitmap)
// {
// iBackBufferContext->BitBlt( iPicturePoint, iBitmap );
// }
}
 
void CMyContainer::Draw(const TRect& aRect) const
{
CWindowGc& gc = SystemGc();
 
// Copy backbuffer to the screen
gc.BitBlt(TPoint(0, 0), iBackBuffer);
 
// TODO: Remove your all drawing from there to DrawToBackBuffer
}
 
CMyContainer::~CMyContainer()
{
ReleaseBackBuffer();
}

[edit] Using

Previously this was done as follows:

iAppContainer->DrawNow();

and now with double buffering:

iAppContainer->DrawToBackBuffer();
iAppContainer->DrawNow();

[edit] Postconditions

The screen does not flicker any more.

[edit] See also

Anti-tearing with CDirectScreenBitmap

Double buffering in Wikipedia

This page was last modified on 23 January 2013, at 16:06.
93 page views in the last 30 days.
×