renderer-native: Draw stage separately per CRTC

Prior to this commit the stage was drawn separately for each logical
monitor. This allowed to draw different parts of the stage with
different transformations, e.g. with a different viewport to implement
HiDPI support.

Go even further and have one view per CRTC. This causes the stage to
e.g. draw two mirrored monitors twice, instead of using the same
framebuffer on both. This enables us to do two things: one is to support
tiled monitors and monitor mirroring using the EGLStreams backend; the
other is that it'll enable us to tie rendering directly to the CRTC it
will render for. It is also a requirement for rendering being affected
by CRTC state, such as gamma.

It'll be possible to still inhibit re-drawing of the same content
twice, but it should be implemented differently, so that it will still
be possible to implement features requiring the CRTC split.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
This commit is contained in:
Jonas Ådahl 2020-01-17 21:08:02 +01:00
parent e3f30371aa
commit 1c98f01a65
11 changed files with 313 additions and 770 deletions

View File

@ -4476,49 +4476,42 @@ capture_view_into (ClutterStage *stage,
cogl_object_unref (bitmap);
}
static ClutterStageView *
get_view_at_rect (ClutterStage *stage,
cairo_rectangle_int_t *rect)
{
ClutterStagePrivate *priv = stage->priv;
GList *views = _clutter_stage_window_get_views (priv->impl);
GList *l;
for (l = views; l; l = l->next)
{
ClutterStageView *view = l->data;
cairo_rectangle_int_t view_layout;
cairo_region_t *region;
cairo_rectangle_int_t view_capture_rect;
clutter_stage_view_get_layout (view, &view_layout);
region = cairo_region_create_rectangle (&view_layout);
cairo_region_intersect_rectangle (region, rect);
cairo_region_get_extents (region, &view_capture_rect);
cairo_region_destroy (region);
if (view_capture_rect.width == 0 || view_capture_rect.height == 0)
continue;
g_assert (view_capture_rect.width == rect->width &&
view_capture_rect.height == rect->height);
return view;
}
return NULL;
}
void
clutter_stage_capture_into (ClutterStage *stage,
gboolean paint,
cairo_rectangle_int_t *rect,
uint8_t *data)
{
ClutterStageView *view;
ClutterStagePrivate *priv = stage->priv;
GList *l;
int bpp = 4;
int stride;
view = get_view_at_rect (stage, rect);
capture_view_into (stage, paint, view, rect, data, rect->width * bpp);
stride = rect->width * 4;
for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next)
{
ClutterStageView *view = l->data;
cairo_rectangle_int_t view_layout;
cairo_region_t *region;
cairo_rectangle_int_t capture_rect;
int x_offset, y_offset;
clutter_stage_view_get_layout (view, &view_layout);
region = cairo_region_create_rectangle (&view_layout);
cairo_region_intersect_rectangle (region, rect);
cairo_region_get_extents (region, &capture_rect);
cairo_region_destroy (region);
x_offset = capture_rect.x - rect->x;
y_offset = capture_rect.y - rect->y;
capture_view_into (stage, paint, view,
&capture_rect,
data + (x_offset * bpp) + (y_offset * stride),
stride);
}
}
/**

View File

@ -39,7 +39,6 @@ enum
{
PROP_0,
PROP_MONITOR_INFO,
PROP_TRANSFORM,
PROP_LAST
@ -52,18 +51,11 @@ struct _MetaRendererView
ClutterStageViewCogl parent;
MetaMonitorTransform transform;
MetaLogicalMonitor *logical_monitor;
};
G_DEFINE_TYPE (MetaRendererView, meta_renderer_view,
CLUTTER_TYPE_STAGE_VIEW_COGL)
MetaLogicalMonitor *
meta_renderer_view_get_logical_monitor (MetaRendererView *view)
{
return view->logical_monitor;
}
MetaMonitorTransform
meta_renderer_view_get_transform (MetaRendererView *view)
{
@ -146,9 +138,6 @@ meta_renderer_view_get_property (GObject *object,
switch (prop_id)
{
case PROP_MONITOR_INFO:
g_value_set_pointer (value, view->logical_monitor);
break;
case PROP_TRANSFORM:
g_value_set_uint (value, view->transform);
break;
@ -168,9 +157,6 @@ meta_renderer_view_set_property (GObject *object,
switch (prop_id)
{
case PROP_MONITOR_INFO:
view->logical_monitor = g_value_get_pointer (value);
break;
case PROP_TRANSFORM:
meta_renderer_view_set_transform (view, g_value_get_uint (value));
break;
@ -199,13 +185,6 @@ meta_renderer_view_class_init (MetaRendererViewClass *klass)
object_class->get_property = meta_renderer_view_get_property;
object_class->set_property = meta_renderer_view_set_property;
obj_props[PROP_MONITOR_INFO] =
g_param_spec_pointer ("logical-monitor",
"MetaLogicalMonitor",
"The logical monitor of the view",
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY);
obj_props[PROP_TRANSFORM] =
g_param_spec_uint ("transform",
"Transform",

View File

@ -26,8 +26,6 @@ G_DECLARE_FINAL_TYPE (MetaRendererView, meta_renderer_view,
META, RENDERER_VIEW,
ClutterStageViewCogl)
MetaLogicalMonitor *meta_renderer_view_get_logical_monitor (MetaRendererView *view);
MetaMonitorTransform meta_renderer_view_get_transform (MetaRendererView *view);
#endif /* META_RENDERER_VIEW_H */

View File

@ -47,6 +47,7 @@
#include <glib-object.h>
#include "backends/meta-backend-private.h"
#include "backends/meta-logical-monitor.h"
enum
{
@ -93,10 +94,14 @@ meta_renderer_create_cogl_renderer (MetaRenderer *renderer)
static MetaRendererView *
meta_renderer_create_view (MetaRenderer *renderer,
MetaLogicalMonitor *logical_monitor)
MetaLogicalMonitor *logical_monitor,
MetaOutput *output,
MetaCrtc *crtc)
{
return META_RENDERER_GET_CLASS (renderer)->create_view (renderer,
logical_monitor);
logical_monitor,
output,
crtc);
}
/**
@ -114,6 +119,21 @@ meta_renderer_rebuild_views (MetaRenderer *renderer)
return META_RENDERER_GET_CLASS (renderer)->rebuild_views (renderer);
}
static void
create_crtc_view (MetaLogicalMonitor *logical_monitor,
MetaMonitor *monitor,
MetaOutput *output,
MetaCrtc *crtc,
gpointer user_data)
{
MetaRenderer *renderer = user_data;
MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
MetaRendererView *view;
view = meta_renderer_create_view (renderer, logical_monitor, output, crtc);
priv->views = g_list_append (priv->views, view);
}
static void
meta_renderer_real_rebuild_views (MetaRenderer *renderer)
{
@ -132,10 +152,10 @@ meta_renderer_real_rebuild_views (MetaRenderer *renderer)
for (l = logical_monitors; l; l = l->next)
{
MetaLogicalMonitor *logical_monitor = l->data;
MetaRendererView *view;
view = meta_renderer_create_view (renderer, logical_monitor);
priv->views = g_list_append (priv->views, view);
meta_logical_monitor_foreach_crtc (logical_monitor,
create_crtc_view,
renderer);
}
}
@ -168,24 +188,6 @@ meta_renderer_get_views (MetaRenderer *renderer)
return priv->views;
}
MetaRendererView *
meta_renderer_get_view_from_logical_monitor (MetaRenderer *renderer,
MetaLogicalMonitor *logical_monitor)
{
GList *l;
for (l = meta_renderer_get_views (renderer); l; l = l->next)
{
MetaRendererView *view = l->data;
if (meta_renderer_view_get_logical_monitor (view) ==
logical_monitor)
return view;
}
return NULL;
}
gboolean
meta_renderer_is_hardware_accelerated (MetaRenderer *renderer)
{

View File

@ -42,7 +42,9 @@ struct _MetaRendererClass
CoglRenderer * (* create_cogl_renderer) (MetaRenderer *renderer);
MetaRendererView * (* create_view) (MetaRenderer *renderer,
MetaLogicalMonitor *logical_monitor);
MetaLogicalMonitor *logical_monitor,
MetaOutput *output,
MetaCrtc *crtc);
void (* rebuild_views) (MetaRenderer *renderer);
};
@ -58,9 +60,6 @@ void meta_renderer_set_legacy_view (MetaRenderer *renderer,
META_EXPORT_TEST
GList * meta_renderer_get_views (MetaRenderer *renderer);
MetaRendererView * meta_renderer_get_view_from_logical_monitor (MetaRenderer *renderer,
MetaLogicalMonitor *logical_monitor);
gboolean meta_renderer_is_hardware_accelerated (MetaRenderer *renderer);
#endif /* META_RENDERER_H */

View File

@ -42,9 +42,9 @@ struct _MetaScreenCastMonitorStreamSrc
MetaScreenCastStreamSrc parent;
gboolean cursor_bitmap_invalid;
gboolean hw_cursor_inhibited;
MetaStageWatch *paint_watch;
MetaStageWatch *after_paint_watch;
GList *watches;
gulong cursor_moved_handler_id;
gulong cursor_changed_handler_id;
@ -226,9 +226,13 @@ inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
MetaCursorRenderer *cursor_renderer;
MetaHwCursorInhibitor *inhibitor;
g_return_if_fail (!monitor_src->hw_cursor_inhibited);
cursor_renderer = get_cursor_renderer (monitor_src);
inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src);
meta_cursor_renderer_add_hw_cursor_inhibitor (cursor_renderer, inhibitor);
monitor_src->hw_cursor_inhibited = TRUE;
}
static void
@ -237,9 +241,53 @@ uninhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src)
MetaCursorRenderer *cursor_renderer;
MetaHwCursorInhibitor *inhibitor;
g_return_if_fail (monitor_src->hw_cursor_inhibited);
cursor_renderer = get_cursor_renderer (monitor_src);
inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src);
meta_cursor_renderer_remove_hw_cursor_inhibitor (cursor_renderer, inhibitor);
monitor_src->hw_cursor_inhibited = FALSE;
}
static void
add_view_painted_watches (MetaScreenCastMonitorStreamSrc *monitor_src,
MetaStageWatchPhase watch_phase)
{
MetaBackend *backend = get_backend (monitor_src);
MetaRenderer *renderer = meta_backend_get_renderer (backend);
ClutterStage *stage;
MetaStage *meta_stage;
MetaMonitor *monitor;
MetaLogicalMonitor *logical_monitor;
MetaRectangle logical_monitor_layout;
GList *l;
stage = get_stage (monitor_src);
meta_stage = META_STAGE (stage);
monitor = get_monitor (monitor_src);
logical_monitor = meta_monitor_get_logical_monitor (monitor);
logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor);
for (l = meta_renderer_get_views (renderer); l; l = l->next)
{
MetaRendererView *view = l->data;
MetaRectangle view_layout;
clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout);
if (meta_rectangle_overlap (&logical_monitor_layout, &view_layout))
{
MetaStageWatch *watch;
watch = meta_stage_watch_view (meta_stage,
CLUTTER_STAGE_VIEW (view),
watch_phase,
stage_painted,
monitor_src);
monitor_src->watches = g_list_prepend (monitor_src->watches, watch);
}
}
}
static void
@ -248,28 +296,12 @@ meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src)
MetaScreenCastMonitorStreamSrc *monitor_src =
META_SCREEN_CAST_MONITOR_STREAM_SRC (src);
MetaBackend *backend = get_backend (monitor_src);
MetaRenderer *renderer = meta_backend_get_renderer (backend);
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
MetaRendererView *view;
MetaMonitor *monitor;
MetaLogicalMonitor *logical_monitor;
MetaStage *meta_stage;
ClutterStageView *stage_view;
ClutterStage *stage;
MetaScreenCastStream *stream;
stream = meta_screen_cast_stream_src_get_stream (src);
stage = get_stage (monitor_src);
meta_stage = META_STAGE (stage);
monitor = get_monitor (monitor_src);
logical_monitor = meta_monitor_get_logical_monitor (monitor);
view = meta_renderer_get_view_from_logical_monitor (renderer,
logical_monitor);
if (view)
stage_view = CLUTTER_STAGE_VIEW (view);
else
stage_view = NULL;
switch (meta_screen_cast_stream_get_cursor_mode (stream))
{
@ -284,21 +316,13 @@ meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src)
monitor_src);
G_GNUC_FALLTHROUGH;
case META_SCREEN_CAST_CURSOR_MODE_HIDDEN:
monitor_src->paint_watch =
meta_stage_watch_view (meta_stage,
stage_view,
META_STAGE_WATCH_AFTER_ACTOR_PAINT,
stage_painted,
monitor_src);
add_view_painted_watches (monitor_src,
META_STAGE_WATCH_AFTER_ACTOR_PAINT);
break;
case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED:
inhibit_hw_cursor (monitor_src);
monitor_src->after_paint_watch =
meta_stage_watch_view (meta_stage,
stage_view,
META_STAGE_WATCH_AFTER_PAINT,
stage_painted,
monitor_src);
add_view_painted_watches (monitor_src,
META_STAGE_WATCH_AFTER_PAINT);
break;
}
@ -314,22 +338,21 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src)
MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
ClutterStage *stage;
MetaStage *meta_stage;
GList *l;
stage = get_stage (monitor_src);
meta_stage = META_STAGE (stage);
if (monitor_src->paint_watch)
for (l = monitor_src->watches; l; l = l->next)
{
meta_stage_remove_watch (meta_stage, monitor_src->paint_watch);
monitor_src->paint_watch = NULL;
}
MetaStageWatch *watch = l->data;
if (monitor_src->after_paint_watch)
{
meta_stage_remove_watch (meta_stage, monitor_src->after_paint_watch);
monitor_src->after_paint_watch = NULL;
uninhibit_hw_cursor (monitor_src);
meta_stage_remove_watch (meta_stage, watch);
}
g_clear_pointer (&monitor_src->watches, g_list_free);
if (monitor_src->hw_cursor_inhibited)
uninhibit_hw_cursor (monitor_src);
g_clear_signal_handler (&monitor_src->cursor_moved_handler_id,
cursor_tracker);
@ -367,13 +390,11 @@ meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc
MetaBackend *backend = get_backend (monitor_src);
MetaCursorRenderer *cursor_renderer =
meta_backend_get_cursor_renderer (backend);
MetaRenderer *renderer = meta_backend_get_renderer (backend);
MetaCursorSprite *cursor_sprite;
MetaMonitor *monitor;
MetaLogicalMonitor *logical_monitor;
MetaRectangle logical_monitor_layout;
graphene_rect_t logical_monitor_rect;
MetaRendererView *view;
float view_scale;
graphene_point_t cursor_position;
int x, y;
@ -393,10 +414,8 @@ meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc
logical_monitor_rect =
meta_rectangle_to_graphene_rect (&logical_monitor_layout);
view = meta_renderer_get_view_from_logical_monitor (renderer,
logical_monitor);
if (view)
view_scale = clutter_stage_view_get_scale (CLUTTER_STAGE_VIEW (view));
if (meta_is_stage_views_scaled ())
view_scale = meta_logical_monitor_get_scale (logical_monitor);
else
view_scale = 1.0;

View File

@ -76,14 +76,10 @@ meta_crtc_kms_apply_transform (MetaCrtc *crtc,
void
meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
MetaMonitor *monitor,
MetaOutput *output,
uint32_t fb_id,
MetaKmsUpdate *kms_update)
{
MetaMonitorMode *monitor_mode;
MetaCrtcConfig *crtc_config;
int crtc_x, crtc_y;
MetaFixed16Rectangle src_rect;
MetaFixed16Rectangle dst_rect;
MetaKmsAssignPlaneFlag flags;
@ -94,17 +90,10 @@ meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
crtc_config = crtc->config;
monitor_mode = meta_monitor_get_current_mode (monitor);
meta_monitor_calculate_crtc_pos (monitor,
monitor_mode,
output,
crtc_config->transform,
&crtc_x,
&crtc_y);
src_rect = (MetaFixed16Rectangle) {
.x = meta_fixed_16_from_int (crtc_x),
.y = meta_fixed_16_from_int (crtc_y),
.x = meta_fixed_16_from_int (0),
.y = meta_fixed_16_from_int (0),
.width = meta_fixed_16_from_int (crtc_config->mode->width),
.height = meta_fixed_16_from_int (crtc_config->mode->height),
};

View File

@ -38,8 +38,6 @@ void meta_crtc_kms_apply_transform (MetaCrtc *crtc,
MetaKmsPlaneAssignment *kms_plane_assignment);
void meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
MetaMonitor *monitor,
MetaOutput *output,
uint32_t fb_id,
MetaKmsUpdate *kms_update);

File diff suppressed because it is too large Load Diff

View File

@ -172,7 +172,9 @@ meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11
static MetaRendererView *
meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
MetaLogicalMonitor *logical_monitor)
MetaLogicalMonitor *logical_monitor,
MetaOutput *output,
MetaCrtc *crtc)
{
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
@ -184,6 +186,8 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
int width, height;
CoglOffscreen *fake_onscreen;
CoglOffscreen *offscreen;
MetaRectangle view_layout;
MetaRendererView *view;
view_transform = calculate_view_transform (monitor_manager, logical_monitor);
@ -192,18 +196,8 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
else
view_scale = 1.0;
if (meta_monitor_transform_is_rotated (view_transform))
{
width = logical_monitor->rect.height;
height = logical_monitor->rect.width;
}
else
{
width = logical_monitor->rect.width;
height = logical_monitor->rect.height;
}
width = roundf (width * view_scale);
height = roundf (height * view_scale);
width = roundf (crtc->config->layout.size.width * view_scale);
height = roundf (crtc->config->layout.size.height * view_scale);
fake_onscreen = create_offscreen (cogl_context, width, height);
@ -212,14 +206,20 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
else
offscreen = NULL;
return g_object_new (META_TYPE_RENDERER_VIEW,
"layout", &logical_monitor->rect,
meta_rectangle_from_graphene_rect (&crtc->config->layout,
META_ROUNDING_STRATEGY_ROUND,
&view_layout);
view = g_object_new (META_TYPE_RENDERER_VIEW,
"layout", &view_layout,
"framebuffer", COGL_FRAMEBUFFER (fake_onscreen),
"offscreen", COGL_FRAMEBUFFER (offscreen),
"transform", view_transform,
"scale", view_scale,
"logical-monitor", logical_monitor,
NULL);
g_object_set_data (G_OBJECT (view), "crtc", crtc);
return view;
}
static void

View File

@ -101,46 +101,33 @@ typedef struct
} DrawCrtcData;
static gboolean
draw_crtc (MetaMonitor *monitor,
MetaMonitorMode *monitor_mode,
MetaMonitorCrtcMode *monitor_crtc_mode,
gpointer user_data,
GError **error)
draw_view (MetaStageX11Nested *stage_nested,
MetaRendererView *renderer_view,
CoglTexture *texture)
{
DrawCrtcData *data = user_data;
MetaStageX11 *stage_x11 = META_STAGE_X11 (data->stage_nested);
MetaStageX11 *stage_x11 = META_STAGE_X11 (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;
ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (renderer_view);
MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
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);
crtc = g_object_get_data (G_OBJECT (renderer_view), "crtc");
crtc_config = crtc->config;
clutter_stage_view_get_layout (data->view, &view_layout);
sample_x = (int) roundf (crtc_config->layout.origin.x) - view_layout.x;
sample_y = (int) roundf (crtc_config->layout.origin.y) - view_layout.y;
sample_width = (int) roundf (crtc_config->layout.size.width);
sample_height = (int) roundf (crtc_config->layout.size.height);
sample_x = 0;
sample_y = 0;
sample_width = texture_width;
sample_height = texture_height;
clutter_stage_view_get_offscreen_transformation_matrix (data->view,
clutter_stage_view_get_offscreen_transformation_matrix (stage_view,
&transform);
cogl_framebuffer_push_matrix (onscreen);
@ -156,62 +143,14 @@ draw_crtc (MetaMonitor *monitor,
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);
crtc_config->layout.origin.x,
crtc_config->layout.origin.y,
crtc_config->layout.size.width,
crtc_config->layout.size.height);
cogl_framebuffer_draw_textured_rectangle (onscreen,
data->stage_nested->pipeline,
stage_nested->pipeline,
0, 0, 1, 1,
s_1, t_1, s_2, t_2);
@ -219,32 +158,6 @@ draw_crtc (MetaMonitor *monitor,
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)
{
@ -267,39 +180,17 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window)
{
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);
cogl_pipeline_set_layer_wrap_mode (stage_nested->pipeline, 0,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
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);
}
}
draw_view (stage_nested, renderer_view, texture);
}
cogl_onscreen_swap_buffers (stage_x11->onscreen);