After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 624025 - gdk_draw_rectangle bogged down by ColorSync
gdk_draw_rectangle bogged down by ColorSync
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Quartz
2.14.x
Other Mac OS
: Normal normal
: ---
Assigned To: gtk-quartz maintainers
gtk-bugs
: 615917 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2010-07-10 08:40 UTC by Dimitri Tcaciuc
Modified: 2010-10-19 00:19 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Reduced test case (1.99 KB, application/octet-stream)
2010-08-08 22:44 UTC, Dimitri Tcaciuc
Details
test case that does exhibit the performance problem (2.58 KB, application/octet-stream)
2010-10-18 23:14 UTC, Kristian Rietveld
Details

Description Dimitri Tcaciuc 2010-07-10 08:40:43 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,
Comment 1 Dimitri Tcaciuc 2010-07-11 03:50:29 UTC
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.
Comment 2 Dimitri Tcaciuc 2010-07-12 07:34:38 UTC
I just tried building the latest Gtk-OSX tree from http://github.com/jralls/gtk-osx-framework, it still exhibits the above described behaviour.
Comment 3 Kristian Rietveld 2010-08-08 20:04:50 UTC
(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.
Comment 4 Dimitri Tcaciuc 2010-08-08 22:43:28 UTC
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
Comment 5 Dimitri Tcaciuc 2010-08-08 22:44:15 UTC
Created attachment 167389 [details]
Reduced test case
Comment 6 Matthias Clasen 2010-08-25 05:51:02 UTC
gdk_draw_rectangle has been removed in GTK3
Comment 7 Kristian Rietveld 2010-09-07 19:23:36 UTC
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.
Comment 8 Kristian Rietveld 2010-09-07 19:52:34 UTC
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 ...
Comment 9 Kristian Rietveld 2010-09-08 07:54:39 UTC
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.)
Comment 10 Kristian Rietveld 2010-10-17 19:24:02 UTC
*** Bug 615917 has been marked as a duplicate of this bug. ***
Comment 11 Kristian Rietveld 2010-10-18 23:14:19 UTC
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.
Comment 12 Kristian Rietveld 2010-10-18 23:32:38 UTC
(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.
Comment 13 Dimitri Tcaciuc 2010-10-19 00:19:46 UTC
Fantastic, thanks for fix!