From c1d6194d24ba04ebb8fe15aacea5017f8b49ce37 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 16 Jan 2014 12:24:57 +0000 Subject: [PATCH] canvas: Use the window-scaling-factor setting ClutterCanvas is a ClutterContent interface implementation; this means that it can be created and modified regardless of whether it is associated to a specific actor or a stage. For this reason, we cannot walk the hierarchy and get the window scaling factor for high DPI density displays out of the ClutterStage when we create the Cairo surface that we will use to draw the canvas contents on. We can use ClutterSettings:window-scaling-factor instead, since it's what each ClutterStage will use anyway. This will get slightly more complicated when we support per-output window scaling factors (like on Wayland), but that will require changes in the entire settings architecture anyway. https://bugzilla.gnome.org/show_bug.cgi?id=705915 --- clutter/clutter-canvas.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/clutter/clutter-canvas.c b/clutter/clutter-canvas.c index 482bdd13e..071d1d868 100644 --- a/clutter/clutter-canvas.c +++ b/clutter/clutter-canvas.c @@ -62,10 +62,12 @@ #include "clutter-cairo.h" #include "clutter-color.h" #include "clutter-content-private.h" +#include "clutter-debug.h" #include "clutter-marshal.h" #include "clutter-paint-node.h" #include "clutter-paint-nodes.h" #include "clutter-private.h" +#include "clutter-settings.h" struct _ClutterCanvasPrivate { @@ -353,23 +355,37 @@ static void clutter_canvas_emit_draw (ClutterCanvas *self) { ClutterCanvasPrivate *priv = self->priv; + int real_width, real_height; cairo_surface_t *surface; gboolean mapped_buffer; unsigned char *data; CoglBuffer *buffer; + int window_scale = 1; gboolean res; cairo_t *cr; g_assert (priv->width > 0 && priv->width > 0); + g_object_get (clutter_settings_get_default (), + "window-scaling-factor", &window_scale, + NULL); + + real_width = priv->width * window_scale; + real_height = priv->height * window_scale; + + CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d (real: %d x %d, scale: %d)", + priv->width, priv->height, + real_width, real_height, + window_scale); + if (priv->buffer == NULL) { CoglContext *ctx; ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ()); priv->buffer = cogl_bitmap_new_with_size (ctx, - priv->width, - priv->height, + real_width, + real_height, CLUTTER_CAIRO_FORMAT_ARGB32); } @@ -389,20 +405,24 @@ clutter_canvas_emit_draw (ClutterCanvas *self) surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, - priv->width, - priv->height, + real_width, + real_height, bitmap_stride); mapped_buffer = TRUE; } else { surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, - priv->width, - priv->height); + real_width, + real_height); mapped_buffer = FALSE; } +#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE + cairo_surface_set_device_scale (surface, window_scale, window_scale); +#endif + self->priv->cr = cr = cairo_create (surface); g_signal_emit (self, canvas_signals[DRAW], 0,