diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c index 8c2fbfe3c..5d606907a 100644 --- a/src/backends/native/meta-crtc-kms.c +++ b/src/backends/native/meta-crtc-kms.c @@ -40,7 +40,8 @@ typedef struct _MetaCrtcKms { - unsigned int index; + MetaKmsCrtc *kms_crtc; + uint32_t primary_plane_id; uint32_t rotation_prop_id; uint32_t rotation_map[ALL_TRANSFORMS]; @@ -409,6 +410,7 @@ init_crtc_rotations (MetaCrtc *crtc, drmModePlaneRes *planes; drmModePlane *drm_plane; unsigned int i; + int crtc_idx; kms_fd = meta_gpu_kms_get_fd (gpu_kms); @@ -416,6 +418,7 @@ init_crtc_rotations (MetaCrtc *crtc, if (planes == NULL) return; + crtc_idx = meta_kms_crtc_get_idx (crtc_kms->kms_crtc); for (i = 0; i < planes->count_planes; i++) { drmModePropertyPtr prop; @@ -425,7 +428,7 @@ init_crtc_rotations (MetaCrtc *crtc, if (!drm_plane) continue; - if ((drm_plane->possible_crtcs & (1 << crtc_kms->index))) + if ((drm_plane->possible_crtcs & (1 << crtc_idx))) { props = drmModeObjectGetProperties (kms_fd, drm_plane->plane_id, @@ -493,8 +496,8 @@ meta_crtc_destroy_notify (MetaCrtc *crtc) MetaCrtc * meta_create_kms_crtc (MetaGpuKms *gpu_kms, - drmModeCrtc *drm_crtc, - unsigned int crtc_index) + MetaKmsCrtc *kms_crtc, + drmModeCrtc *drm_crtc) { MetaGpu *gpu = META_GPU (gpu_kms); MetaCrtc *crtc; @@ -503,7 +506,7 @@ meta_create_kms_crtc (MetaGpuKms *gpu_kms, crtc = g_object_new (META_TYPE_CRTC, NULL); crtc->gpu = gpu; - crtc->crtc_id = drm_crtc->crtc_id; + crtc->crtc_id = meta_kms_crtc_get_id (kms_crtc); crtc->rect.x = drm_crtc->x; crtc->rect.y = drm_crtc->y; crtc->rect.width = drm_crtc->width; @@ -529,7 +532,7 @@ meta_create_kms_crtc (MetaGpuKms *gpu_kms, } crtc_kms = g_new0 (MetaCrtcKms, 1); - crtc_kms->index = crtc_index; + crtc_kms->kms_crtc = kms_crtc; crtc_kms->formats_modifiers = g_hash_table_new_full (g_direct_hash, diff --git a/src/backends/native/meta-crtc-kms.h b/src/backends/native/meta-crtc-kms.h index 456f4400a..8e09614c9 100644 --- a/src/backends/native/meta-crtc-kms.h +++ b/src/backends/native/meta-crtc-kms.h @@ -29,6 +29,7 @@ #include "backends/meta-backend-types.h" #include "backends/meta-crtc.h" #include "backends/native/meta-gpu-kms.h" +#include "backends/native/meta-kms-crtc.h" typedef struct _MetaDrmFormatBuf { @@ -55,7 +56,7 @@ meta_crtc_kms_supports_format (MetaCrtc *crtc, uint32_t drm_format); MetaCrtc * meta_create_kms_crtc (MetaGpuKms *gpu_kms, - drmModeCrtc *drm_crtc, - unsigned int crtc_index); + MetaKmsCrtc *kms_crtc, + drmModeCrtc *drm_crtc); #endif /* META_CRTC_KMS_H */ diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c index 0128f767f..12e820abe 100644 --- a/src/backends/native/meta-gpu-kms.c +++ b/src/backends/native/meta-gpu-kms.c @@ -706,21 +706,23 @@ init_crtcs (MetaGpuKms *gpu_kms, MetaKmsResources *resources) { MetaGpu *gpu = META_GPU (gpu_kms); + MetaKmsDevice *kms_device = gpu_kms->kms_device; + GList *l; GList *crtcs; - unsigned int i; crtcs = NULL; - for (i = 0; i < (unsigned int) resources->resources->count_crtcs; i++) + for (l = meta_kms_device_get_crtcs (kms_device); l; l = l->next) { + MetaKmsCrtc *kms_crtc = l->data; + int crtc_idx; drmModeCrtc *drm_crtc; MetaCrtc *crtc; + crtc_idx = meta_kms_crtc_get_idx (kms_crtc); drm_crtc = drmModeGetCrtc (gpu_kms->fd, - resources->resources->crtcs[i]); - - crtc = meta_create_kms_crtc (gpu_kms, drm_crtc, i); - + resources->resources->crtcs[crtc_idx]); + crtc = meta_create_kms_crtc (gpu_kms, kms_crtc, drm_crtc); drmModeFreeCrtc (drm_crtc); crtcs = g_list_append (crtcs, crtc); diff --git a/src/backends/native/meta-kms-crtc-private.h b/src/backends/native/meta-kms-crtc-private.h new file mode 100644 index 000000000..ad4492bf1 --- /dev/null +++ b/src/backends/native/meta-kms-crtc-private.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2019 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_KMS_CRTC_PRIVATE_H +#define META_KMS_CRTC_PRIVATE_H + +#include + +#include "backends/native/meta-kms-types.h" + +MetaKmsCrtc * meta_kms_crtc_new (MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc, + int idx); + +#endif /* META_KMS_CRTC_PRIVATE_H */ diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c new file mode 100644 index 000000000..73ae8ab9c --- /dev/null +++ b/src/backends/native/meta-kms-crtc.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2019 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-kms-crtc.h" +#include "backends/native/meta-kms-crtc-private.h" + +#include "backends/native/meta-kms-impl-device.h" + +struct _MetaKmsCrtc +{ + GObject parent; + + MetaKmsDevice *device; + + uint32_t id; + int idx; +}; + +G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT) + +MetaKmsDevice * +meta_kms_crtc_get_device (MetaKmsCrtc *crtc) +{ + return crtc->device; +} + +uint32_t +meta_kms_crtc_get_id (MetaKmsCrtc *crtc) +{ + return crtc->id; +} + +int +meta_kms_crtc_get_idx (MetaKmsCrtc *crtc) +{ + return crtc->idx; +} + +MetaKmsCrtc * +meta_kms_crtc_new (MetaKmsImplDevice *impl_device, + drmModeCrtc *drm_crtc, + int idx) +{ + MetaKmsCrtc *crtc; + + crtc = g_object_new (META_TYPE_KMS_CRTC, NULL); + crtc->device = meta_kms_impl_device_get_device (impl_device); + crtc->id = drm_crtc->crtc_id; + crtc->idx = idx; + + return crtc; +} + +static void +meta_kms_crtc_init (MetaKmsCrtc *crtc) +{ +} + +static void +meta_kms_crtc_class_init (MetaKmsCrtcClass *klass) +{ +} diff --git a/src/backends/native/meta-kms-crtc.h b/src/backends/native/meta-kms-crtc.h new file mode 100644 index 000000000..12eda39f2 --- /dev/null +++ b/src/backends/native/meta-kms-crtc.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2019 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_KMS_CRTC_H +#define META_KMS_CRTC_H + +#include +#include +#include + +#include "backends/native/meta-kms-types.h" + +#define META_TYPE_KMS_CRTC (meta_kms_crtc_get_type ()) +G_DECLARE_FINAL_TYPE (MetaKmsCrtc, meta_kms_crtc, + META, KMS_CRTC, + GObject) + +MetaKmsDevice * meta_kms_crtc_get_device (MetaKmsCrtc *crtc); + +uint32_t meta_kms_crtc_get_id (MetaKmsCrtc *crtc); + +int meta_kms_crtc_get_idx (MetaKmsCrtc *crtc); + +#endif /* META_KMS_CRTC_H */ diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c index cdfef0b4c..eb45eda96 100644 --- a/src/backends/native/meta-kms-device.c +++ b/src/backends/native/meta-kms-device.c @@ -36,6 +36,8 @@ struct _MetaKmsDevice MetaKmsDeviceFlag flags; char *path; + + GList *crtcs; }; G_DEFINE_TYPE (MetaKmsDevice, meta_kms_device, G_TYPE_OBJECT); @@ -58,12 +60,19 @@ meta_kms_device_get_flags (MetaKmsDevice *device) return device->flags; } +GList * +meta_kms_device_get_crtcs (MetaKmsDevice *device) +{ + return device->crtcs; +} + typedef struct _CreateImplDeviceData { MetaKmsDevice *device; int fd; MetaKmsImplDevice *out_impl_device; + GList *out_crtcs; } CreateImplDeviceData; static gboolean @@ -77,6 +86,7 @@ create_impl_device_in_impl (MetaKmsImpl *impl, impl_device = meta_kms_impl_device_new (data->device, impl, data->fd); data->out_impl_device = impl_device; + data->out_crtcs = meta_kms_impl_device_copy_crtcs (impl_device); return TRUE; } @@ -116,6 +126,7 @@ meta_kms_device_new (MetaKms *kms, device->impl_device = data.out_impl_device; device->flags = flags; device->path = g_strdup (path); + device->crtcs = data.out_crtcs; return device; } @@ -154,6 +165,8 @@ meta_kms_device_finalize (GObject *object) FreeImplDeviceData data; GError *error = NULL; + g_list_free (device->crtcs); + data = (FreeImplDeviceData) { .impl_device = device->impl_device, }; diff --git a/src/backends/native/meta-kms-device.h b/src/backends/native/meta-kms-device.h index 9972f1318..480f8aa1d 100644 --- a/src/backends/native/meta-kms-device.h +++ b/src/backends/native/meta-kms-device.h @@ -35,6 +35,8 @@ const char * meta_kms_device_get_path (MetaKmsDevice *device); MetaKmsDeviceFlag meta_kms_device_get_flags (MetaKmsDevice *device); +GList * meta_kms_device_get_crtcs (MetaKmsDevice *device); + MetaKmsDevice * meta_kms_device_new (MetaKms *kms, const char *path, MetaKmsDeviceFlag flags, diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index 6727bb024..231f4a9c6 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -21,6 +21,10 @@ #include "backends/native/meta-kms-impl-device.h" +#include + +#include "backends/native/meta-kms-crtc-private.h" +#include "backends/native/meta-kms-crtc.h" #include "backends/native/meta-kms-impl.h" #include "backends/native/meta-kms-private.h" @@ -32,6 +36,8 @@ struct _MetaKmsImplDevice MetaKmsImpl *impl; int fd; + + GList *crtcs; }; G_DEFINE_TYPE (MetaKmsImplDevice, meta_kms_impl_device, G_TYPE_OBJECT) @@ -42,12 +48,39 @@ meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device) return impl_device->device; } +GList * +meta_kms_impl_device_copy_crtcs (MetaKmsImplDevice *impl_device) +{ + return g_list_copy (impl_device->crtcs); +} + +static void +init_crtcs (MetaKmsImplDevice *impl_device, + drmModeRes *drm_resources) +{ + int idx; + + for (idx = 0; idx < drm_resources->count_crtcs; idx++) + { + drmModeCrtc *drm_crtc; + MetaKmsCrtc *crtc; + + drm_crtc = drmModeGetCrtc (impl_device->fd, drm_resources->crtcs[idx]); + crtc = meta_kms_crtc_new (impl_device, drm_crtc, idx); + drmModeFreeCrtc (drm_crtc); + + impl_device->crtcs = g_list_prepend (impl_device->crtcs, crtc); + } + impl_device->crtcs = g_list_reverse (impl_device->crtcs); +} + MetaKmsImplDevice * meta_kms_impl_device_new (MetaKmsDevice *device, MetaKmsImpl *impl, int fd) { MetaKmsImplDevice *impl_device; + drmModeRes *drm_resources; meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl)); @@ -56,6 +89,12 @@ meta_kms_impl_device_new (MetaKmsDevice *device, impl_device->impl = impl; impl_device->fd = fd; + drm_resources = drmModeGetResources (fd); + + init_crtcs (impl_device, drm_resources); + + drmModeFreeResources (drm_resources); + return impl_device; } @@ -86,6 +125,16 @@ meta_kms_impl_device_close (MetaKmsImplDevice *impl_device) return fd; } +static void +meta_kms_impl_device_finalize (GObject *object) +{ + MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (object); + + g_list_free_full (impl_device->crtcs, g_object_unref); + + G_OBJECT_CLASS (meta_kms_impl_device_parent_class)->finalize (object); +} + static void meta_kms_impl_device_init (MetaKmsImplDevice *device) { @@ -94,5 +143,8 @@ meta_kms_impl_device_init (MetaKmsImplDevice *device) static void meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass) { + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = meta_kms_impl_device_finalize; } diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h index 3c316d82d..bbd481312 100644 --- a/src/backends/native/meta-kms-impl-device.h +++ b/src/backends/native/meta-kms-impl-device.h @@ -33,6 +33,8 @@ G_DECLARE_FINAL_TYPE (MetaKmsImplDevice, meta_kms_impl_device, MetaKmsDevice * meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device); +GList * meta_kms_impl_device_copy_crtcs (MetaKmsImplDevice *impl_device); + int meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device); int meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device); diff --git a/src/backends/native/meta-kms-types.h b/src/backends/native/meta-kms-types.h index 43337eff2..47e3b56e1 100644 --- a/src/backends/native/meta-kms-types.h +++ b/src/backends/native/meta-kms-types.h @@ -23,6 +23,8 @@ typedef struct _MetaKms MetaKms; typedef struct _MetaKmsDevice MetaKmsDevice; +typedef struct _MetaKmsCrtc MetaKmsCrtc; + typedef struct _MetaKmsImpl MetaKmsImpl; typedef struct _MetaKmsImplDevice MetaKmsImplDevice; diff --git a/src/meson.build b/src/meson.build index f4f27b32e..73fc2751b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -595,6 +595,9 @@ if have_native_backend 'backends/native/meta-output-kms.c', 'backends/native/meta-output-kms.h', 'backends/native/meta-renderer-native.c', + 'backends/native/meta-kms-crtc-private.h', + 'backends/native/meta-kms-crtc.c', + 'backends/native/meta-kms-crtc.h', 'backends/native/meta-kms-device.c', 'backends/native/meta-kms-device.h', 'backends/native/meta-kms-impl-device.c',