gdk double buffering
- From: Wouter van Kleunen <w a p vankleunen student utwente nl>
- To: gtk-devel-list gnome org
- Subject: gdk double buffering
- Date: Wed, 12 Mar 2003 13:06:45 +0100
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
I have some questions/ideas regarding the "speed" of GDK/gtk.
Double buffering Usage
- ----------------------
Like Owen Taylor said in:
http://www.gtk.org/~otaylor/gtk/2.0/gdk-drawing.html
part of the gtk speed problem is the fact not all widgets are draw at once.
GDK has functions for double buffering ( begin_paint() / end_paint() ) but
this will not solve the problem. This because this will buffer a x11 window.
On most expose events however, it's not enough to redraw one x11 window. But
several expose events will come in back to back. These individual expose
events can be double buffered. But if the time between the events is to large
that will also be seen as "flicker". An example of what happens now:
- -- Gtk Application --
expose event1
1 buffer is created
2 widget drawn to buffer
3 buffer blitted
expose event2
1 buffer is created
2 widget drawn to buffer
3 buffer blitted
...
This can be improved by:
- -- GTK Application --
expose event1:
1 buffer is created
2 widget drawn to buffer
3 buffer pushed on blit stack
expose event2:
1 buffer is created
2 widget drawn to buffer
3 buffer pushed on blit stack
...
; all widgets drawn
blit all buffers on stack to screen
This will not solve all problems. This is because X can't guarantee that all
operations happen in one frame. This is large problem. Because how hard the
widget set library tries, it can't ever guarantee that a operation is flicker
free.
For example, when the user shades a window. 2 apps might become visible. These
apps have to redraw all windows. But even if both apps stack all drawing
operations. It might happen that app1 is several msecs earlier than app2.
That way, when one app redraws it's window, the other app might still be busy
filling it's draw stack. That way, one window is redraw, while the other is
not. Leaving the user with a screen that is half updated and half not.
What we want is that operations are atomic. We know atomic operations from
databases. Atomic operations in databases are handled with transactions. So
handling events in X should be done in a way of transactions. Here is how i
see it:
- -- XFree --
struct TBACKBUFFER {
list /* list containing all draw operations */
locked /* is the buffer still in a transaction */
draw /* is the buffer drawn yet */
} back_buffer;
begin_transaction()
{
back_buffer->locked = true
back_buffer->drawn = FAlSE
}
vsync()
{
/* vsync should be called on a vsync */
/* we still need to draw the back buffer */
if(back_buffer->drawn == false) {
/* transaction is finished so it's safe to draw */
if(back_buffer->locked == true) {
do all operations in back_buffer->list
back_buffer->draw = TRUE;
clear(back_buffer->list);
}
}
}
transaction_end()
{
/* we are done here */
back_buffer->locked = false;
}
User clicks button
begin_transaction();
for window<-window_list[] do
expose_event(window); /* All draw operations will be appended to list */
/* Ok done, on next vsync all operations will be drawn */
end_transaction();
Problem with this approach is that if a program does not respond to a expose
event the whole transaction will stale. I am sure there are ways to solve
this. And the above example is just an idea not a concept.
Double buffering implementation
- -------------------------------
There are several ways to implement buffering:
- - Create pixmap and draw to pixmap. This is how gtk does it at the moment. It
would be more efficient to create a pixmap the size of the expose event. And
only draw the part of the widget that needs te be redrawn.
- - Save the operations. It is also possible to save the operations that need to
be drawn. e.g. save the fact that a line needs to be drawn from
(0,0)-(100,100). And do the draw operation later.
I don't know which one is faster or smaller in memory usage. But at first
sight it seems to me the second method uses less memory.
Transactions using a deamon
- ---------------------------
It would be possible to create the transactions described above using a deamon
that sends all X operations from gtk apps to X. You would need a special
version of gdk that communicates with the daemon. It would be cleaner to
implement it in X, but it's just a thought.
Ok, that's about it. I hope i'm not talking (too much) out of my arse. I don't
really like the way widget sets communicate with X these days. I always think
that the applications "fall apart" when doing a redraw. It doesn't feel
"solid".
Wouter van Kleunen
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)
iD8DBQE+byLdw4uuzvY55gsRAkELAJ9YIflbJ1mgR9sN/20WqoN1BcH11QCeKN3u
JnJj66gxAWhoAZ8MHIewN4k=
=3zuS
-----END PGP SIGNATURE-----
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]