Implement primitive frame synchronization on Haiku
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.
This commit is contained in:
parent
bc03a5b2c4
commit
99754dad3c
4 changed files with 48 additions and 9 deletions
|
@ -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
|
||||
|
|
|
@ -1512,6 +1512,8 @@ class EmacsView : public BView
|
|||
|
||||
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 @@ class EmacsView : public BView
|
|||
cr_context (NULL),
|
||||
#endif
|
||||
wait_for_release_message (NULL),
|
||||
grabbed_buttons (0)
|
||||
grabbed_buttons (0),
|
||||
use_frame_synchronization (false)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -1546,6 +1549,16 @@ class EmacsView : public BView
|
|||
grab_view_locker.Unlock ();
|
||||
}
|
||||
|
||||
void
|
||||
SetFrameSynchronization (bool sync)
|
||||
{
|
||||
if (LockLooper ())
|
||||
{
|
||||
use_frame_synchronization = sync;
|
||||
UnlockLooper ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MessageReceived (BMessage *msg)
|
||||
{
|
||||
|
@ -1722,14 +1735,14 @@ class EmacsView : public BView
|
|||
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 @@ class EmacsView : public BView
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue