Join Now
Quality Rating:
  • Currently 5.0 / 5
(5.0 / 5 - 1 vote cast)
Expertise Level:
  • Currently 4.0 / 5
(4.0 / 5 - 1 vote cast)

This page was last modified 07:34, 31 December 2007.

Anti-tearing with CDirectScreenBitmap

From Forum Nokia Wiki

When developing games with fast-paced graphics it is desirable to avoid using Windows server when drawing to screen. There are several options to access screen directly, see here.

This article focuses on using CDirectScreenBitmap class.

The Anti-Tearing API

With this API it is possible to synchronize drawing to the LCD refresh rate (which is typically between 60 and 75Hz).

More details about the phenomenon "tearing" can be read here.

Quick description of CDirectScreenBitmap (also called as Anti-Tearing API) can be found here

(Note that some phones may not support this API!)

Sample code

This sample code contains a class (partially) that implements anti-tearing rendering.

Important!

For performance reasons, the code does not wait video driver to complete drawing the frame to the LCD. Instead it lets the application deal with the next frame. It the frame rate of the game is too fast, it may happen that we start updating the screen buffer while the video driver is still busy with rendering the previous frame. (It may lead to flickering.) To avoid flickering, the game's frame rate should be maximized to the half of the LCD refresh rate (e.g. max. 30 frames / sec).


// -------------------------------------------
// header file
// -------------------------------------------
 
...
#include <cdsb.h>	//CDirectScreenBitmap link to scdv.lib
 
#define TMpPixel TUint32
 
class CRendering : public CActive, public MDirectScreenAccess
    {
    
    // Construction, etc
    ... 
    
    public:
    
    	void ProcessFrame();
    	void BeginDraw();
    	void EndDraw();
    
    public: // from MDirectScreenAccess
    
    	virtual void Restart( RDirectScreenAccess::TTerminationReasons aReason );
    	virtual void AbortNow( RDirectScreenAccess::TTerminationReasons aReason );
    
    protected: // from CActive
    
    	void DoCancel();
    	void RunL();
    
    private:
    
    	CRendering();
    	void ConstructL( RWindow& aWindow );
    
    private:
    
    	CDirectScreenAccess* iDrawer;
    	CDirectScreenBitmap* iDSBitmap;
    
    	TMpPixel* iScreenAddress;
    };
 
...
 
// -------------------------------------------
// cpp file
// -------------------------------------------
 
...
 
CRendering::~CRendering()
    {
    // "Cancel" is a meaningless call, since the service 
    // (video driver's screen update process) is not cancellable.
    // When destroying this active object, you must make sure, 
    // that the last update request (CDirectScreenBitmap::EndUpdate()) is completed.
    // Assuming that LCD refresh rate is not less than 60 Hz,
    // the wait time should be more than 1/60 secs.
    // (Otherwise a stay signal comes.)
    Cancel();
    delete iDrawer;
    delete iDSBitmap;
    }
 
CRendering::CRendering():
CActive( CActive::EPriorityStandard )
    {
    }
 
void CRendering::ConstructL( RWindow& aWindow )
    {
    CActiveScheduler::Add( this );
    
    // Setting up direct screen access
    iDSBitmap = CDirectScreenBitmap::NewL();
    iDrawer = CDirectScreenAccess::NewL(
    	CEikonEnv::Static()->WsSession(),
    	*CEikonEnv::Static()->ScreenDevice(),
    	aWindow,
    	*this);
    CEikonEnv::Static()->WsSession().Flush();
    
    iDrawer->StartL();
    
    CFbsBitGc* gc = iDrawer->Gc();
    RRegion* region = iDrawer->DrawingRegion();
    gc->SetClippingRegion(region);
    
    // It may happen that a device does not support double buffering.
    User::LeaveIfError(
        iDSBitmap->Create(
            TRect(0, 0, KMpScreenWidth, KMpScreenHeight), CDirectScreenBitmap::EDoubleBuffer));
    }
 
void CRendering::Restart( RDirectScreenAccess::TTerminationReasons /*aReason*/ )
    {
    TRAPD( err, iDrawer->StartL() ); // You may panic here, if you want
    CFbsBitGc* gc = iDrawer->Gc();
    RRegion* region = iDrawer->DrawingRegion();
    gc->SetClippingRegion(region);
    
    iDSBitmap->Create(
        TRect(0, 0, KMpScreenWidth, KMpScreenHeight), CDirectScreenBitmap::EDoubleBuffer); 
    
    // Put some code here to continue game engine	
    }
 
void CRendering::AbortNow( RDirectScreenAccess::TTerminationReasons /*aReason*/ )
    {
    // Put some code here to suspend game engine	
    iDSBitmap->Close();
    }
 
void CRendering::RunL()
    {
    // Video driver finished to draw the last frame on the screen
    // You may initiate rendering the next frame from here, 
    // but it would be slow, since there is a delay between CDirectScreenBitmap::EndUpdate() 
    // and the completition of screen refresh by the video driver	
    }
 
void CRendering::DoCancel()
    {
    // Cancel not implemented in service provider, so we can't do anything here
    }
 
void CRendering::BeginDraw()
    {
    // Obtain the screen address every time before drawing the frame, 
    // since the address always changes
    TAcceleratedBitmapInfo bitmapInfo;
    iDSBitmap->BeginUpdate(bitmapInfo);        
    iScreenAddress = (TMpPixel*)bitmapInfo.iAddress;
    }
 
void CRendering::EndDraw()
    {
    if (IsActive())
    	{
    	Cancel();
    	}
    iDSBitmap->EndUpdate(iStatus);
    SetActive();
    // We don't need to wait to complete the request
    // We can start making the next frame instead.
    }
 
void CRendering::ProcessFrame()
    {
    // This method is responsible to render and draw a frame to the screen
    BeginDraw();
    
    // render the frame using iScreenAddress
    
    EndDraw();
    }
Related Discussions
Thread Thread Starter Forum Replies Last Post
MSCOMM commevent=3 glenn_johnson PC Suite API and PC Connectivity SDK 1 2003-12-17 22:32
How to - Dynamically update icons in List or Dialog relliott98 Symbian User Interface 1 2005-06-13 14:08
6630 Hard reset without using *#7370# brianpegan General Discussion 16 2008-07-04 03:18
Nokia 6630 and Internet Connection through PC jufaily General Discussion 1 2005-09-18 18:45
N80 midlet icon problem revisited... questions kounapuu Mobile Java General 1 2006-10-07 20:15
 
Powered by MediaWiki
     
     RDF Facets:
     
     
     qfnZtopicQUqfnTopicZgamesQ
     qfnZtypeQUqfnTypeZCommunityContentQ
     qfnZtypeQUqfnTypeZWebpageQ
     qfnZtypeQUqfnTypeZWikiContentQ
     qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX