diff options
Diffstat (limited to 'src/backends/native/meta-output-kms.c')
-rw-r--r-- | src/backends/native/meta-output-kms.c | 414 |
1 files changed, 0 insertions, 414 deletions
diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c deleted file mode 100644 index f35cdf04e..000000000 --- a/src/backends/native/meta-output-kms.c +++ /dev/null @@ -1,414 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* - * Copyright (C) 2013-2017 Red Hat - * Copyright (C) 2018 DisplayLink (UK) Ltd. - * - * 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-output-kms.h" - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include "backends/meta-crtc.h" -#include "backends/native/meta-kms-connector.h" -#include "backends/native/meta-kms-device.h" -#include "backends/native/meta-kms-mode.h" -#include "backends/native/meta-kms-update.h" -#include "backends/native/meta-kms-utils.h" -#include "backends/native/meta-crtc-kms.h" -#include "backends/native/meta-crtc-mode-kms.h" - -#define SYNC_TOLERANCE 0.01 /* 1 percent */ - -struct _MetaOutputKms -{ - MetaOutputNative parent; - - MetaKmsConnector *kms_connector; -}; - -G_DEFINE_TYPE (MetaOutputKms, meta_output_kms, META_TYPE_OUTPUT_NATIVE) - -MetaKmsConnector * -meta_output_kms_get_kms_connector (MetaOutputKms *output_kms) -{ - return output_kms->kms_connector; -} - -void -meta_output_kms_set_underscan (MetaOutputKms *output_kms, - MetaKmsUpdate *kms_update) -{ - MetaOutput *output = META_OUTPUT (output_kms); - const MetaOutputInfo *output_info = meta_output_get_info (output); - - if (!output_info->supports_underscanning) - return; - - if (meta_output_is_underscanning (output)) - { - MetaCrtc *crtc; - const MetaCrtcConfig *crtc_config; - const MetaCrtcModeInfo *crtc_mode_info; - uint64_t hborder, vborder; - - crtc = meta_output_get_assigned_crtc (output); - crtc_config = meta_crtc_get_config (crtc); - crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode); - - hborder = MIN (128, (uint64_t) round (crtc_mode_info->width * 0.05)); - vborder = MIN (128, (uint64_t) round (crtc_mode_info->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), - hborder, vborder); - - meta_kms_update_set_underscanning (kms_update, - output_kms->kms_connector, - hborder, vborder); - } - else - { - g_debug ("Unsetting underscan of connector %s", - meta_kms_connector_get_name (output_kms->kms_connector)); - - meta_kms_update_unset_underscanning (kms_update, - output_kms->kms_connector); - } -} - -uint32_t -meta_output_kms_get_connector_id (MetaOutputKms *output_kms) -{ - return meta_kms_connector_get_id (output_kms->kms_connector); -} - -gboolean -meta_output_kms_can_clone (MetaOutputKms *output_kms, - MetaOutputKms *other_output_kms) -{ - return meta_kms_connector_can_clone (output_kms->kms_connector, - other_output_kms->kms_connector); -} - -static GBytes * -meta_output_kms_read_edid (MetaOutputNative *output_native) -{ - MetaOutputKms *output_kms = META_OUTPUT_KMS (output_native); - const MetaKmsConnectorState *connector_state; - GBytes *edid_data; - - connector_state = - meta_kms_connector_get_current_state (output_kms->kms_connector); - edid_data = connector_state->edid_data; - if (!edid_data) - return NULL; - - return g_bytes_new_from_bytes (edid_data, 0, g_bytes_get_size (edid_data)); -} - -static void -add_common_modes (MetaOutputInfo *output_info, - MetaGpuKms *gpu_kms) -{ - MetaCrtcMode *crtc_mode; - GPtrArray *array; - float refresh_rate; - unsigned i; - unsigned max_hdisplay = 0; - unsigned max_vdisplay = 0; - float max_refresh_rate = 0.0; - float max_bandwidth = 0.0; - MetaKmsDevice *kms_device; - MetaKmsModeFlag flag_filter; - GList *l; - - for (i = 0; i < output_info->n_modes; i++) - { - MetaCrtcMode *crtc_mode = output_info->modes[i]; - MetaCrtcModeKms *crtc_mode_kms = META_CRTC_MODE_KMS (crtc_mode); - MetaKmsMode *kms_mode = meta_crtc_mode_kms_get_kms_mode (crtc_mode_kms); - const drmModeModeInfo *drm_mode = meta_kms_mode_get_drm_mode (kms_mode); - float bandwidth; - - refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); - bandwidth = refresh_rate * drm_mode->hdisplay * drm_mode->vdisplay; - max_hdisplay = MAX (max_hdisplay, drm_mode->hdisplay); - max_vdisplay = MAX (max_vdisplay, drm_mode->vdisplay); - max_refresh_rate = MAX (max_refresh_rate, refresh_rate); - max_bandwidth = MAX (max_bandwidth, bandwidth); - } - - max_refresh_rate = MAX (max_refresh_rate, 60.0); - max_refresh_rate *= (1 + SYNC_TOLERANCE); - - kms_device = meta_gpu_kms_get_kms_device (gpu_kms); - - array = g_ptr_array_new (); - - if (max_hdisplay > max_vdisplay) - flag_filter = META_KMS_MODE_FLAG_FALLBACK_LANDSCAPE; - else - flag_filter = META_KMS_MODE_FLAG_FALLBACK_PORTRAIT; - - for (l = meta_kms_device_get_fallback_modes (kms_device); l; l = l->next) - { - MetaKmsMode *fallback_mode = l->data; - const drmModeModeInfo *drm_mode; - float bandwidth; - - if (!(meta_kms_mode_get_flags (fallback_mode) & flag_filter)) - continue; - - drm_mode = meta_kms_mode_get_drm_mode (fallback_mode); - refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); - bandwidth = refresh_rate * drm_mode->hdisplay * drm_mode->vdisplay; - if (drm_mode->hdisplay > max_hdisplay || - drm_mode->vdisplay > max_vdisplay || - refresh_rate > max_refresh_rate || - bandwidth > max_bandwidth) - continue; - - crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, fallback_mode); - g_ptr_array_add (array, crtc_mode); - } - - output_info->modes = g_renew (MetaCrtcMode *, output_info->modes, - output_info->n_modes + array->len); - memcpy (output_info->modes + output_info->n_modes, array->pdata, - array->len * sizeof (MetaCrtcMode *)); - output_info->n_modes += array->len; - - g_ptr_array_free (array, TRUE); -} - -static int -compare_modes (const void *one, - const void *two) -{ - MetaCrtcMode *crtc_mode_one = *(MetaCrtcMode **) one; - MetaCrtcMode *crtc_mode_two = *(MetaCrtcMode **) two; - const MetaCrtcModeInfo *crtc_mode_info_one = - meta_crtc_mode_get_info (crtc_mode_one); - const MetaCrtcModeInfo *crtc_mode_info_two = - meta_crtc_mode_get_info (crtc_mode_two); - - if (crtc_mode_info_one->width != crtc_mode_info_two->width) - return crtc_mode_info_one->width > crtc_mode_info_two->width ? -1 : 1; - if (crtc_mode_info_one->height != crtc_mode_info_two->height) - return crtc_mode_info_one->height > crtc_mode_info_two->height ? -1 : 1; - if (crtc_mode_info_one->refresh_rate != crtc_mode_info_two->refresh_rate) - return (crtc_mode_info_one->refresh_rate > crtc_mode_info_two->refresh_rate - ? -1 : 1); - - return g_strcmp0 (meta_crtc_mode_get_name (crtc_mode_one), - meta_crtc_mode_get_name (crtc_mode_two)); -} - -static gboolean -init_output_modes (MetaOutputInfo *output_info, - MetaGpuKms *gpu_kms, - MetaKmsConnector *kms_connector, - GError **error) -{ - const MetaKmsConnectorState *connector_state; - GList *l; - int i; - - connector_state = meta_kms_connector_get_current_state (kms_connector); - - output_info->preferred_mode = NULL; - - output_info->n_modes = g_list_length (connector_state->modes); - output_info->modes = g_new0 (MetaCrtcMode *, output_info->n_modes); - for (l = connector_state->modes, i = 0; l; l = l->next, i++) - { - MetaKmsMode *kms_mode = l->data; - const drmModeModeInfo *drm_mode = meta_kms_mode_get_drm_mode (kms_mode); - MetaCrtcMode *crtc_mode; - - crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, kms_mode); - output_info->modes[i] = crtc_mode; - if (drm_mode->type & DRM_MODE_TYPE_PREFERRED) - output_info->preferred_mode = output_info->modes[i]; - } - - if (connector_state->has_scaling) - { - meta_topic (META_DEBUG_KMS, "Adding common modes to connector %u on %s", - meta_kms_connector_get_id (kms_connector), - meta_gpu_kms_get_file_path (gpu_kms)); - add_common_modes (output_info, gpu_kms); - } - - if (!output_info->modes) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "No modes available"); - return FALSE; - } - - qsort (output_info->modes, output_info->n_modes, - sizeof (MetaCrtcMode *), compare_modes); - - if (!output_info->preferred_mode) - output_info->preferred_mode = output_info->modes[0]; - - return TRUE; -} - -static MetaConnectorType -meta_kms_connector_type_from_drm (uint32_t drm_connector_type) -{ - g_warn_if_fail (drm_connector_type < META_CONNECTOR_TYPE_META); - - return (MetaConnectorType) drm_connector_type; -} - -MetaOutputKms * -meta_output_kms_new (MetaGpuKms *gpu_kms, - MetaKmsConnector *kms_connector, - MetaOutput *old_output, - GError **error) -{ - MetaGpu *gpu = META_GPU (gpu_kms); - uint32_t connector_id; - uint32_t gpu_id; - g_autoptr (MetaOutputInfo) output_info = NULL; - MetaOutput *output; - MetaOutputKms *output_kms; - uint32_t drm_connector_type; - const MetaKmsConnectorState *connector_state; - GArray *crtcs; - GList *l; - - gpu_id = meta_gpu_kms_get_id (gpu_kms); - connector_id = meta_kms_connector_get_id (kms_connector); - - output_info = meta_output_info_new (); - output_info->name = g_strdup (meta_kms_connector_get_name (kms_connector)); - - connector_state = meta_kms_connector_get_current_state (kms_connector); - - output_info->panel_orientation_transform = - connector_state->panel_orientation_transform; - if (meta_monitor_transform_is_rotated (output_info->panel_orientation_transform)) - { - output_info->width_mm = connector_state->height_mm; - output_info->height_mm = connector_state->width_mm; - } - else - { - output_info->width_mm = connector_state->width_mm; - output_info->height_mm = connector_state->height_mm; - } - - if (!init_output_modes (output_info, gpu_kms, kms_connector, error)) - return NULL; - - crtcs = g_array_new (FALSE, FALSE, sizeof (MetaCrtc *)); - - for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) - { - MetaCrtcKms *crtc_kms = META_CRTC_KMS (l->data); - MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); - uint32_t crtc_idx; - - crtc_idx = meta_kms_crtc_get_idx (kms_crtc); - if (connector_state->common_possible_crtcs & (1 << crtc_idx)) - g_array_append_val (crtcs, crtc_kms); - } - - output_info->n_possible_crtcs = crtcs->len; - output_info->possible_crtcs = (MetaCrtc **) g_array_free (crtcs, FALSE); - - output_info->suggested_x = connector_state->suggested_x; - output_info->suggested_y = connector_state->suggested_y; - output_info->hotplug_mode_update = connector_state->hotplug_mode_update; - output_info->supports_underscanning = - meta_kms_connector_is_underscanning_supported (kms_connector); - - meta_output_info_parse_edid (output_info, connector_state->edid_data); - - drm_connector_type = meta_kms_connector_get_connector_type (kms_connector); - output_info->connector_type = - meta_kms_connector_type_from_drm (drm_connector_type); - - output_info->tile_info = connector_state->tile_info; - - output = g_object_new (META_TYPE_OUTPUT_KMS, - "id", ((uint64_t) gpu_id << 32) | connector_id, - "gpu", gpu, - "info", output_info, - NULL); - output_kms = META_OUTPUT_KMS (output); - output_kms->kms_connector = kms_connector; - - if (connector_state->current_crtc_id) - { - for (l = meta_gpu_get_crtcs (gpu); l; l = l->next) - { - MetaCrtc *crtc = l->data; - - if (meta_crtc_get_id (crtc) == connector_state->current_crtc_id) - { - MetaOutputAssignment output_assignment; - - if (old_output) - { - output_assignment = (MetaOutputAssignment) { - .is_primary = meta_output_is_primary (old_output), - .is_presentation = meta_output_is_presentation (old_output), - }; - } - else - { - output_assignment = (MetaOutputAssignment) { - .is_primary = FALSE, - .is_presentation = FALSE, - }; - } - meta_output_assign_crtc (output, crtc, &output_assignment); - break; - } - } - } - else - { - meta_output_unassign_crtc (output); - } - - return output_kms; -} - -static void -meta_output_kms_init (MetaOutputKms *output_kms) -{ -} - -static void -meta_output_kms_class_init (MetaOutputKmsClass *klass) -{ - MetaOutputNativeClass *output_native_class = META_OUTPUT_NATIVE_CLASS (klass); - - output_native_class->read_edid = meta_output_kms_read_edid; -} |