crtc: Move configured state to separate struct

To make it more reliable to distinguish between values that are read
from the backend implementation (which is likely to be irrelevant for
anything but the backend implementation), split out those values (e.g.
layout).

This changes the meaning of what was MetaCrtc::rect, to a
MetaCrtcConfig::layout which is the layout the CRTC has in the global
coordinate space.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
This commit is contained in:
Jonas Ådahl 2020-01-14 22:34:44 +01:00
parent a11f9bd513
commit fe42d56db3
20 changed files with 370 additions and 350 deletions

View File

@ -31,6 +31,30 @@ meta_crtc_get_gpu (MetaCrtc *crtc)
return crtc->gpu; return crtc->gpu;
} }
void
meta_crtc_set_config (MetaCrtc *crtc,
graphene_rect_t *layout,
MetaCrtcMode *mode,
MetaMonitorTransform transform)
{
MetaCrtcConfig *config;
meta_crtc_unset_config (crtc);
config = g_new0 (MetaCrtcConfig, 1);
config->layout = *layout;
config->mode = mode;
config->transform = transform;
crtc->config = config;
}
void
meta_crtc_unset_config (MetaCrtc *crtc)
{
g_clear_pointer (&crtc->config, g_free);
}
static void static void
meta_crtc_finalize (GObject *object) meta_crtc_finalize (GObject *object)
{ {

View File

@ -49,6 +49,13 @@ typedef enum _MetaCrtcModeFlag
META_CRTC_MODE_FLAG_MASK = 0x3fff META_CRTC_MODE_FLAG_MASK = 0x3fff
} MetaCrtcModeFlag; } MetaCrtcModeFlag;
typedef struct _MetaCrtcConfig
{
graphene_rect_t layout;
MetaMonitorTransform transform;
MetaCrtcMode *mode;
} MetaCrtcConfig;
struct _MetaCrtc struct _MetaCrtc
{ {
GObject parent; GObject parent;
@ -56,12 +63,10 @@ struct _MetaCrtc
MetaGpu *gpu; MetaGpu *gpu;
glong crtc_id; glong crtc_id;
MetaRectangle rect;
MetaCrtcMode *current_mode;
MetaMonitorTransform transform;
unsigned int all_transforms; unsigned int all_transforms;
MetaLogicalMonitor *logical_monitor; MetaLogicalMonitor *logical_monitor;
MetaCrtcConfig *config;
/* Used when changing configuration */ /* Used when changing configuration */
gboolean is_dirty; gboolean is_dirty;
@ -98,4 +103,13 @@ META_EXPORT_TEST G_DECLARE_FINAL_TYPE (MetaCrtcMode, meta_crtc_mode, META, CRTC_
MetaGpu * meta_crtc_get_gpu (MetaCrtc *crtc); MetaGpu * meta_crtc_get_gpu (MetaCrtc *crtc);
META_EXPORT_TEST
void meta_crtc_set_config (MetaCrtc *crtc,
graphene_rect_t *layout,
MetaCrtcMode *mode,
MetaMonitorTransform transform);
META_EXPORT_TEST
void meta_crtc_unset_config (MetaCrtc *crtc);
#endif /* META_CRTC_H */ #endif /* META_CRTC_H */

View File

@ -122,7 +122,7 @@ derive_monitor_transform (MetaMonitor *monitor)
MetaMonitorTransform transform; MetaMonitorTransform transform;
main_output = meta_monitor_get_main_output (monitor); main_output = meta_monitor_get_main_output (monitor);
transform = meta_output_get_assigned_crtc (main_output)->transform; transform = meta_output_get_assigned_crtc (main_output)->config->transform;
return meta_monitor_crtc_to_logical_transform (monitor, transform); return meta_monitor_crtc_to_logical_transform (monitor, transform);
} }

View File

@ -172,6 +172,11 @@ assign_monitor_crtc (MetaMonitor *monitor,
MetaMonitorTransform transform; MetaMonitorTransform transform;
MetaMonitorTransform crtc_transform; MetaMonitorTransform crtc_transform;
int crtc_x, crtc_y; int crtc_x, crtc_y;
float x_offset, y_offset;
float scale;
float width, height;
MetaCrtcMode *crtc_mode;
graphene_rect_t crtc_layout;
MetaCrtcInfo *crtc_info; MetaCrtcInfo *crtc_info;
MetaOutputInfo *output_info; MetaOutputInfo *output_info;
MetaMonitorConfig *first_monitor_config; MetaMonitorConfig *first_monitor_config;
@ -202,29 +207,37 @@ assign_monitor_crtc (MetaMonitor *monitor,
meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform, meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform,
&crtc_x, &crtc_y); &crtc_x, &crtc_y);
x_offset = data->logical_monitor_config->layout.x;
y_offset = data->logical_monitor_config->layout.y;
scale = data->logical_monitor_config->scale;
crtc_mode = monitor_crtc_mode->crtc_mode;
if (meta_monitor_transform_is_rotated (crtc_transform))
{
width = crtc_mode->height / scale;
height = crtc_mode->width / scale;
}
else
{
width = crtc_mode->width / scale;
height = crtc_mode->height / scale;
}
crtc_layout = GRAPHENE_RECT_INIT (x_offset + (crtc_x / scale),
y_offset + (crtc_y / scale),
width,
height);
crtc_info = g_slice_new0 (MetaCrtcInfo); crtc_info = g_slice_new0 (MetaCrtcInfo);
*crtc_info = (MetaCrtcInfo) { *crtc_info = (MetaCrtcInfo) {
.crtc = crtc, .crtc = crtc,
.mode = monitor_crtc_mode->crtc_mode, .mode = crtc_mode,
.x = crtc_x, .layout = crtc_layout,
.y = crtc_y,
.transform = crtc_transform, .transform = crtc_transform,
.outputs = g_ptr_array_new () .outputs = g_ptr_array_new ()
}; };
g_ptr_array_add (crtc_info->outputs, output); g_ptr_array_add (crtc_info->outputs, output);
/*
* Currently, MetaCrtcInfo are deliberately offset incorrectly to carry over
* logical monitor location inside the MetaCrtc struct, when in fact this
* depends on the framebuffer configuration. This will eventually be negated
* when setting the actual KMS mode.
*
* TODO: Remove this hack when we don't need to rely on MetaCrtc to pass
* logical monitor state.
*/
crtc_info->x += data->logical_monitor_config->layout.x;
crtc_info->y += data->logical_monitor_config->layout.y;
/* /*
* Only one output can be marked as primary (due to Xrandr limitation), * Only one output can be marked as primary (due to Xrandr limitation),
* so only mark the main output of the first monitor in the logical monitor * so only mark the main output of the first monitor in the logical monitor

View File

@ -512,38 +512,17 @@ apply_crtc_assignments (MetaMonitorManager *manager,
if (crtc_info->mode == NULL) if (crtc_info->mode == NULL)
{ {
crtc->rect.x = 0; meta_crtc_unset_config (crtc);
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
} }
else else
{ {
MetaCrtcMode *mode;
MetaOutput *output; MetaOutput *output;
unsigned int j; unsigned int j;
int width, height;
mode = crtc_info->mode; meta_crtc_set_config (crtc,
&crtc_info->layout,
if (meta_monitor_transform_is_rotated (crtc_info->transform)) crtc_info->mode,
{ crtc_info->transform);
width = mode->height;
height = mode->width;
}
else
{
width = mode->width;
height = mode->height;
}
crtc->rect.x = crtc_info->x;
crtc->rect.y = crtc_info->y;
crtc->rect.width = width;
crtc->rect.height = height;
crtc->current_mode = mode;
crtc->transform = crtc_info->transform;
for (j = 0; j < crtc_info->outputs->len; j++) for (j = 0; j < crtc_info->outputs->len; j++)
{ {
@ -577,11 +556,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue; continue;
} }
crtc->rect.x = 0; meta_crtc_unset_config (crtc);
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
} }
/* Disable outputs not mentioned in the list */ /* Disable outputs not mentioned in the list */

View File

@ -24,6 +24,7 @@
#define META_MONITOR_MANAGER_PRIVATE_H #define META_MONITOR_MANAGER_PRIVATE_H
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <graphene.h>
#include <libgnome-desktop/gnome-pnp-ids.h> #include <libgnome-desktop/gnome-pnp-ids.h>
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
@ -72,8 +73,7 @@ struct _MetaCrtcInfo
{ {
MetaCrtc *crtc; MetaCrtc *crtc;
MetaCrtcMode *mode; MetaCrtcMode *mode;
int x; graphene_rect_t layout;
int y;
MetaMonitorTransform transform; MetaMonitorTransform transform;
GPtrArray *outputs; GPtrArray *outputs;
}; };

View File

@ -1014,28 +1014,46 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
{ {
MetaCrtc *crtc = l->data; MetaCrtc *crtc = l->data;
GVariantBuilder transforms; GVariantBuilder transforms;
int current_mode_index; MetaCrtcConfig *crtc_config;
g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au")); g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++) for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
if (crtc->all_transforms & (1 << j)) if (crtc->all_transforms & (1 << j))
g_variant_builder_add (&transforms, "u", j); g_variant_builder_add (&transforms, "u", j);
if (crtc->current_mode) crtc_config = crtc->config;
current_mode_index = g_list_index (combined_modes, crtc->current_mode);
if (crtc_config)
{
int current_mode_index;
current_mode_index = g_list_index (combined_modes, crtc_config->mode);
g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
i, /* ID */
(int64_t) crtc->crtc_id,
(int) roundf (crtc_config->layout.origin.x),
(int) roundf (crtc_config->layout.origin.y),
(int) roundf (crtc_config->layout.size.width),
(int) roundf (crtc_config->layout.size.height),
current_mode_index,
(uint32_t) crtc_config->transform,
&transforms,
NULL /* properties */);
}
else else
current_mode_index = -1; {
g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})", g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
i, /* ID */ i, /* ID */
(gint64)crtc->crtc_id, (int64_t) crtc->crtc_id,
(int)crtc->rect.x, 0,
(int)crtc->rect.y, 0,
(int)crtc->rect.width, 0,
(int)crtc->rect.height, 0,
current_mode_index, -1,
(guint32)crtc->transform, (uint32_t) META_MONITOR_TRANSFORM_NORMAL,
&transforms, &transforms,
NULL /* properties */); NULL /* properties */);
}
} }
for (l = combined_outputs, i = 0; l; l = l->next, i++) for (l = combined_outputs, i = 0; l; l = l->next, i++)

View File

@ -29,6 +29,7 @@
#include "backends/meta-monitor-manager-private.h" #include "backends/meta-monitor-manager-private.h"
#include "backends/meta-settings-private.h" #include "backends/meta-settings-private.h"
#include "backends/meta-output.h" #include "backends/meta-output.h"
#include "core/boxes-private.h"
#define SCALE_FACTORS_PER_INTEGER 4 #define SCALE_FACTORS_PER_INTEGER 4
#define SCALE_FACTORS_STEPS (1.0 / (float) SCALE_FACTORS_PER_INTEGER) #define SCALE_FACTORS_STEPS (1.0 / (float) SCALE_FACTORS_PER_INTEGER)
@ -636,7 +637,7 @@ meta_monitor_normal_generate_modes (MetaMonitorNormal *monitor_normal)
monitor_priv->preferred_mode = mode; monitor_priv->preferred_mode = mode;
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
if (crtc && crtc_mode == crtc->current_mode) if (crtc && crtc->config && crtc_mode == crtc->config->mode)
monitor_priv->current_mode = mode; monitor_priv->current_mode = mode;
} }
} }
@ -683,10 +684,17 @@ meta_monitor_normal_derive_layout (MetaMonitor *monitor,
{ {
MetaOutput *output; MetaOutput *output;
MetaCrtc *crtc; MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
output = meta_monitor_get_main_output (monitor); output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
*layout = crtc->rect; crtc_config = crtc->config;
g_return_if_fail (crtc_config);
meta_rectangle_from_graphene_rect (&crtc_config->layout,
META_ROUNDING_STRATEGY_ROUND,
layout);
} }
static gboolean static gboolean
@ -880,7 +888,8 @@ is_monitor_mode_assigned (MetaMonitor *monitor,
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
if (monitor_crtc_mode->crtc_mode && if (monitor_crtc_mode->crtc_mode &&
(!crtc || crtc->current_mode != monitor_crtc_mode->crtc_mode)) (!crtc || !crtc->config ||
crtc->config->mode != monitor_crtc_mode->crtc_mode))
return FALSE; return FALSE;
else if (!monitor_crtc_mode->crtc_mode && crtc) else if (!monitor_crtc_mode->crtc_mode && crtc)
return FALSE; return FALSE;
@ -1324,32 +1333,39 @@ meta_monitor_tiled_derive_layout (MetaMonitor *monitor,
MetaMonitorPrivate *monitor_priv = MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor); meta_monitor_get_instance_private (monitor);
GList *l; GList *l;
int min_x, min_y, max_x, max_y; float min_x, min_y, max_x, max_y;
min_x = INT_MAX; min_x = FLT_MAX;
min_y = INT_MAX; min_y = FLT_MAX;
max_x = 0; max_x = 0.0;
max_y = 0; max_y = 0.0;
for (l = monitor_priv->outputs; l; l = l->next) for (l = monitor_priv->outputs; l; l = l->next)
{ {
MetaOutput *output = l->data; MetaOutput *output = l->data;
MetaCrtc *crtc; MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
graphene_rect_t *crtc_layout;
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
if (!crtc) if (!crtc)
continue; continue;
min_x = MIN (crtc->rect.x, min_x); crtc_config = crtc->config;
min_y = MIN (crtc->rect.y, min_y); g_return_if_fail (crtc_config);
max_x = MAX (crtc->rect.x + crtc->rect.width, max_x);
max_y = MAX (crtc->rect.y + crtc->rect.height, max_y); crtc_layout = &crtc_config->layout;
min_x = MIN (crtc_layout->origin.x, min_x);
min_y = MIN (crtc_layout->origin.y, min_y);
max_x = MAX (crtc_layout->origin.x + crtc_layout->size.width, max_x);
max_y = MAX (crtc_layout->origin.y + crtc_layout->size.height, max_y);
} }
*layout = (MetaRectangle) { *layout = (MetaRectangle) {
.x = min_x, .x = roundf (min_x),
.y = min_y, .y = roundf (min_y),
.width = max_x - min_x, .width = roundf (max_x - min_x),
.height = max_y - min_y .height = roundf (max_y - min_y)
}; };
} }
@ -1508,7 +1524,7 @@ is_current_mode_known (MetaMonitor *monitor)
output = meta_monitor_get_main_output (monitor); output = meta_monitor_get_main_output (monitor);
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
return meta_monitor_is_active (monitor) == (crtc && crtc->current_mode); return meta_monitor_is_active (monitor) == (crtc && crtc->config);
} }
void void

View File

@ -63,7 +63,7 @@ meta_crtc_kms_apply_transform (MetaCrtc *crtc,
MetaCrtcKms *crtc_kms = crtc->driver_private; MetaCrtcKms *crtc_kms = crtc->driver_private;
MetaMonitorTransform hw_transform; MetaMonitorTransform hw_transform;
hw_transform = crtc->transform; hw_transform = crtc->config->transform;
if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform)) if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform))
hw_transform = META_MONITOR_TRANSFORM_NORMAL; hw_transform = META_MONITOR_TRANSFORM_NORMAL;
if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform)) if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform))
@ -76,11 +76,14 @@ meta_crtc_kms_apply_transform (MetaCrtc *crtc,
void void
meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc, meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
MetaMonitor *monitor,
MetaOutput *output,
uint32_t fb_id, uint32_t fb_id,
MetaKmsUpdate *kms_update) MetaKmsUpdate *kms_update)
{ {
MetaRectangle logical_monitor_rect; MetaMonitorMode *monitor_mode;
int x, y; MetaCrtcConfig *crtc_config;
int crtc_x, crtc_y;
MetaFixed16Rectangle src_rect; MetaFixed16Rectangle src_rect;
MetaFixed16Rectangle dst_rect; MetaFixed16Rectangle dst_rect;
MetaKmsAssignPlaneFlag flags; MetaKmsAssignPlaneFlag flags;
@ -89,21 +92,27 @@ meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
MetaKmsPlane *primary_kms_plane; MetaKmsPlane *primary_kms_plane;
MetaKmsPlaneAssignment *plane_assignment; MetaKmsPlaneAssignment *plane_assignment;
logical_monitor_rect = crtc_config = crtc->config;
meta_logical_monitor_get_layout (crtc->logical_monitor);
x = crtc->rect.x - logical_monitor_rect.x; monitor_mode = meta_monitor_get_current_mode (monitor);
y = crtc->rect.y - logical_monitor_rect.y; meta_monitor_calculate_crtc_pos (monitor,
monitor_mode,
output,
crtc_config->transform,
&crtc_x,
&crtc_y);
src_rect = (MetaFixed16Rectangle) { src_rect = (MetaFixed16Rectangle) {
.x = meta_fixed_16_from_int (x), .x = meta_fixed_16_from_int (crtc_x),
.y = meta_fixed_16_from_int (y), .y = meta_fixed_16_from_int (crtc_y),
.width = meta_fixed_16_from_int (crtc->rect.width), .width = meta_fixed_16_from_int (crtc_config->mode->width),
.height = meta_fixed_16_from_int (crtc->rect.height), .height = meta_fixed_16_from_int (crtc_config->mode->height),
}; };
dst_rect = (MetaFixed16Rectangle) { dst_rect = (MetaFixed16Rectangle) {
.x = meta_fixed_16_from_int (0), .x = meta_fixed_16_from_int (0),
.y = meta_fixed_16_from_int (0), .y = meta_fixed_16_from_int (0),
.width = meta_fixed_16_from_int (crtc->rect.width), .width = meta_fixed_16_from_int (crtc_config->mode->width),
.height = meta_fixed_16_from_int (crtc->rect.height), .height = meta_fixed_16_from_int (crtc_config->mode->height),
}; };
flags = META_KMS_ASSIGN_PLANE_FLAG_NONE; flags = META_KMS_ASSIGN_PLANE_FLAG_NONE;
@ -151,6 +160,7 @@ void
meta_crtc_kms_set_mode (MetaCrtc *crtc, meta_crtc_kms_set_mode (MetaCrtc *crtc,
MetaKmsUpdate *kms_update) MetaKmsUpdate *kms_update)
{ {
MetaCrtcConfig *crtc_config = crtc->config;
MetaGpu *gpu = meta_crtc_get_gpu (crtc); MetaGpu *gpu = meta_crtc_get_gpu (crtc);
GList *connectors; GList *connectors;
drmModeModeInfo *mode; drmModeModeInfo *mode;
@ -159,7 +169,7 @@ meta_crtc_kms_set_mode (MetaCrtc *crtc,
if (connectors) if (connectors)
{ {
mode = crtc->current_mode->driver_private; mode = crtc_config->mode->driver_private;
g_debug ("Setting CRTC (%ld) mode to %s", crtc->crtc_id, mode->name); g_debug ("Setting CRTC (%ld) mode to %s", crtc->crtc_id, mode->name);
} }
@ -274,37 +284,16 @@ meta_create_kms_crtc (MetaGpuKms *gpu_kms,
MetaCrtc *crtc; MetaCrtc *crtc;
MetaCrtcKms *crtc_kms; MetaCrtcKms *crtc_kms;
MetaKmsPlane *primary_plane; MetaKmsPlane *primary_plane;
const MetaKmsCrtcState *crtc_state;
kms_device = meta_gpu_kms_get_kms_device (gpu_kms); kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
primary_plane = meta_kms_device_get_primary_plane_for (kms_device, primary_plane = meta_kms_device_get_primary_plane_for (kms_device,
kms_crtc); kms_crtc);
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
crtc = g_object_new (META_TYPE_CRTC, NULL); crtc = g_object_new (META_TYPE_CRTC, NULL);
crtc->gpu = gpu; crtc->gpu = gpu;
crtc->crtc_id = meta_kms_crtc_get_id (kms_crtc); crtc->crtc_id = meta_kms_crtc_get_id (kms_crtc);
crtc->rect = crtc_state->rect;
crtc->is_dirty = FALSE; crtc->is_dirty = FALSE;
crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
crtc->all_transforms = ALL_TRANSFORMS_MASK; crtc->all_transforms = ALL_TRANSFORMS_MASK;
if (crtc_state->is_drm_mode_valid)
{
GList *l;
for (l = meta_gpu_get_modes (gpu); l; l = l->next)
{
MetaCrtcMode *mode = l->data;
if (meta_drm_mode_equal (&crtc_state->drm_mode, mode->driver_private))
{
crtc->current_mode = mode;
break;
}
}
}
crtc_kms = g_new0 (MetaCrtcKms, 1); crtc_kms = g_new0 (MetaCrtcKms, 1);
crtc_kms->kms_crtc = kms_crtc; crtc_kms->kms_crtc = kms_crtc;
crtc_kms->primary_plane = primary_plane; crtc_kms->primary_plane = primary_plane;

View File

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

View File

@ -189,37 +189,16 @@ apply_crtc_assignments (MetaMonitorManager *manager,
if (crtc_info->mode == NULL) if (crtc_info->mode == NULL)
{ {
crtc->rect.x = 0; meta_crtc_unset_config (crtc);
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
} }
else else
{ {
MetaCrtcMode *mode;
unsigned int j; unsigned int j;
int width, height;
mode = crtc_info->mode; meta_crtc_set_config (crtc,
&crtc_info->layout,
if (meta_monitor_transform_is_rotated (crtc_info->transform)) crtc_info->mode,
{ crtc_info->transform);
width = mode->height;
height = mode->width;
}
else
{
width = mode->width;
height = mode->height;
}
crtc->rect.x = crtc_info->x;
crtc->rect.y = crtc_info->y;
crtc->rect.width = width;
crtc->rect.height = height;
crtc->current_mode = mode;
crtc->transform = crtc_info->transform;
for (j = 0; j < crtc_info->outputs->len; j++) for (j = 0; j < crtc_info->outputs->len; j++)
{ {
@ -250,11 +229,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue; continue;
} }
crtc->rect.x = 0; meta_crtc_unset_config (crtc);
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
} }
} }

View File

@ -64,11 +64,13 @@ meta_output_kms_set_underscan (MetaOutput *output,
if (output->is_underscanning) if (output->is_underscanning)
{ {
MetaCrtc *crtc; MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
uint64_t hborder, vborder; uint64_t hborder, vborder;
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
hborder = MIN (128, (uint64_t) round (crtc->current_mode->width * 0.05)); crtc_config = crtc->config;
vborder = MIN (128, (uint64_t) round (crtc->current_mode->height * 0.05)); hborder = MIN (128, (uint64_t) round (crtc_config->mode->width * 0.05));
vborder = MIN (128, (uint64_t) round (crtc_config->mode->height * 0.05));
g_debug ("Setting underscan of connector %s to %" G_GUINT64_FORMAT " x %" G_GUINT64_FORMAT, g_debug ("Setting underscan of connector %s to %" G_GUINT64_FORMAT " x %" G_GUINT64_FORMAT,
meta_kms_connector_get_name (output_kms->kms_connector), meta_kms_connector_get_name (output_kms->kms_connector),

View File

@ -1342,8 +1342,8 @@ notify_view_crtc_presented (MetaRendererView *view,
frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos); frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
crtc = meta_crtc_kms_from_kms_crtc (kms_crtc); crtc = meta_crtc_kms_from_kms_crtc (kms_crtc);
refresh_rate = crtc && crtc->current_mode ? refresh_rate = crtc && crtc->config ?
crtc->current_mode->refresh_rate : crtc->config->mode->refresh_rate :
0.0f; 0.0f;
if (refresh_rate >= frame_info->refresh_rate) if (refresh_rate >= frame_info->refresh_rate)
{ {
@ -1555,6 +1555,8 @@ queue_dummy_power_save_page_flip (CoglOnscreen *onscreen)
static void static void
meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaRendererView *view, MetaRendererView *view,
MetaMonitor *monitor,
MetaOutput *output,
MetaCrtc *crtc, MetaCrtc *crtc,
MetaKmsUpdate *kms_update) MetaKmsUpdate *kms_update)
{ {
@ -1586,7 +1588,8 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
fb_id = meta_drm_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb); fb_id = meta_drm_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb);
} }
meta_crtc_kms_assign_primary_plane (crtc, fb_id, kms_update); meta_crtc_kms_assign_primary_plane (crtc, monitor, output,
fb_id, kms_update);
meta_crtc_kms_page_flip (crtc, meta_crtc_kms_page_flip (crtc,
&page_flip_feedback, &page_flip_feedback,
g_object_ref (view), g_object_ref (view),
@ -1637,7 +1640,8 @@ set_crtc_mode (MetaLogicalMonitor *logical_monitor,
uint32_t fb_id; uint32_t fb_id;
fb_id = data->onscreen_native->egl.dumb_fb.fb_id; fb_id = data->onscreen_native->egl.dumb_fb.fb_id;
meta_crtc_kms_assign_primary_plane (crtc, fb_id, data->kms_update); meta_crtc_kms_assign_primary_plane (crtc, monitor, output,
fb_id, data->kms_update);
break; break;
} }
#endif #endif
@ -1688,6 +1692,8 @@ flip_crtc (MetaLogicalMonitor *logical_monitor,
meta_onscreen_native_flip_crtc (data->onscreen, meta_onscreen_native_flip_crtc (data->onscreen,
data->view, data->view,
monitor,
output,
crtc, crtc,
data->kms_update); data->kms_update);
} }
@ -3437,7 +3443,7 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
{ {
MetaCrtc *crtc = k->data; MetaCrtc *crtc = k->data;
if (crtc->current_mode) if (crtc->config)
continue; continue;
kms_update = meta_kms_ensure_pending_update (kms); kms_update = meta_kms_ensure_pending_update (kms);

View File

@ -41,12 +41,20 @@
#include "backends/meta-backend-private.h" #include "backends/meta-backend-private.h"
#include "backends/meta-crtc.h" #include "backends/meta-crtc.h"
#include "backends/meta-output.h"
#include "backends/x11/meta-crtc-xrandr.h" #include "backends/x11/meta-crtc-xrandr.h"
#include "backends/x11/meta-gpu-xrandr.h" #include "backends/x11/meta-gpu-xrandr.h"
#include "backends/x11/meta-monitor-manager-xrandr.h" #include "backends/x11/meta-monitor-manager-xrandr.h"
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1) #define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
typedef struct _MetaCrtcXrandr
{
MetaRectangle rect;
MetaMonitorTransform transform;
MetaCrtcMode *current_mode;
} MetaCrtcXrandr;
gboolean gboolean
meta_crtc_xrandr_set_config (MetaCrtc *crtc, meta_crtc_xrandr_set_config (MetaCrtc *crtc,
xcb_randr_crtc_t xrandr_crtc, xcb_randr_crtc_t xrandr_crtc,
@ -174,6 +182,52 @@ meta_monitor_transform_from_xrandr_all (Rotation rotation)
return ret; return ret;
} }
gboolean
meta_crtc_xrandr_is_assignment_changed (MetaCrtc *crtc,
MetaCrtcInfo *crtc_info)
{
MetaCrtcXrandr *crtc_xrandr = crtc->driver_private;
unsigned int i;
if (crtc_xrandr->current_mode != crtc_info->mode)
return TRUE;
if (crtc_xrandr->rect.x != (int) roundf (crtc_info->layout.origin.x))
return TRUE;
if (crtc_xrandr->rect.y != (int) roundf (crtc_info->layout.origin.x))
return TRUE;
if (crtc_xrandr->transform != crtc_info->transform)
return TRUE;
for (i = 0; i < crtc_info->outputs->len; i++)
{
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[i];
MetaCrtc *assigned_crtc;
assigned_crtc = meta_output_get_assigned_crtc (output);
if (assigned_crtc != crtc)
return TRUE;
}
return FALSE;
}
MetaCrtcMode *
meta_crtc_xrandr_get_current_mode (MetaCrtc *crtc)
{
MetaCrtcXrandr *crtc_xrandr = crtc->driver_private;
return crtc_xrandr->current_mode;
}
static void
meta_crtc_destroy_notify (MetaCrtc *crtc)
{
g_free (crtc->driver_private);
}
MetaCrtc * MetaCrtc *
meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr, meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr,
XRRCrtcInfo *xrandr_crtc, XRRCrtcInfo *xrandr_crtc,
@ -181,20 +235,27 @@ meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr,
XRRScreenResources *resources) XRRScreenResources *resources)
{ {
MetaCrtc *crtc; MetaCrtc *crtc;
MetaCrtcXrandr *crtc_xrandr;
unsigned int i; unsigned int i;
GList *modes; GList *modes;
crtc = g_object_new (META_TYPE_CRTC, NULL); crtc = g_object_new (META_TYPE_CRTC, NULL);
crtc_xrandr = g_new0 (MetaCrtcXrandr, 1);
crtc_xrandr->rect = (MetaRectangle) {
.x = xrandr_crtc->x,
.y = xrandr_crtc->y,
.width = xrandr_crtc->width,
.height = xrandr_crtc->height,
};
crtc_xrandr->transform =
meta_monitor_transform_from_xrandr (xrandr_crtc->rotation);
crtc->driver_private = crtc_xrandr;
crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
crtc->gpu = META_GPU (gpu_xrandr); crtc->gpu = META_GPU (gpu_xrandr);
crtc->crtc_id = crtc_id; crtc->crtc_id = crtc_id;
crtc->rect.x = xrandr_crtc->x;
crtc->rect.y = xrandr_crtc->y;
crtc->rect.width = xrandr_crtc->width;
crtc->rect.height = xrandr_crtc->height;
crtc->is_dirty = FALSE; crtc->is_dirty = FALSE;
crtc->transform =
meta_monitor_transform_from_xrandr (xrandr_crtc->rotation);
crtc->all_transforms = crtc->all_transforms =
meta_monitor_transform_from_xrandr_all (xrandr_crtc->rotations); meta_monitor_transform_from_xrandr_all (xrandr_crtc->rotations);
@ -203,10 +264,21 @@ meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr,
{ {
if (resources->modes[i].id == xrandr_crtc->mode) if (resources->modes[i].id == xrandr_crtc->mode)
{ {
crtc->current_mode = g_list_nth_data (modes, i); crtc_xrandr->current_mode = g_list_nth_data (modes, i);
break; break;
} }
} }
if (crtc_xrandr->current_mode)
{
meta_crtc_set_config (crtc,
&GRAPHENE_RECT_INIT (crtc_xrandr->rect.x,
crtc_xrandr->rect.y,
crtc_xrandr->rect.width,
crtc_xrandr->rect.height),
crtc_xrandr->current_mode,
crtc_xrandr->transform);
}
return crtc; return crtc;
} }

View File

@ -39,6 +39,11 @@ gboolean meta_crtc_xrandr_set_config (MetaCrtc *crtc,
int n_outputs, int n_outputs,
xcb_timestamp_t *out_timestamp); xcb_timestamp_t *out_timestamp);
gboolean meta_crtc_xrandr_is_assignment_changed (MetaCrtc *crtc,
MetaCrtcInfo *crtc_info);
MetaCrtcMode * meta_crtc_xrandr_get_current_mode (MetaCrtc *crtc);
MetaCrtc * meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr, MetaCrtc * meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr,
XRRCrtcInfo *xrandr_crtc, XRRCrtcInfo *xrandr_crtc,
RRCrtc crtc_id, RRCrtc crtc_id,

View File

@ -250,37 +250,14 @@ is_crtc_assignment_changed (MetaCrtc *crtc,
for (i = 0; i < n_crtc_infos; i++) for (i = 0; i < n_crtc_infos; i++)
{ {
MetaCrtcInfo *crtc_info = crtc_infos[i]; MetaCrtcInfo *crtc_info = crtc_infos[i];
unsigned int j;
if (crtc_info->crtc != crtc) if (crtc_info->crtc != crtc)
continue; continue;
if (crtc->current_mode != crtc_info->mode) return meta_crtc_xrandr_is_assignment_changed (crtc, crtc_info);
return TRUE;
if (crtc->rect.x != crtc_info->x)
return TRUE;
if (crtc->rect.y != crtc_info->y)
return TRUE;
if (crtc->transform != crtc_info->transform)
return TRUE;
for (j = 0; j < crtc_info->outputs->len; j++)
{
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[j];
MetaCrtc *assigned_crtc;
assigned_crtc = meta_output_get_assigned_crtc (output);
if (assigned_crtc != crtc)
return TRUE;
}
return FALSE;
} }
return crtc->current_mode != NULL; return !!meta_crtc_xrandr_get_current_mode (crtc);
} }
static gboolean static gboolean
@ -408,16 +385,10 @@ apply_crtc_assignments (MetaMonitorManager *manager,
if (crtc_info->mode == NULL) if (crtc_info->mode == NULL)
continue; continue;
if (meta_monitor_transform_is_rotated (crtc_info->transform)) width = MAX (width, (int) roundf (crtc_info->layout.origin.x +
{ crtc_info->layout.size.width));
width = MAX (width, crtc_info->x + crtc_info->mode->height); height = MAX (height, (int) roundf (crtc_info->layout.origin.y +
height = MAX (height, crtc_info->y + crtc_info->mode->width); crtc_info->layout.size.height));
}
else
{
width = MAX (width, crtc_info->x + crtc_info->mode->width);
height = MAX (height, crtc_info->y + crtc_info->mode->height);
}
} }
/* Second disable all newly disabled CRTCs, or CRTCs that in the previous /* Second disable all newly disabled CRTCs, or CRTCs that in the previous
@ -429,10 +400,15 @@ apply_crtc_assignments (MetaMonitorManager *manager,
{ {
MetaCrtcInfo *crtc_info = crtcs[i]; MetaCrtcInfo *crtc_info = crtcs[i];
MetaCrtc *crtc = crtc_info->crtc; MetaCrtc *crtc = crtc_info->crtc;
MetaCrtcConfig *crtc_config = crtc->config;
int x2, y2;
if (crtc_info->mode == NULL || x2 = (int) roundf (crtc_config->layout.origin.x +
crtc->rect.x + crtc->rect.width > width || crtc_config->layout.size.width);
crtc->rect.y + crtc->rect.height > height) y2 = (int) roundf (crtc_config->layout.origin.y +
crtc_config->layout.size.height);
if (!crtc_info->mode || x2 > width || y2 > height)
{ {
xrandr_set_crtc_config (manager_xrandr, xrandr_set_crtc_config (manager_xrandr,
crtc, crtc,
@ -443,11 +419,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
XCB_RANDR_ROTATION_ROTATE_0, XCB_RANDR_ROTATION_ROTATE_0,
NULL, 0); NULL, 0);
crtc->rect.x = 0; meta_crtc_unset_config (crtc);
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
} }
} }
@ -461,7 +433,8 @@ apply_crtc_assignments (MetaMonitorManager *manager,
crtc->is_dirty = FALSE; crtc->is_dirty = FALSE;
continue; continue;
} }
if (crtc->current_mode == NULL)
if (!crtc->config)
continue; continue;
xrandr_set_crtc_config (manager_xrandr, xrandr_set_crtc_config (manager_xrandr,
@ -473,11 +446,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
XCB_RANDR_ROTATION_ROTATE_0, XCB_RANDR_ROTATION_ROTATE_0,
NULL, 0); NULL, 0);
crtc->rect.x = 0; meta_crtc_unset_config (crtc);
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
} }
g_assert (width > 0 && height > 0); g_assert (width > 0 && height > 0);
@ -527,7 +496,8 @@ apply_crtc_assignments (MetaMonitorManager *manager,
save_timestamp, save_timestamp,
(xcb_randr_crtc_t) crtc->crtc_id, (xcb_randr_crtc_t) crtc->crtc_id,
XCB_CURRENT_TIME, XCB_CURRENT_TIME,
crtc_info->x, crtc_info->y, (int) roundf (crtc_info->layout.origin.x),
(int) roundf (crtc_info->layout.origin.y),
(xcb_randr_mode_t) mode->mode_id, (xcb_randr_mode_t) mode->mode_id,
rotation, rotation,
output_ids, n_output_ids)) output_ids, n_output_ids))
@ -535,27 +505,16 @@ apply_crtc_assignments (MetaMonitorManager *manager,
meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transform %u failed\n", meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transform %u failed\n",
(unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id), (unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id),
mode->width, mode->height, (float)mode->refresh_rate, mode->width, mode->height, (float)mode->refresh_rate,
crtc_info->x, crtc_info->y, crtc_info->transform); (int) roundf (crtc_info->layout.origin.x),
(int) roundf (crtc_info->layout.origin.y),
crtc_info->transform);
continue; continue;
} }
if (meta_monitor_transform_is_rotated (crtc_info->transform)) meta_crtc_set_config (crtc,
{ &crtc_info->layout,
width = mode->height; mode,
height = mode->width; crtc_info->transform);
}
else
{
width = mode->width;
height = mode->height;
}
crtc->rect.x = crtc_info->x;
crtc->rect.y = crtc_info->y;
crtc->rect.width = width;
crtc->rect.height = height;
crtc->current_mode = mode;
crtc->transform = crtc_info->transform;
} }
} }

View File

@ -101,12 +101,14 @@ output_set_underscanning_xrandr (MetaOutput *output,
if (underscanning) if (underscanning)
{ {
MetaCrtc *crtc; MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
uint32_t border_value; uint32_t border_value;
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
crtc_config = crtc->config;
prop = XInternAtom (xdisplay, "underscan hborder", False); prop = XInternAtom (xdisplay, "underscan hborder", False);
border_value = crtc->current_mode->width * 0.05; border_value = crtc_config->mode->width * 0.05;
xcb_randr_change_output_property (XGetXCBConnection (xdisplay), xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
(XID) output->winsys_id, (XID) output->winsys_id,
@ -115,7 +117,7 @@ output_set_underscanning_xrandr (MetaOutput *output,
1, &border_value); 1, &border_value);
prop = XInternAtom (xdisplay, "underscan vborder", False); prop = XInternAtom (xdisplay, "underscan vborder", False);
border_value = crtc->current_mode->height * 0.05; border_value = crtc_config->mode->height * 0.05;
xcb_randr_change_output_property (XGetXCBConnection (xdisplay), xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
(XID) output->winsys_id, (XID) output->winsys_id,

View File

@ -114,6 +114,7 @@ draw_crtc (MetaMonitor *monitor,
MetaLogicalMonitor *logical_monitor = data->logical_monitor; MetaLogicalMonitor *logical_monitor = data->logical_monitor;
MetaOutput *output = monitor_crtc_mode->output; MetaOutput *output = monitor_crtc_mode->output;
MetaCrtc *crtc; MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view); MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view);
MetaMonitorTransform view_transform; MetaMonitorTransform view_transform;
MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL; MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL;
@ -131,12 +132,13 @@ draw_crtc (MetaMonitor *monitor,
texture_height = cogl_texture_get_height (texture); texture_height = cogl_texture_get_height (texture);
crtc = meta_output_get_assigned_crtc (output); crtc = meta_output_get_assigned_crtc (output);
crtc_config = crtc->config;
clutter_stage_view_get_layout (data->view, &view_layout); clutter_stage_view_get_layout (data->view, &view_layout);
sample_x = crtc->rect.x - view_layout.x; sample_x = (int) roundf (crtc_config->layout.origin.x) - view_layout.x;
sample_y = crtc->rect.y - view_layout.y; sample_y = (int) roundf (crtc_config->layout.origin.y) - view_layout.y;
sample_width = crtc->rect.width; sample_width = (int) roundf (crtc_config->layout.size.width);
sample_height = crtc->rect.height; sample_height = (int) roundf (crtc_config->layout.size.height);
clutter_stage_view_get_offscreen_transformation_matrix (data->view, clutter_stage_view_get_offscreen_transformation_matrix (data->view,
&transform); &transform);

View File

@ -140,38 +140,17 @@ apply_crtc_assignments (MetaMonitorManager *manager,
if (crtc_info->mode == NULL) if (crtc_info->mode == NULL)
{ {
crtc->rect.x = 0; meta_crtc_unset_config (crtc);
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
} }
else else
{ {
MetaCrtcMode *mode;
MetaOutput *output; MetaOutput *output;
unsigned int j; unsigned int j;
int width, height;
mode = crtc_info->mode; meta_crtc_set_config (crtc,
&crtc_info->layout,
if (meta_monitor_transform_is_rotated (crtc_info->transform)) crtc_info->mode,
{ crtc_info->transform);
width = mode->height;
height = mode->width;
}
else
{
width = mode->width;
height = mode->height;
}
crtc->rect.x = crtc_info->x;
crtc->rect.y = crtc_info->y;
crtc->rect.width = width;
crtc->rect.height = height;
crtc->current_mode = mode;
crtc->transform = crtc_info->transform;
for (j = 0; j < crtc_info->outputs->len; j++) for (j = 0; j < crtc_info->outputs->len; j++)
{ {
@ -206,11 +185,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue; continue;
} }
crtc->rect.x = 0; meta_crtc_unset_config (crtc);
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
} }
/* Disable outputs not mentioned in the list */ /* Disable outputs not mentioned in the list */

View File

@ -175,8 +175,8 @@ typedef struct _MonitorTestCaseCrtcExpect
{ {
MetaMonitorTransform transform; MetaMonitorTransform transform;
int current_mode; int current_mode;
int x; float x;
int y; float y;
} MonitorTestCaseCrtcExpect; } MonitorTestCaseCrtcExpect;
typedef struct _MonitorTestCaseExpect typedef struct _MonitorTestCaseExpect
@ -313,6 +313,7 @@ static MonitorTestCase initial_test_case = {
}, },
{ {
.current_mode = 0, .current_mode = 0,
.x = 1024,
} }
}, },
.n_crtcs = 2, .n_crtcs = 2,
@ -509,10 +510,15 @@ check_current_monitor_mode (MetaMonitor *monitor,
} }
else else
{ {
MetaCrtcConfig *crtc_config;
MetaLogicalMonitor *logical_monitor; MetaLogicalMonitor *logical_monitor;
g_assert_nonnull (crtc); g_assert_nonnull (crtc);
g_assert (monitor_crtc_mode->crtc_mode == crtc->current_mode);
crtc_config = crtc->config;
g_assert_nonnull (crtc_config);
g_assert (monitor_crtc_mode->crtc_mode == crtc_config->mode);
logical_monitor = crtc->logical_monitor; logical_monitor = crtc->logical_monitor;
g_assert_nonnull (logical_monitor); g_assert_nonnull (logical_monitor);
@ -623,42 +629,6 @@ check_logical_monitor (MonitorTestCase *test_case,
g_assert_nonnull (primary_output); g_assert_nonnull (primary_output);
} }
static void
get_compensated_crtc_position (MetaCrtc *crtc,
int *x,
int *y)
{
MetaLogicalMonitor *logical_monitor;
MetaBackend *backend = meta_get_backend ();
MetaRenderer *renderer = meta_backend_get_renderer (backend);
GList *views;
GList *l;
logical_monitor = crtc->logical_monitor;
g_assert_nonnull (logical_monitor);
views = meta_renderer_get_views (renderer);
for (l = views; 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_equal (&view_layout,
&logical_monitor->rect))
{
*x = crtc->rect.x - view_layout.x;
*y = crtc->rect.y - view_layout.y;
return;
}
}
*x = crtc->rect.x;
*y = crtc->rect.y;
}
static void static void
check_monitor_configuration (MonitorTestCase *test_case) check_monitor_configuration (MonitorTestCase *test_case)
{ {
@ -853,50 +823,37 @@ check_monitor_configuration (MonitorTestCase *test_case)
for (l = crtcs, i = 0; l; l = l->next, i++) for (l = crtcs, i = 0; l; l = l->next, i++)
{ {
MetaCrtc *crtc = l->data; MetaCrtc *crtc = l->data;
MetaCrtcConfig *crtc_config = crtc->config;
if (test_case->expect.crtcs[i].current_mode == -1) if (test_case->expect.crtcs[i].current_mode == -1)
{ {
g_assert_null (crtc->current_mode); g_assert_null (crtc_config);
} }
else else
{ {
MetaLogicalMonitor *logical_monitor = crtc->logical_monitor; MetaLogicalMonitor *logical_monitor = crtc->logical_monitor;
MetaCrtcMode *expected_current_mode; MetaCrtcMode *expected_current_mode;
int crtc_x, crtc_y;
g_assert_nonnull (crtc_config);
expected_current_mode = expected_current_mode =
g_list_nth_data (meta_gpu_get_modes (gpu), g_list_nth_data (meta_gpu_get_modes (gpu),
test_case->expect.crtcs[i].current_mode); test_case->expect.crtcs[i].current_mode);
g_assert (crtc->current_mode == expected_current_mode); g_assert (crtc_config->mode == expected_current_mode);
g_assert_cmpuint (crtc->transform, g_assert_cmpuint (crtc_config->transform,
==, ==,
test_case->expect.crtcs[i].transform); test_case->expect.crtcs[i].transform);
if (meta_is_stage_views_enabled ()) logical_monitor = crtc->logical_monitor;
{ g_assert_nonnull (logical_monitor);
get_compensated_crtc_position (crtc, &crtc_x, &crtc_y);
g_assert_cmpint (crtc_x, ==, test_case->expect.crtcs[i].x); g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.x,
g_assert_cmpint (crtc_y, ==, test_case->expect.crtcs[i].y); test_case->expect.crtcs[i].x,
} FLT_EPSILON);
else g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.y,
{ test_case->expect.crtcs[i].y,
int expect_crtc_x; FLT_EPSILON);
int expect_crtc_y;
g_assert_cmpuint (logical_monitor->transform,
==,
crtc->transform);
expect_crtc_x = (test_case->expect.crtcs[i].x +
logical_monitor->rect.x);
expect_crtc_y = (test_case->expect.crtcs[i].y +
logical_monitor->rect.y);
g_assert_cmpint (crtc->rect.x, ==, expect_crtc_x);
g_assert_cmpint (crtc->rect.y, ==, expect_crtc_y);
}
} }
} }
@ -945,19 +902,9 @@ create_monitor_test_setup (MonitorTestCase *test_case,
for (i = 0; i < test_case->setup.n_crtcs; i++) for (i = 0; i < test_case->setup.n_crtcs; i++)
{ {
MetaCrtc *crtc; MetaCrtc *crtc;
int current_mode_index;
MetaCrtcMode *current_mode;
current_mode_index = test_case->setup.crtcs[i].current_mode;
if (current_mode_index == -1)
current_mode = NULL;
else
current_mode = g_list_nth_data (test_setup->modes, current_mode_index);
crtc = g_object_new (META_TYPE_CRTC, NULL); crtc = g_object_new (META_TYPE_CRTC, NULL);
crtc->crtc_id = i + 1; crtc->crtc_id = i + 1;
crtc->current_mode = current_mode;
crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
crtc->all_transforms = ALL_TRANSFORMS; crtc->all_transforms = ALL_TRANSFORMS;
test_setup->crtcs = g_list_append (test_setup->crtcs, crtc); test_setup->crtcs = g_list_append (test_setup->crtcs, crtc);
@ -1258,6 +1205,7 @@ meta_test_monitor_one_off_linear_config (void)
}, },
{ {
.current_mode = 0, .current_mode = 0,
.x = 1024,
} }
}, },
.n_crtcs = 2, .n_crtcs = 2,
@ -1966,6 +1914,7 @@ meta_test_monitor_hidpi_linear_config (void)
}, },
{ {
.current_mode = 1, .current_mode = 1,
.x = 640,
} }
}, },
.n_crtcs = 2, .n_crtcs = 2,
@ -2118,6 +2067,8 @@ meta_test_monitor_suggested_config (void)
.crtcs = { .crtcs = {
{ {
.current_mode = 0, .current_mode = 0,
.x = 1024,
.y = 758,
}, },
{ {
.current_mode = 1, .current_mode = 1,
@ -2386,6 +2337,7 @@ meta_test_monitor_lid_switch_config (void)
}, },
{ {
.current_mode = 0, .current_mode = 0,
.x = 1024,
} }
}, },
.n_crtcs = 2, .n_crtcs = 2,
@ -2417,6 +2369,7 @@ meta_test_monitor_lid_switch_config (void)
test_case.expect.screen_width = 1024; test_case.expect.screen_width = 1024;
test_case.expect.monitors[0].current_mode = -1; test_case.expect.monitors[0].current_mode = -1;
test_case.expect.crtcs[0].current_mode = -1; test_case.expect.crtcs[0].current_mode = -1;
test_case.expect.crtcs[1].x = 0;
check_monitor_configuration (&test_case); check_monitor_configuration (&test_case);
@ -2436,6 +2389,7 @@ meta_test_monitor_lid_switch_config (void)
test_case.expect.crtcs[0].current_mode = 0; test_case.expect.crtcs[0].current_mode = 0;
test_case.expect.crtcs[1].current_mode = 0; test_case.expect.crtcs[1].current_mode = 0;
test_case.expect.crtcs[1].x = 1024;
check_monitor_configuration (&test_case); check_monitor_configuration (&test_case);
} }
@ -2584,7 +2538,9 @@ meta_test_monitor_lid_opened_config (void)
test_case.expect.screen_width = 1024 * 2; test_case.expect.screen_width = 1024 * 2;
test_case.expect.monitors[0].current_mode = 0; test_case.expect.monitors[0].current_mode = 0;
test_case.expect.crtcs[0].current_mode = 0; test_case.expect.crtcs[0].current_mode = 0;
test_case.expect.crtcs[0].x = 1024;
test_case.expect.crtcs[1].current_mode = 0; test_case.expect.crtcs[1].current_mode = 0;
test_case.expect.crtcs[1].x = 0;
check_monitor_configuration (&test_case); check_monitor_configuration (&test_case);
} }
@ -2831,6 +2787,7 @@ meta_test_monitor_lid_closed_with_hotplugged_external (void)
test_case.expect.n_monitors = 2; test_case.expect.n_monitors = 2;
test_case.expect.n_logical_monitors = 2; test_case.expect.n_logical_monitors = 2;
test_case.expect.crtcs[1].current_mode = 0; test_case.expect.crtcs[1].current_mode = 0;
test_case.expect.crtcs[1].x = 1024;
test_case.expect.screen_width = 1024 * 2; test_case.expect.screen_width = 1024 * 2;
test_setup = create_monitor_test_setup (&test_case, test_setup = create_monitor_test_setup (&test_case,
@ -2844,6 +2801,7 @@ meta_test_monitor_lid_closed_with_hotplugged_external (void)
test_case.expect.logical_monitors[0].monitors[0] = 1, test_case.expect.logical_monitors[0].monitors[0] = 1,
test_case.expect.n_logical_monitors = 1; test_case.expect.n_logical_monitors = 1;
test_case.expect.crtcs[0].current_mode = -1; test_case.expect.crtcs[0].current_mode = -1;
test_case.expect.crtcs[1].x = 0;
test_case.expect.screen_width = 1024; test_case.expect.screen_width = 1024;
test_setup = create_monitor_test_setup (&test_case, test_setup = create_monitor_test_setup (&test_case,
@ -2867,6 +2825,7 @@ meta_test_monitor_lid_closed_with_hotplugged_external (void)
test_case.expect.logical_monitors[1].monitors[0] = 1, test_case.expect.logical_monitors[1].monitors[0] = 1,
test_case.expect.n_logical_monitors = 2; test_case.expect.n_logical_monitors = 2;
test_case.expect.crtcs[0].current_mode = 0; test_case.expect.crtcs[0].current_mode = 0;
test_case.expect.crtcs[1].x = 1024;
test_case.expect.screen_width = 1024 * 2; test_case.expect.screen_width = 1024 * 2;
test_setup = create_monitor_test_setup (&test_case, test_setup = create_monitor_test_setup (&test_case,
@ -3301,6 +3260,7 @@ meta_test_monitor_custom_vertical_config (void)
}, },
{ {
.current_mode = 1, .current_mode = 1,
.y = 768,
} }
}, },
.n_crtcs = 2, .n_crtcs = 2,
@ -3440,6 +3400,7 @@ meta_test_monitor_custom_primary_config (void)
}, },
{ {
.current_mode = 1, .current_mode = 1,
.x = 1024,
} }
}, },
.n_crtcs = 2, .n_crtcs = 2,
@ -3952,7 +3913,7 @@ meta_test_monitor_custom_tiled_config (void)
}, },
{ {
.current_mode = 0, .current_mode = 0,
.x = 400, .x = 200,
.y = 0 .y = 0
} }
}, },
@ -4555,6 +4516,7 @@ meta_test_monitor_custom_first_rotated_config (void)
}, },
{ {
.current_mode = 0, .current_mode = 0,
.x = 768,
} }
}, },
.n_crtcs = 2, .n_crtcs = 2,
@ -4685,10 +4647,12 @@ meta_test_monitor_custom_second_rotated_config (void)
.crtcs = { .crtcs = {
{ {
.current_mode = 0, .current_mode = 0,
.y = 256,
}, },
{ {
.current_mode = 0, .current_mode = 0,
.transform = META_MONITOR_TRANSFORM_90 .transform = META_MONITOR_TRANSFORM_90,
.x = 1024,
} }
}, },
.n_crtcs = 2, .n_crtcs = 2,
@ -4859,16 +4823,18 @@ meta_test_monitor_custom_second_rotated_tiled_config (void)
.crtcs = { .crtcs = {
{ {
.current_mode = 0, .current_mode = 0,
.y = 256,
}, },
{ {
.current_mode = 1, .current_mode = 1,
.transform = META_MONITOR_TRANSFORM_90, .transform = META_MONITOR_TRANSFORM_90,
.x = 0, .x = 1024,
.y = 400, .y = 400,
}, },
{ {
.current_mode = 1, .current_mode = 1,
.transform = META_MONITOR_TRANSFORM_90 .transform = META_MONITOR_TRANSFORM_90,
.x = 1024,
} }
}, },
.n_crtcs = 3, .n_crtcs = 3,
@ -5008,10 +4974,12 @@ meta_test_monitor_custom_second_rotated_nonnative_config (void)
.crtcs = { .crtcs = {
{ {
.current_mode = 0, .current_mode = 0,
.y = 256,
}, },
{ {
.current_mode = 0, .current_mode = 0,
.transform = META_MONITOR_TRANSFORM_NORMAL .transform = META_MONITOR_TRANSFORM_NORMAL,
.x = 1024,
} }
}, },
.n_crtcs = 2, .n_crtcs = 2,
@ -5423,6 +5391,7 @@ meta_test_monitor_custom_lid_switch_config (void)
test_case.expect.n_outputs = 2; test_case.expect.n_outputs = 2;
test_case.expect.crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL; test_case.expect.crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
test_case.expect.crtcs[1].current_mode = 0; test_case.expect.crtcs[1].current_mode = 0;
test_case.expect.crtcs[1].x = 1024;
test_case.expect.crtcs[1].transform = META_MONITOR_TRANSFORM_270; test_case.expect.crtcs[1].transform = META_MONITOR_TRANSFORM_270;
test_case.expect.logical_monitors[0].layout = test_case.expect.logical_monitors[0].layout =
(MetaRectangle) { .width = 1024, .height = 768 }; (MetaRectangle) { .width = 1024, .height = 768 };
@ -5440,6 +5409,7 @@ meta_test_monitor_custom_lid_switch_config (void)
test_case.expect.crtcs[0].current_mode = -1; test_case.expect.crtcs[0].current_mode = -1;
test_case.expect.crtcs[1].transform = META_MONITOR_TRANSFORM_90; test_case.expect.crtcs[1].transform = META_MONITOR_TRANSFORM_90;
test_case.expect.crtcs[1].x = 0;
test_case.expect.monitors[0].current_mode = -1; test_case.expect.monitors[0].current_mode = -1;
test_case.expect.logical_monitors[0].layout = test_case.expect.logical_monitors[0].layout =
(MetaRectangle) { .width = 768, .height = 1024 }; (MetaRectangle) { .width = 768, .height = 1024 };
@ -5460,6 +5430,7 @@ meta_test_monitor_custom_lid_switch_config (void)
test_case.expect.crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL; test_case.expect.crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
test_case.expect.crtcs[1].current_mode = 0; test_case.expect.crtcs[1].current_mode = 0;
test_case.expect.crtcs[1].transform = META_MONITOR_TRANSFORM_270; test_case.expect.crtcs[1].transform = META_MONITOR_TRANSFORM_270;
test_case.expect.crtcs[1].x = 1024;
test_case.expect.monitors[0].current_mode = 0; test_case.expect.monitors[0].current_mode = 0;
test_case.expect.logical_monitors[0].layout = test_case.expect.logical_monitors[0].layout =
(MetaRectangle) { .width = 1024, .height = 768 }; (MetaRectangle) { .width = 1024, .height = 768 };