[gtk/wip/chergert/macos-fixes: 21/23] macos: align image surface rowstride to 16-bytes
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/macos-fixes: 21/23] macos: align image surface rowstride to 16-bytes
- Date: Fri, 4 Feb 2022 03:26:38 +0000 (UTC)
commit 4373743d4c76637dac308f418d4e0f1090aa630f
Author: Christian Hergert <christian hergert me>
Date: Thu Feb 3 18:21:43 2022 -0800
macos: align image surface rowstride to 16-bytes
When creating a cairo_image_surface_t we want both the framebuffer pointer
and each row to be aligned to 16-bytes so that Core Graphics will use more
optimal paths.
However, cairo_image_surface_create() will not guarantee that the rowstride
is aligned to 16-bytes so we must do that ourselves.
gdk/macos/gdkmacoscairocontext.c | 40 ++++++++++++++++++++++++++++++----------
1 file changed, 30 insertions(+), 10 deletions(-)
---
diff --git a/gdk/macos/gdkmacoscairocontext.c b/gdk/macos/gdkmacoscairocontext.c
index 78cb61c0c1..dadbfe4132 100644
--- a/gdk/macos/gdkmacoscairocontext.c
+++ b/gdk/macos/gdkmacoscairocontext.c
@@ -47,26 +47,46 @@ G_DEFINE_TYPE (GdkMacosCairoContext, _gdk_macos_cairo_context, GDK_TYPE_CAIRO_CO
static cairo_surface_t *
create_cairo_surface_for_surface (GdkSurface *surface)
{
+ static const cairo_user_data_key_t buffer_key;
cairo_surface_t *cairo_surface;
+ guint8 *data;
+ cairo_format_t format;
+ size_t size;
+ size_t rowstride;
+ size_t width;
+ size_t height;
int scale;
- int width;
- int height;
g_assert (GDK_IS_MACOS_SURFACE (surface));
+ /* We use a cairo image surface here instead of a quartz surface because
+ * we get strange artifacts with the quartz surface such as empty
+ * cross-fades when hovering buttons. For performance, we want to be using
+ * GL rendering so there isn't much point here as correctness is better.
+ *
+ * Additionally, so we can take avantage of faster paths in Core
+ * Graphics, we want our data pointer to be 16-byte aligned and our rows
+ * to be 16-byte aligned or we risk errors below us. Normally, cairo
+ * image surface does not guarantee the later, which means we could end
+ * up doing some costly copies along the way to compositing.
+ */
+
+ if ([GDK_MACOS_SURFACE (surface)->window isOpaque])
+ format = CAIRO_FORMAT_RGB24;
+ else
+ format = CAIRO_FORMAT_ARGB32;
+
scale = gdk_surface_get_scale_factor (surface);
width = scale * gdk_surface_get_width (surface);
height = scale * gdk_surface_get_height (surface);
+ rowstride = (cairo_format_stride_for_width (format, width) + 0xF) & ~0xF;
+ size = rowstride * height;
+ data = g_malloc0 (size);
+ cairo_surface = cairo_image_surface_create_for_data (data, format, width, height, rowstride);
+ cairo_surface_set_user_data (cairo_surface, &buffer_key, data, g_free);
+ cairo_surface_set_device_scale (cairo_surface, scale, scale);
- /* We use a cairo image surface here instead of a quartz surface because we
- * get strange artifacts with the quartz surface such as empty cross-fades
- * when hovering buttons. For performance, we want to be using GL rendering
- * so there isn't much point here as correctness is better.
- */
- cairo_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
- if (cairo_surface != NULL)
- cairo_surface_set_device_scale (cairo_surface, scale, scale);
return cairo_surface;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]