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;
}
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
meta_crtc_finalize (GObject *object)
{

View File

@ -49,6 +49,13 @@ typedef enum _MetaCrtcModeFlag
META_CRTC_MODE_FLAG_MASK = 0x3fff
} MetaCrtcModeFlag;
typedef struct _MetaCrtcConfig
{
graphene_rect_t layout;
MetaMonitorTransform transform;
MetaCrtcMode *mode;
} MetaCrtcConfig;
struct _MetaCrtc
{
GObject parent;
@ -56,12 +63,10 @@ struct _MetaCrtc
MetaGpu *gpu;
glong crtc_id;
MetaRectangle rect;
MetaCrtcMode *current_mode;
MetaMonitorTransform transform;
unsigned int all_transforms;
MetaLogicalMonitor *logical_monitor;
MetaCrtcConfig *config;
/* Used when changing configuration */
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);
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 */

View File

@ -122,7 +122,7 @@ derive_monitor_transform (MetaMonitor *monitor)
MetaMonitorTransform transform;
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);
}

View File

@ -172,6 +172,11 @@ assign_monitor_crtc (MetaMonitor *monitor,
MetaMonitorTransform transform;
MetaMonitorTransform crtc_transform;
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;
MetaOutputInfo *output_info;
MetaMonitorConfig *first_monitor_config;
@ -202,29 +207,37 @@ assign_monitor_crtc (MetaMonitor *monitor,
meta_monitor_calculate_crtc_pos (monitor, mode, output, crtc_transform,
&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 = (MetaCrtcInfo) {
.crtc = crtc,
.mode = monitor_crtc_mode->crtc_mode,
.x = crtc_x,
.y = crtc_y,
.mode = crtc_mode,
.layout = crtc_layout,
.transform = crtc_transform,
.outputs = g_ptr_array_new ()
};
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),
* 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)
{
crtc->rect.x = 0;
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
meta_crtc_unset_config (crtc);
}
else
{
MetaCrtcMode *mode;
MetaOutput *output;
unsigned int j;
int width, height;
mode = crtc_info->mode;
if (meta_monitor_transform_is_rotated (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;
meta_crtc_set_config (crtc,
&crtc_info->layout,
crtc_info->mode,
crtc_info->transform);
for (j = 0; j < crtc_info->outputs->len; j++)
{
@ -577,11 +556,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
continue;
}
crtc->rect.x = 0;
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
meta_crtc_unset_config (crtc);
}
/* Disable outputs not mentioned in the list */

View File

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

View File

@ -1014,28 +1014,46 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
{
MetaCrtc *crtc = l->data;
GVariantBuilder transforms;
int current_mode_index;
MetaCrtcConfig *crtc_config;
g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
if (crtc->all_transforms & (1 << j))
g_variant_builder_add (&transforms, "u", j);
if (crtc->current_mode)
current_mode_index = g_list_index (combined_modes, crtc->current_mode);
crtc_config = crtc->config;
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
current_mode_index = -1;
g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
i, /* ID */
(gint64)crtc->crtc_id,
(int)crtc->rect.x,
(int)crtc->rect.y,
(int)crtc->rect.width,
(int)crtc->rect.height,
current_mode_index,
(guint32)crtc->transform,
&transforms,
NULL /* properties */);
{
g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
i, /* ID */
(int64_t) crtc->crtc_id,
0,
0,
0,
0,
-1,
(uint32_t) META_MONITOR_TRANSFORM_NORMAL,
&transforms,
NULL /* properties */);
}
}
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-settings-private.h"
#include "backends/meta-output.h"
#include "core/boxes-private.h"
#define SCALE_FACTORS_PER_INTEGER 4
#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;
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;
}
}
@ -683,10 +684,17 @@ meta_monitor_normal_derive_layout (MetaMonitor *monitor,
{
MetaOutput *output;
MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
output = meta_monitor_get_main_output (monitor);
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
@ -880,7 +888,8 @@ is_monitor_mode_assigned (MetaMonitor *monitor,
crtc = meta_output_get_assigned_crtc (output);
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;
else if (!monitor_crtc_mode->crtc_mode && crtc)
return FALSE;
@ -1324,32 +1333,39 @@ meta_monitor_tiled_derive_layout (MetaMonitor *monitor,
MetaMonitorPrivate *monitor_priv =
meta_monitor_get_instance_private (monitor);
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_y = INT_MAX;
max_x = 0;
max_y = 0;
min_x = FLT_MAX;
min_y = FLT_MAX;
max_x = 0.0;
max_y = 0.0;
for (l = monitor_priv->outputs; l; l = l->next)
{
MetaOutput *output = l->data;
MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
graphene_rect_t *crtc_layout;
crtc = meta_output_get_assigned_crtc (output);
if (!crtc)
continue;
min_x = MIN (crtc->rect.x, min_x);
min_y = MIN (crtc->rect.y, min_y);
max_x = MAX (crtc->rect.x + crtc->rect.width, max_x);
max_y = MAX (crtc->rect.y + crtc->rect.height, max_y);
crtc_config = crtc->config;
g_return_if_fail (crtc_config);
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) {
.x = min_x,
.y = min_y,
.width = max_x - min_x,
.height = max_y - min_y
.x = roundf (min_x),
.y = roundf (min_y),
.width = roundf (max_x - min_x),
.height = roundf (max_y - min_y)
};
}
@ -1508,7 +1524,7 @@ is_current_mode_known (MetaMonitor *monitor)
output = meta_monitor_get_main_output (monitor);
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

View File

@ -63,7 +63,7 @@ meta_crtc_kms_apply_transform (MetaCrtc *crtc,
MetaCrtcKms *crtc_kms = crtc->driver_private;
MetaMonitorTransform hw_transform;
hw_transform = crtc->transform;
hw_transform = crtc->config->transform;
if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform))
hw_transform = META_MONITOR_TRANSFORM_NORMAL;
if (!meta_crtc_kms_is_transform_handled (crtc, hw_transform))
@ -76,11 +76,14 @@ 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)
{
MetaRectangle logical_monitor_rect;
int x, y;
MetaMonitorMode *monitor_mode;
MetaCrtcConfig *crtc_config;
int crtc_x, crtc_y;
MetaFixed16Rectangle src_rect;
MetaFixed16Rectangle dst_rect;
MetaKmsAssignPlaneFlag flags;
@ -89,21 +92,27 @@ meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc,
MetaKmsPlane *primary_kms_plane;
MetaKmsPlaneAssignment *plane_assignment;
logical_monitor_rect =
meta_logical_monitor_get_layout (crtc->logical_monitor);
x = crtc->rect.x - logical_monitor_rect.x;
y = crtc->rect.y - logical_monitor_rect.y;
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 (x),
.y = meta_fixed_16_from_int (y),
.width = meta_fixed_16_from_int (crtc->rect.width),
.height = meta_fixed_16_from_int (crtc->rect.height),
.x = meta_fixed_16_from_int (crtc_x),
.y = meta_fixed_16_from_int (crtc_y),
.width = meta_fixed_16_from_int (crtc_config->mode->width),
.height = meta_fixed_16_from_int (crtc_config->mode->height),
};
dst_rect = (MetaFixed16Rectangle) {
.x = meta_fixed_16_from_int (0),
.y = meta_fixed_16_from_int (0),
.width = meta_fixed_16_from_int (crtc->rect.width),
.height = meta_fixed_16_from_int (crtc->rect.height),
.width = meta_fixed_16_from_int (crtc_config->mode->width),
.height = meta_fixed_16_from_int (crtc_config->mode->height),
};
flags = META_KMS_ASSIGN_PLANE_FLAG_NONE;
@ -151,6 +160,7 @@ void
meta_crtc_kms_set_mode (MetaCrtc *crtc,
MetaKmsUpdate *kms_update)
{
MetaCrtcConfig *crtc_config = crtc->config;
MetaGpu *gpu = meta_crtc_get_gpu (crtc);
GList *connectors;
drmModeModeInfo *mode;
@ -159,7 +169,7 @@ meta_crtc_kms_set_mode (MetaCrtc *crtc,
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);
}
@ -274,37 +284,16 @@ meta_create_kms_crtc (MetaGpuKms *gpu_kms,
MetaCrtc *crtc;
MetaCrtcKms *crtc_kms;
MetaKmsPlane *primary_plane;
const MetaKmsCrtcState *crtc_state;
kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
primary_plane = meta_kms_device_get_primary_plane_for (kms_device,
kms_crtc);
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
crtc = g_object_new (META_TYPE_CRTC, NULL);
crtc->gpu = gpu;
crtc->crtc_id = meta_kms_crtc_get_id (kms_crtc);
crtc->rect = crtc_state->rect;
crtc->is_dirty = FALSE;
crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
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->kms_crtc = kms_crtc;
crtc_kms->primary_plane = primary_plane;

View File

@ -38,6 +38,8 @@ 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);

View File

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

View File

@ -64,11 +64,13 @@ meta_output_kms_set_underscan (MetaOutput *output,
if (output->is_underscanning)
{
MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
uint64_t hborder, vborder;
crtc = meta_output_get_assigned_crtc (output);
hborder = MIN (128, (uint64_t) round (crtc->current_mode->width * 0.05));
vborder = MIN (128, (uint64_t) round (crtc->current_mode->height * 0.05));
crtc_config = crtc->config;
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,
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);
crtc = meta_crtc_kms_from_kms_crtc (kms_crtc);
refresh_rate = crtc && crtc->current_mode ?
crtc->current_mode->refresh_rate :
refresh_rate = crtc && crtc->config ?
crtc->config->mode->refresh_rate :
0.0f;
if (refresh_rate >= frame_info->refresh_rate)
{
@ -1555,6 +1555,8 @@ queue_dummy_power_save_page_flip (CoglOnscreen *onscreen)
static void
meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaRendererView *view,
MetaMonitor *monitor,
MetaOutput *output,
MetaCrtc *crtc,
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);
}
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,
&page_flip_feedback,
g_object_ref (view),
@ -1637,7 +1640,8 @@ set_crtc_mode (MetaLogicalMonitor *logical_monitor,
uint32_t 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;
}
#endif
@ -1688,6 +1692,8 @@ flip_crtc (MetaLogicalMonitor *logical_monitor,
meta_onscreen_native_flip_crtc (data->onscreen,
data->view,
monitor,
output,
crtc,
data->kms_update);
}
@ -3437,7 +3443,7 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
{
MetaCrtc *crtc = k->data;
if (crtc->current_mode)
if (crtc->config)
continue;
kms_update = meta_kms_ensure_pending_update (kms);

View File

@ -41,12 +41,20 @@
#include "backends/meta-backend-private.h"
#include "backends/meta-crtc.h"
#include "backends/meta-output.h"
#include "backends/x11/meta-crtc-xrandr.h"
#include "backends/x11/meta-gpu-xrandr.h"
#include "backends/x11/meta-monitor-manager-xrandr.h"
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
typedef struct _MetaCrtcXrandr
{
MetaRectangle rect;
MetaMonitorTransform transform;
MetaCrtcMode *current_mode;
} MetaCrtcXrandr;
gboolean
meta_crtc_xrandr_set_config (MetaCrtc *crtc,
xcb_randr_crtc_t xrandr_crtc,
@ -174,6 +182,52 @@ meta_monitor_transform_from_xrandr_all (Rotation rotation)
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 *
meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr,
XRRCrtcInfo *xrandr_crtc,
@ -181,20 +235,27 @@ meta_create_xrandr_crtc (MetaGpuXrandr *gpu_xrandr,
XRRScreenResources *resources)
{
MetaCrtc *crtc;
MetaCrtcXrandr *crtc_xrandr;
unsigned int i;
GList *modes;
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->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->transform =
meta_monitor_transform_from_xrandr (xrandr_crtc->rotation);
crtc->all_transforms =
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)
{
crtc->current_mode = g_list_nth_data (modes, i);
crtc_xrandr->current_mode = g_list_nth_data (modes, i);
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;
}

View File

@ -39,6 +39,11 @@ gboolean meta_crtc_xrandr_set_config (MetaCrtc *crtc,
int n_outputs,
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,
XRRCrtcInfo *xrandr_crtc,
RRCrtc crtc_id,

View File

@ -250,37 +250,14 @@ is_crtc_assignment_changed (MetaCrtc *crtc,
for (i = 0; i < n_crtc_infos; i++)
{
MetaCrtcInfo *crtc_info = crtc_infos[i];
unsigned int j;
if (crtc_info->crtc != crtc)
continue;
if (crtc->current_mode != crtc_info->mode)
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 meta_crtc_xrandr_is_assignment_changed (crtc, crtc_info);
}
return crtc->current_mode != NULL;
return !!meta_crtc_xrandr_get_current_mode (crtc);
}
static gboolean
@ -408,16 +385,10 @@ apply_crtc_assignments (MetaMonitorManager *manager,
if (crtc_info->mode == NULL)
continue;
if (meta_monitor_transform_is_rotated (crtc_info->transform))
{
width = MAX (width, crtc_info->x + crtc_info->mode->height);
height = MAX (height, crtc_info->y + crtc_info->mode->width);
}
else
{
width = MAX (width, crtc_info->x + crtc_info->mode->width);
height = MAX (height, crtc_info->y + crtc_info->mode->height);
}
width = MAX (width, (int) roundf (crtc_info->layout.origin.x +
crtc_info->layout.size.width));
height = MAX (height, (int) roundf (crtc_info->layout.origin.y +
crtc_info->layout.size.height));
}
/* 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];
MetaCrtc *crtc = crtc_info->crtc;
MetaCrtcConfig *crtc_config = crtc->config;
int x2, y2;
if (crtc_info->mode == NULL ||
crtc->rect.x + crtc->rect.width > width ||
crtc->rect.y + crtc->rect.height > height)
x2 = (int) roundf (crtc_config->layout.origin.x +
crtc_config->layout.size.width);
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,
crtc,
@ -443,11 +419,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
XCB_RANDR_ROTATION_ROTATE_0,
NULL, 0);
crtc->rect.x = 0;
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
meta_crtc_unset_config (crtc);
}
}
@ -461,7 +433,8 @@ apply_crtc_assignments (MetaMonitorManager *manager,
crtc->is_dirty = FALSE;
continue;
}
if (crtc->current_mode == NULL)
if (!crtc->config)
continue;
xrandr_set_crtc_config (manager_xrandr,
@ -473,11 +446,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
XCB_RANDR_ROTATION_ROTATE_0,
NULL, 0);
crtc->rect.x = 0;
crtc->rect.y = 0;
crtc->rect.width = 0;
crtc->rect.height = 0;
crtc->current_mode = NULL;
meta_crtc_unset_config (crtc);
}
g_assert (width > 0 && height > 0);
@ -527,7 +496,8 @@ apply_crtc_assignments (MetaMonitorManager *manager,
save_timestamp,
(xcb_randr_crtc_t) crtc->crtc_id,
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,
rotation,
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",
(unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id),
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;
}
if (meta_monitor_transform_is_rotated (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;
meta_crtc_set_config (crtc,
&crtc_info->layout,
mode,
crtc_info->transform);
}
}

View File

@ -101,12 +101,14 @@ output_set_underscanning_xrandr (MetaOutput *output,
if (underscanning)
{
MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
uint32_t border_value;
crtc = meta_output_get_assigned_crtc (output);
crtc_config = crtc->config;
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),
(XID) output->winsys_id,
@ -115,7 +117,7 @@ output_set_underscanning_xrandr (MetaOutput *output,
1, &border_value);
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),
(XID) output->winsys_id,

View File

@ -114,6 +114,7 @@ draw_crtc (MetaMonitor *monitor,
MetaLogicalMonitor *logical_monitor = data->logical_monitor;
MetaOutput *output = monitor_crtc_mode->output;
MetaCrtc *crtc;
MetaCrtcConfig *crtc_config;
MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view);
MetaMonitorTransform view_transform;
MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL;
@ -131,12 +132,13 @@ draw_crtc (MetaMonitor *monitor,
texture_height = cogl_texture_get_height (texture);
crtc = meta_output_get_assigned_crtc (output);
crtc_config = crtc->config;
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;
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);
clutter_stage_view_get_offscreen_transformation_matrix (data->view,
&transform);

View File

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

View File

@ -175,8 +175,8 @@ typedef struct _MonitorTestCaseCrtcExpect
{
MetaMonitorTransform transform;
int current_mode;
int x;
int y;
float x;
float y;
} MonitorTestCaseCrtcExpect;
typedef struct _MonitorTestCaseExpect
@ -313,6 +313,7 @@ static MonitorTestCase initial_test_case = {
},
{
.current_mode = 0,
.x = 1024,
}
},
.n_crtcs = 2,
@ -509,10 +510,15 @@ check_current_monitor_mode (MetaMonitor *monitor,
}
else
{
MetaCrtcConfig *crtc_config;
MetaLogicalMonitor *logical_monitor;
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;
g_assert_nonnull (logical_monitor);
@ -623,42 +629,6 @@ check_logical_monitor (MonitorTestCase *test_case,
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
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++)
{
MetaCrtc *crtc = l->data;
MetaCrtcConfig *crtc_config = crtc->config;
if (test_case->expect.crtcs[i].current_mode == -1)
{
g_assert_null (crtc->current_mode);
g_assert_null (crtc_config);
}
else
{
MetaLogicalMonitor *logical_monitor = crtc->logical_monitor;
MetaCrtcMode *expected_current_mode;
int crtc_x, crtc_y;
g_assert_nonnull (crtc_config);
expected_current_mode =
g_list_nth_data (meta_gpu_get_modes (gpu),
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);
if (meta_is_stage_views_enabled ())
{
get_compensated_crtc_position (crtc, &crtc_x, &crtc_y);
logical_monitor = crtc->logical_monitor;
g_assert_nonnull (logical_monitor);
g_assert_cmpint (crtc_x, ==, test_case->expect.crtcs[i].x);
g_assert_cmpint (crtc_y, ==, test_case->expect.crtcs[i].y);
}
else
{
int expect_crtc_x;
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);
}
g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.x,
test_case->expect.crtcs[i].x,
FLT_EPSILON);
g_assert_cmpfloat_with_epsilon (crtc_config->layout.origin.y,
test_case->expect.crtcs[i].y,
FLT_EPSILON);
}
}
@ -945,19 +902,9 @@ create_monitor_test_setup (MonitorTestCase *test_case,
for (i = 0; i < test_case->setup.n_crtcs; i++)
{
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->crtc_id = i + 1;
crtc->current_mode = current_mode;
crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
crtc->all_transforms = ALL_TRANSFORMS;
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,
.x = 1024,
}
},
.n_crtcs = 2,
@ -1966,6 +1914,7 @@ meta_test_monitor_hidpi_linear_config (void)
},
{
.current_mode = 1,
.x = 640,
}
},
.n_crtcs = 2,
@ -2118,6 +2067,8 @@ meta_test_monitor_suggested_config (void)
.crtcs = {
{
.current_mode = 0,
.x = 1024,
.y = 758,
},
{
.current_mode = 1,
@ -2386,6 +2337,7 @@ meta_test_monitor_lid_switch_config (void)
},
{
.current_mode = 0,
.x = 1024,
}
},
.n_crtcs = 2,
@ -2417,6 +2369,7 @@ meta_test_monitor_lid_switch_config (void)
test_case.expect.screen_width = 1024;
test_case.expect.monitors[0].current_mode = -1;
test_case.expect.crtcs[0].current_mode = -1;
test_case.expect.crtcs[1].x = 0;
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[1].current_mode = 0;
test_case.expect.crtcs[1].x = 1024;
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.monitors[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].x = 0;
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_logical_monitors = 2;
test_case.expect.crtcs[1].current_mode = 0;
test_case.expect.crtcs[1].x = 1024;
test_case.expect.screen_width = 1024 * 2;
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.n_logical_monitors = 1;
test_case.expect.crtcs[0].current_mode = -1;
test_case.expect.crtcs[1].x = 0;
test_case.expect.screen_width = 1024;
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.n_logical_monitors = 2;
test_case.expect.crtcs[0].current_mode = 0;
test_case.expect.crtcs[1].x = 1024;
test_case.expect.screen_width = 1024 * 2;
test_setup = create_monitor_test_setup (&test_case,
@ -3301,6 +3260,7 @@ meta_test_monitor_custom_vertical_config (void)
},
{
.current_mode = 1,
.y = 768,
}
},
.n_crtcs = 2,
@ -3440,6 +3400,7 @@ meta_test_monitor_custom_primary_config (void)
},
{
.current_mode = 1,
.x = 1024,
}
},
.n_crtcs = 2,
@ -3952,7 +3913,7 @@ meta_test_monitor_custom_tiled_config (void)
},
{
.current_mode = 0,
.x = 400,
.x = 200,
.y = 0
}
},
@ -4555,6 +4516,7 @@ meta_test_monitor_custom_first_rotated_config (void)
},
{
.current_mode = 0,
.x = 768,
}
},
.n_crtcs = 2,
@ -4685,10 +4647,12 @@ meta_test_monitor_custom_second_rotated_config (void)
.crtcs = {
{
.current_mode = 0,
.y = 256,
},
{
.current_mode = 0,
.transform = META_MONITOR_TRANSFORM_90
.transform = META_MONITOR_TRANSFORM_90,
.x = 1024,
}
},
.n_crtcs = 2,
@ -4859,16 +4823,18 @@ meta_test_monitor_custom_second_rotated_tiled_config (void)
.crtcs = {
{
.current_mode = 0,
.y = 256,
},
{
.current_mode = 1,
.transform = META_MONITOR_TRANSFORM_90,
.x = 0,
.x = 1024,
.y = 400,
},
{
.current_mode = 1,
.transform = META_MONITOR_TRANSFORM_90
.transform = META_MONITOR_TRANSFORM_90,
.x = 1024,
}
},
.n_crtcs = 3,
@ -5008,10 +4974,12 @@ meta_test_monitor_custom_second_rotated_nonnative_config (void)
.crtcs = {
{
.current_mode = 0,
.y = 256,
},
{
.current_mode = 0,
.transform = META_MONITOR_TRANSFORM_NORMAL
.transform = META_MONITOR_TRANSFORM_NORMAL,
.x = 1024,
}
},
.n_crtcs = 2,
@ -5423,6 +5391,7 @@ meta_test_monitor_custom_lid_switch_config (void)
test_case.expect.n_outputs = 2;
test_case.expect.crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
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.logical_monitors[0].layout =
(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[1].transform = META_MONITOR_TRANSFORM_90;
test_case.expect.crtcs[1].x = 0;
test_case.expect.monitors[0].current_mode = -1;
test_case.expect.logical_monitors[0].layout =
(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[1].current_mode = 0;
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.logical_monitors[0].layout =
(MetaRectangle) { .width = 1024, .height = 768 };