macos: fix cairo renderer with double buffering
authorChristian Hergert <christian@hergert.me>
Mon, 28 Feb 2022 09:42:48 +0000 (01:42 -0800)
committerChristian Hergert <christian@hergert.me>
Mon, 28 Feb 2022 19:36:27 +0000 (11:36 -0800)
commitfc4d36e50afe446797aa422382dfa9fb53d37d0b
tree7fc0c07c5a2621fa22daf3deef991158f6d4dfb6
parentdbede0b11599b284bf57154a334254789fc16ab1
macos: fix cairo renderer with double buffering

If we are double buffering surfaces with IOSurface then we need to copy
the area that was damaged in the previous frame to the back buffer. This
can be done with IOSurface but we need to hold the read-only lock so that
we don't cause the underlying IOSurface contents to be invalidated.

Additionally, since this is only used in the context of rendering to a
GdkMacosSurface, we know the life-time of the cairo_surface_t and can
simply lock/unlock the IOSurface buffer from begin_frame/end_frame to have
the buffer flushing semantics we want.

To ensure that we don't over damage, we store the damage in begin_frame
(and copy it) and then subtract it from the next frames damage to determine
the smallest amount we need to copy (taking scale factor into account).

We don't care to modify the damage region to swapBuffers because they
already have the right contents and could potentially fall into another
tile anyway and we'd like to avoid damaging that.

Fixes #4735
gdk/macos/gdkmacosbuffer.c
gdk/macos/gdkmacoscairocontext.c