From de40ced8b413a852d15ff235c750c945a5faaea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 4 Jul 2017 16:04:39 +0800 Subject: [PATCH] backends/native: Move CRTC code to its own file Move code dealing with MetaCrtcKms and related functionality to its own file. Eventually, MetaCrtcKms should become a GObject based on MetaCrtc, and this commit is in preparation for that. https://bugzilla.gnome.org/show_bug.cgi?id=785381 --- src/Makefile.am | 2 + src/backends/native/meta-crtc-kms.c | 365 ++++++++++++++++++ src/backends/native/meta-crtc-kms.h | 42 ++ .../native/meta-monitor-manager-kms.c | 355 ++--------------- .../native/meta-monitor-manager-kms.h | 3 + src/backends/native/meta-output-kms.c | 11 + src/backends/native/meta-output-kms.h | 2 + 7 files changed, 455 insertions(+), 325 deletions(-) create mode 100644 src/backends/native/meta-crtc-kms.c create mode 100644 src/backends/native/meta-crtc-kms.h diff --git a/src/Makefile.am b/src/Makefile.am index c98578416..afcbc3e7e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -444,6 +444,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES += \ backends/native/meta-backend-native-private.h \ backends/native/meta-barrier-native.c \ backends/native/meta-barrier-native.h \ + backends/native/meta-crtc-kms.c \ + backends/native/meta-crtc-kms.h \ backends/native/meta-clutter-backend-native.c \ backends/native/meta-clutter-backend-native.h \ backends/native/meta-cursor-renderer-native.c \ diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c new file mode 100644 index 000000000..0531452d6 --- /dev/null +++ b/src/backends/native/meta-crtc-kms.c @@ -0,0 +1,365 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2013-2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "backends/native/meta-crtc-kms.h" + +#include "backends/meta-backend-private.h" +#include "backends/native/meta-monitor-manager-kms.h" + +#define ALL_TRANSFORMS (META_MONITOR_TRANSFORM_FLIPPED_270 + 1) +#define ALL_TRANSFORMS_MASK ((1 << ALL_TRANSFORMS) - 1) + +typedef struct _MetaCrtcKms +{ + unsigned int index; + uint32_t underscan_prop_id; + uint32_t underscan_hborder_prop_id; + uint32_t underscan_vborder_prop_id; + uint32_t primary_plane_id; + uint32_t rotation_prop_id; + uint32_t rotation_map[ALL_TRANSFORMS]; + uint32_t all_hw_transforms; +} MetaCrtcKms; + +gboolean +meta_crtc_kms_is_transform_handled (MetaCrtc *crtc, + MetaMonitorTransform transform) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + + if ((1 << transform) & crtc_kms->all_hw_transforms) + return TRUE; + else + return FALSE; +} + +void +meta_crtc_kms_apply_transform (MetaCrtc *crtc) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + MetaMonitorManager *monitor_manager = meta_crtc_get_monitor_manager (crtc); + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); + int kms_fd; + MetaMonitorTransform hw_transform; + + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); + + if (crtc_kms->all_hw_transforms & (1 << crtc->transform)) + hw_transform = crtc->transform; + else + hw_transform = META_MONITOR_TRANSFORM_NORMAL; + + if (drmModeObjectSetProperty (kms_fd, + crtc_kms->primary_plane_id, + DRM_MODE_OBJECT_PLANE, + crtc_kms->rotation_prop_id, + crtc_kms->rotation_map[hw_transform]) != 0) + { + g_warning ("Failed to apply DRM plane transform %d: %m", hw_transform); + + /* + * Blacklist this HW transform, we want to fallback to our + * fallbacks in this case. + */ + crtc_kms->all_hw_transforms &= ~(1 << hw_transform); + } +} + +void +meta_crtc_kms_set_underscan (MetaCrtc *crtc, + gboolean is_underscanning) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + MetaMonitorManager *monitor_manager = meta_crtc_get_monitor_manager (crtc); + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); + int kms_fd; + + if (!crtc_kms->underscan_prop_id) + return; + + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); + + if (is_underscanning) + { + drmModeObjectSetProperty (kms_fd, crtc->crtc_id, + DRM_MODE_OBJECT_CRTC, + crtc_kms->underscan_prop_id, (uint64_t) 1); + + if (crtc_kms->underscan_hborder_prop_id) + { + uint64_t value; + + value = crtc->current_mode->width * 0.05; + drmModeObjectSetProperty (kms_fd, crtc->crtc_id, + DRM_MODE_OBJECT_CRTC, + crtc_kms->underscan_hborder_prop_id, value); + } + if (crtc_kms->underscan_vborder_prop_id) + { + uint64_t value; + + value = crtc->current_mode->height * 0.05; + drmModeObjectSetProperty (kms_fd, crtc->crtc_id, + DRM_MODE_OBJECT_CRTC, + crtc_kms->underscan_vborder_prop_id, value); + } + + } + else + { + drmModeObjectSetProperty (kms_fd, crtc->crtc_id, + DRM_MODE_OBJECT_CRTC, + crtc_kms->underscan_prop_id, (uint64_t) 0); + } +} + +static int +find_property_index (MetaMonitorManager *monitor_manager, + drmModeObjectPropertiesPtr props, + const char *prop_name, + drmModePropertyPtr *out_prop) +{ + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); + int kms_fd; + unsigned int i; + + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); + + for (i = 0; i < props->count_props; i++) + { + drmModePropertyPtr prop; + + prop = drmModeGetProperty (kms_fd, props->props[i]); + if (!prop) + continue; + + if (strcmp (prop->name, prop_name) == 0) + { + *out_prop = prop; + return i; + } + + drmModeFreeProperty (prop); + } + + return -1; +} + +static void +parse_transforms (MetaCrtc *crtc, + drmModePropertyPtr prop) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + int i; + + for (i = 0; i < prop->count_enums; i++) + { + int transform = -1; + + if (strcmp (prop->enums[i].name, "rotate-0") == 0) + transform = META_MONITOR_TRANSFORM_NORMAL; + else if (strcmp (prop->enums[i].name, "rotate-90") == 0) + transform = META_MONITOR_TRANSFORM_90; + else if (strcmp (prop->enums[i].name, "rotate-180") == 0) + transform = META_MONITOR_TRANSFORM_180; + else if (strcmp (prop->enums[i].name, "rotate-270") == 0) + transform = META_MONITOR_TRANSFORM_270; + + if (transform != -1) + { + crtc_kms->all_hw_transforms |= 1 << transform; + crtc_kms->rotation_map[transform] = 1 << prop->enums[i].value; + } + } +} + +static gboolean +is_primary_plane (MetaMonitorManager *monitor_manager, + drmModeObjectPropertiesPtr props) +{ + drmModePropertyPtr prop; + int idx; + + idx = find_property_index (monitor_manager, props, "type", &prop); + if (idx < 0) + return FALSE; + + drmModeFreeProperty (prop); + return props->prop_values[idx] == DRM_PLANE_TYPE_PRIMARY; +} + +static void +init_crtc_rotations (MetaCrtc *crtc, + MetaMonitorManager *monitor_manager) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); + int kms_fd; + drmModeObjectPropertiesPtr props; + drmModePlaneRes *planes; + drmModePlane *drm_plane; + unsigned int i; + + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); + + planes = drmModeGetPlaneResources (kms_fd); + if (planes == NULL) + return; + + for (i = 0; i < planes->count_planes; i++) + { + drmModePropertyPtr prop; + + drm_plane = drmModeGetPlane (kms_fd, planes->planes[i]); + + if (!drm_plane) + continue; + + if ((drm_plane->possible_crtcs & (1 << crtc_kms->index))) + { + props = drmModeObjectGetProperties (kms_fd, + drm_plane->plane_id, + DRM_MODE_OBJECT_PLANE); + + if (props && is_primary_plane (monitor_manager, props)) + { + int rotation_idx; + + crtc_kms->primary_plane_id = drm_plane->plane_id; + rotation_idx = find_property_index (monitor_manager, props, + "rotation", &prop); + if (rotation_idx >= 0) + { + crtc_kms->rotation_prop_id = props->props[rotation_idx]; + parse_transforms (crtc, prop); + drmModeFreeProperty (prop); + } + } + + if (props) + drmModeFreeObjectProperties (props); + } + + drmModeFreePlane (drm_plane); + } + + crtc->all_transforms |= crtc_kms->all_hw_transforms; + + drmModeFreePlaneResources (planes); +} + +static void +find_crtc_properties (MetaCrtc *crtc, + MetaMonitorManagerKms *monitor_manager_kms) +{ + MetaCrtcKms *crtc_kms = crtc->driver_private; + int kms_fd; + drmModeObjectPropertiesPtr props; + unsigned int i; + + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); + props = drmModeObjectGetProperties (kms_fd, crtc->crtc_id, + DRM_MODE_OBJECT_CRTC); + if (!props) + return; + + for (i = 0; i < props->count_props; i++) + { + drmModePropertyPtr prop = drmModeGetProperty (kms_fd, props->props[i]); + if (!prop) + continue; + + if ((prop->flags & DRM_MODE_PROP_ENUM) && + strcmp (prop->name, "underscan") == 0) + crtc_kms->underscan_prop_id = prop->prop_id; + else if ((prop->flags & DRM_MODE_PROP_RANGE) && + strcmp (prop->name, "underscan hborder") == 0) + crtc_kms->underscan_hborder_prop_id = prop->prop_id; + else if ((prop->flags & DRM_MODE_PROP_RANGE) && + strcmp (prop->name, "underscan vborder") == 0) + crtc_kms->underscan_vborder_prop_id = prop->prop_id; + + drmModeFreeProperty (prop); + } +} + +static void +meta_crtc_destroy_notify (MetaCrtc *crtc) +{ + g_free (crtc->driver_private); +} + +MetaCrtc * +meta_create_kms_crtc (MetaMonitorManager *monitor_manager, + drmModeCrtc *drm_crtc, + unsigned int crtc_index) +{ + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); + MetaCrtc *crtc; + MetaCrtcKms *crtc_kms; + + crtc = g_object_new (META_TYPE_CRTC, NULL); + + crtc->monitor_manager = monitor_manager; + crtc->crtc_id = drm_crtc->crtc_id; + crtc->rect.x = drm_crtc->x; + crtc->rect.y = drm_crtc->y; + crtc->rect.width = drm_crtc->width; + crtc->rect.height = drm_crtc->height; + crtc->is_dirty = FALSE; + crtc->transform = META_MONITOR_TRANSFORM_NORMAL; + crtc->all_transforms = meta_is_stage_views_enabled () ? + ALL_TRANSFORMS_MASK : META_MONITOR_TRANSFORM_NORMAL; + + if (drm_crtc->mode_valid) + { + GList *l; + + for (l = monitor_manager->modes; l; l = l->next) + { + MetaCrtcMode *mode = l->data; + + if (meta_drm_mode_equal (&drm_crtc->mode, mode->driver_private)) + { + crtc->current_mode = mode; + break; + } + } + } + + crtc_kms = g_new0 (MetaCrtcKms, 1); + crtc_kms->index = crtc_index; + + crtc->driver_private = crtc_kms; + crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify; + + find_crtc_properties (crtc, monitor_manager_kms); + init_crtc_rotations (crtc, monitor_manager); + + return crtc; +} diff --git a/src/backends/native/meta-crtc-kms.h b/src/backends/native/meta-crtc-kms.h new file mode 100644 index 000000000..7abad147c --- /dev/null +++ b/src/backends/native/meta-crtc-kms.h @@ -0,0 +1,42 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* + * Copyright (C) 2017 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef META_CRTC_KMS_H +#define META_CRTC_KMS_H + +#include +#include + +#include "backends/meta-crtc.h" + +gboolean meta_crtc_kms_is_transform_handled (MetaCrtc *crtc, + MetaMonitorTransform transform); + +void meta_crtc_kms_apply_transform (MetaCrtc *crtc); + +void meta_crtc_kms_set_underscan (MetaCrtc *crtc, + gboolean is_underscanning); + +MetaCrtc * meta_create_kms_crtc (MetaMonitorManager *monitor_manager, + drmModeCrtc *drm_crtc, + unsigned int crtc_index); + +#endif /* META_CRTC_KMS_H */ diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index cb10c43b6..e96dded32 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -29,6 +29,7 @@ #include "meta-output.h" #include "meta-backend-private.h" #include "meta-renderer-native.h" +#include "meta-crtc-kms.h" #include "meta-output-kms.h" #include @@ -48,20 +49,6 @@ #include "meta-default-modes.h" -#define ALL_TRANSFORMS (META_MONITOR_TRANSFORM_FLIPPED_270 + 1) -#define ALL_TRANSFORMS_MASK ((1 << ALL_TRANSFORMS) - 1) - -typedef struct -{ - uint32_t underscan_prop_id; - uint32_t underscan_hborder_prop_id; - uint32_t underscan_vborder_prop_id; - uint32_t primary_plane_id; - uint32_t rotation_prop_id; - uint32_t rotation_map[ALL_TRANSFORMS]; - uint32_t all_hw_transforms; -} MetaCrtcKms; - typedef struct { GSource source; @@ -128,34 +115,25 @@ meta_monitor_mode_destroy_notify (MetaCrtcMode *mode) g_slice_free (drmModeModeInfo, mode->driver_private); } -static void -meta_crtc_destroy_notify (MetaCrtc *crtc) +gboolean +meta_drm_mode_equal (const drmModeModeInfo *one, + const drmModeModeInfo *two) { - g_free (crtc->driver_private); -} - -static gboolean -drm_mode_equal (gconstpointer one, - gconstpointer two) -{ - const drmModeModeInfo *m_one = one; - const drmModeModeInfo *m_two = two; - - return m_one->clock == m_two->clock && - m_one->hdisplay == m_two->hdisplay && - m_one->hsync_start == m_two->hsync_start && - m_one->hsync_end == m_two->hsync_end && - m_one->htotal == m_two->htotal && - m_one->hskew == m_two->hskew && - m_one->vdisplay == m_two->vdisplay && - m_one->vsync_start == m_two->vsync_start && - m_one->vsync_end == m_two->vsync_end && - m_one->vtotal == m_two->vtotal && - m_one->vscan == m_two->vscan && - m_one->vrefresh == m_two->vrefresh && - m_one->flags == m_two->flags && - m_one->type == m_two->type && - strncmp (m_one->name, m_two->name, DRM_DISPLAY_MODE_LEN) == 0; + return (one->clock == two->clock && + one->hdisplay == two->hdisplay && + one->hsync_start == two->hsync_start && + one->hsync_end == two->hsync_end && + one->htotal == two->htotal && + one->hskew == two->hskew && + one->vdisplay == two->vdisplay && + one->vsync_start == two->vsync_start && + one->vsync_end == two->vsync_end && + one->vtotal == two->vtotal && + one->vscan == two->vscan && + one->vrefresh == two->vrefresh && + one->flags == two->flags && + one->type == two->type && + strncmp (one->name, two->name, DRM_DISPLAY_MODE_LEN) == 0); } static guint @@ -177,37 +155,6 @@ drm_mode_hash (gconstpointer ptr) return hash; } -static void -find_crtc_properties (MetaMonitorManagerKms *manager_kms, - MetaCrtc *meta_crtc) -{ - MetaCrtcKms *crtc_kms; - drmModeObjectPropertiesPtr props; - size_t i; - - crtc_kms = meta_crtc->driver_private; - - props = drmModeObjectGetProperties (manager_kms->fd, meta_crtc->crtc_id, DRM_MODE_OBJECT_CRTC); - if (!props) - return; - - for (i = 0; i < props->count_props; i++) - { - drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, props->props[i]); - if (!prop) - continue; - - if ((prop->flags & DRM_MODE_PROP_ENUM) && strcmp (prop->name, "underscan") == 0) - crtc_kms->underscan_prop_id = prop->prop_id; - else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan hborder") == 0) - crtc_kms->underscan_hborder_prop_id = prop->prop_id; - else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan vborder") == 0) - crtc_kms->underscan_vborder_prop_id = prop->prop_id; - - drmModeFreeProperty (prop); - } -} - MetaCrtcMode * meta_monitor_manager_kms_get_mode_from_drm_mode (MetaMonitorManagerKms *manager_kms, const drmModeModeInfo *drm_mode) @@ -219,7 +166,7 @@ meta_monitor_manager_kms_get_mode_from_drm_mode (MetaMonitorManagerKms *manager_ { MetaCrtcMode *mode = l->data; - if (drm_mode_equal (drm_mode, mode->driver_private)) + if (meta_drm_mode_equal (drm_mode, mode->driver_private)) return mode; } @@ -281,180 +228,6 @@ find_output_by_id (GList *outputs, return NULL; } -static int -find_property_index (MetaMonitorManager *manager, - drmModeObjectPropertiesPtr props, - const gchar *prop_name, - drmModePropertyPtr *found) -{ - MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager); - unsigned int i; - - for (i = 0; i < props->count_props; i++) - { - drmModePropertyPtr prop; - - prop = drmModeGetProperty (manager_kms->fd, props->props[i]); - if (!prop) - continue; - - if (strcmp (prop->name, prop_name) == 0) - { - *found = prop; - return i; - } - - drmModeFreeProperty (prop); - } - - return -1; -} - -static void -parse_transforms (MetaMonitorManager *manager, - drmModePropertyPtr prop, - MetaCrtc *crtc) -{ - MetaCrtcKms *crtc_kms = crtc->driver_private; - int i; - - for (i = 0; i < prop->count_enums; i++) - { - int cur = -1; - - if (strcmp (prop->enums[i].name, "rotate-0") == 0) - cur = META_MONITOR_TRANSFORM_NORMAL; - else if (strcmp (prop->enums[i].name, "rotate-90") == 0) - cur = META_MONITOR_TRANSFORM_90; - else if (strcmp (prop->enums[i].name, "rotate-180") == 0) - cur = META_MONITOR_TRANSFORM_180; - else if (strcmp (prop->enums[i].name, "rotate-270") == 0) - cur = META_MONITOR_TRANSFORM_270; - - if (cur != -1) - { - crtc_kms->all_hw_transforms |= 1 << cur; - crtc_kms->rotation_map[cur] = 1 << prop->enums[i].value; - } - } -} - -static gboolean -is_primary_plane (MetaMonitorManager *manager, - drmModeObjectPropertiesPtr props) -{ - drmModePropertyPtr prop; - int idx; - - idx = find_property_index (manager, props, "type", &prop); - if (idx < 0) - return FALSE; - - drmModeFreeProperty (prop); - return props->prop_values[idx] == DRM_PLANE_TYPE_PRIMARY; -} - -static void -init_crtc_rotations (MetaMonitorManager *manager, - MetaCrtc *crtc, - unsigned int idx) -{ - MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager); - drmModeObjectPropertiesPtr props; - drmModePlaneRes *planes; - drmModePlane *drm_plane; - MetaCrtcKms *crtc_kms; - unsigned int i; - - crtc_kms = crtc->driver_private; - - planes = drmModeGetPlaneResources(manager_kms->fd); - if (planes == NULL) - return; - - for (i = 0; i < planes->count_planes; i++) - { - drmModePropertyPtr prop; - - drm_plane = drmModeGetPlane (manager_kms->fd, planes->planes[i]); - - if (!drm_plane) - continue; - - if ((drm_plane->possible_crtcs & (1 << idx))) - { - props = drmModeObjectGetProperties (manager_kms->fd, - drm_plane->plane_id, - DRM_MODE_OBJECT_PLANE); - - if (props && is_primary_plane (manager, props)) - { - int rotation_idx; - - crtc_kms->primary_plane_id = drm_plane->plane_id; - rotation_idx = find_property_index (manager, props, "rotation", &prop); - - if (rotation_idx >= 0) - { - crtc_kms->rotation_prop_id = props->props[rotation_idx]; - parse_transforms (manager, prop, crtc); - drmModeFreeProperty (prop); - } - } - - if (props) - drmModeFreeObjectProperties (props); - } - - drmModeFreePlane (drm_plane); - } - - crtc->all_transforms |= crtc_kms->all_hw_transforms; - - drmModeFreePlaneResources (planes); -} - -static MetaCrtc * -create_crtc (MetaMonitorManager *manager, - drmModeCrtc *drm_crtc) -{ - MetaCrtc *crtc; - - crtc = g_object_new (META_TYPE_CRTC, NULL); - - crtc->monitor_manager = manager; - crtc->crtc_id = drm_crtc->crtc_id; - crtc->rect.x = drm_crtc->x; - crtc->rect.y = drm_crtc->y; - crtc->rect.width = drm_crtc->width; - crtc->rect.height = drm_crtc->height; - crtc->is_dirty = FALSE; - crtc->transform = META_MONITOR_TRANSFORM_NORMAL; - crtc->all_transforms = meta_is_stage_views_enabled () ? - ALL_TRANSFORMS_MASK : META_MONITOR_TRANSFORM_NORMAL; - - if (drm_crtc->mode_valid) - { - GList *l; - - for (l = manager->modes; l; l = l->next) - { - MetaCrtcMode *mode = l->data; - - if (drm_mode_equal (&drm_crtc->mode, mode->driver_private)) - { - crtc->current_mode = mode; - break; - } - } - } - - crtc->driver_private = g_new0 (MetaCrtcKms, 1); - crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify; - - return crtc; -} - static void setup_output_clones (MetaMonitorManager *manager) { @@ -518,7 +291,7 @@ init_modes (MetaMonitorManager *manager, /* * Gather all modes on all connected connectors. */ - modes = g_hash_table_new (drm_mode_hash, drm_mode_equal); + modes = g_hash_table_new (drm_mode_hash, (GEqualFunc) meta_drm_mode_equal); for (i = 0; i < manager_kms->n_connectors; i++) { drmModeConnector *drm_connector; @@ -562,23 +335,22 @@ init_modes (MetaMonitorManager *manager, static void init_crtcs (MetaMonitorManager *manager, - drmModeRes *resources) + MetaKmsResources *resources) { MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager); unsigned int i; manager->crtcs = NULL; - for (i = 0; i < (unsigned)resources->count_crtcs; i++) + for (i = 0; i < (unsigned int) resources->resources->count_crtcs; i++) { drmModeCrtc *drm_crtc; MetaCrtc *crtc; - drm_crtc = drmModeGetCrtc (manager_kms->fd, resources->crtcs[i]); + drm_crtc = drmModeGetCrtc (manager_kms->fd, + resources->resources->crtcs[i]); - crtc = create_crtc (manager, drm_crtc); - find_crtc_properties (manager_kms, crtc); - init_crtc_rotations (manager, crtc, i); + crtc = meta_create_kms_crtc (manager, drm_crtc, i); drmModeFreeCrtc (drm_crtc); @@ -671,7 +443,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager) init_connectors (manager, resources.resources); init_modes (manager, resources.resources); - init_crtcs (manager, resources.resources); + init_crtcs (manager, &resources); init_outputs (manager, &resources); meta_kms_resources_release (&resources); @@ -716,48 +488,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager, } } -static void -set_underscan (MetaMonitorManagerKms *manager_kms, - MetaOutput *output) -{ - if (!output->crtc) - return; - - MetaCrtc *crtc = output->crtc; - MetaCrtcKms *crtc_kms = crtc->driver_private; - if (!crtc_kms->underscan_prop_id) - return; - - if (output->is_underscanning) - { - drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id, - DRM_MODE_OBJECT_CRTC, - crtc_kms->underscan_prop_id, (uint64_t) 1); - - if (crtc_kms->underscan_hborder_prop_id) - { - uint64_t value = crtc->current_mode->width * 0.05; - drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id, - DRM_MODE_OBJECT_CRTC, - crtc_kms->underscan_hborder_prop_id, value); - } - if (crtc_kms->underscan_vborder_prop_id) - { - uint64_t value = crtc->current_mode->height * 0.05; - drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id, - DRM_MODE_OBJECT_CRTC, - crtc_kms->underscan_vborder_prop_id, value); - } - - } - else - { - drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id, - DRM_MODE_OBJECT_CRTC, - crtc_kms->underscan_prop_id, (uint64_t) 0); - } -} - static void meta_monitor_manager_kms_ensure_initial_config (MetaMonitorManager *manager) { @@ -775,7 +505,6 @@ apply_crtc_assignments (MetaMonitorManager *manager, MetaOutputInfo **outputs, unsigned int n_outputs) { - MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager); unsigned i; GList *l; @@ -783,8 +512,6 @@ apply_crtc_assignments (MetaMonitorManager *manager, { MetaCrtcInfo *crtc_info = crtcs[i]; MetaCrtc *crtc = crtc_info->crtc; - MetaCrtcKms *crtc_kms = crtc->driver_private; - MetaMonitorTransform hw_transform; crtc->is_dirty = TRUE; @@ -831,24 +558,7 @@ apply_crtc_assignments (MetaMonitorManager *manager, } } - if (crtc_kms->all_hw_transforms & (1 << crtc->transform)) - hw_transform = crtc->transform; - else - hw_transform = META_MONITOR_TRANSFORM_NORMAL; - - if (drmModeObjectSetProperty (manager_kms->fd, - crtc_kms->primary_plane_id, - DRM_MODE_OBJECT_PLANE, - crtc_kms->rotation_prop_id, - crtc_kms->rotation_map[hw_transform]) != 0) - { - g_warning ("Failed to apply DRM plane transform %d: %m", hw_transform); - - /* Blacklist this HW transform, we want to fallback to our - * fallbacks in this case. - */ - crtc_kms->all_hw_transforms &= ~(1 << hw_transform); - } + meta_crtc_kms_apply_transform (crtc); } /* Disable CRTCs not mentioned in the list (they have is_dirty == FALSE, because they weren't seen in the first loop) */ @@ -880,7 +590,7 @@ apply_crtc_assignments (MetaMonitorManager *manager, output->is_presentation = output_info->is_presentation; output->is_underscanning = output_info->is_underscanning; - set_underscan (manager_kms, output); + meta_output_kms_set_underscan (output); } /* Disable outputs not mentioned in the list */ @@ -1294,12 +1004,7 @@ meta_monitor_manager_kms_is_transform_handled (MetaMonitorManager *manager, MetaCrtc *crtc, MetaMonitorTransform transform) { - MetaCrtcKms *crtc_kms = crtc->driver_private; - - if ((1 << transform) & crtc_kms->all_hw_transforms) - return TRUE; - else - return FALSE; + return meta_crtc_kms_is_transform_handled (crtc, transform); } static float diff --git a/src/backends/native/meta-monitor-manager-kms.h b/src/backends/native/meta-monitor-manager-kms.h index 24d7c4e36..67ccbfef5 100644 --- a/src/backends/native/meta-monitor-manager-kms.h +++ b/src/backends/native/meta-monitor-manager-kms.h @@ -44,6 +44,9 @@ typedef void (*MetaKmsFlipCallback) (void *user_data); int meta_monitor_manager_kms_get_fd (MetaMonitorManagerKms *manager_kms); +gboolean meta_drm_mode_equal (const drmModeModeInfo *one, + const drmModeModeInfo *two); + MetaCrtcMode * meta_monitor_manager_kms_get_mode_from_drm_mode (MetaMonitorManagerKms *manager_kms, const drmModeModeInfo *drm_mode); diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index 6181c8c92..faa843234 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -28,6 +28,7 @@ #include #include "backends/meta-crtc.h" +#include "backends/native/meta-crtc-kms.h" #include "backends/native/meta-default-modes.h" #include "backends/native/meta-monitor-manager-kms.h" @@ -61,6 +62,16 @@ typedef struct _MetaOutputKms gboolean has_scaling; } MetaOutputKms; +void +meta_output_kms_set_underscan (MetaOutput *output) +{ + if (!output->crtc) + return; + + meta_crtc_kms_set_underscan (output->crtc, + output->is_underscanning); +} + void meta_output_kms_set_power_save_mode (MetaOutput *output, uint64_t state) diff --git a/src/backends/native/meta-output-kms.h b/src/backends/native/meta-output-kms.h index 61846a983..84ec17ad4 100644 --- a/src/backends/native/meta-output-kms.h +++ b/src/backends/native/meta-output-kms.h @@ -25,6 +25,8 @@ #include "backends/meta-output.h" #include "backends/native/meta-monitor-manager-kms.h" +void meta_output_kms_set_underscan (MetaOutput *output); + void meta_output_kms_set_power_save_mode (MetaOutput *output, uint64_t state);