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 <chergert@redhat.com>
Wed, 16 Mar 2022 19:24:11 +0000 (12:24 -0700)
commit998c787638b7821a5377c3475ca085e6a8506fba
tree0887c9d96741aeb97f55b1535481bde660a537d3
parentb2ab0b1fcb8f17f992f58157a4c157c58abb613e
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