backends/native: Introduce MetaKmsCrtcColorUpdate

To store gamma updates. In the future this will grow other CRTC level
color pipeline properties.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2861>
This commit is contained in:
Sebastian Wick 2023-02-17 23:47:04 +01:00 committed by Marge Bot
parent 37639295db
commit 0180ffdaa1
7 changed files with 115 additions and 66 deletions

View File

@ -248,8 +248,7 @@ meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc,
"Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s",
meta_crtc_get_id (crtc), gamma_ramp_string);
crtc_gamma = meta_kms_crtc_gamma_new (kms_crtc,
lut->size,
crtc_gamma = meta_kms_crtc_gamma_new (lut->size,
lut->red,
lut->green,
lut->blue);

View File

@ -316,9 +316,10 @@ meta_kms_crtc_predict_state_in_impl (MetaKmsCrtc *crtc,
crtc_color_updates = meta_kms_update_get_crtc_color_updates (update);
for (l = crtc_color_updates; l; l = l->next)
{
MetaKmsCrtcGamma *gamma = l->data;
MetaKmsCrtcColorUpdate *color_update = l->data;
MetaKmsCrtcGamma *gamma = color_update->gamma.state;
if (gamma->crtc != crtc)
if (color_update->crtc != crtc)
continue;
clear_gamma_state (&crtc->current_state);

View File

@ -47,7 +47,6 @@ typedef struct _MetaKmsCrtcState
typedef struct _MetaKmsCrtcGamma
{
MetaKmsCrtc *crtc;
int size;
uint16_t *red;
uint16_t *green;
@ -76,8 +75,7 @@ gboolean meta_kms_crtc_is_active (MetaKmsCrtc *crtc);
void meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma);
MetaKmsCrtcGamma * meta_kms_crtc_gamma_new (MetaKmsCrtc *crtc,
int size,
MetaKmsCrtcGamma * meta_kms_crtc_gamma_new (int size,
const uint16_t *red,
const uint16_t *green,
const uint16_t *blue);

View File

@ -621,40 +621,45 @@ process_crtc_color_updates (MetaKmsImplDevice *impl_device,
gpointer user_data,
GError **error)
{
MetaKmsCrtcGamma *gamma = update_entry;
MetaKmsCrtc *crtc = gamma->crtc;
struct drm_color_lut drm_color_lut[gamma->size];
int i;
uint32_t color_lut_blob_id;
MetaKmsCrtcColorUpdate *color_update = update_entry;
MetaKmsCrtc *crtc = color_update->crtc;
for (i = 0; i < gamma->size; i++)
if (color_update->gamma.has_update)
{
drm_color_lut[i].red = gamma->red[i];
drm_color_lut[i].green = gamma->green[i];
drm_color_lut[i].blue = gamma->blue[i];
MetaKmsCrtcGamma *gamma = color_update->gamma.state;
struct drm_color_lut drm_color_lut[gamma->size];
int i;
uint32_t color_lut_blob_id;
for (i = 0; i < gamma->size; i++)
{
drm_color_lut[i].red = gamma->red[i];
drm_color_lut[i].green = gamma->green[i];
drm_color_lut[i].blue = gamma->blue[i];
}
color_lut_blob_id = store_new_blob (impl_device,
blob_ids,
drm_color_lut,
sizeof drm_color_lut,
error);
if (!color_lut_blob_id)
return FALSE;
meta_topic (META_DEBUG_KMS,
"[atomic] Setting CRTC (%u, %s) gamma, size: %d",
meta_kms_crtc_get_id (crtc),
meta_kms_impl_device_get_path (impl_device),
gamma->size);
if (!add_crtc_property (impl_device,
crtc, req,
META_KMS_CRTC_PROP_GAMMA_LUT,
color_lut_blob_id,
error))
return FALSE;
}
color_lut_blob_id = store_new_blob (impl_device,
blob_ids,
drm_color_lut,
sizeof drm_color_lut,
error);
if (!color_lut_blob_id)
return FALSE;
meta_topic (META_DEBUG_KMS,
"[atomic] Setting CRTC (%u, %s) gamma, size: %d",
meta_kms_crtc_get_id (crtc),
meta_kms_impl_device_get_path (impl_device),
gamma->size);
if (!add_crtc_property (impl_device,
crtc, req,
META_KMS_CRTC_PROP_GAMMA_LUT,
color_lut_blob_id,
error))
return FALSE;
return TRUE;
}

View File

@ -508,30 +508,35 @@ process_crtc_color_updates (MetaKmsImplDevice *impl_device,
gpointer update_entry,
GError **error)
{
MetaKmsCrtcGamma *gamma = update_entry;
MetaKmsCrtc *crtc = gamma->crtc;
int fd;
int ret;
MetaKmsCrtcColorUpdate *color_update = update_entry;
MetaKmsCrtc *crtc = color_update->crtc;
meta_topic (META_DEBUG_KMS,
"[simple] Setting CRTC %u (%s) gamma, size: %d",
meta_kms_crtc_get_id (crtc),
meta_kms_impl_device_get_path (impl_device),
gamma->size);
fd = meta_kms_impl_device_get_fd (impl_device);
ret = drmModeCrtcSetGamma (fd, meta_kms_crtc_get_id (crtc),
gamma->size,
gamma->red,
gamma->green,
gamma->blue);
if (ret != 0)
if (color_update->gamma.has_update)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
"drmModeCrtcSetGamma on CRTC %u failed: %s",
meta_kms_crtc_get_id (crtc),
g_strerror (-ret));
return FALSE;
MetaKmsCrtcGamma *gamma = color_update->gamma.state;
int fd;
int ret;
meta_topic (META_DEBUG_KMS,
"[simple] Setting CRTC %u (%s) gamma, size: %d",
meta_kms_crtc_get_id (crtc),
meta_kms_impl_device_get_path (impl_device),
gamma->size);
fd = meta_kms_impl_device_get_fd (impl_device);
ret = drmModeCrtcSetGamma (fd, meta_kms_crtc_get_id (crtc),
gamma->size,
gamma->red,
gamma->green,
gamma->blue);
if (ret != 0)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
"drmModeCrtcSetGamma on CRTC %u failed: %s",
meta_kms_crtc_get_id (crtc),
g_strerror (-ret));
return FALSE;
}
}
return TRUE;

View File

@ -23,10 +23,21 @@
#include <glib.h>
#include <stdint.h>
#include "backends/native/meta-kms-crtc.h"
#include "backends/native/meta-kms-plane-private.h"
#include "backends/native/meta-kms-types.h"
#include "backends/native/meta-kms-update.h"
typedef struct _MetaKmsCrtcColorUpdate
{
MetaKmsCrtc *crtc;
struct {
gboolean has_update;
MetaKmsCrtcGamma *state;
} gamma;
} MetaKmsCrtcColorUpdate;
typedef struct _MetaKmsFeedback
{
MetaKmsFeedbackResult result;

View File

@ -370,6 +370,30 @@ meta_kms_update_set_max_bpc (MetaKmsUpdate *update,
connector_update->max_bpc.has_update = TRUE;
}
static MetaKmsCrtcColorUpdate *
ensure_color_update (MetaKmsUpdate *update,
MetaKmsCrtc *crtc)
{
GList *l;
MetaKmsCrtcColorUpdate *color_update;
for (l = update->crtc_color_updates; l; l = l->next)
{
color_update = l->data;
if (color_update->crtc == crtc)
return color_update;
}
color_update = g_new0 (MetaKmsCrtcColorUpdate, 1);
color_update->crtc = crtc;
update->crtc_color_updates = g_list_prepend (update->crtc_color_updates,
color_update);
return color_update;
}
void
meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma)
{
@ -380,8 +404,7 @@ meta_kms_crtc_gamma_free (MetaKmsCrtcGamma *gamma)
}
MetaKmsCrtcGamma *
meta_kms_crtc_gamma_new (MetaKmsCrtc *crtc,
int size,
meta_kms_crtc_gamma_new (int size,
const uint16_t *red,
const uint16_t *green,
const uint16_t *blue)
@ -390,7 +413,6 @@ meta_kms_crtc_gamma_new (MetaKmsCrtc *crtc,
gamma = g_new0 (MetaKmsCrtcGamma, 1);
*gamma = (MetaKmsCrtcGamma) {
.crtc = crtc,
.size = size,
.red = g_memdup2 (red, size * sizeof (*red)),
.green = g_memdup2 (green, size * sizeof (*green)),
@ -408,14 +430,21 @@ meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
const uint16_t *green,
const uint16_t *blue)
{
MetaKmsCrtcGamma *gamma;
MetaKmsCrtcColorUpdate *color_update;
g_assert (!meta_kms_update_is_locked (update));
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
gamma = meta_kms_crtc_gamma_new (crtc, size, red, green, blue);
color_update = ensure_color_update (update, crtc);
color_update->gamma.state = meta_kms_crtc_gamma_new (size, red, green, blue);
color_update->gamma.has_update = TRUE;
}
update->crtc_color_updates = g_list_prepend (update->crtc_color_updates, gamma);
static void
meta_kms_crtc_color_updates_free (MetaKmsCrtcColorUpdate *color_update)
{
if (color_update->gamma.has_update)
g_clear_pointer (&color_update->gamma.state, meta_kms_crtc_gamma_free);
}
void
@ -700,7 +729,8 @@ meta_kms_update_free (MetaKmsUpdate *update)
g_list_free_full (update->page_flip_listeners,
(GDestroyNotify) meta_kms_page_flip_listener_free);
g_list_free_full (update->connector_updates, g_free);
g_list_free_full (update->crtc_color_updates, (GDestroyNotify) meta_kms_crtc_gamma_free);
g_list_free_full (update->crtc_color_updates,
(GDestroyNotify) meta_kms_crtc_color_updates_free);
g_clear_pointer (&update->custom_page_flip, meta_kms_custom_page_flip_free);
g_free (update);