Skip to content

Commit

Permalink
Expose the sync method to preferences (#452)
Browse files Browse the repository at this point in the history
* window-actor: Only toggle sync for fullscreen apps while redirected

* Expose the sync method to preferences

* master-clock: Only set the preferred sync method

* master-clock: Call _clutter_stage_clear_update_time on sync method change

* Fix flashing when toggling fullscreen unredirected windows
  • Loading branch information
jaszhix authored and clefebvre committed Apr 13, 2019
1 parent be627af commit 40d073d
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 66 deletions.
13 changes: 13 additions & 0 deletions clutter/clutter/clutter-main.c
Expand Up @@ -98,6 +98,7 @@ static gboolean clutter_disable_mipmap_text = FALSE;
static gboolean clutter_use_fuzzy_picking = FALSE;
static gboolean clutter_enable_accessibility = TRUE;
static gboolean clutter_sync_to_vblank = TRUE;
SyncMethod clutter_sync_method = SYNC_PRESENTATION_TIME;

static guint clutter_default_fps = 60;

Expand Down Expand Up @@ -3672,6 +3673,18 @@ _clutter_get_sync_to_vblank (void)
return clutter_sync_to_vblank;
}

void
_clutter_set_sync_method (SyncMethod sync_method)
{
clutter_sync_method = sync_method;
}

SyncMethod
_clutter_get_sync_method (void)
{
return clutter_sync_method;
}

void
_clutter_debug_messagev (const char *format,
va_list var_args)
Expand Down
51 changes: 20 additions & 31 deletions clutter/clutter/clutter-master-clock-default.c
Expand Up @@ -55,20 +55,6 @@
#define clutter_warn_if_over_budget(master_clock,start_time,section)
#endif

typedef enum _SyncMethod /* In order of priority */
{ /* SUPPORTED LATENCY SMOOTHNESS */
SYNC_NONE = 0, /* Always High Poor */
SYNC_FALLBACK, /* Always Medium Medium */
SYNC_SWAP_THROTTLING, /* Usually Medium-high Medium, sometimes best */
SYNC_PRESENTATION_TIME /* Usually Low Good, sometimes best */
/* ^ As you can see SWAP_THROTTLING doesn't add much
value. And it does create the the very real
risk of blocking the main loop for up to 16ms
at a time. So it might be a good idea to retire
it in future and instead just make the backends
use swap interval 0 + PRESENTATION_TIME. */
} SyncMethod;

typedef struct _ClutterClockSource ClutterClockSource;

struct _ClutterMasterClockDefault
Expand Down Expand Up @@ -588,47 +574,50 @@ clutter_master_clock_default_class_init (ClutterMasterClockDefaultClass *klass)
}

void
clutter_master_clock_set_sync_method (gint state)
clutter_master_clock_set_sync_method (SyncMethod method)
{
SyncMethod method;
const GSList *stages, *l;
ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();

switch (state)
switch (method)
{
case 0:
method = SYNC_NONE;
case SYNC_NONE:
g_message ("Sync method: NONE");
break;
case 1:
method = SYNC_PRESENTATION_TIME;
case SYNC_PRESENTATION_TIME:
g_message ("Sync method: PRESENTATION TIME");
break;
case 2:
method = SYNC_FALLBACK;
case SYNC_FALLBACK:
g_message ("Sync method: FALLBACK");
break;
case 3:
method = SYNC_SWAP_THROTTLING;
case SYNC_SWAP_THROTTLING:
g_message ("Sync method: SWAP THROTTLING");
break;
default:
method = SYNC_PRESENTATION_TIME;
g_warning ("Invalid sync state passed to clutter_master_clock_set_sync_method: %i", state);
g_warning ("Invalid sync state passed to clutter_master_clock_set_sync_method: %i", method);
}

master_clock_global->preferred_sync_method = method;
master_clock_global->active_sync_method = method;

stages = stage_manager->stages;

for (l = stages; l; l = l->next)
{
_clutter_stage_clear_update_time (l->data);
}
}

static void
clutter_master_clock_default_init (ClutterMasterClockDefault *self)
{
GSource *source;
GSource *source = clutter_clock_source_new (self);
SyncMethod method = _clutter_get_sync_method ();

source = clutter_clock_source_new (self);
self->source = source;
master_clock_global = self;

clutter_master_clock_set_sync_method (_clutter_get_sync_to_vblank ());
self->active_sync_method = method;
clutter_master_clock_set_sync_method (method);

self->ensure_next_iteration = FALSE;
self->paused = FALSE;
Expand Down
24 changes: 22 additions & 2 deletions clutter/clutter/clutter-muffin.h
Expand Up @@ -66,6 +66,26 @@
#include "deprecated/clutter-behaviour.h"
#include "deprecated/clutter-container.h"

typedef enum _SyncMethod /* In order of priority */
{ /* SUPPORTED LATENCY SMOOTHNESS */
SYNC_NONE = 0, /* Always High Poor */
SYNC_FALLBACK, /* Always Medium Medium */
SYNC_SWAP_THROTTLING, /* Usually Medium-high Medium, sometimes best */
SYNC_PRESENTATION_TIME /* Usually Low Good, sometimes best */
/* ^ As you can see SWAP_THROTTLING doesn't add much
value. And it does create the the very real
risk of blocking the main loop for up to 16ms
at a time. So it might be a good idea to retire
it in future and instead just make the backends
use swap interval 0 + PRESENTATION_TIME. */
} SyncMethod;

CLUTTER_AVAILABLE_IN_MUFFIN
SyncMethod _clutter_get_sync_method (void);

CLUTTER_AVAILABLE_IN_MUFFIN
void _clutter_set_sync_method (SyncMethod sync_method);

CLUTTER_AVAILABLE_IN_MUFFIN
void clutter_set_custom_backend_func (ClutterBackend *(* func) (void));

Expand All @@ -76,11 +96,11 @@ CLUTTER_AVAILABLE_IN_MUFFIN
void _clutter_set_sync_to_vblank (gboolean sync_to_vblank);

CLUTTER_AVAILABLE_IN_MUFFIN
void clutter_master_clock_set_sync_method (gint state);
void clutter_master_clock_set_sync_method (SyncMethod method);

CLUTTER_AVAILABLE_IN_MUFFIN
void clutter_stage_x11_update_sync_state (ClutterStage *stage,
gint state);
SyncMethod method);

CLUTTER_AVAILABLE_IN_MUFFIN
int64_t clutter_stage_get_frame_counter (ClutterStage *stage);
Expand Down
1 change: 1 addition & 0 deletions clutter/clutter/cogl/clutter-stage-cogl.c
Expand Up @@ -48,6 +48,7 @@
#include "clutter-main.h"
#include "clutter-private.h"
#include "clutter-stage-private.h"
#include "clutter-muffin.h"

typedef struct _ClutterStageViewCoglPrivate
{
Expand Down
13 changes: 7 additions & 6 deletions clutter/clutter/x11/clutter-stage-x11.c
Expand Up @@ -613,24 +613,24 @@ frame_cb (CoglOnscreen *onscreen,

void
clutter_stage_x11_update_sync_state (ClutterStage *stage,
gint state)
SyncMethod method)
{
ClutterStageWindow *stage_window;
ClutterStageX11 *stage_x11;
gboolean state;

g_return_if_fail (stage != NULL);

if (_clutter_get_sync_to_vblank () == state)
return;

stage_window = CLUTTER_STAGE_WINDOW (_clutter_stage_get_window (CLUTTER_STAGE (stage)));
stage_x11 = CLUTTER_STAGE_X11 (stage_window);

g_return_if_fail (stage_x11->onscreen != NULL);

state = method != SYNC_NONE;

_clutter_set_sync_to_vblank (state);
cogl_onscreen_set_swap_throttled (stage_x11->onscreen, state);
clutter_master_clock_set_sync_method (state);
clutter_master_clock_set_sync_method (method);
}

static gboolean
Expand All @@ -642,6 +642,7 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
ClutterDeviceManager *device_manager;
gfloat width, height;
SyncMethod sync_method = _clutter_get_sync_method();
GError *error = NULL;

clutter_actor_get_size (CLUTTER_ACTOR (stage_cogl->wrapper), &width, &height);
Expand All @@ -654,7 +655,7 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);

cogl_onscreen_set_swap_throttled (stage_x11->onscreen,
_clutter_get_sync_to_vblank ());
sync_method != SYNC_NONE);

stage_x11->frame_closure =
cogl_onscreen_add_frame_callback (stage_x11->onscreen,
Expand Down
2 changes: 1 addition & 1 deletion src/compositor/compositor-private.h
Expand Up @@ -89,7 +89,7 @@ void meta_compositor_grab_op_end (MetaCompositor *compositor);
void meta_check_end_modal (MetaScreen *screen);

void meta_compositor_update_sync_state (MetaCompositor *compositor,
gboolean state);
MetaSyncMethod method);

void meta_compositor_grab_op_begin (MetaCompositor *compositor);
void meta_compositor_grab_op_end (MetaCompositor *compositor);
Expand Down
4 changes: 2 additions & 2 deletions src/compositor/compositor.c
Expand Up @@ -1542,8 +1542,8 @@ meta_compositor_get_cogl_context (void)

void
meta_compositor_update_sync_state (MetaCompositor *compositor,
gboolean state)
MetaSyncMethod method)
{
clutter_stage_x11_update_sync_state (compositor->stage, state);
clutter_stage_x11_update_sync_state (compositor->stage, method);
}

27 changes: 24 additions & 3 deletions src/compositor/meta-window-actor.c
Expand Up @@ -2030,6 +2030,22 @@ meta_window_actor_should_unredirect (MetaWindowActor *self)
return FALSE;
}

static void
fullscreen_sync_toggle (MetaWindowActor *self,
gboolean state)
{
MetaSyncMethod method = meta_prefs_get_sync_method ();

if (meta_prefs_get_unredirect_fullscreen_windows () &&
method != META_SYNC_NONE)
{
clutter_stage_x11_update_sync_state (
self->priv->window->display->compositor->stage,
state ? method : META_SYNC_NONE
);
}
}

LOCAL_SYMBOL void
meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state)
{
Expand All @@ -2040,24 +2056,26 @@ meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state)
Display *xdisplay = display->xdisplay;
Window xwin = meta_window_actor_get_x_window (self);

if (priv->unredirected != state)
return;

meta_error_trap_push (display);

if (state)
{
XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual);
fullscreen_sync_toggle (self, TRUE);
priv->unredirected = FALSE;
}
else
{
fullscreen_sync_toggle (self, FALSE);
meta_window_actor_detach (self);
XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual);
priv->repaint_scheduled = TRUE;
priv->unredirected = TRUE;
}

if (meta_prefs_get_unredirect_fullscreen_windows () && meta_prefs_get_sync_to_vblank ())
clutter_stage_x11_update_sync_state (display->compositor->stage, state);

meta_error_trap_pop (display);
}

Expand Down Expand Up @@ -2162,6 +2180,9 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
priv->needs_pixmap = TRUE;
meta_window_actor_update_shape (self);

if (priv->unredirected)
meta_display_set_all_obscured ();

clutter_actor_set_size (CLUTTER_ACTOR (self),
window_rect.width, window_rect.height);
}
Expand Down
3 changes: 2 additions & 1 deletion src/core/display-private.h
Expand Up @@ -299,6 +299,7 @@ struct _MetaDisplay
#define META_DISPLAY_HAS_COMPOSITE(display) ((display)->have_composite)
#define META_DISPLAY_HAS_DAMAGE(display) ((display)->have_damage)
#define META_DISPLAY_HAS_XFIXES(display) ((display)->have_xfixes)
MetaSyncMethod sync_method;

guint shadows_enabled : 1;
guint debug_button_grabs : 1;
Expand Down Expand Up @@ -442,7 +443,7 @@ guint meta_display_get_above_tab_keycode (MetaDisplay *display);

void meta_display_notify_restart (MetaDisplay *display);

void meta_display_update_sync_state (gboolean state);
void meta_display_update_sync_state (MetaSyncMethod method);

void meta_display_set_all_obscured (void);

Expand Down
6 changes: 4 additions & 2 deletions src/core/display.c
Expand Up @@ -545,6 +545,8 @@ meta_display_open (void)

the_display->rebuild_keybinding_idle_id = 0;

the_display->sync_method = meta_prefs_get_sync_method();

/* FIXME copy the checks from GDK probably */
the_display->static_gravity_works = g_getenv ("MUFFIN_USE_STATIC_GRAVITY") != NULL;

Expand Down Expand Up @@ -5784,9 +5786,9 @@ meta_display_restart (MetaDisplay *display)
}

void
meta_display_update_sync_state (gboolean state)
meta_display_update_sync_state (MetaSyncMethod method)
{
meta_compositor_update_sync_state (the_display->compositor, state);
meta_compositor_update_sync_state (the_display->compositor, method);
}

void
Expand Down
6 changes: 3 additions & 3 deletions src/core/main.c
Expand Up @@ -492,7 +492,7 @@ meta_init (void)

/* Load prefs */
meta_prefs_init ();
_clutter_set_sync_to_vblank(meta_prefs_get_sync_to_vblank());
_clutter_set_sync_method (meta_prefs_get_sync_method ());

/*
* Clutter can only be initialized after the UI.
Expand Down Expand Up @@ -630,8 +630,8 @@ prefs_changed_callback (MetaPreference pref,
meta_display_set_cursor_theme (meta_prefs_get_cursor_theme (),
meta_prefs_get_cursor_size ());
break;
case META_PREF_SYNC_TO_VBLANK:
meta_display_update_sync_state (meta_prefs_get_sync_to_vblank());
case META_PREF_SYNC_METHOD:
meta_display_update_sync_state (meta_prefs_get_sync_method ());
break;
default:
/* handled elsewhere or otherwise */
Expand Down

0 comments on commit 40d073d

Please sign in to comment.