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
This commit is contained in:
parent
cfee58798e
commit
de40ced8b4
@ -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 \
|
||||
|
365
src/backends/native/meta-crtc-kms.c
Normal file
365
src/backends/native/meta-crtc-kms.c
Normal file
@ -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;
|
||||
}
|
42
src/backends/native/meta-crtc-kms.h
Normal file
42
src/backends/native/meta-crtc-kms.h
Normal file
@ -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 <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#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 */
|
@ -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 <string.h>
|
||||
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#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)
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user