Regularize main loop priorities

If there is a client that is continually redrawing, then
sources that are less-prioritized than CLUTTER_PRIORITY_REDRAW
will never get run. This patch sorts out how all the different
main loop sources fit in CLUTTER_PRIORITY_REDRAW.

common.h: Document all the relevant priorities and how they
  fit in with each other.
ui.h common.h: Move META_PRIORITY_RESIZE to to common.h with
  other priorities.
src/core/window.c src/core/screen.c: Change calc-showing,
  update-icon, and update-work-area idles to be prioritized above
  redraws so they don't get starved.
bell.c: Make the visual bell priority the same as the clutter
  redraw priority.
delete.c: Use a G_PRIORITY_DEFAULT idle when responding to the
  dialog response; we want to handle it as soon as practical.

http://bugzilla.gnome.org/show_bug.cgi?id=568874
This commit is contained in:
Owen W. Taylor 2009-06-11 17:16:44 -04:00
parent 9127993d84
commit 413acc9574
6 changed files with 62 additions and 10 deletions

View File

@ -210,7 +210,12 @@ bell_flash_window_frame (MetaWindow *window)
g_assert (window->frame != NULL);
window->frame->is_flashing = 1;
meta_frame_queue_draw (window->frame);
g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, 100,
/* Since this idle is added after the Clutter clock source, with
* the same priority, it will be executed after it as well, so
* we are guaranteed to get at least one frame drawn in the
* flashed state, no matter how loaded we are.
*/
g_timeout_add_full (META_PRIORITY_REDRAW, 100,
bell_unflash_frame, window->frame, NULL);
}

View File

@ -71,7 +71,8 @@ sigchld_handler (MetaNexus *nexus, guint arg1, gpointer arg2, gpointer user_data
if (GPOINTER_TO_INT (arg2) == ours->dialog_pid)
{
if (arg1 == 1 /* pressed "force quit" */)
g_idle_add (delete_window_callback, user_data);
g_idle_add_full (G_PRIORITY_DEFAULT,
delete_window_callback, user_data, NULL);
ours->dialog_pid = -1; /* forget it anyway */
}

View File

@ -2115,7 +2115,7 @@ meta_screen_queue_workarea_recalc (MetaScreen *screen)
meta_topic (META_DEBUG_WORKAREA,
"Adding work area hint idle function\n");
screen->work_area_idle =
g_idle_add_full (META_PRIORITY_WORK_AREA_HINT,
g_idle_add_full (META_PRIORITY_BEFORE_REDRAW,
(GSourceFunc) set_work_area_idle_func,
screen,
NULL);

View File

@ -1987,9 +1987,9 @@ meta_window_queue (MetaWindow *window, guint queuebits)
const gint window_queue_idle_priority[NUMBER_OF_QUEUES] =
{
G_PRIORITY_DEFAULT_IDLE, /* CALC_SHOWING */
META_PRIORITY_RESIZE, /* MOVE_RESIZE */
G_PRIORITY_DEFAULT_IDLE /* UPDATE_ICON */
META_PRIORITY_BEFORE_REDRAW, /* CALC_SHOWING */
META_PRIORITY_RESIZE, /* MOVE_RESIZE */
META_PRIORITY_BEFORE_REDRAW /* UPDATE_ICON */
};
const GSourceFunc window_queue_idle_handler[NUMBER_OF_QUEUES] =

View File

@ -287,8 +287,57 @@ struct _MetaButtonLayout
#define META_DEFAULT_ICON_NAME "window"
/* Main loop priorities determine when activity in the GLib
* will take precendence over the others. Priorities are sometimes
* used to enforce ordering: give A a higher priority than B if
* A must occur before B. But that poses a problem since then
* if A occurs frequently enough, B will never occur.
*
* Anything we want to occur more or less immediately should
* have a priority of G_PRIORITY_DEFAULT. When we want to
* coelesce multiple things together, the appropriate place to
* do it is usually META_PRIORITY_BEFORE_REDRAW.
*
* (FIXME: Use a Clutter paint() function instead, to prevent
* starving the repaints)
*
* If something has a priority lower than the redraw priority
* (such as a default priority idle), then it may be arbitrarily
* delayed. This happens if the screen is updating rapidly: we
* are spending all our time either redrawing or waiting for a
* vblank-synced buffer swap. (When X is improved to allow
* clutter to do the buffer-swap asychronously, this will get
* better.)
*/
/* G_PRIORITY_DEFAULT:
* events
* many timeouts
*/
/* GTK_PRIORITY_RESIZE: (G_PRIORITY_HIGH_IDLE + 10) */
#define META_PRIORITY_RESIZE (G_PRIORITY_HIGH_IDLE + 15)
/* GTK_PRIORITY_REDRAW: (G_PRIORITY_HIGH_IDLE + 20) */
#define META_PRIORITY_BEFORE_REDRAW (G_PRIORITY_HIGH_IDLE + 40)
/* calc-showing idle
* update-icon idle
*/
/* CLUTTER_PRIORITY_REDRAW: (G_PRIORITY_HIGH_IDLE + 50) */
#define META_PRIORITY_REDRAW (G_PRIORITY_HIGH_IDLE + 50)
/* ==== Anything below here can be starved arbitrarily ==== */
/* G_PRIORITY_DEFAULT_IDLE:
* Mutter plugin unloading
* GConf notify idle
*/
/* Chosen to be below the GConf notify idle */
#define META_PRIORITY_PREFS_NOTIFY (G_PRIORITY_DEFAULT_IDLE + 10)
#define META_PRIORITY_WORK_AREA_HINT (G_PRIORITY_DEFAULT_IDLE + 15)
/************************************************************/
#define POINT_IN_RECT(xcoord, ycoord, rect) \
((xcoord) >= (rect).x && \

View File

@ -31,9 +31,6 @@
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
/* This is between GTK_PRIORITY_RESIZE (+10) and GTK_PRIORITY_REDRAW (+20) */
#define META_PRIORITY_RESIZE (G_PRIORITY_HIGH_IDLE + 15)
typedef struct _MetaUI MetaUI;
typedef struct _MetaImageWindow MetaImageWindow;