]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement primitive frame synchronization on Haiku
authorPo Lu <luangruo@yahoo.com>
Mon, 1 Aug 2022 05:51:59 +0000 (05:51 +0000)
committerPo Lu <luangruo@yahoo.com>
Mon, 1 Aug 2022 05:51:59 +0000 (05:51 +0000)
Instead of relying on a compositor to do the work, we simply
wait for VBLANK and hope that the update finishes soon enough.

* doc/lispref/frames.texi (Management Parameters): Document that
frame synchronization is now supported on Haiku.

* src/haiku_support.cc (class EmacsView): New field
`use_frame_synchronization'.
(FlipBuffers): Wait for vertical blanking period.
(be_set_use_frame_synchronization): New function.
* src/haiku_support.h: Update prototypes.
* src/haikufns.c (haiku_create_frame): Set
`use-frame-synchronization'.

(haiku_set_use_frame_synchronization)
(haiku_frame_parm_handlers): New param handler.

doc/lispref/frames.texi
src/haiku_support.cc
src/haiku_support.h
src/haikufns.c

index e5dec4f8072790ce10399e167254d9a87459ffcd..262b86672da92b1bfceb9c08e1db175a34cf3ec6 100644 (file)
@@ -2188,11 +2188,11 @@ way that its contents are hidden, leaving only the title bar.
 @item use-frame-synchronization
 If non-@code{nil}, synchronize the frame redisplay with the refresh
 rate of the monitor to avoid graphics tearing.  At present, this is
-only implemented on the X window system inside no-toolkit and X
-toolkit builds, does not work correctly with toolkit scroll bars, and
-requires a compositing manager supporting the relevant display
-synchronization protocols.  The @code{synchronizeResize} X resource
-must also be set to the string @code{"extended"}.
+only implemented on Haiku and the X window system inside no-toolkit
+and X toolkit builds, does not work correctly with toolkit scroll
+bars, and requires a compositing manager supporting the relevant
+display synchronization protocols.  The @code{synchronizeResize} X
+resource must also be set to the string @code{"extended"}.
 
 @vindex inhibit-double-buffering@r{, a frame parameter}
 @item inhibit-double-buffering
index b7590f68a487d455ea8874df005b4d066a907ccf..983928442a136af89c285f32763099d2810dbdd9 100644 (file)
@@ -1512,6 +1512,8 @@ public:
 
   BMessage *wait_for_release_message;
   int64 grabbed_buttons;
+  BScreen screen;
+  bool use_frame_synchronization;
 
   EmacsView () : BView (BRect (0, 0, 0, 0), "Emacs",
                        B_FOLLOW_NONE, B_WILL_DRAW),
@@ -1524,7 +1526,8 @@ public:
                 cr_context (NULL),
 #endif
                 wait_for_release_message (NULL),
-                grabbed_buttons (0)
+                grabbed_buttons (0),
+                use_frame_synchronization (false)
   {
 
   }
@@ -1546,6 +1549,16 @@ public:
     grab_view_locker.Unlock ();
   }
 
+  void
+  SetFrameSynchronization (bool sync)
+  {
+    if (LockLooper ())
+      {
+       use_frame_synchronization = sync;
+       UnlockLooper ();
+      }
+  }
+
   void
   MessageReceived (BMessage *msg)
   {
@@ -1722,14 +1735,14 @@ public:
   void
   FlipBuffers (void)
   {
+    EmacsWindow *w;
     if (!LockLooper ())
       gui_abort ("Failed to lock looper during buffer flip");
     if (!offscreen_draw_view)
       gui_abort ("Failed to lock offscreen view during buffer flip");
 
     offscreen_draw_view->Sync ();
-
-    EmacsWindow *w = (EmacsWindow *) Window ();
+    w = (EmacsWindow *) Window ();
     w->shown_flag = 0;
 
     if (copy_bitmap &&
@@ -1750,6 +1763,11 @@ public:
     if (copy_bitmap->InitCheck () != B_OK)
       gui_abort ("Failed to init copy bitmap during buffer flip");
 
+    /* Wait for VBLANK.  If responding to the invalidation or buffer
+       flipping takes longer than the blanking period, we lose.  */
+    if (use_frame_synchronization)
+      screen.WaitForRetrace ();
+
     Invalidate (&invalid_region);
     invalid_region.MakeEmpty ();
     UnlockLooper ();
@@ -5474,3 +5492,12 @@ be_clear_grab_view (void)
       grab_view_locker.Unlock ();
     }
 }
+
+void
+be_set_use_frame_synchronization (void *view, bool sync)
+{
+  EmacsView *vw;
+
+  vw = (EmacsView *) view;
+  vw->SetFrameSynchronization (sync);
+}
index 76fe071f2c9af746887e94161b9aa8189fb1bbd0..ca1808556a4abc2c3c94d4404e4e0dc4f0edded0 100644 (file)
@@ -728,6 +728,7 @@ extern void be_lock_window (void *);
 extern void be_unlock_window (void *);
 extern bool be_get_explicit_workarea (int *, int *, int *, int *);
 extern void be_clear_grab_view (void);
+extern void be_set_use_frame_synchronization (void *, bool);
 #ifdef __cplusplus
 }
 
index 055a33e2c1e45f75fc253640d02ad7a813979f4b..64aa2fde4a1c9f7b8e111084ec9e11a8bcbe910a 100644 (file)
@@ -949,6 +949,10 @@ haiku_create_frame (Lisp_Object parms)
          || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
     kset_default_minibuffer_frame (kb, frame);
 
+  /* Set whether or not frame synchronization is enabled.  */
+  gui_default_parameter (f, parms, Quse_frame_synchronization, Qt,
+                        NULL, NULL, RES_TYPE_BOOLEAN);
+
   gui_default_parameter (f, parms, Qz_group, Qnil,
                         NULL, NULL, RES_TYPE_SYMBOL);
 
@@ -2115,6 +2119,13 @@ haiku_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
   update_face_from_frame_parameter (f, Qmouse_color, arg);
 }
 
+static void
+haiku_set_use_frame_synchronization (struct frame *f, Lisp_Object arg,
+                                    Lisp_Object oldval)
+{
+  be_set_use_frame_synchronization (FRAME_HAIKU_VIEW (f), !NILP (arg));
+}
+
 \f
 
 DEFUN ("haiku-set-mouse-absolute-pixel-position",
@@ -3128,7 +3139,7 @@ frame_parm_handler haiku_frame_parm_handlers[] =
     haiku_set_override_redirect,
     gui_set_no_special_glyphs,
     gui_set_alpha_background,
-    NULL,
+    haiku_set_use_frame_synchronization,
   };
 
 void