1
0
Fork 0
mutter-performance-source/src/backends/native/meta-kms-update.c
Jonas Ådahl 1cc249fe18 kms: Always predict state after processing update
Not only mode sets have state that should be predicted; changing gamma
currently happens with its own update, so we missed predicting that.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/840
2019-10-10 14:46:32 +00:00

315 lines
8.4 KiB
C

/*
* Copyright (C) 2018 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-update.h"
#include "backends/native/meta-kms-update-private.h"
#include "backends/meta-display-config-shared.h"
#include "backends/native/meta-kms-plane.h"
struct _MetaKmsUpdate
{
gboolean is_sealed;
MetaPowerSave power_save;
GList *mode_sets;
GList *plane_assignments;
GList *page_flips;
GList *connector_properties;
GList *crtc_gammas;
};
static MetaKmsProperty *
meta_kms_property_new (uint32_t prop_id,
uint64_t value)
{
MetaKmsProperty *prop;
prop = g_new0 (MetaKmsProperty, 1);
*prop = (MetaKmsProperty) {
.prop_id = prop_id,
.value = value,
};
return prop;
}
static void
meta_kms_property_free (MetaKmsProperty *prop)
{
g_free (prop);
}
static void
meta_kms_plane_assignment_free (MetaKmsPlaneAssignment *plane_assignment)
{
g_list_free_full (plane_assignment->plane_properties,
(GDestroyNotify) meta_kms_property_free);
g_free (plane_assignment);
}
static void
meta_kms_mode_set_free (MetaKmsModeSet *mode_set)
{
g_free (mode_set->drm_mode);
g_list_free (mode_set->connectors);
g_free (mode_set);
}
MetaKmsPlaneAssignment *
meta_kms_update_assign_plane (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
MetaKmsPlane *plane,
uint32_t fb_id,
MetaFixed16Rectangle src_rect,
MetaFixed16Rectangle dst_rect)
{
MetaKmsPlaneAssignment *plane_assignment;
g_assert (!meta_kms_update_is_sealed (update));
plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1);
*plane_assignment = (MetaKmsPlaneAssignment) {
.update = update,
.crtc = crtc,
.plane = plane,
.fb_id = fb_id,
.src_rect = src_rect,
.dst_rect = dst_rect,
};
update->plane_assignments = g_list_prepend (update->plane_assignments,
plane_assignment);
return plane_assignment;
}
void
meta_kms_update_mode_set (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
GList *connectors,
drmModeModeInfo *drm_mode)
{
MetaKmsModeSet *mode_set;
g_assert (!meta_kms_update_is_sealed (update));
mode_set = g_new0 (MetaKmsModeSet, 1);
*mode_set = (MetaKmsModeSet) {
.crtc = crtc,
.connectors = connectors,
.drm_mode = drm_mode ? g_memdup (drm_mode, sizeof *drm_mode) : NULL,
};
update->mode_sets = g_list_prepend (update->mode_sets, mode_set);
}
void
meta_kms_update_set_connector_property (MetaKmsUpdate *update,
MetaKmsConnector *connector,
uint32_t prop_id,
uint64_t value)
{
MetaKmsConnectorProperty *prop;
g_assert (!meta_kms_update_is_sealed (update));
prop = g_new0 (MetaKmsConnectorProperty, 1);
*prop = (MetaKmsConnectorProperty) {
.connector = connector,
.prop_id = prop_id,
.value = value,
};
update->connector_properties = g_list_prepend (update->connector_properties,
prop);
}
static void
meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma)
{
g_free (gamma->red);
g_free (gamma->green);
g_free (gamma->blue);
g_free (gamma);
}
void
meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
int size,
const uint16_t *red,
const uint16_t *green,
const uint16_t *blue)
{
MetaKmsCrtcGamma *gamma;
g_assert (!meta_kms_update_is_sealed (update));
gamma = g_new0 (MetaKmsCrtcGamma, 1);
*gamma = (MetaKmsCrtcGamma) {
.crtc = crtc,
.size = size,
.red = g_memdup (red, size * sizeof *red),
.green = g_memdup (green, size * sizeof *green),
.blue = g_memdup (blue, size * sizeof *blue),
};
update->crtc_gammas = g_list_prepend (update->crtc_gammas, gamma);
}
void
meta_kms_update_page_flip (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
const MetaKmsPageFlipFeedback *feedback,
gpointer user_data)
{
MetaKmsPageFlip *page_flip;
g_assert (!meta_kms_update_is_sealed (update));
page_flip = g_new0 (MetaKmsPageFlip, 1);
*page_flip = (MetaKmsPageFlip) {
.crtc = crtc,
.feedback = feedback,
.user_data = user_data,
};
update->page_flips = g_list_prepend (update->page_flips, page_flip);
}
void
meta_kms_update_custom_page_flip (MetaKmsUpdate *update,
MetaKmsCrtc *crtc,
const MetaKmsPageFlipFeedback *feedback,
gpointer user_data,
MetaKmsCustomPageFlipFunc custom_page_flip_func,
gpointer custom_page_flip_user_data)
{
MetaKmsPageFlip *page_flip;
g_assert (!meta_kms_update_is_sealed (update));
page_flip = g_new0 (MetaKmsPageFlip, 1);
*page_flip = (MetaKmsPageFlip) {
.crtc = crtc,
.feedback = feedback,
.user_data = user_data,
.custom_page_flip_func = custom_page_flip_func,
.custom_page_flip_user_data = custom_page_flip_user_data,
};
update->page_flips = g_list_prepend (update->page_flips, page_flip);
}
void
meta_kms_plane_assignment_set_plane_property (MetaKmsPlaneAssignment *plane_assignment,
uint32_t prop_id,
uint64_t value)
{
MetaKmsProperty *plane_prop;
g_assert (!meta_kms_update_is_sealed (plane_assignment->update));
plane_prop = meta_kms_property_new (prop_id, value);
plane_assignment->plane_properties =
g_list_prepend (plane_assignment->plane_properties, plane_prop);
}
MetaKmsPlaneAssignment *
meta_kms_update_get_primary_plane_assignment (MetaKmsUpdate *update,
MetaKmsCrtc *crtc)
{
GList *l;
for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next)
{
MetaKmsPlaneAssignment *plane_assignment = l->data;
if (plane_assignment->crtc == crtc)
return plane_assignment;
}
return NULL;
}
GList *
meta_kms_update_get_plane_assignments (MetaKmsUpdate *update)
{
return update->plane_assignments;
}
GList *
meta_kms_update_get_mode_sets (MetaKmsUpdate *update)
{
return update->mode_sets;
}
GList *
meta_kms_update_get_page_flips (MetaKmsUpdate *update)
{
return update->page_flips;
}
GList *
meta_kms_update_get_connector_properties (MetaKmsUpdate *update)
{
return update->connector_properties;
}
GList *
meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update)
{
return update->crtc_gammas;
}
void
meta_kms_update_seal (MetaKmsUpdate *update)
{
update->is_sealed = TRUE;
}
gboolean
meta_kms_update_is_sealed (MetaKmsUpdate *update)
{
return update->is_sealed;
}
MetaKmsUpdate *
meta_kms_update_new (void)
{
return g_new0 (MetaKmsUpdate, 1);
}
void
meta_kms_update_free (MetaKmsUpdate *update)
{
g_list_free_full (update->plane_assignments,
(GDestroyNotify) meta_kms_plane_assignment_free);
g_list_free_full (update->mode_sets,
(GDestroyNotify) meta_kms_mode_set_free);
g_list_free_full (update->page_flips, g_free);
g_list_free_full (update->connector_properties, g_free);
g_list_free_full (update->crtc_gammas, (GDestroyNotify) meta_kms_crtc_gamma_free);
g_free (update);
}