backends/native: Let the monitor manager manage KMS modes

Let MetaMonitorManagerKms manage KMS modes. This lets us pass less
state to MetaRendererNative. Instead let MetaMonitorManager tell the
monitor manager when it should set the mode and with what framebuffer.

https://bugzilla.gnome.org/show_bug.cgi?id=768976
This commit is contained in:
Jonas Ådahl 2016-05-11 16:26:34 +08:00
parent ec1da588cf
commit 12ef1a5e4b
4 changed files with 82 additions and 42 deletions

View File

@ -1008,7 +1008,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
static void
crtc_free (CoglKmsCrtc *crtc)
{
g_free (crtc->connectors);
g_slice_free (CoglKmsCrtc, crtc);
}
@ -1087,12 +1086,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
if (crtc_info->mode == NULL)
{
cogl_crtc->id = crtc->crtc_id;
cogl_crtc->x = 0;
cogl_crtc->y = 0;
cogl_crtc->count = 0;
memset (&cogl_crtc->mode, 0, sizeof (drmModeModeInfo));
cogl_crtc->connectors = NULL;
cogl_crtc->count = 0;
crtc->rect.x = 0;
crtc->rect.y = 0;
@ -1109,11 +1102,11 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
mode = crtc_info->mode;
n_connectors = crtc_info->outputs->len;
connectors = g_new (uint32_t, n_connectors);
cogl_crtc->id = crtc->crtc_id;
cogl_crtc->x = crtc_info->x;
cogl_crtc->y = crtc_info->y;
cogl_crtc->count = n_connectors = crtc_info->outputs->len;
cogl_crtc->connectors = connectors = g_new (uint32_t, n_connectors);
cogl_crtc->connected = n_connectors > 0;
for (j = 0; j < n_connectors; j++)
{
@ -1125,9 +1118,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
output->crtc = crtc;
}
memcpy (&cogl_crtc->mode, crtc_info->mode->driver_private,
sizeof (drmModeModeInfo));
if (meta_monitor_transform_is_rotated (crtc_info->transform))
{
width = mode->height;
@ -1177,12 +1167,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
g_ptr_array_add (cogl_crtcs, cogl_crtc);
cogl_crtc->id = crtc->crtc_id;
cogl_crtc->x = 0;
cogl_crtc->y = 0;
cogl_crtc->count = 0;
memset (&cogl_crtc->mode, 0, sizeof (drmModeModeInfo));
cogl_crtc->connectors = NULL;
cogl_crtc->count = 0;
crtc->rect.x = 0;
crtc->rect.y = 0;
@ -1314,6 +1298,72 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
manager_kms->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
}
static void
get_crtc_connectors (MetaMonitorManager *manager,
MetaCRTC *crtc,
uint32_t **connectors,
unsigned int *n_connectors)
{
GArray *connectors_array = NULL;
unsigned int i;
for (i = 0; i < manager->n_outputs; i++)
{
MetaOutput *output = &manager->outputs[i];
if (output->crtc == crtc)
{
if (!connectors_array)
connectors_array = g_array_new (FALSE, FALSE, sizeof (uint32_t));
g_array_append_val (connectors_array, output->winsys_id);
}
}
if (connectors_array)
{
*connectors = (uint32_t *) connectors_array->data;
*n_connectors = connectors_array->len;
}
else
{
*connectors = NULL;
*n_connectors = 0;
}
}
void
meta_monitor_manager_kms_apply_crtc_modes (MetaMonitorManagerKms *manager_kms,
uint32_t fb_id)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
unsigned int i;
for (i = 0; i < manager->n_crtcs; i++)
{
MetaCRTC *crtc = &manager->crtcs[i];
uint32_t *connectors;
unsigned int n_connectors;
drmModeModeInfo *mode;
get_crtc_connectors (manager, crtc, &connectors, &n_connectors);
if (connectors)
mode = crtc->current_mode->driver_private;
else
mode = NULL;
if (drmModeSetCrtc (manager_kms->fd,
crtc->crtc_id,
fb_id,
crtc->rect.x, crtc->rect.y,
connectors, n_connectors,
mode) != 0)
g_warning ("Failed to set CRTC mode %s: %m", crtc->current_mode->name);
g_free (connectors);
}
}
static void
meta_monitor_manager_kms_dispose (GObject *object)
{

View File

@ -37,4 +37,7 @@ typedef struct _MetaMonitorManagerKms MetaMonitorManagerKms;
GType meta_monitor_manager_kms_get_type (void);
void meta_monitor_manager_kms_apply_crtc_modes (MetaMonitorManagerKms *manager_kms,
uint32_t fb_id);
#endif /* META_MONITOR_MANAGER_KMS_H */

View File

@ -47,6 +47,7 @@
#include <xf86drm.h>
#include "backends/meta-backend-private.h"
#include "backends/native/meta-monitor-manager-kms.h"
#include "backends/native/meta-renderer-native.h"
#include "cogl/cogl.h"
@ -332,22 +333,13 @@ fail:
static void
setup_crtc_modes (CoglDisplay *display, int fb_id)
{
CoglRendererEGL *egl_renderer = display->renderer->winsys;
MetaRendererNative *renderer_native = egl_renderer->platform;
GList *l;
MetaBackend *backend = meta_get_backend ();
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaMonitorManagerKms *monitor_manager_kms =
META_MONITOR_MANAGER_KMS (monitor_manager);
for (l = renderer_native->crtcs; l; l = l->next)
{
CoglKmsCrtc *crtc = l->data;
int ret = drmModeSetCrtc (renderer_native->kms_fd,
crtc->id,
fb_id, crtc->x, crtc->y,
crtc->connectors, crtc->count,
crtc->count ? &crtc->mode : NULL);
if (ret)
g_warning ("Failed to set crtc mode %s: %m", crtc->mode.name);
}
meta_monitor_manager_kms_apply_crtc_modes (monitor_manager_kms, fb_id);
}
static void
@ -363,7 +355,7 @@ flip_all_crtcs (CoglDisplay *display, CoglFlipKMS *flip, int fb_id)
CoglKmsCrtc *crtc = l->data;
int ret = 0;
if (crtc->count == 0 || crtc->ignore)
if (!crtc->connected || crtc->ignore)
continue;
needs_flip = TRUE;
@ -392,7 +384,6 @@ flip_all_crtcs (CoglDisplay *display, CoglFlipKMS *flip, int fb_id)
static void
crtc_free (CoglKmsCrtc *crtc)
{
g_free (crtc->connectors);
g_slice_free (CoglKmsCrtc, crtc);
}
@ -404,7 +395,6 @@ crtc_copy (CoglKmsCrtc *from)
new = g_slice_new (CoglKmsCrtc);
*new = *from;
new->connectors = g_memdup (from->connectors, from->count * sizeof(uint32_t));
return new;
}

View File

@ -32,11 +32,8 @@
typedef struct {
uint32_t id;
uint32_t x, y;
drmModeModeInfo mode;
uint32_t *connectors;
uint32_t count;
gboolean connected;
CoglBool ignore;
} CoglKmsCrtc;