GNOME Bugzilla – Bug 467269
Inkscape Flickers horribly
Last modified: 2007-11-05 19:20:15 UTC
Please describe the problem: I compiled inkscape using the latest gtk+quartz as per build instructions. I also installed cairomm glibmm gtkmm poppler popt under the jhbuild prompt. I just added /opt/gtk/lib/pkgconfig. I don't have the exact configure options I used. Along the lines of: --disable-static --enable-shared --without-x --prefix=/opt/gtk So it builds and starts. But whenever I move my mouse in inkscape it blanks until I stop moving it. I noticed that in general windows don't update live when dragged, so maybe this is related. Steps to reproduce: 1. Compile and install gtk+ as per build instructions 2. Compile and install cairomm glibmm gtkmm poppler popt and inkscape as described above 3. start inkscape and move your mouse over the canvas. Actual results: builds and starts (and basically works). But whenever I move my mouse in inkscape it blanks until I stop moving it. Expected results: no flicker :) Does this happen every time? yep Other information:
It might be the same issue as in bug #445626, it would be great if you could test the patch that is attached there and see if that helps.
I have problems applying your patch. first I couldn't figure out how to use diff with it, so I went and applied it manually. now I get series of these errors when I "make install" Cannot load module /Users/daniel/Source/gnome/gtk+/modules/input/im-thai.la: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-thai.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace /Users/daniel/Source/gnome/gtk+/modules/input/im-thai.la does not export GTK+ IM module API: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-thai.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace Cannot load module /Users/daniel/Source/gnome/gtk+/modules/input/im-ti-er.la: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-ti-er.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace /Users/daniel/Source/gnome/gtk+/modules/input/im-ti-er.la does not export GTK+ IM module API: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-ti-er.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace Cannot load module /Users/daniel/Source/gnome/gtk+/modules/input/im-ti-et.la: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-ti-et.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace /Users/daniel/Source/gnome/gtk+/modules/input/im-ti-et.la does not export GTK+ IM module API: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-ti-et.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace Cannot load module /Users/daniel/Source/gnome/gtk+/modules/input/im-viqr.la: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-viqr.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace /Users/daniel/Source/gnome/gtk+/modules/input/im-viqr.la does not export GTK+ IM module API: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-viqr.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace Cannot load module /Users/daniel/Source/gnome/gtk+/modules/input/im-multipress.la: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-multipress.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace /Users/daniel/Source/gnome/gtk+/modules/input/im-multipress.la does not export GTK+ IM module API: dlopen(/Users/daniel/Source/gnome/gtk+/modules/input/.libs/im-multipress.so, 10): Symbol not found: __gdk_quartz_drawable_can_flush Referenced from: /Users/daniel/Source/gnome/gtk+/gdk/.libs/libgdk-quartz-2.0.0.dylib Expected in: flat namespace
I can confirm this bug. After applying the patch, things work a little bit more as expected. Unfortunately, however, it does not get rid of the flickering. I'm going to look into making a simple testcase to work against, to make it easier to pinpoint the bottleneck. I havent looked at the code in the patch. Is there something that could be done there?
One thing you could do is to start Quartz Debug and enable the frame rate meter. Then look at what you get when enabling/disabling "beam syncronization". If you get rid of all the flickering when it's disabled, it might be possible to tweak the patch to get better behavior. Otherwise the whole drawing/exposing code probably needs some tweaking.
OK, I tried quartz debug and can confirm that the beam sync is unreated to this, the flickering is still there when beam sync is turned off.
It seems that just moving the mouse is causing move_resize_window_internal() to be called. I added a simple test in move_resize_window_internal() to see if the window in question is actually changing size or moving, and if it isn't had it return. Doing so got rid of the flickering. This change combined with the patch in bug #445626, and the disabling of beam synchronization in Quartz Debug brings Inkscape up to what seems to be about the speed of the X11 version for me, at least in the (very) small bit of testing I have done.
Good catch! I wonder why move_resize is called here, did you see where it was triggered from?
Jonathan, btw, if you attach your patch here I can use it to tweak the patch from #445626 to work better.
Well, all I did was add: if (private->x == x && private->y == y && impl->width == width && impl->height == height) { return; } to move_resize_window_internal() in gdkwindow-quartz.c. I'm really not familiar enough with gtk+ to know if such a simple test is sufficient. And to respond to the previous question about where the move_resize event was triggered from . . . I don't know. I'm still working my way through the basics of gtk+ and don't quite follow some of its logic.
Thanks! I looked into where the call is triggered from, seems that it's the container that does it idle resizing whenever the mouse is moved but I couldn't see why or if that is correct. I did it by running inkscape in gdb with a breakpoint for move_resize_window_internal and then setting a command: b move_resize_window_internal commands 1 bt continue end which makes gdb print a stack trace and continue, very useful when looking at things like this. Either way, I think your approach is good, I will try it out a bit to make sure it doesn't break anything.
Committed, thanks for the analysis and patch!
i've submitted an improved patch over in bug #445626. richard's one did 50% of the job, but missed cases where the "new" x&y coordinates were -1, -1 (which means "no change"). this vastly improved visual performance in my app. note that the/one reason this code is called at times when you might not expect it is not totally obvious. any change to a widget's style (even just its fg color) will cause a resize to take place, which starts out in the top level container holding the widget in question. this will terminate in a call to gdk_window_resize() *even if the new size is no different*. in the existing quartz code, this led to the entire container-widget being marked for redraw, which causes flicker/slow performance etc.
Hi, Shouldn't this be considered a gtk bug then? It doesn't really make much sense, or does it? Btw, i recently updated my local copy of gtk-quartz (last week or so) and it actually performs "too few" updates in inkscape. I.e. in live resize it does not update, and sometimes damage to the canvas won't be rapaired, so that part of the drawing wont show until I somehow (f.e. resize) cause a full refresh.
no, it was caused by a bug in the gdk-quartz layer. nothing more. regarding live resize ... apple have some specific guidelines on how apps should handle live resizing, and i am not sure that gtk/osx currently does much about them: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaViewsGuide/index.html#//apple_ref/doc/uid/TP40002978 i'm not sure how divergent the canvas object that inkscape is using has become from GnomeCanvas, but there are definitely issues with GnomeCanvas that i've had to fix in ardour (http://ardour.org). these are not the fault of gtk/osx, but rather some design assumptions that are the canvas implementation and how they interact with the gdk layer (specifically the use of the idle loop).