Any tricks to get more performance out of Cairo ?


ekianjo

Hardcore Member
Joined
May 7, 2012
Messages
8,261
Location
神戸市、日本 (Japan)
I am working on a picture (photo) viewer application right now, in pyGtK/Cairo, and I am reaching a bottleneck. I am displaying 16 thumbnails in png on screen (100px * 133 px usually but sizes differ a litle) but I seem to be stuck at 15-18 fps when refreshing the screen. On my desktop the code runs much faster of course, at 90 fps at least.


I am coming on this forum after checking what I could find on the net (including stackoverflow) but after some initial boost (I started at 3 fps, and moved to 15-18 fps by preloading the surfaces and simply copying them at the drawing time - major boost) I am now finding it harder to optimize further.


A few questions:


1. would loading jpg in pixbuffer instead of png be faster to display in the end ? (i am preloading the images anyway, so not sure if it does make a difference when rendering on screen)


2. Is there any reduction in quality that I can use in cairo's settings to speed up rendering ?


3. Any other ideas?
 
I suggest don't render the whole view from scratch for each frame, that's hard work! Can you render the scaled thumbnails or even the whole page into a pixmap? Ideally render everything into the framebuffer (or drawing buffer) then update it only as needed (for cursor, highlight or whatever). I'm not experienced with cairo however, can it render into a clipped region of a pixmap or framebuffer? Are you writing a windowed X app with GTK or fullscreen with SDL, or framebuffer? Good luck! I'm interested in efficient rendering in the context of games and diagram tools. I figured out how to achieve vsync in X windowed apps too, but t's very tricky the way I'm doing it!


Pandora ARM can copy a full screen worth of video data very quickly (in a small fraction of 60Hz) so even without framebuffer we can do smooth animation in X, fullscreen or in a window.
 
Last edited by a moderator:
I suggest don't render the whole view from scratch for each frame, that's hard work! Can you render the scaled thumbnails or even the whole page into a pixmap? Ideally render everything into the framebuffer (or drawing buffer) then update it only as needed (for cursor, highlight or whatever). I'm not experienced with cairo however, can it render into a clipped region of a pixmap or framebuffer? Are you writing a windowed X app with GTK or fullscreen with SDL, or framebuffer? Good luck! I'm interested in efficient rendering in the context of games and diagram tools. I figured out how to achieve vsync in X windowed apps too, but t's very tricky the way I'm doing it!


Pandora ARM can copy a full screen worth of video data very quickly (in a small fraction of 60Hz) so even without framebuffer we can do smooth animation in X, fullscreen or in a window.

Thanks Dredd for the answer.


- What is do is I am pre-rendering each thumbnail in a surface and only copy the surface on screen during every refresh. Creating the images on the fly was a huge bottleneck (thats why I got 3 fps in the beginning) and this is much more efficient but still does not get there.


- What you are suggesting is to pre-render the whole screen and then copy it at ONCE on the actual window, if I understand well ?


Is copying a surface of 800*480 pixels at once faster than copying 16 small surfaces (100*200 pixels) ?


If you do not know the answer I will have to try it. Maybe it makes sense !


I definitely want to reach something like 60 fps, so I need a 3* improvement in terms of performance with Cairo / GTK. :) Not sure if it is possible. By the way to answer your question, I am running with X-window in a GTK environment. If this does not work in terms of performance I will probably go for SDL in full screen, I guess.
 
Why do you need to render that many frames per second for a picture viewer? I would expect the screen to be mostly static - or are those thumbnails moving around all the time?
 
Why do you need to render that many frames per second for a picture viewer? I would expect the screen to be mostly static - or are those thumbnails moving around all the time?

That's how cairo works. Nothing is persistent in cairo and you need to refresh the screen continously. of course, if nothing happens you can make exceptions to refresh the screen at longer intervals, but in my case, if I want to select a picture, it needs to update the screen right after you press the button, and the longer your interval to refresh the screen the longer the apparent "lag" to the viewer.


Plus, I am including animations, and these animations will only look fluid if I can update the screen at 30FPS or more. (preferably above 50).
 
Needing to refresh a static screen seems awkward to me, if only for power reasons. You may want to consider using SDL instead, with notaz' SDL you could easily do what you're describing (even with alpha blended previews for interesting animations) at 100 fps or so - I'd recommend limiting it to 30FPS though because that is smooth enough for human eyes.


Also there's no need in SDL to refresh the screen just to catch key/mouse events, so you could get effectively near 0 cpu usage when displaying just a static image.
 
Are you using hardware drawing? That could give a significant boost if what you're using is forcing you to update the entire screen all at once.


But I'm confused as to why you're using Cairo and not Pygame, because a quick read (I'm not familiar with Cairo) tells me it's mainly for vector graphics. Images you would view with your photo viewer would invariably be raster graphics.
 
Are you using hardware drawing? That could give a significant boost if what you're using is forcing you to update the entire screen all at once.


But I'm confused as to why you're using Cairo and not Pygame, because a quick read (I'm not familiar with Cairo) tells me it's mainly for vector graphics. Images you would view with your photo viewer would invariably be raster graphics.

Cairo does not support hardware drawing as far as I know.


As for the choice of Cairo, this is purely a test at this stage. I think Cairo can still deliver appropiate performance if I use it properly. If I am proven wrong I will definitely move to pygame but I am not sure how much boost I can expect from that move either.
 
If I am proven wrong I will definitely move to pygame but I am not sure how much boost I can expect from that move either.

Well, Pygame is actually designed for raster graphics, so it's better optimized for that. It also supports hardware drawing if you're in fullscreen, and you can also easily only update the parts of the screen that actually changed when using software drawing.


Even if Cairo can do better, if it is indeed designed for vector graphics, you really shouldn't use it for a program centered around raster graphics without a really good reason.
 
Last edited by a moderator:
At minimum, you coudl maybe do dirty buffering -- ie: the unchanged regions, don't update them :)


The full screen is a lot of pixels and therefore bandwidth (especially at full colour depth..), but can you only refresh the changing parts? ie: animations, things that moved, etc; your biggestd hti woudl be if theres smooth scrolling.. if user slides everything 3 pixels over, a full rerender would be rough. Even then though, if your'e clever (and cairo is _not_), you could just re-blit the already rendered stuff, to the new location..


But perhaps you can render cairo chunks to offscreen buffers, then blit the buffers to the real display, and then track what is changing/needs-to-change and just render that.


Thats the first stepo anyway, and can result in _massive_ fps increase, depending how much total area is being saved from rendering.


But ideally, you want to increase render speed overall, so that a full screen redraw is still 30fps, but you're really pushign it with 'heavy' cairo and full screen, I think. Can you use more fundamental object typew sin cairo, more limited things, that render faster?


Is there any GLES acceleration going on? That could help enormously..


I did get a picture viewer going for awhile, that coudl show a dozen pictures at a time, with rotation etc, doing full speed, but I aborted it (and it sucked :) .. it can be done, but I was using gles raw myself, no libraries int he way..


jeff
 
Back
Top