Re: Correct use of pixbuf, pixmap, and image?
- From: muppet <scott asofyet org>
- To: Ari Jolma <ari jolma tkk fi>
- Cc: gtk-perl-list gnome org
- Subject: Re: Correct use of pixbuf, pixmap, and image?
- Date: Tue, 14 Mar 2006 22:24:12 -0500
On Mar 14, 2006, at 3:25 PM, Ari Jolma wrote:
I've got a derivative (subclass in Perl sense) of
Gtk2::Gdk::Pixbuf. I create it using gdk_pixbuf_new_from_data. The
data is created in C using my own draw routines. From this pixbuf I
create a pixmap by calling render_pixmap_and_mask in Gtk-Perl. And
in the last step I create an Gtk2::Image by calling set_from_pixmap.
The image is used in a subclass of Gtk2::ScrolledWindow. Everything
works. But there is somewhere a problem of wasting memory.
Creating the initial pixbuf may take a long time (seconds) and it
is not possible to draw on a pixbuf, only on a pixmap. In my code I
want to be able to re-use once created pixbuf. For example there is
a dialog box, where the user may select a graphical object and it
is highlighted by drawing it (with Gtk-Perl) on the pixmap. So
every time the user selects a new object, this procedure is executed:
1. create pixmap from the initial pixbuf and set the pixmap into
the image
2. draw on the pixmap
3. hide the ScrolledWindow
4. show the ScrolledWindow
Why the hide and show?
I haven't seen a good documentation on some of the functions I use,
so I've ended up to this procedure with some experimentation. I
also don't understand well the client/server concept related to
this (if the program is running over X, the pixmap is created on
the client?). I just played with this and I believe the code is
hogging memory when the above procedure is run multiple times. Does
anybody have any ideas?
First, a little context:
The X Window System uses a client/server architecture in which the
screen and windows on it are managed by a window server, which deals
with the display and input hardware. This server provides windowing
services to client applications. (Many people think X's client and
server names are backwards, but when seen from the point of view that
the server provides windowing services to client applications, it
makes sense.)
The client and server are not only separate processes, but may be on
different physical machines. Because of this, the latency for a
round trip to the server can be quite large, and the X model for many
operations is designed to minimize this. That's where graphics
contexts and pixmaps come from. A graphics context ("GC") is a
server-side resource that contains information on how to perform
drawing operations. The client has a handle which refers to a
particular GC, and passes the handle with drawing operations. This
keeps the client from having to transmit all of that information with
each drawing command.
Similarly, image data can be stored in "bitmaps" (1-bit images, or
maps of bits) or "pixmaps" (maps of more-than-one-bit pixels, or
pixel maps). These are stored on the server, at device bit
resolution and bit depth, and this can be manipulated quite quickly.
Operations like $drawable->draw_pixmap() involve copying only the
command information from the client to the server, because all of the
bits are already on the server. These are stored in the server's
memory.
So where does a GdkPixbuf fit in? Recall that the pixmap is stored
on the server at device resolution and bitdepth. This means that if
you want to change just one pixel, you have to do a round trip, which
is expensive. Also, you'll have to deal with the image data at the
server's bit depth, which could be anything -- 888, 565, indexed
pseudocolor, etc, maybe involving dithering. Because this is a royal
PITA, the gnome guys came up with GdkPixbuf, which is a simple 24-bit
RGB or 32-bit RGBA image buffer stored in the *client*, which can be
dithered and transferred to the server as needed. (The RENDER
extension includes features to make this more efficient.)
GtkImage provides a way for you to set the source data directly from
a pixbuf --- $image->set_from_pixbuf($pixbuf) --- so you could avoid
the pixmap/mask stage.
You can also place a GdkPixbuf into a GnomeCanvas, which gives you
more efficient rendering of the changed portions. You could use
GnomeCanvasItems for the selected objects text overlays and that sort
of stuff, along with scaling and other fun tricks.
You'll probably want also check for reference leaks in your code to
make sure you're not piling up pixbufs.
If using a Canvas is not practical, you can probably drop a few steps
by writing some of the more compute-intensive display stuff in C ---
if you already have custom C code, then binding your own C widgets to
gtk2-perl should be no problem. You could do stuff like render much
smaller pieces from the source data and blit them exactly where they
need to go in the master pixbuf.
About documentation.. I just found the Havoc Pennington's book on
developer.gnome.org and I have Warkus' book. Are there other good
sources?
I find it very helpful to look at the code of applications that do
similar things to what i want to do. The gimp is a bit complicated,
but has lots of good stuff.
--
"that's it! you're a genius!" "yes. that's what i think. do you
think i deserve a raise?"
- dialogue from 'Godzilla versus Mothra', 1964
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]