Visar inlägg med etikett GTK. Visa alla inlägg
Visar inlägg med etikett GTK. Visa alla inlägg

Not much action on gtk-devel-list

The mailing list for GTK+ is gtk-devel-list@gnome.org. Unfortunately, it seem to be serverly underused and it is almost impossible to get discussions going there. Most discussions seem to take place at bugzilla or the (in)famous planet.gnome.org. But part of the problem also seem to be that most gtk developers are employed by a few companies, namely Red Hat and Imendio. When you work in the same office it becomes easier to communicate orally, than having to use a text medium.

I think it would be nice if there was more "flow" on the mailing list. I fear that important information is getting lost and it creates a divide between employed hackers and others.

Patch advertisement

Just advertising the patch at #103811. Actually it is an old patch from Søren Sandmann and I have just updated it to work with latest GTK+. It is an old patch but the smooth scrolling feature is so kick ass. It would GNOME look so much better.

Efficient scrolling in X11

Lately, I've been trying to make scrolling as efficient as possible. On the surface, it is a simple problem, the algorithm is like this:

def scroll(surface, xscroll, yscroll): # Scroll it. Auto clip in case xscroll or yscroll is negative. surface.draw(surface, xscroll, yscroll) top = (0, 0, surface.width, yscroll) left = (0, 0, xscroll, surface.height) bottom = (0, surface.height + yscroll, surface.width, -yscroll) right = (surface.width + xscroll, 0, -xscroll, surface.height) # Filter out the ones to redraw. rects = [rect for rect in top, left, bottom, right if rect[2] * rect[3] >= 0] for x, y, width, height in rects: # Assume redraw is the expensive step. redraw(surface, x, y, width, height)

So, if you scroll a surface of size 100x100 20 steps to the right and 20 steps down the rectangles become:

xscroll = 20
yscroll = 20

top = (0, 0, 100, 20)
left = (0, 0, 20, 100)
bottom = (0, 120, 100, -20)
right = (120, 0, -20, 100)

bottom and right whose area is negative becomes discarded and you are left with two rectangles totalling 4000 pixels (100 * 20 + 100 * 20) to redraw which is not so bad.

The problem is that this algorithm is freakishly hard to realize on X11 without theComposite extension. X11 doesn't store your surface, so how are you going to redraw it? You could store it yourself, in a GdkPixbuf for example. However, that would mean that the data is stored client side and you'll run into slowdowns when transferring it to the X11 server.

... Client-server is great for some things, but definitely not for computer graphics.

GdkPixbufs are drawn with gdk_draw_pixbuf() which should (or could) be a fast operation because it uses XShmPutImage(), but it is not. GdkPixbuf has a different format from the one that X11 want's so you run into a slowdown caused by the format mismatch.

Next attempt, use a GdkPixmap as the cache. surface.draw(surface, xscroll, yscroll) becomes one fast call to gdk_draw_drawable(). But it still isn't fast enough because pixmaps aren't easy to work with. There is no gdk_pixbuf_scale() equivalent for drawables so we still have to use a pixbuf to store the result of the scale operation. That pixbuf then has to be blitted to our pixmap cache which is then blitted, for real, to the XWindow we are drawing on. In effect, we are using triple buffering and redraws becomes to slow.

Third attempt, use the actual drawable we are drawing on as the cache. It would work except that it totally breaks down when the window is minimized, then your cache is gone.

GtkImageView uses a combination of the first and third method. It special cases scrolling operations and uses the third method to redraw them. By setting exposures to true, it detects when occluded areas becomes visible and then redraws them using the first method. That is far from ideal but is more or less the best thing you can do without composite.

Bloggarkiv