From 91784d87b6b87c68a6f1b5d4b77cc24c22d7109b Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 22 Apr 2014 15:06:42 -0400 Subject: [PATCH] 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. --- src/backends/meta-cursor-renderer.c | 77 ++--------------- src/backends/meta-cursor-renderer.h | 2 - src/compositor/meta-stage.c | 127 ++++++++++++++++++++++++++-- src/compositor/meta-stage.h | 6 ++ 4 files changed, 134 insertions(+), 78 deletions(-) diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c index e2bb5afb9..314f6f1d8 100644 --- a/src/backends/meta-cursor-renderer.c +++ b/src/backends/meta-cursor-renderer.c @@ -33,6 +33,7 @@ #include #include "meta-monitor-manager.h" +#include "meta-stage.h" #include "wayland/meta-wayland-private.h" @@ -42,10 +43,7 @@ struct _MetaCursorRendererPrivate int current_x, current_y; MetaRectangle current_rect; - MetaRectangle previous_rect; - gboolean previous_is_valid; - CoglPipeline *pipeline; int drm_fd; struct gbm_device *gbm; @@ -120,8 +118,6 @@ meta_cursor_renderer_finalize (GObject *object) MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object); MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer); - if (priv->pipeline) - cogl_object_unref (priv->pipeline); if (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_CALLBACK (on_monitors_changed), renderer, 0); - priv->pipeline = cogl_pipeline_new (ctx); - #if defined(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); MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); ClutterActor *stage = compositor->stage; - cairo_rectangle_int_t clip; g_assert (meta_is_wayland_compositor ()); @@ -240,25 +233,13 @@ queue_redraw (MetaCursorRenderer *renderer) if (!stage) return; - /* 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 (stage, &clip); - priv->previous_is_valid = FALSE; - } - - if (priv->has_hw_cursor || !priv->displayed_cursor) + /* If we're not using a MetaStage, quit early */ + if (!META_IS_STAGE (stage)) return; - 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 (stage, &clip); + meta_stage_set_cursor (META_STAGE (stage), + priv->displayed_cursor, + &priv->current_rect); } static void @@ -289,28 +270,12 @@ update_cursor (MetaCursorRenderer *renderer) if (meta_is_wayland_compositor ()) { 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); - cogl_pipeline_set_layer_texture (priv->pipeline, 0, texture); + update_hw_cursor (renderer); + move_hw_cursor (renderer); } else - cogl_pipeline_set_layer_texture (priv->pipeline, 0, NULL); - - update_hw_cursor (renderer); + queue_redraw (renderer); } } @@ -330,7 +295,6 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer, return; priv->displayed_cursor = cursor; - update_pipeline (renderer); update_cursor (renderer); } @@ -348,29 +312,6 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *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 meta_cursor_renderer_force_update (MetaCursorRenderer *renderer) { diff --git a/src/backends/meta-cursor-renderer.h b/src/backends/meta-cursor-renderer.h index 218c2cd88..02a417036 100644 --- a/src/backends/meta-cursor-renderer.h +++ b/src/backends/meta-cursor-renderer.h @@ -62,8 +62,6 @@ void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer, void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer, int x, int y); -void meta_cursor_renderer_paint (MetaCursorRenderer *renderer); - void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer); struct gbm_device * meta_cursor_renderer_get_gbm_device (MetaCursorRenderer *renderer); diff --git a/src/compositor/meta-stage.c b/src/compositor/meta-stage.c index b7bfab62f..55290beee 100644 --- a/src/compositor/meta-stage.c +++ b/src/compositor/meta-stage.c @@ -24,36 +24,102 @@ #include "meta-stage.h" +#include "meta-cursor-private.h" #include "meta-backend.h" #include -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 meta_stage_paint (ClutterActor *actor) { + MetaStage *stage = META_STAGE (actor); + CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor); if (meta_is_wayland_compositor ()) - { - MetaBackend *backend = meta_get_backend (); - MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend); - meta_cursor_renderer_paint (renderer); - } + paint_cursor (stage); } static void meta_stage_class_init (MetaStageClass *klass) { ClutterActorClass *actor_class = (ClutterActorClass *) klass; + GObjectClass *object_class = (GObjectClass *) klass; + + object_class->finalize = meta_stage_finalize; actor_class->paint = meta_stage_paint; } 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 * @@ -63,3 +129,48 @@ meta_stage_new (void) "cursor-visible", FALSE, 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); +} diff --git a/src/compositor/meta-stage.h b/src/compositor/meta-stage.h index 20bdd0a81..df11feba0 100644 --- a/src/compositor/meta-stage.h +++ b/src/compositor/meta-stage.h @@ -22,6 +22,9 @@ #include +#include "meta-cursor.h" +#include + G_BEGIN_DECLS #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); +void meta_stage_set_cursor (MetaStage *stage, + MetaCursorReference *cursor, + MetaRectangle *rect); G_END_DECLS #endif /* META_STAGE_H */