How to use double-buffering to draw on a form
This tutorial is related to the SimpleDrawing bada app (v. 1.1.0) that you can find in the projects section. I will use it as an example to show, in my opinion, the most effective way to draw on a form through the use of double buffering.
The idea behind double-buffering is that you perform many drawing operations on an invisible bitmap, and only when you are ready to “submit” all the changes to the screen, this bitmap is copied as a whole to the bitmap that is finally made visible. This approach saves a lot of drawing resources, since the screen does not have to update each single time a small part is drawn. This is specially useful in games and other drawing-intensive bada apps.
The only difference in our example is that we will not use bitmaps but rather Canvas objects. First of all the drawing board gets a private member called Canvas * canvas_ , it will be our buffer we draw on. First we need to construct it though:
canvas_ = new Canvas(); canvas_->Construct(GetBounds()); canvas_->SetBackgroundColor(Color::COLOR_WHITE); canvas_->Clear();
We set its size to the size of our form (through GetBounds()), give it a white background and clear it. Then we edit the drawing function that is called by touch events:
inline void
DrawingBoardForm::DrawBrush(const Osp::Ui::Control & source,
const Osp::Graphics::Point& currentPosition)
{
int radius = brush_->size;
int x = currentPosition.x-radius;
int y = currentPosition.y-radius;
canvas_->FillEllipse(brush_->color.GetRGB32(),
Rectangle(x, y,radius*2,radius*2));
this->RequestRedraw(true);
}
We simply draw on our canvas buffer and then, when all the drawing is done, we request an asynchronous redrawing of the form through RequestRedraw(true). Please note that in this example the drawing operation is quiet simple. In a complex game you would perform hundreds of drawing operations on the buffer before requesting a redraw. The boolean passed to RequestRedraw() tells the form whether it should automatically call Show() after drawing.
Finally, we override the OnDraw() function of the form:
result
DrawingBoardForm::OnDraw()
{
Canvas* pCanvas = GetCanvasN();
if (pCanvas)
{
pCanvas->Copy(Point(GetClientAreaBounds().x, GetClientAreaBounds().y),*canvas_, GetClientAreaBounds());
delete pCanvas;
}
// Do not call Show(). It will be called automatically after OnDraw() callback.
return E_SUCCESS;
}
There we simply copy the buffered canvas contents into the canvas of the form. The form is redrawn and shown with this new contents. Pretty easy, huh?
I was pretty amazed on how much smoother the thing runs, compared to earlier versions when I was first getting started in bada
Oh well, we are all bada beginners!
Related posts:
the Flagship of independent news, reviews and resources for Developers and Users of Samsung's mobile platform Bada 




5 Responses to “How to use double-buffering to draw on a form”
By james on Jan 29, 2010 | Reply
just saw your post, and it works great! thanks!
The SDK documentation seems a little misleading. GetCanvasN() dosent quite create a new canvas, but is somehow linked to the control/frame/form? Clears up automatically everytime without me explictly calling Canvas::Clear()
By wit on Jan 29, 2010 | Reply
Yeah, that’s what GetCanvasN() seems to be doing, James. I couldn’t have said it better
Nevertheless, since the function ends with a big N, you still have to remember to delete the resulting canvas properly, as soon as you are done with it.
Furthermore, I am not sure whether this canvas is simply automatically cleared each time you draw, or if bada creates a new empty canvas for each drawing round heh
By pl1987 on Mar 29, 2010 | Reply
I’m not sure, but doesn’t the canvas with it’s method Show() acts as double buffered mechanizm?
By wit on Mar 29, 2010 | Reply
Ummm…
Well the problem is that once you Show(), the canvas of the form is cleared and you lose everything you have drawn till that point.
Maybe the wording wasn’t precise. Sure, you draw on some “virtual” canvas and only once you call Show(), it is drawn to the screen. That is a double-buffering principle indeed.
What I meant with “double buffering” was rather a way of keeping existing drawing in a separate location, so that it doesn’t get lost. Sorry for the confusion