Re: GDK_POINTER_MOTION_HINT_MASK has no effect



Paul,

Thanks for the information, it's good to learn about how GTK+ does its
double buffering in detail.  However...

On Nov 29, 2007 5:22 PM, Paul Davis <paul linuxaudiosystems com> wrote:

    >   And this particular
    > case is wholly not addressed in code sample 1; there, you must
redraw the
    > entire screen even if only 4 pixels in the lower right corner require a
    > re-draw.  As I said before, using the GdkEvent* info to be efficient in
    > redrawing only what's required is impossible, and if not, a complete
waste
    > of programming time and resources.

    no, there is never any need to do this. expose events always contain
    information on the region (a collection of 1 or more non-overlapping
    rectangles) to redraw. this is based either on information from the
    underlying window system or whatever was passed to
    gdk_window_invalidate_rect() and its cousins. the only limitation is
    that GDK generally "tiles" a drawable with rects no smaller than a given
    size, so if there were really just 4 pixels to redraw, you'd like end up
    redrawing 32 or 16 or some such number.

I'm still confused as to how this case should be handled in an expose
handler if you do all your drawing there.

To illustrate: I have been called once, and GTK+ has drawn to the double
buffer pixmap as you say.  I was partially obscured and am now re-exposed,
i.e., the main loop calls me again specifying an invalidated rectangle via
the GdkEvent structure.

Do I:
  1) redraw the entire picture since I've been called, ignoring all else,
knowing this will result in a fully refreshed screen?

  2) redraw only that part which was obscured (rectangle parameters
provided), having to determine programmatically what drawing commands
actually constitute refreshing the obscured portion?

  3) know that my drawing hasn't changed its state since the last complete
draw and doesn't need to be redrawn at all since upon exiting this call,
the double buffer I had previously written to still contains my drawing
and will physically refresh only the rectangle which was passed to the
expose handler for re-exposure?

Naturally I will demand that the third option is really the only
acceptable answer since:

  1) option 1 is a complete waste of resources when I have to process 100
million data points for drawing to the screen (I exaggerate not).

  2) option 2 is simply impossible to make a one-to-one calculation as to
which pixels must be refreshed, programmatically.

If the third option is how GTK+ handles this scenario (more kudos...),
then the expose handler would look something like?:

gboolean exposeME(.....)
{
   if (redrawRequired || firstTime)
   {
      // process 100,000,000 data points to draw to da->window
   }
   return TRUE;
}

If, however, the double buffer no longer exists when called the second
time, and I have to take option 1, then it is utterly inefficient to have
to redraw the entire screen each time the expose handler is called when I
have to do so much to actually redraw.  (And besides, what's the
invalidated rectangle information used for then anyway?)

(Getting a little ahead of myself since I don't know the answer to my
previous question yet, but...)

If I must do it as per option 1, consider then the two options:

Option 1:
- draw to da->window in expose handler (...of 100M data points)
- expose handler called 10 times by main loop

Option 2:
- make bg pixmap in separate routine (...of 100M data points)
- expose pixmap in expose handler via drawing of bg pixmap
- expose handler called 10 times

Would you not take option 2 and save the time required to process 900M
points of data unnecessarily?

Or am I missing something?  It just strikes me as more efficient to issue
real drawing commands as little as possible, i.e., once to a bg pixmap,
and then to draw this pixmap to the screen.  Not only is it more efficient
(simple less CPU usage), it also makes the application more "responsive"
and "snappy" since the operation of transferring a pixmap to the screen is
instantaneous, while processing 100M data points is, er, not.

And we haven't even begun to discuss animations of these drawings.  Most
definitely in this case, you would want to:
- make all your drawings making up the entire animation as bg pixmaps
- use g_timeout_add() to invalidate the entire drawing area for redraw,
being called over and over until no more drawings
- while the expose handler does nothing more than render the next pixmap
of the animation sequence to the screen.

No?  Or would you still do all your drawing in the expose handler for an
animation?

And I still don't understand why this particular paradigm which works
without fail for me is opposite to GTK+ design.  It's nothing more than an
alternative to the scribble example that, for my requirements, doesn't
work.

The way I see it, the GTK+ designers and developers have succeeded at
doing what you said: to make it as efficient and as smooth as possible,
and this they have done well.  Is that to say, however, that the scribble
example is the best answer for all cases beyond the most trivial?

Obviously, I don't think so.  The scribble paradigm didn't work for me
back when and I had to come up with something else.  So I did, and it has
served me very, very well.

I am not convinced that using bg pixmaps is not an advantage or is somehow
opposite to GTK+ design when the requirements are necessarily complex.  I
know first-hand the programming power I have gained is very real by
managing multiple pixmaps in the background as static images instead of
having to render to the screen directly via drawing commands on each call
to exposeME().

cheers,

richard



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]