From c710a569033bbd9327eede901b6f7bf2dce710a6 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 29 Mar 2019 21:18:07 +0100 Subject: backends: Move nested stage to src/backends/x11/nested We now have a MetaStageX11, so it's extra confusing to have both in the same directory. https://gitlab.gnome.org/GNOME/mutter/merge_requests/672 --- src/backends/x11/meta-clutter-backend-x11.c | 2 +- src/backends/x11/meta-stage-x11-nested.c | 362 ------------------------ src/backends/x11/meta-stage-x11-nested.h | 35 --- src/backends/x11/nested/meta-stage-x11-nested.c | 362 ++++++++++++++++++++++++ src/backends/x11/nested/meta-stage-x11-nested.h | 35 +++ src/meson.build | 4 +- 6 files changed, 400 insertions(+), 400 deletions(-) delete mode 100644 src/backends/x11/meta-stage-x11-nested.c delete mode 100644 src/backends/x11/meta-stage-x11-nested.h create mode 100644 src/backends/x11/nested/meta-stage-x11-nested.c create mode 100644 src/backends/x11/nested/meta-stage-x11-nested.h (limited to 'src') diff --git a/src/backends/x11/meta-clutter-backend-x11.c b/src/backends/x11/meta-clutter-backend-x11.c index 05af25c90..8d4b64b03 100644 --- a/src/backends/x11/meta-clutter-backend-x11.c +++ b/src/backends/x11/meta-clutter-backend-x11.c @@ -31,8 +31,8 @@ #include "backends/x11/meta-clutter-backend-x11.h" #include "backends/x11/meta-device-manager-x11.h" #include "backends/x11/meta-keymap-x11.h" -#include "backends/x11/meta-stage-x11-nested.h" #include "backends/x11/meta-xkb-a11y-x11.h" +#include "backends/x11/nested/meta-stage-x11-nested.h" #include "clutter/clutter-mutter.h" #include "clutter/clutter.h" #include "core/bell.h" diff --git a/src/backends/x11/meta-stage-x11-nested.c b/src/backends/x11/meta-stage-x11-nested.c deleted file mode 100644 index f6dc5dbcb..000000000 --- a/src/backends/x11/meta-stage-x11-nested.c +++ /dev/null @@ -1,362 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2016 Red Hat Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written by: - * Jonas Ådahl - */ - -#include "config.h" - -#include "backends/x11/meta-stage-x11-nested.h" - -#include "backends/meta-backend-private.h" -#include "backends/meta-crtc.h" -#include "backends/meta-logical-monitor.h" -#include "backends/meta-monitor.h" -#include "backends/meta-output.h" -#include "backends/meta-renderer.h" -#include "backends/x11/nested/meta-renderer-x11-nested.h" -#include "clutter/clutter-mutter.h" - -static ClutterStageWindowInterface *clutter_stage_window_parent_iface = NULL; - -struct _MetaStageX11Nested -{ - MetaStageX11 parent; - - CoglPipeline *pipeline; -}; - -static void -clutter_stage_window_iface_init (ClutterStageWindowInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (MetaStageX11Nested, meta_stage_x11_nested, - META_TYPE_STAGE_X11, - G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, - clutter_stage_window_iface_init)) - -typedef struct _MetaStageX11View -{ - CoglTexture *texture; - ClutterStageViewCogl *view; -} MetaStageX11NestedView; - -static void -meta_stage_x11_nested_resize (ClutterStageWindow *stage_window, - gint width, - gint height) -{ - if (!meta_is_stage_views_enabled ()) - { - MetaBackend *backend = meta_get_backend (); - MetaRenderer *renderer = meta_backend_get_renderer (backend); - MetaRendererX11Nested *renderer_x11_nested = - META_RENDERER_X11_NESTED (renderer); - - meta_renderer_x11_nested_ensure_legacy_view (renderer_x11_nested, - width, height); - } - - clutter_stage_window_parent_iface->resize (stage_window, width, height); -} - -static gboolean -meta_stage_x11_nested_can_clip_redraws (ClutterStageWindow *stage_window) -{ - return FALSE; -} - -static GList * -meta_stage_x11_nested_get_views (ClutterStageWindow *stage_window) -{ - MetaBackend *backend = meta_get_backend (); - MetaRenderer *renderer = meta_backend_get_renderer (backend); - - return meta_renderer_get_views (renderer); -} - -typedef struct -{ - MetaStageX11Nested *stage_nested; - CoglTexture *texture; - ClutterStageView *view; - MetaLogicalMonitor *logical_monitor; -} DrawCrtcData; - -static gboolean -draw_crtc (MetaMonitor *monitor, - MetaMonitorMode *monitor_mode, - MetaMonitorCrtcMode *monitor_crtc_mode, - gpointer user_data, - GError **error) -{ - DrawCrtcData *data = user_data; - MetaStageX11 *stage_x11 = META_STAGE_X11 (data->stage_nested); - CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen); - CoglTexture *texture = data->texture; - MetaLogicalMonitor *logical_monitor = data->logical_monitor; - MetaOutput *output = monitor_crtc_mode->output; - MetaCrtc *crtc; - MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view); - MetaMonitorTransform view_transform; - MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL; - cairo_rectangle_int_t view_layout; - CoglMatrix projection_matrix; - CoglMatrix transform; - float texture_width, texture_height; - float sample_x, sample_y, sample_width, sample_height; - float scale; - int viewport_x, viewport_y; - int viewport_width, viewport_height; - float s_1, t_1, s_2, t_2; - - texture_width = cogl_texture_get_width (texture); - texture_height = cogl_texture_get_height (texture); - - crtc = meta_output_get_assigned_crtc (output); - - clutter_stage_view_get_layout (data->view, &view_layout); - sample_x = crtc->rect.x - view_layout.x; - sample_y = crtc->rect.y - view_layout.y; - sample_width = crtc->rect.width; - sample_height = crtc->rect.height; - - clutter_stage_view_get_offscreen_transformation_matrix (data->view, - &transform); - - cogl_framebuffer_push_matrix (onscreen); - cogl_matrix_init_identity (&projection_matrix); - cogl_matrix_translate (&projection_matrix, -1, 1, 0); - cogl_matrix_scale (&projection_matrix, 2, -2, 0); - - cogl_matrix_multiply (&projection_matrix, &projection_matrix, &transform); - cogl_framebuffer_set_projection_matrix (onscreen, &projection_matrix); - - s_1 = sample_x / texture_width; - t_1 = sample_y / texture_height; - s_2 = (sample_x + sample_width) / texture_width; - t_2 = (sample_y + sample_height) / texture_height; - - view_transform = meta_renderer_view_get_transform (renderer_view); - - if (view_transform == logical_monitor->transform) - { - switch (view_transform) - { - case META_MONITOR_TRANSFORM_NORMAL: - case META_MONITOR_TRANSFORM_FLIPPED: - layout_transform = META_MONITOR_TRANSFORM_NORMAL; - break; - case META_MONITOR_TRANSFORM_270: - case META_MONITOR_TRANSFORM_FLIPPED_270: - layout_transform = META_MONITOR_TRANSFORM_90; - break; - case META_MONITOR_TRANSFORM_180: - case META_MONITOR_TRANSFORM_FLIPPED_180: - layout_transform = META_MONITOR_TRANSFORM_180; - break; - case META_MONITOR_TRANSFORM_90: - case META_MONITOR_TRANSFORM_FLIPPED_90: - layout_transform = META_MONITOR_TRANSFORM_270; - break; - } - } - else - { - layout_transform = logical_monitor->transform; - } - - meta_monitor_calculate_crtc_pos (monitor, monitor_mode, output, - layout_transform, - &viewport_x, - &viewport_y); - viewport_x += logical_monitor->rect.x; - viewport_y += logical_monitor->rect.y; - if (meta_monitor_transform_is_rotated (logical_monitor->transform)) - { - viewport_width = monitor_crtc_mode->crtc_mode->height; - viewport_height = monitor_crtc_mode->crtc_mode->width; - } - else - { - viewport_width = monitor_crtc_mode->crtc_mode->width; - viewport_height = monitor_crtc_mode->crtc_mode->height; - } - - scale = clutter_stage_view_get_scale (data->view); - viewport_width = roundf (viewport_width / scale); - viewport_height = roundf (viewport_height / scale); - - cogl_framebuffer_set_viewport (onscreen, - viewport_x, viewport_y, - viewport_width, viewport_height); - - cogl_framebuffer_draw_textured_rectangle (onscreen, - data->stage_nested->pipeline, - 0, 0, 1, 1, - s_1, t_1, s_2, t_2); - - cogl_framebuffer_pop_matrix (onscreen); - return TRUE; -} - -static void -draw_logical_monitor (MetaStageX11Nested *stage_nested, - MetaLogicalMonitor *logical_monitor, - CoglTexture *texture, - ClutterStageView *view, - cairo_rectangle_int_t *view_layout) -{ - MetaMonitor *monitor; - MetaMonitorMode *current_mode; - - cogl_pipeline_set_layer_wrap_mode (stage_nested->pipeline, 0, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - - monitor = meta_logical_monitor_get_monitors (logical_monitor)->data; - current_mode = meta_monitor_get_current_mode (monitor); - meta_monitor_mode_foreach_crtc (monitor, current_mode, - draw_crtc, - &(DrawCrtcData) { - .stage_nested = stage_nested, - .texture = texture, - .view = view, - .logical_monitor = logical_monitor - }, - NULL); -} - -static void -meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window) -{ - MetaStageX11Nested *stage_nested = META_STAGE_X11_NESTED (stage_window); - MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); - MetaBackend *backend = meta_get_backend (); - MetaRenderer *renderer = meta_backend_get_renderer (backend); - ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); - CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen); - GList *l; - - if (!stage_nested->pipeline) - stage_nested->pipeline = cogl_pipeline_new (clutter_backend->cogl_context); - - cogl_framebuffer_clear4f (onscreen, - COGL_BUFFER_BIT_COLOR, - 0.0f, 0.0f, 0.0f, 1.0f); - - for (l = meta_renderer_get_views (renderer); l; l = l->next) - { - ClutterStageView *view = l->data; - MetaRendererView *renderer_view = META_RENDERER_VIEW (view); - MetaLogicalMonitor *logical_monitor; - cairo_rectangle_int_t view_layout; - CoglFramebuffer *framebuffer; - CoglTexture *texture; - - clutter_stage_view_get_layout (view, &view_layout); - - framebuffer = clutter_stage_view_get_onscreen (view); - texture = cogl_offscreen_get_texture (COGL_OFFSCREEN (framebuffer)); - - cogl_pipeline_set_layer_texture (stage_nested->pipeline, 0, texture); - - logical_monitor = meta_renderer_view_get_logical_monitor (renderer_view); - if (logical_monitor) - { - draw_logical_monitor (stage_nested, logical_monitor, texture, view, &view_layout); - } - else - { - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - GList *logical_monitors; - GList *k; - - logical_monitors = - meta_monitor_manager_get_logical_monitors (monitor_manager); - for (k = logical_monitors; k; k = k->next) - { - logical_monitor = k->data; - - draw_logical_monitor (stage_nested, logical_monitor, texture, view, &view_layout); - } - } - } - - cogl_onscreen_swap_buffers (stage_x11->onscreen); -} - -static void -meta_stage_x11_nested_unrealize (ClutterStageWindow *stage_window) -{ - MetaStageX11Nested *stage_nested = META_STAGE_X11_NESTED (stage_window); - ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); - MetaBackend *backend = meta_get_backend (); - MetaRenderer *renderer = meta_backend_get_renderer (backend); - GList *l; - - /* Clutter still uses part of the deprecated stateful API of Cogl - * (in particulart cogl_set_framebuffer). It means Cogl can keep an - * internal reference to the onscreen object we rendered to. In the - * case of foreign window, we want to avoid this, as we don't know - * what's going to happen to that window. - * - * The following call sets the current Cogl framebuffer to a dummy - * 1x1 one if we're unrealizing the current one, so Cogl doesn't - * keep any reference to the foreign window. - */ - for (l = meta_renderer_get_views (renderer); l ;l = l->next) - { - ClutterStageView *view = l->data; - CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view); - - if (cogl_get_draw_framebuffer () == framebuffer) - { - _clutter_backend_reset_cogl_framebuffer (stage_cogl->backend); - break; - } - } - - g_clear_pointer (&stage_nested->pipeline, cogl_object_unref); - - clutter_stage_window_parent_iface->unrealize (stage_window); -} - -static void -meta_stage_x11_nested_init (MetaStageX11Nested *stage_x11_nested) -{ -} - -static void -meta_stage_x11_nested_class_init (MetaStageX11NestedClass *klass) -{ -} - -static void -clutter_stage_window_iface_init (ClutterStageWindowInterface *iface) -{ - clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface); - - iface->resize = meta_stage_x11_nested_resize; - iface->can_clip_redraws = meta_stage_x11_nested_can_clip_redraws; - iface->unrealize = meta_stage_x11_nested_unrealize; - iface->get_views = meta_stage_x11_nested_get_views; - iface->finish_frame = meta_stage_x11_nested_finish_frame; -} diff --git a/src/backends/x11/meta-stage-x11-nested.h b/src/backends/x11/meta-stage-x11-nested.h deleted file mode 100644 index b605e07e2..000000000 --- a/src/backends/x11/meta-stage-x11-nested.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2016 Red Hat Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Written by: - * Jonas Ådahl - */ - -#ifndef META_STAGE_X11_NESTED_H -#define META_STAGE_X11_NESTED_H - -#include "clutter/clutter-mutter.h" -#include "meta-stage-x11.h" - -#define META_TYPE_STAGE_X11_NESTED (meta_stage_x11_nested_get_type ()) -G_DECLARE_FINAL_TYPE (MetaStageX11Nested, meta_stage_x11_nested, - META, STAGE_X11_NESTED, MetaStageX11) - -#endif /* META_STAGE_X11_NESTED_H */ diff --git a/src/backends/x11/nested/meta-stage-x11-nested.c b/src/backends/x11/nested/meta-stage-x11-nested.c new file mode 100644 index 000000000..73b8f2854 --- /dev/null +++ b/src/backends/x11/nested/meta-stage-x11-nested.c @@ -0,0 +1,362 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl + */ + +#include "config.h" + +#include "backends/x11/nested/meta-stage-x11-nested.h" + +#include "backends/meta-backend-private.h" +#include "backends/meta-crtc.h" +#include "backends/meta-logical-monitor.h" +#include "backends/meta-monitor.h" +#include "backends/meta-output.h" +#include "backends/meta-renderer.h" +#include "backends/x11/nested/meta-renderer-x11-nested.h" +#include "clutter/clutter-mutter.h" + +static ClutterStageWindowInterface *clutter_stage_window_parent_iface = NULL; + +struct _MetaStageX11Nested +{ + MetaStageX11 parent; + + CoglPipeline *pipeline; +}; + +static void +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (MetaStageX11Nested, meta_stage_x11_nested, + META_TYPE_STAGE_X11, + G_IMPLEMENT_INTERFACE (CLUTTER_TYPE_STAGE_WINDOW, + clutter_stage_window_iface_init)) + +typedef struct _MetaStageX11View +{ + CoglTexture *texture; + ClutterStageViewCogl *view; +} MetaStageX11NestedView; + +static void +meta_stage_x11_nested_resize (ClutterStageWindow *stage_window, + gint width, + gint height) +{ + if (!meta_is_stage_views_enabled ()) + { + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + MetaRendererX11Nested *renderer_x11_nested = + META_RENDERER_X11_NESTED (renderer); + + meta_renderer_x11_nested_ensure_legacy_view (renderer_x11_nested, + width, height); + } + + clutter_stage_window_parent_iface->resize (stage_window, width, height); +} + +static gboolean +meta_stage_x11_nested_can_clip_redraws (ClutterStageWindow *stage_window) +{ + return FALSE; +} + +static GList * +meta_stage_x11_nested_get_views (ClutterStageWindow *stage_window) +{ + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + + return meta_renderer_get_views (renderer); +} + +typedef struct +{ + MetaStageX11Nested *stage_nested; + CoglTexture *texture; + ClutterStageView *view; + MetaLogicalMonitor *logical_monitor; +} DrawCrtcData; + +static gboolean +draw_crtc (MetaMonitor *monitor, + MetaMonitorMode *monitor_mode, + MetaMonitorCrtcMode *monitor_crtc_mode, + gpointer user_data, + GError **error) +{ + DrawCrtcData *data = user_data; + MetaStageX11 *stage_x11 = META_STAGE_X11 (data->stage_nested); + CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen); + CoglTexture *texture = data->texture; + MetaLogicalMonitor *logical_monitor = data->logical_monitor; + MetaOutput *output = monitor_crtc_mode->output; + MetaCrtc *crtc; + MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view); + MetaMonitorTransform view_transform; + MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL; + cairo_rectangle_int_t view_layout; + CoglMatrix projection_matrix; + CoglMatrix transform; + float texture_width, texture_height; + float sample_x, sample_y, sample_width, sample_height; + float scale; + int viewport_x, viewport_y; + int viewport_width, viewport_height; + float s_1, t_1, s_2, t_2; + + texture_width = cogl_texture_get_width (texture); + texture_height = cogl_texture_get_height (texture); + + crtc = meta_output_get_assigned_crtc (output); + + clutter_stage_view_get_layout (data->view, &view_layout); + sample_x = crtc->rect.x - view_layout.x; + sample_y = crtc->rect.y - view_layout.y; + sample_width = crtc->rect.width; + sample_height = crtc->rect.height; + + clutter_stage_view_get_offscreen_transformation_matrix (data->view, + &transform); + + cogl_framebuffer_push_matrix (onscreen); + cogl_matrix_init_identity (&projection_matrix); + cogl_matrix_translate (&projection_matrix, -1, 1, 0); + cogl_matrix_scale (&projection_matrix, 2, -2, 0); + + cogl_matrix_multiply (&projection_matrix, &projection_matrix, &transform); + cogl_framebuffer_set_projection_matrix (onscreen, &projection_matrix); + + s_1 = sample_x / texture_width; + t_1 = sample_y / texture_height; + s_2 = (sample_x + sample_width) / texture_width; + t_2 = (sample_y + sample_height) / texture_height; + + view_transform = meta_renderer_view_get_transform (renderer_view); + + if (view_transform == logical_monitor->transform) + { + switch (view_transform) + { + case META_MONITOR_TRANSFORM_NORMAL: + case META_MONITOR_TRANSFORM_FLIPPED: + layout_transform = META_MONITOR_TRANSFORM_NORMAL; + break; + case META_MONITOR_TRANSFORM_270: + case META_MONITOR_TRANSFORM_FLIPPED_270: + layout_transform = META_MONITOR_TRANSFORM_90; + break; + case META_MONITOR_TRANSFORM_180: + case META_MONITOR_TRANSFORM_FLIPPED_180: + layout_transform = META_MONITOR_TRANSFORM_180; + break; + case META_MONITOR_TRANSFORM_90: + case META_MONITOR_TRANSFORM_FLIPPED_90: + layout_transform = META_MONITOR_TRANSFORM_270; + break; + } + } + else + { + layout_transform = logical_monitor->transform; + } + + meta_monitor_calculate_crtc_pos (monitor, monitor_mode, output, + layout_transform, + &viewport_x, + &viewport_y); + viewport_x += logical_monitor->rect.x; + viewport_y += logical_monitor->rect.y; + if (meta_monitor_transform_is_rotated (logical_monitor->transform)) + { + viewport_width = monitor_crtc_mode->crtc_mode->height; + viewport_height = monitor_crtc_mode->crtc_mode->width; + } + else + { + viewport_width = monitor_crtc_mode->crtc_mode->width; + viewport_height = monitor_crtc_mode->crtc_mode->height; + } + + scale = clutter_stage_view_get_scale (data->view); + viewport_width = roundf (viewport_width / scale); + viewport_height = roundf (viewport_height / scale); + + cogl_framebuffer_set_viewport (onscreen, + viewport_x, viewport_y, + viewport_width, viewport_height); + + cogl_framebuffer_draw_textured_rectangle (onscreen, + data->stage_nested->pipeline, + 0, 0, 1, 1, + s_1, t_1, s_2, t_2); + + cogl_framebuffer_pop_matrix (onscreen); + return TRUE; +} + +static void +draw_logical_monitor (MetaStageX11Nested *stage_nested, + MetaLogicalMonitor *logical_monitor, + CoglTexture *texture, + ClutterStageView *view, + cairo_rectangle_int_t *view_layout) +{ + MetaMonitor *monitor; + MetaMonitorMode *current_mode; + + cogl_pipeline_set_layer_wrap_mode (stage_nested->pipeline, 0, + COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); + + monitor = meta_logical_monitor_get_monitors (logical_monitor)->data; + current_mode = meta_monitor_get_current_mode (monitor); + meta_monitor_mode_foreach_crtc (monitor, current_mode, + draw_crtc, + &(DrawCrtcData) { + .stage_nested = stage_nested, + .texture = texture, + .view = view, + .logical_monitor = logical_monitor + }, + NULL); +} + +static void +meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window) +{ + MetaStageX11Nested *stage_nested = META_STAGE_X11_NESTED (stage_window); + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_window); + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); + CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen); + GList *l; + + if (!stage_nested->pipeline) + stage_nested->pipeline = cogl_pipeline_new (clutter_backend->cogl_context); + + cogl_framebuffer_clear4f (onscreen, + COGL_BUFFER_BIT_COLOR, + 0.0f, 0.0f, 0.0f, 1.0f); + + for (l = meta_renderer_get_views (renderer); l; l = l->next) + { + ClutterStageView *view = l->data; + MetaRendererView *renderer_view = META_RENDERER_VIEW (view); + MetaLogicalMonitor *logical_monitor; + cairo_rectangle_int_t view_layout; + CoglFramebuffer *framebuffer; + CoglTexture *texture; + + clutter_stage_view_get_layout (view, &view_layout); + + framebuffer = clutter_stage_view_get_onscreen (view); + texture = cogl_offscreen_get_texture (COGL_OFFSCREEN (framebuffer)); + + cogl_pipeline_set_layer_texture (stage_nested->pipeline, 0, texture); + + logical_monitor = meta_renderer_view_get_logical_monitor (renderer_view); + if (logical_monitor) + { + draw_logical_monitor (stage_nested, logical_monitor, texture, view, &view_layout); + } + else + { + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + GList *logical_monitors; + GList *k; + + logical_monitors = + meta_monitor_manager_get_logical_monitors (monitor_manager); + for (k = logical_monitors; k; k = k->next) + { + logical_monitor = k->data; + + draw_logical_monitor (stage_nested, logical_monitor, texture, view, &view_layout); + } + } + } + + cogl_onscreen_swap_buffers (stage_x11->onscreen); +} + +static void +meta_stage_x11_nested_unrealize (ClutterStageWindow *stage_window) +{ + MetaStageX11Nested *stage_nested = META_STAGE_X11_NESTED (stage_window); + ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window); + MetaBackend *backend = meta_get_backend (); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + GList *l; + + /* Clutter still uses part of the deprecated stateful API of Cogl + * (in particulart cogl_set_framebuffer). It means Cogl can keep an + * internal reference to the onscreen object we rendered to. In the + * case of foreign window, we want to avoid this, as we don't know + * what's going to happen to that window. + * + * The following call sets the current Cogl framebuffer to a dummy + * 1x1 one if we're unrealizing the current one, so Cogl doesn't + * keep any reference to the foreign window. + */ + for (l = meta_renderer_get_views (renderer); l ;l = l->next) + { + ClutterStageView *view = l->data; + CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view); + + if (cogl_get_draw_framebuffer () == framebuffer) + { + _clutter_backend_reset_cogl_framebuffer (stage_cogl->backend); + break; + } + } + + g_clear_pointer (&stage_nested->pipeline, cogl_object_unref); + + clutter_stage_window_parent_iface->unrealize (stage_window); +} + +static void +meta_stage_x11_nested_init (MetaStageX11Nested *stage_x11_nested) +{ +} + +static void +meta_stage_x11_nested_class_init (MetaStageX11NestedClass *klass) +{ +} + +static void +clutter_stage_window_iface_init (ClutterStageWindowInterface *iface) +{ + clutter_stage_window_parent_iface = g_type_interface_peek_parent (iface); + + iface->resize = meta_stage_x11_nested_resize; + iface->can_clip_redraws = meta_stage_x11_nested_can_clip_redraws; + iface->unrealize = meta_stage_x11_nested_unrealize; + iface->get_views = meta_stage_x11_nested_get_views; + iface->finish_frame = meta_stage_x11_nested_finish_frame; +} diff --git a/src/backends/x11/nested/meta-stage-x11-nested.h b/src/backends/x11/nested/meta-stage-x11-nested.h new file mode 100644 index 000000000..76678465b --- /dev/null +++ b/src/backends/x11/nested/meta-stage-x11-nested.h @@ -0,0 +1,35 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2016 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: + * Jonas Ådahl + */ + +#ifndef META_STAGE_X11_NESTED_H +#define META_STAGE_X11_NESTED_H + +#include "clutter/clutter-mutter.h" +#include "backends/x11/meta-stage-x11.h" + +#define META_TYPE_STAGE_X11_NESTED (meta_stage_x11_nested_get_type ()) +G_DECLARE_FINAL_TYPE (MetaStageX11Nested, meta_stage_x11_nested, + META, STAGE_X11_NESTED, MetaStageX11) + +#endif /* META_STAGE_X11_NESTED_H */ diff --git a/src/meson.build b/src/meson.build index e5fafc6dc..2aff56146 100644 --- a/src/meson.build +++ b/src/meson.build @@ -264,8 +264,6 @@ mutter_sources = [ 'backends/x11/meta-renderer-x11.h', 'backends/x11/meta-stage-x11.c', 'backends/x11/meta-stage-x11.h', - 'backends/x11/meta-stage-x11-nested.c', - 'backends/x11/meta-stage-x11-nested.h', 'backends/x11/meta-virtual-input-device-x11.c', 'backends/x11/meta-virtual-input-device-x11.h', 'backends/x11/meta-xkb-a11y-x11.c', @@ -274,6 +272,8 @@ mutter_sources = [ 'backends/x11/nested/meta-backend-x11-nested.h', 'backends/x11/nested/meta-cursor-renderer-x11-nested.c', 'backends/x11/nested/meta-cursor-renderer-x11-nested.h', + 'backends/x11/nested/meta-stage-x11-nested.c', + 'backends/x11/nested/meta-stage-x11-nested.h', 'backends/x11/nested/meta-renderer-x11-nested.c', 'backends/x11/nested/meta-renderer-x11-nested.h', 'compositor/clutter-utils.c', -- cgit v1.2.1