GNOME Bugzilla – Bug 624025
gdk_draw_rectangle bogged down by ColorSync
Last modified: 2010-10-19 00:19:46 UTC
Not sure if this is a proper bug, but here it goes.. I was profiling an application that uses Scintilla component, which was horribly slow when scrolling a file back and forth. I ran the thing through shark and here's the relevant part: 0.0% 26.1% libgdk-quartz-2.0.0.dylib gdk_draw_rectangle 0.0% 24.0% libgdk-quartz-2.0.0.dylib gdk_quartz_draw_rectangle 0.0% 21.3% CoreGraphics CGContextFillRect 0.0% 21.3% CoreGraphics CGContextFillRects 0.0% 21.3% libRIP.A.dylib ripc_DrawRects 0.0% 21.1% libRIP.A.dylib ripc_Render 0.0% 21.0% libRIP.A.dylib ripc_GetColor 0.0% 20.9% CoreGraphics CGColorTransformConvertColorFloatComponents 0.0% 20.8% CoreGraphics CGCMSInterfaceTransformConvertColorComponents 0.0% 20.8% libCSync.A.dylib CMSTransformConvertComponents 0.0% 20.5% libCSync.A.dylib acquireColorWorld 0.0% 20.4% libCSync.A.dylib aquireColorWorldByAttributes 0.1% 19.5% libCSync.A.dylib create 0.0% 18.0% ColorSync ColorSyncTransformCreate 0.0% 17.5% ColorSync ColorSyncCMMInitializeTransform 0.0% 17.5% ColorSync AppleCMMInitializeTransform 0.0% 17.2% ColorSync DoInitializeTransform 0.0% 14.5% ColorSync ConversionManager::MakeColorMatchSequence(CMMProfileInfoContainer*, CMMColorConversionInfo*) 0.0% 14.5% ColorSync CMMProfileInfoContainer::EliminateNULLTransforms(CMMMemMgr&) 0.0% 14.3% ColorSync CMMProfileInfoContainer::ProfilesIdentical(CMMProfile*, CMMProfile*, CMMMemMgr&) 0.1% 13.4% ColorSync CMMProfile::GetRelevantTags(unsigned long&) 0.0% 11.7% ColorSync ColorSyncProfileCopyTagSignatures 0.0% 10.5% CoreFoundation CFArraySortValues 0.0% 10.5% CoreFoundation CFQSortArray 0.0% 10.4% CoreFoundation CFSortIndexes 0.1% 10.3% CoreFoundation __CFSimpleMergeSort 0.0% 7.0% CoreFoundation __CFSimpleMergeSort 0.0% 4.1% CoreFoundation __CFSimpleMergeSort 0.2% 2.3% ColorSync compareTags 0.8% 2.0% CoreFoundation CFEqual 0.8% 0.9% CoreFoundation __CFStringEqual 0.0% 0.0% CoreFoundation dyld_stub_memcmp 0.0% 0.0% libSystem.B.dylib memcmp As far as I understand this, it seems that the overwhelming majority of the runtime is spent performing colour conversion, which is seems to do on every invocation of draw_rectangle. I remember I was seeing some discussion about GDK colour space or something similar, is this related? Can this be improved at all? Is it something fixable on user-level? Surely there's some way to cache all this trip through ColourSync framework.. Thanks,
Some additional information; I'm building Textadept v3.0 with GTK framework build installed from http://people.imendio.com/richard/stuff/Gtk-Framework-2.14.3-2-test1.dmg (this one is linked from the developer site). I'm running OS X 10.6.4.
I just tried building the latest Gtk-OSX tree from http://github.com/jralls/gtk-osx-framework, it still exhibits the above described behaviour.
(In reply to comment #0) > As far as I understand this, it seems that the overwhelming majority of the > runtime is spent performing colour conversion, which is seems to do on every > invocation of draw_rectangle. I remember I was seeing some discussion about GDK > colour space or something similar, is this related? Can this be improved at I am not sure to which discussion of GDK color space you are referring to, but it is likely not related to this. > all? Is it something fixable on user-level? Surely there's some way to cache > all this trip through ColourSync framework.. Not sure, would have to debug/profile myself. If you have a small testcase, that would help. Otherwise I need to look into building the application that exhibits the problem myself at some point.
Attaching the reduced test case (rect-test-1.c), however couldn't make it exhibit the problem. This time the colour conversion is taking significantly less, while `gdk_quartz_draw_rectangle` is taking longer... The difference seems to be that in the above problem, `acquireColorWorld` called by `CMSTransformConvertComponents` is taking forever, while not so in the reduced case. TextAdept: 0.0% 100.0% libgdk-quartz-2.0.0.dylib gdk_draw_rectangle 0.0% 99.2% libgdk-quartz-2.0.0.dylib gdk_pixmap_draw_rectangle 0.0% 99.2% libgdk-quartz-2.0.0.dylib gdk_draw_rectangle 0.1% 99.1% libgdk-quartz-2.0.0.dylib gdk_quartz_draw_rectangle 0.0% 77.2% CoreGraphics CGContextFillRect 0.0% 77.2% CoreGraphics CGContextFillRects 0.1% 77.2% libRIP.A.dylib ripc_DrawRects 0.0% 76.4% libRIP.A.dylib ripc_Render 0.0% 75.4% libRIP.A.dylib ripc_GetColor 0.1% 75.3% CoreGraphics CGColorTransformConvertColorFloatComponents 0.0% 74.5% CoreGraphics CGCMSInterfaceTransformConvertColorComponents 0.0% 74.4% libCSync.A.dylib CMSTransformConvertComponents 0.0% 73.3% libCSync.A.dylib acquireColorWorld 0.0% 1.1% libCSync.A.dylib CMSColorWorldConvertData 0.0% 0.0% CoreFoundation _CFRelease 0.1% 0.1% CoreGraphics CGColorSpaceGetNumberOfComponents 0.0% 0.0% libCSync.A.dylib acquireColorWorld rect-test-1: 0.4% 100.0% libgdk-quartz-2.0.0.dylib gdk_draw_rectangle 0.4% 98.9% libgdk-quartz-2.0.0.dylib gdk_window_draw_rectangle 0.3% 94.1% libgdk-quartz-2.0.0.dylib gdk_draw_rectangle 0.3% 92.9% libgdk-quartz-2.0.0.dylib gdk_quartz_draw_rectangle 0.1% 45.1% CoreGraphics CGContextFillRect 0.2% 44.8% CoreGraphics CGContextFillRects 0.5% 44.2% libRIP.A.dylib ripc_DrawRects 0.5% 36.6% libRIP.A.dylib ripc_Render 0.7% 21.0% libRIP.A.dylib ripc_GetColor 0.6% 19.9% CoreGraphics CGColorTransformConvertColorFloatComponents 0.1% 14.0% CoreGraphics CGCMSInterfaceTransformConvertColorComponents 0.2% 13.6% libCSync.A.dylib CMSTransformConvertComponents 0.1% 11.4% libCSync.A.dylib CMSColorWorldConvertData 0.1% 1.2% libCSync.A.dylib acquireColorWorld 0.1% 0.2% CoreFoundation _CFRelease
Created attachment 167389 [details] Reduced test case
gdk_draw_rectangle has been removed in GTK3
Reopening as I want to figure out what exactly is causing this, there are more cases that are affected by this. Once we know what's going on, we can also check if cairo is suffering from this.
Okay, I got SciTE going here and indeed see ColorSync things at the top of the profile. Let's see what can be done about it ...
I did some more profiling here. Interestingly, ColorSync only kicks in on gdk_draw* calls to a GdkPixmap, and drawing the pixmap to another drawable. This made me suspect the pixmap handling in GTK+ Quartz, which uses CGImage. Google gave me: http://lists.apple.com/archives/perfoptimization-dev/2008/Feb/msg00028.html Which is kind of the same as we are facing here, ColorSync correcting colors taking a lot of time, even though you wouldn't expect it to be needed. It appears that the ColorSpace API has seen some changes in 10.4 and in my experience continuing to use the old calls is showing this performance problem -- likely because the color space is set up differently. So in _gdk_pixmap_new(), changing colorspace = CGColorSpaceCreateDeviceRGB (); to colorspace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB); makes the performance problem go away and ColorSync no longer shows up that high in the profile. However, this completely breaks the text drawing in Scintilla for some reason (it is exposing the wrong areas or missing updates). This puzzles me a bit, so I need to do some debugging in Scintilla to figure out what is going on. (PS. Cairo does not seem to be suffering from this performance problem.)
*** Bug 615917 has been marked as a duplicate of this bug. ***
Created attachment 172663 [details] test case that does exhibit the performance problem This is an updated test case that does exhibit the problem by more closely simulating what scintilla is actually doing. The problems are arising by drawing to pixmaps and drawing these to windows. Since pixmaps and windows used different color spaces, conversion was required. Switching the colorspace as noted in an earlier comment will have a very noticeable effect on this test case.
(In reply to comment #9) > makes the performance problem go away and ColorSync no longer shows up that > high in the profile. However, this completely breaks the text drawing in > Scintilla for some reason (it is exposing the wrong areas or missing updates). > This puzzles me a bit, so I need to do some debugging in Scintilla to figure > out what is going on. After days of debugging I finally managed to track this down. Nothing is wrong with changing the color space, which is good because that's where our performance win is. It turns out there is some caching going on behind the CGImage; when writing to a GdkPixmap we were writing to the data backing a CGImage, but the CGImage was not always updated. Fixed this by creating the CGImage on-demand instead. This fix and the color space change is on the gtk-2-22 branch now and gtk-2-24 tomorrow (need to fix the build). With these fixes, scrolling in Scintilla is much faster. Note that GTK+ 3 does not longer use GdkPixmap and the legacy drawing API: here Cairo is used instead.
Fantastic, thanks for fix!