mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00:00
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:
parent
e3f30371aa
commit
1c98f01a65
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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",
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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),
|
||||
};
|
||||
|
@ -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
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user