[mutter] backends/native: Move CRTC code to its own file



commit de40ced8b413a852d15ff235c750c945a5faaea6
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Jul 4 16:04:39 2017 +0800

    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 +++
 src/backends/native/meta-monitor-manager-kms.c |  357 ++---------------------
 src/backends/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, 456 insertions(+), 326 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index c985784..afcbc3e 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 0000000..0531452
--- /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 0000000..7abad14
--- /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 <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 */
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index cb10c43..e96dded 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 <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)
-{
-  g_free (crtc->driver_private);
-}
-
-static gboolean
-drm_mode_equal (gconstpointer one,
-                gconstpointer two)
+gboolean
+meta_drm_mode_equal (const drmModeModeInfo *one,
+                     const drmModeModeInfo *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);
@@ -717,48 +489,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)
 {
   MetaMonitorsConfig *config;
@@ -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 24d7c4e..67ccbfe 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 6181c8c..faa8432 100644
--- a/src/backends/native/meta-output-kms.c
+++ b/src/backends/native/meta-output-kms.c
@@ -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"
 
@@ -62,6 +63,16 @@ typedef struct _MetaOutputKms
 } 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 61846a9..84ec17a 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);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]