Move the painting of the cursor on the stage out of the cursor renderer

This logic is now well-contained the stage. This is the start of us
moving to backend-specific cursor renderers.
This commit is contained in:
Jasper St. Pierre 2014-04-22 15:06:42 -04:00
parent 2769683521
commit 91784d87b6
4 changed files with 134 additions and 78 deletions

View File

@ -33,6 +33,7 @@
#include <gbm.h> #include <gbm.h>
#include "meta-monitor-manager.h" #include "meta-monitor-manager.h"
#include "meta-stage.h"
#include "wayland/meta-wayland-private.h" #include "wayland/meta-wayland-private.h"
@ -42,10 +43,7 @@ struct _MetaCursorRendererPrivate
int current_x, current_y; int current_x, current_y;
MetaRectangle current_rect; MetaRectangle current_rect;
MetaRectangle previous_rect;
gboolean previous_is_valid;
CoglPipeline *pipeline;
int drm_fd; int drm_fd;
struct gbm_device *gbm; struct gbm_device *gbm;
@ -120,8 +118,6 @@ meta_cursor_renderer_finalize (GObject *object)
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object); MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
if (priv->pipeline)
cogl_object_unref (priv->pipeline);
if (priv->gbm) if (priv->gbm)
gbm_device_destroy (priv->gbm); gbm_device_destroy (priv->gbm);
@ -147,8 +143,6 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
g_signal_connect_object (monitors, "monitors-changed", g_signal_connect_object (monitors, "monitors-changed",
G_CALLBACK (on_monitors_changed), renderer, 0); G_CALLBACK (on_monitors_changed), renderer, 0);
priv->pipeline = cogl_pipeline_new (ctx);
#if defined(CLUTTER_WINDOWING_EGL) #if defined(CLUTTER_WINDOWING_EGL)
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL)) if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
{ {
@ -232,7 +226,6 @@ queue_redraw (MetaCursorRenderer *renderer)
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
ClutterActor *stage = compositor->stage; ClutterActor *stage = compositor->stage;
cairo_rectangle_int_t clip;
g_assert (meta_is_wayland_compositor ()); g_assert (meta_is_wayland_compositor ());
@ -240,25 +233,13 @@ queue_redraw (MetaCursorRenderer *renderer)
if (!stage) if (!stage)
return; return;
/* Clear the location the cursor was at before, if we need to. */ /* If we're not using a MetaStage, quit early */
if (priv->previous_is_valid) if (!META_IS_STAGE (stage))
{
clip.x = priv->previous_rect.x;
clip.y = priv->previous_rect.y;
clip.width = priv->previous_rect.width;
clip.height = priv->previous_rect.height;
clutter_actor_queue_redraw_with_clip (stage, &clip);
priv->previous_is_valid = FALSE;
}
if (priv->has_hw_cursor || !priv->displayed_cursor)
return; return;
clip.x = priv->current_rect.x; meta_stage_set_cursor (META_STAGE (stage),
clip.y = priv->current_rect.y; priv->displayed_cursor,
clip.width = priv->current_rect.width; &priv->current_rect);
clip.height = priv->current_rect.height;
clutter_actor_queue_redraw_with_clip (stage, &clip);
} }
static void static void
@ -289,28 +270,12 @@ update_cursor (MetaCursorRenderer *renderer)
if (meta_is_wayland_compositor ()) if (meta_is_wayland_compositor ())
{ {
if (priv->has_hw_cursor) if (priv->has_hw_cursor)
move_hw_cursor (renderer);
else
queue_redraw (renderer);
}
}
static void
update_pipeline (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
if (meta_is_wayland_compositor ())
{
if (priv->displayed_cursor)
{ {
CoglTexture *texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, NULL, NULL); update_hw_cursor (renderer);
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); move_hw_cursor (renderer);
} }
else else
cogl_pipeline_set_layer_texture (priv->pipeline, 0, NULL); queue_redraw (renderer);
update_hw_cursor (renderer);
} }
} }
@ -330,7 +295,6 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
return; return;
priv->displayed_cursor = cursor; priv->displayed_cursor = cursor;
update_pipeline (renderer);
update_cursor (renderer); update_cursor (renderer);
} }
@ -348,29 +312,6 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
update_cursor (renderer); update_cursor (renderer);
} }
void
meta_cursor_renderer_paint (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
g_assert (meta_is_wayland_compositor ());
if (priv->has_hw_cursor || !priv->displayed_cursor)
return;
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
priv->pipeline,
priv->current_rect.x,
priv->current_rect.y,
priv->current_rect.x +
priv->current_rect.width,
priv->current_rect.y +
priv->current_rect.height);
priv->previous_rect = priv->current_rect;
priv->previous_is_valid = TRUE;
}
void void
meta_cursor_renderer_force_update (MetaCursorRenderer *renderer) meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
{ {

View File

@ -62,8 +62,6 @@ void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
int x, int y); int x, int y);
void meta_cursor_renderer_paint (MetaCursorRenderer *renderer);
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer); void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
struct gbm_device * meta_cursor_renderer_get_gbm_device (MetaCursorRenderer *renderer); struct gbm_device * meta_cursor_renderer_get_gbm_device (MetaCursorRenderer *renderer);

View File

@ -24,36 +24,102 @@
#include "meta-stage.h" #include "meta-stage.h"
#include "meta-cursor-private.h"
#include "meta-backend.h" #include "meta-backend.h"
#include <meta/util.h> #include <meta/util.h>
G_DEFINE_TYPE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE); struct _MetaStagePrivate {
CoglPipeline *pipeline;
gboolean should_paint_cursor;
MetaCursorReference *cursor;
MetaRectangle current_rect;
MetaRectangle previous_rect;
gboolean previous_is_valid;
};
typedef struct _MetaStagePrivate MetaStagePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
static void
update_pipeline (MetaStage *stage)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
if (priv->cursor)
{
CoglTexture *texture = meta_cursor_reference_get_cogl_texture (priv->cursor, NULL, NULL);
cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture);
}
else
cogl_pipeline_set_layer_texture (priv->pipeline, 0, NULL);
}
static void
meta_stage_finalize (GObject *object)
{
MetaStage *stage = META_STAGE (object);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
if (priv->pipeline)
cogl_object_unref (priv->pipeline);
}
static void
paint_cursor (MetaStage *stage)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
g_assert (meta_is_wayland_compositor ());
if (!priv->cursor)
return;
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
priv->pipeline,
priv->current_rect.x,
priv->current_rect.y,
priv->current_rect.x +
priv->current_rect.width,
priv->current_rect.y +
priv->current_rect.height);
priv->previous_rect = priv->current_rect;
priv->previous_is_valid = TRUE;
}
static void static void
meta_stage_paint (ClutterActor *actor) meta_stage_paint (ClutterActor *actor)
{ {
MetaStage *stage = META_STAGE (actor);
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor); CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
if (meta_is_wayland_compositor ()) if (meta_is_wayland_compositor ())
{ paint_cursor (stage);
MetaBackend *backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend);
meta_cursor_renderer_paint (renderer);
}
} }
static void static void
meta_stage_class_init (MetaStageClass *klass) meta_stage_class_init (MetaStageClass *klass)
{ {
ClutterActorClass *actor_class = (ClutterActorClass *) klass; ClutterActorClass *actor_class = (ClutterActorClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->finalize = meta_stage_finalize;
actor_class->paint = meta_stage_paint; actor_class->paint = meta_stage_paint;
} }
static void static void
meta_stage_init (MetaStage *self) meta_stage_init (MetaStage *stage)
{ {
clutter_stage_set_user_resizable (CLUTTER_STAGE (self), FALSE); CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
priv->pipeline = cogl_pipeline_new (ctx);
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
} }
ClutterActor * ClutterActor *
@ -63,3 +129,48 @@ meta_stage_new (void)
"cursor-visible", FALSE, "cursor-visible", FALSE,
NULL); NULL);
} }
static void
queue_redraw (MetaStage *stage)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
cairo_rectangle_int_t clip;
/* Clear the location the cursor was at before, if we need to. */
if (priv->previous_is_valid)
{
clip.x = priv->previous_rect.x;
clip.y = priv->previous_rect.y;
clip.width = priv->previous_rect.width;
clip.height = priv->previous_rect.height;
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
priv->previous_is_valid = FALSE;
}
/* And queue a redraw for the current cursor location. */
if (priv->cursor)
{
clip.x = priv->current_rect.x;
clip.y = priv->current_rect.y;
clip.width = priv->current_rect.width;
clip.height = priv->current_rect.height;
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
}
}
void
meta_stage_set_cursor (MetaStage *stage,
MetaCursorReference *cursor,
MetaRectangle *rect)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
if (priv->cursor != cursor)
{
priv->cursor = cursor;
update_pipeline (stage);
}
priv->current_rect = *rect;
queue_redraw (stage);
}

View File

@ -22,6 +22,9 @@
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include "meta-cursor.h"
#include <meta/boxes.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define META_TYPE_STAGE (meta_stage_get_type ()) #define META_TYPE_STAGE (meta_stage_get_type ())
@ -48,6 +51,9 @@ GType meta_stage_get_type (void) G_GNUC_CONST;
ClutterActor *meta_stage_new (void); ClutterActor *meta_stage_new (void);
void meta_stage_set_cursor (MetaStage *stage,
MetaCursorReference *cursor,
MetaRectangle *rect);
G_END_DECLS G_END_DECLS
#endif /* META_STAGE_H */ #endif /* META_STAGE_H */