Add ::first-frame signal to MetaWindowActor
This signal is emitted the first time a frame of contents of the window is completed by the application and has been drawn on the screen. This is meant to be used for performance measurement of application startup. https://bugzilla.gnome.org/show_bug.cgi?id=732343
This commit is contained in:
parent
077606c057
commit
9c6e527d4b
@ -36,6 +36,12 @@
|
|||||||
|
|
||||||
#include "wayland/meta-wayland-surface.h"
|
#include "wayland/meta-wayland-surface.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
INITIALLY_FROZEN,
|
||||||
|
DRAWING_FIRST_FRAME,
|
||||||
|
EMITTED_FIRST_FRAME
|
||||||
|
} FirstFrameState;
|
||||||
|
|
||||||
struct _MetaWindowActorPrivate
|
struct _MetaWindowActorPrivate
|
||||||
{
|
{
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
@ -104,6 +110,7 @@ struct _MetaWindowActorPrivate
|
|||||||
guint no_shadow : 1;
|
guint no_shadow : 1;
|
||||||
|
|
||||||
guint updates_frozen : 1;
|
guint updates_frozen : 1;
|
||||||
|
guint first_frame_state : 2; /* FirstFrameState */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _FrameData FrameData;
|
typedef struct _FrameData FrameData;
|
||||||
@ -115,6 +122,14 @@ struct _FrameData
|
|||||||
gint64 frame_drawn_time;
|
gint64 frame_drawn_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
FIRST_FRAME,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_META_WINDOW = 1,
|
PROP_META_WINDOW = 1,
|
||||||
@ -181,6 +196,31 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
|||||||
actor_class->paint = meta_window_actor_paint;
|
actor_class->paint = meta_window_actor_paint;
|
||||||
actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
|
actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MetaWindowActor::first-frame:
|
||||||
|
* @actor: the #MetaWindowActor instance
|
||||||
|
*
|
||||||
|
* The ::first-frame signal will be emitted the first time a frame
|
||||||
|
* of window contents has been drawn by the application and Mutter
|
||||||
|
* has had the chance to drawn that frame to the screen. If the
|
||||||
|
* window starts off initially hidden, obscured, or on on a
|
||||||
|
* different workspace, the ::first-frame signal will be emitted
|
||||||
|
* even though the user doesn't see the contents.
|
||||||
|
*
|
||||||
|
* MetaDisplay::window-created is a good place to connect to this
|
||||||
|
* signal - at that point, the MetaWindowActor for the window
|
||||||
|
* exists, but the window has reliably not yet been drawn.
|
||||||
|
* Connecting to an existing window that has already been drawn to
|
||||||
|
* the screen is not useful.
|
||||||
|
*/
|
||||||
|
signals[FIRST_FRAME] =
|
||||||
|
g_signal_new ("first-frame",
|
||||||
|
G_TYPE_FROM_CLASS (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
0,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
G_TYPE_NONE, 0);
|
||||||
|
|
||||||
pspec = g_param_spec_object ("meta-window",
|
pspec = g_param_spec_object ("meta-window",
|
||||||
"MetaWindow",
|
"MetaWindow",
|
||||||
"The displayed MetaWindow",
|
"The displayed MetaWindow",
|
||||||
@ -306,6 +346,9 @@ meta_window_actor_thaw (MetaWindowActor *self)
|
|||||||
if (priv->freeze_count > 0)
|
if (priv->freeze_count > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (priv->first_frame_state == INITIALLY_FROZEN)
|
||||||
|
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
||||||
|
|
||||||
if (priv->surface)
|
if (priv->surface)
|
||||||
meta_surface_actor_set_frozen (priv->surface, FALSE);
|
meta_surface_actor_set_frozen (priv->surface, FALSE);
|
||||||
|
|
||||||
@ -348,6 +391,9 @@ set_surface (MetaWindowActor *self,
|
|||||||
* frozen as well... */
|
* frozen as well... */
|
||||||
meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0);
|
meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0);
|
||||||
|
|
||||||
|
if (!is_frozen (self) && priv->first_frame_state == INITIALLY_FROZEN)
|
||||||
|
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
||||||
|
|
||||||
meta_window_actor_update_shape (self);
|
meta_window_actor_update_shape (self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1328,6 +1374,11 @@ meta_window_actor_new (MetaWindow *window)
|
|||||||
|
|
||||||
meta_window_actor_sync_updates_frozen (self);
|
meta_window_actor_sync_updates_frozen (self);
|
||||||
|
|
||||||
|
if (is_frozen (self))
|
||||||
|
priv->first_frame_state = INITIALLY_FROZEN;
|
||||||
|
else
|
||||||
|
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
||||||
|
|
||||||
/* If a window doesn't start off with updates frozen, we should
|
/* If a window doesn't start off with updates frozen, we should
|
||||||
* we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn.
|
* we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn.
|
||||||
*/
|
*/
|
||||||
@ -1910,6 +1961,12 @@ meta_window_actor_post_paint (MetaWindowActor *self)
|
|||||||
do_send_frame_drawn (self, priv->frames->data);
|
do_send_frame_drawn (self, priv->frames->data);
|
||||||
priv->needs_frame_drawn = FALSE;
|
priv->needs_frame_drawn = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priv->first_frame_state == DRAWING_FIRST_FRAME)
|
||||||
|
{
|
||||||
|
priv->first_frame_state = EMITTED_FIRST_FRAME;
|
||||||
|
g_signal_emit (self, signals[FIRST_FRAME], 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user