Re: Still not understanding pixmaps vs RGBs



"Lewin A.R.W. Edwards" <larwe larwe com> writes:
Sorry, I'm probably missing something major, but I don't see what
pixmaps gain me and I'd be really appreciative of some more
explanation. Currently my application works like this:

* Render content into an RGB buffer (Still image decoding and some
special postprocessing). This buffer is the size of the source image,
not the screen size.
* Decimate or expand content, using my own hand-rolled code, into a
second RGB buffer that is screen-sized.
* Draw the RGB buffer into a darea that covers the whole screen (this
step is slow).

One of the reasons I wanted to move to pixmaps is that someone here
recently told me the pixmap functions support resizing. However, they
don't. gdk_draw_pixmap is a 1:1 copy (possibly with clipping). Are
there functions, maybe in XLib, that will do pixmap resizing (scaling)
for me? My decimation/expansion code is horribly inefficient, I
think.

You're right, pixmaps do not support resizing.

Here are the relevant data types, simplified a bit:

  - GdkWindow: a server-side set of pixels that are visible onscreen,
               in hardware display format
  - GdkPixmap: a server-side set of pixels that are not visible
               onscreen, in hardware display format
  - GdkImage:  a client-side set of pixels that are not visible
               onscreen, in hardware display format. 
               when available, uses shared memory optimization to 
               avoid copying pixels to the server.
  - GdkPixbuf: in the separate gdk-pixbuf library for GTK 1.2,
               included in GTK 2.0; an RGB or RGBA format set of
               pixels on the client side. 

The gdk-pixbuf library contains fast scaling code. If you don't need
the scaling just using the raw RGB arrays as supported by GTK 1.2 is
OK.
                
The purpose of GdkPixbuf is that GdkImage has 20-plus different
possible formats, so writing pixel-manipulation code is insanely
difficult if you need to work on all hardware. The purpose of GdkImage
is that sometimes speed is more important than insane difficulty.  

The gdk_rgb_ functions copy RGB format data to any of the GdkImage
formats. So a GdkPixbuf gets copied to a pixmap or window by first
converting it to display format as a GdkImage, then pushing the
GdkImage data over to the server.

Everything has to get copied to a GdkWindow eventually if you want to
see it, but copying a pixmap or an image to a window should be fast.

There are no drawing primitives (gdk_draw_*) for Image or Pixbuf,
because the drawing primitives are implemented on the server side.
   
I should probably define client and server - you have an X server,
which processes graphics requests from X clients (i.e. applications).
The X server can give you resources such as windows, pixmaps, etc.;
the X server is normally across the network, or at least across a
local socket. It's definitely not in the same process as your app. So
making lots of round trips or data copies to the server is not a good
idea.

One of the other reasons I wanted to move to pixmaps is that they are
the same memory layout as the screen, which is 16bpp - so I'd have 30%
less data to move around compared to the same sized RGB buffer. So I
wanted access to the internal structure of the pixmap, on the
assumption that it was internally a header (dimensions, depth, phase
of the moon information) followed by a flat display-format buffer.

Remember, the pixmap is across the network - so accessing individual
pixels will be really, really, really slow. You want GdkImage instead.

You said you saw a "tile" effect as things were copied - I believe
GdkRGB works in tiles. The way to keep that invisible is to create a
screen-sized pixmap, draw to that, then copy the pixmap to the target
window, and free the pixmap. You want to free a huge pixmap like that
as soon as you use it or it will eat up your video RAM and slow
everything down.

Creating pixmaps and copying them to windows is pretty darn cheap, it
shouldn't be an issue. All remotely recent graphics cards can do the
copy in hardware.

Havoc



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