Gtk+ 3.10 uses a back-buffer surface for doing scrolling, rather than clipping and self-surface copying. This causes problems on the Quartz backend, because the back buffer (created by cairo_surface_create_similar()) does not inherit the NSWindow.backingScaleFactor of the window surface passed to create_similar().
This means that the offscreen buffer will be a lower resolution than the actual window resolution and when we draw it to the window it will be upscaled and blurry.
In the cairo master cairo_surface_create_similar() already inherits the device-scale from the other surface, and the quartz backend need to do this similarly, by allocating a larger CGBitmap, and either setting the cairo device scale, or pushing the device scale to a lower quartz level (CGContext?).
Perhaps the description needs to be improved for this bug to be fixed, just speculating. I've looked at it a bit but I don't know the code base at all so the threshold of starting working on it was a bit high, so for me this is the case. Don't know what the timeframe of cairo 1.14 is, but this bug has heavy impact on Gtk on Mac OS X, with everything in a GtkScrolledWindow, tooltips, drag-n-drop etc being blurry.
looking around at various sources, it seems that we should do:
CGContextScaleCTM (cgc, scaleFactor, scaleFactor);
when creating the CGBitmapContext inside cairo_quartz_surface_create(), where scaleFactor is the device scale factor for the surface.
(In reply to Emmanuele Bassi from comment #2)
> looking around at various sources, it seems that we should do:
> CGContextScaleCTM (cgc, scaleFactor, scaleFactor);
> when creating the CGBitmapContext inside cairo_quartz_surface_create(),
> where scaleFactor is the device scale factor for the surface.
Tried that manually, it scales up the rendering size but when it gets drawn it's double-sized (so most everything's offscreen in gdkgears demo). Still needs something else...
Created attachment 109576 [details] [review]
Provisional patch to cairo to go along with GDK quartz backend changes
Provisional fix for cairo scaling on Quartz backend
CGContexts by default apply a device scaling factor, which ends up interfering with the device_scale that is set on cairo at higher levels of the stack (eg in GDK).
Undoing it here makes behavior more consistent with X11, as long as the caller sets the device scale appropriately in cairo.
See GDK quartz patches on https://bugzilla.gnome.org/show_bug.cgi?id=740199 that fix the scaling on that end.
Created attachment 117242 [details] [review]
back buffer scale variant
For completeness, here is a cairo only fix which increases the cairo back buffer and scales it using CGContextScaleCTM.
Brion's patches work as well here and makes set_device_scale() work as with X11, while with this it gets added on top of the osx scaling.
I just tested the second patch here (https://bugs.freedesktop.org/attachment.cgi?id=117242). It seems to fix my issues with pixelcache creating the wrongly scaled surface for textview/treeview.
What needs to be done to get this upstream in cairo master?
Let's see if Bryce can help...
The patches contains some typos, but they are trivial to fix.
Since this patch breaks the normal 1-to-1 mapping of the units, which is assumed to hold in most of the code elsewhere, it would be very desirable to make it possible to test it. I believe that the most effective way to do this is to add a new target in boilerplate/cairo-boilerplate-quartz.c, so that the whole test suite can run on surfaces with HiDPI enabled.
In particular, I expect that everything works just fine as long as Quartz is doing the rendering, but I am worried that fallbacks might break (I'm not sure if the implementation of map-to-image would still be valid).
Comment on attachment 117242 [details] [review]
back buffer scale variant
Marking my patch as obsolete as GTK+ depends on the device scale for extracting the pixel data from surfaces (not sure if it should, but there is no public API to get a CGImage out of cairo afaik) and this breaks it..
-- GitLab Migration Automatic Message --
This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.
You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/cairo/cairo/issues/299.