[gtk/wip/chergert/macos-iosurface] allow drawing cairo without a flip
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/macos-iosurface] allow drawing cairo without a flip
- Date: Fri, 11 Feb 2022 12:17:23 +0000 (UTC)
commit 016f82ffb4f01cce7f4dbfb96fceea7b21894bdd
Author: Christian Hergert <christian hergert me>
Date: Fri Feb 11 04:00:04 2022 -0800
allow drawing cairo without a flip
there appears to be some things that can break if stuff starts diving into
the framebuffers, so just keep it top side up and instead we can use the
identity/flip transforms
gdk/macos/GdkMacosLayer.c | 21 +++++++++++++++++++--
gdk/macos/GdkMacosLayer.h | 1 +
gdk/macos/gdkmacosbuffer-private.h | 3 +++
gdk/macos/gdkmacosbuffer.c | 18 ++++++++++++++++++
gdk/macos/gdkmacoscairocontext.c | 9 +++------
gdk/macos/gdkmacosglcontext.c | 4 ++++
6 files changed, 48 insertions(+), 8 deletions(-)
---
diff --git a/gdk/macos/GdkMacosLayer.c b/gdk/macos/GdkMacosLayer.c
index b4b7b905a3..d09761a468 100644
--- a/gdk/macos/GdkMacosLayer.c
+++ b/gdk/macos/GdkMacosLayer.c
@@ -166,10 +166,15 @@ fromCGRect (const CGRect rect)
-(void)_applyLayout:(GArray *)tiles
{
+ CGAffineTransform transform;
GArray *prev;
gboolean exhausted;
guint j = 0;
+ if (self->_isFlipped)
+ transform = flipTransform;
+ else
+ transform = CGAffineTransformIdentity;
prev = g_steal_pointer (&self->_tiles);
self->_tiles = tiles;
@@ -203,13 +208,14 @@ fromCGRect (const CGRect rect)
{
info->tile = g_steal_pointer (&other->tile);
[info->tile setFrame:info->area];
+ [info->tile setAffineTransform:transform];
continue;
}
}
info->tile = [GdkMacosTile layer];
- [info->tile setAffineTransform:flipTransform];
+ [info->tile setAffineTransform:transform];
[info->tile setContentsScale:1.0f];
[info->tile setOpaque:info->opaque];
[info->tile setFrame:info->area];
@@ -322,10 +328,17 @@ fromCGRect (const CGRect rect)
-(void)swapBuffer:(GdkMacosBuffer *)buffer withDamage:(const cairo_region_t *)damage
{
IOSurfaceRef ioSurface = _gdk_macos_buffer_get_native (buffer);
+ gboolean flipped = _gdk_macos_buffer_get_flipped (buffer);
double scale = _gdk_macos_buffer_get_device_scale (buffer);
double width = _gdk_macos_buffer_get_width (buffer) / scale;
double height = _gdk_macos_buffer_get_height (buffer) / scale;
+ if (flipped != self->_isFlipped)
+ {
+ self->_isFlipped = flipped;
+ self->_layoutInvalid = TRUE;
+ }
+
if (self->_layoutInvalid)
{
self->_layoutInvalid = FALSE;
@@ -351,7 +364,11 @@ fromCGRect (const CGRect rect)
area.origin.x = info->area.origin.x / width;
area.size.width = info->area.size.width / width;
area.size.height = info->area.size.height / height;
- area.origin.y = (height - info->area.origin.y - info->area.size.height) / height;
+
+ if (flipped)
+ area.origin.y = (height - info->area.origin.y - info->area.size.height) / height;
+ else
+ area.origin.y = info->area.origin.y / height;
[info->tile swapBuffer:ioSurface withRect:area];
}
diff --git a/gdk/macos/GdkMacosLayer.h b/gdk/macos/GdkMacosLayer.h
index 18b7d9afae..74ba14ff86 100644
--- a/gdk/macos/GdkMacosLayer.h
+++ b/gdk/macos/GdkMacosLayer.h
@@ -35,6 +35,7 @@
guint _opaque : 1;
guint _layoutInvalid : 1;
guint _inSwapBuffer : 1;
+ guint _isFlipped : 1;
};
-(void)setOpaqueRegion:(const cairo_region_t *)opaqueRegion;
diff --git a/gdk/macos/gdkmacosbuffer-private.h b/gdk/macos/gdkmacosbuffer-private.h
index 0b7b12875a..6be201147c 100644
--- a/gdk/macos/gdkmacosbuffer-private.h
+++ b/gdk/macos/gdkmacosbuffer-private.h
@@ -49,6 +49,9 @@ const cairo_region_t *_gdk_macos_buffer_get_damage (GdkMacosBuffer *self)
void _gdk_macos_buffer_set_damage (GdkMacosBuffer *self,
cairo_region_t *damage);
gpointer _gdk_macos_buffer_get_data (GdkMacosBuffer *self);
+gboolean _gdk_macos_buffer_get_flipped (GdkMacosBuffer *self);
+void _gdk_macos_buffer_set_flipped (GdkMacosBuffer *self,
+ gboolean flipped);
G_END_DECLS
diff --git a/gdk/macos/gdkmacosbuffer.c b/gdk/macos/gdkmacosbuffer.c
index ace6a0e15d..1612eaa9f6 100644
--- a/gdk/macos/gdkmacosbuffer.c
+++ b/gdk/macos/gdkmacosbuffer.c
@@ -38,6 +38,7 @@ struct _GdkMacosBuffer
guint height;
guint stride;
double device_scale;
+ guint flipped : 1;
};
G_DEFINE_TYPE (GdkMacosBuffer, gdk_macos_buffer, G_TYPE_OBJECT)
@@ -234,3 +235,20 @@ _gdk_macos_buffer_get_data (GdkMacosBuffer *self)
return IOSurfaceGetBaseAddress (self->surface);
}
+
+gboolean
+_gdk_macos_buffer_get_flipped (GdkMacosBuffer *self)
+{
+ g_return_val_if_fail (GDK_IS_MACOS_BUFFER (self), FALSE);
+
+ return self->flipped;
+}
+
+void
+_gdk_macos_buffer_set_flipped (GdkMacosBuffer *self,
+ gboolean flipped)
+{
+ g_return_if_fail (GDK_IS_MACOS_BUFFER (self));
+
+ self->flipped = !!flipped;
+}
diff --git a/gdk/macos/gdkmacoscairocontext.c b/gdk/macos/gdkmacoscairocontext.c
index b4fdf717bd..041f1193e6 100644
--- a/gdk/macos/gdkmacoscairocontext.c
+++ b/gdk/macos/gdkmacoscairocontext.c
@@ -152,10 +152,6 @@ _gdk_macos_cairo_context_cairo_create (GdkCairoContext *cairo_context)
cairo_restore (cr);
}
- /* Flip contents upside down to match OpenGL */
- cairo_translate (cr, 0, height/scale);
- cairo_scale (cr, 1.0, -1.0);
-
failure:
cairo_surface_destroy (image_surface);
@@ -180,6 +176,7 @@ _gdk_macos_cairo_context_begin_frame (GdkDrawContext *draw_context,
buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
_gdk_macos_buffer_set_damage (buffer, region);
+ _gdk_macos_buffer_set_flipped (buffer, FALSE);
}
static void
@@ -192,9 +189,9 @@ _gdk_macos_cairo_context_end_frame (GdkDrawContext *draw_context,
g_assert (GDK_IS_MACOS_CAIRO_CONTEXT (draw_context));
surface = gdk_draw_context_get_surface (draw_context);
- _gdk_macos_surface_swap_buffers (GDK_MACOS_SURFACE (surface), painted);
-
buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
+
+ _gdk_macos_surface_swap_buffers (GDK_MACOS_SURFACE (surface), painted);
_gdk_macos_buffer_set_damage (buffer, NULL);
[CATransaction commit];
diff --git a/gdk/macos/gdkmacosglcontext.c b/gdk/macos/gdkmacosglcontext.c
index 25960026a8..592d3c0bbf 100644
--- a/gdk/macos/gdkmacosglcontext.c
+++ b/gdk/macos/gdkmacosglcontext.c
@@ -425,11 +425,15 @@ gdk_macos_gl_context_begin_frame (GdkDrawContext *context,
cairo_region_t *region)
{
GdkMacosGLContext *self = (GdkMacosGLContext *)context;
+ GdkMacosBuffer *buffer;
GdkSurface *surface;
g_assert (GDK_IS_MACOS_GL_CONTEXT (self));
surface = gdk_draw_context_get_surface (context);
+ buffer = _gdk_macos_surface_get_buffer (GDK_MACOS_SURFACE (surface));
+
+ _gdk_macos_buffer_set_flipped (buffer, TRUE);
g_clear_pointer (&self->damage, cairo_region_destroy);
self->damage = cairo_region_copy (region);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]