mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
backends/x11/nested: Emulate per CRTC drawing
Make the nested backend emulate how the real backends actually draw, i.e. by drawing each CRTC separately. This makes it possible to test different configuration paths that can take place on different hardware, without having said hardware. For example, by setting MUTTER_DEBUG_TILED_DUMMY_MONITORS and MUTTER_DEBUG_NESTED_OFFSCREEN_TRANSFORM to "1", one can test a system with MST (tiled) monitors where the GPU doesn't support some transform. https://bugzilla.gnome.org/show_bug.cgi?id=777732
This commit is contained in:
parent
0ac2eba4d3
commit
9787b1cfd5
@ -27,6 +27,8 @@
|
||||
#include "backends/x11/meta-stage-x11-nested.h"
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "backends/meta-monitor.h"
|
||||
#include "backends/meta-renderer.h"
|
||||
#include "backends/x11/nested/meta-renderer-x11-nested.h"
|
||||
#include "clutter/clutter-mutter.h"
|
||||
@ -88,6 +90,149 @@ meta_stage_x11_nested_get_views (ClutterStageWindow *stage_window)
|
||||
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;
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_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 = output->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;
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -109,29 +254,40 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window)
|
||||
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;
|
||||
CoglMatrix matrix;
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
framebuffer = clutter_stage_view_get_onscreen (view);
|
||||
texture = cogl_offscreen_get_texture (COGL_OFFSCREEN (framebuffer));
|
||||
|
||||
clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
|
||||
cogl_matrix_get_inverse (&matrix, &matrix);
|
||||
cogl_pipeline_set_layer_matrix (stage_nested->pipeline, 0, &matrix);
|
||||
|
||||
cogl_framebuffer_set_viewport (onscreen,
|
||||
view_layout.x,
|
||||
view_layout.y,
|
||||
view_layout.width,
|
||||
view_layout.height);
|
||||
cogl_pipeline_set_layer_texture (stage_nested->pipeline, 0, texture);
|
||||
cogl_framebuffer_draw_rectangle (onscreen,
|
||||
stage_nested->pipeline,
|
||||
-1, 1, 1, -1);
|
||||
|
||||
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);
|
||||
|
@ -211,6 +211,7 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer,
|
||||
"offscreen", COGL_FRAMEBUFFER (offscreen),
|
||||
"transform", view_transform,
|
||||
"scale", view_scale,
|
||||
"logical-monitor", logical_monitor,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user