monitor-manager/kms: Use KMS abstraction to get and set CRTC gamma
Still doesn't synchronize with frame drawing, but no point in doing that until gamma is managed by mutter itself and not gnome-settings-daemon. https://gitlab.gnome.org/GNOME/mutter/merge_requests/634
This commit is contained in:
parent
c655166398
commit
68f18f1fe9
@ -40,6 +40,17 @@ struct _MetaKmsCrtc
|
||||
|
||||
G_DEFINE_TYPE (MetaKmsCrtc, meta_kms_crtc, G_TYPE_OBJECT)
|
||||
|
||||
void
|
||||
meta_kms_crtc_set_gamma (MetaKmsCrtc *crtc,
|
||||
MetaKmsUpdate *update,
|
||||
int size,
|
||||
const uint16_t *red,
|
||||
const uint16_t *green,
|
||||
const uint16_t *blue)
|
||||
{
|
||||
meta_kms_update_set_crtc_gamma (update, crtc, size, red, green, blue);
|
||||
}
|
||||
|
||||
MetaKmsDevice *
|
||||
meta_kms_crtc_get_device (MetaKmsCrtc *crtc)
|
||||
{
|
||||
@ -64,6 +75,36 @@ meta_kms_crtc_get_idx (MetaKmsCrtc *crtc)
|
||||
return crtc->idx;
|
||||
}
|
||||
|
||||
static void
|
||||
read_gamma_state (MetaKmsCrtc *crtc,
|
||||
MetaKmsImplDevice *impl_device,
|
||||
drmModeCrtc *drm_crtc)
|
||||
{
|
||||
MetaKmsCrtcState *current_state = &crtc->current_state;
|
||||
|
||||
if (current_state->gamma.size != drm_crtc->gamma_size)
|
||||
{
|
||||
current_state->gamma.size = drm_crtc->gamma_size;
|
||||
|
||||
current_state->gamma.red = g_realloc_n (current_state->gamma.red,
|
||||
drm_crtc->gamma_size,
|
||||
sizeof (uint16_t));
|
||||
current_state->gamma.green = g_realloc_n (current_state->gamma.green,
|
||||
drm_crtc->gamma_size,
|
||||
sizeof (uint16_t));
|
||||
current_state->gamma.blue = g_realloc_n (current_state->gamma.blue,
|
||||
drm_crtc->gamma_size,
|
||||
sizeof (uint16_t));
|
||||
}
|
||||
|
||||
drmModeCrtcGetGamma (meta_kms_impl_device_get_fd (impl_device),
|
||||
crtc->id,
|
||||
current_state->gamma.size,
|
||||
current_state->gamma.red,
|
||||
current_state->gamma.green,
|
||||
current_state->gamma.blue);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
|
||||
MetaKmsImplDevice *impl_device,
|
||||
@ -79,6 +120,8 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
|
||||
.is_drm_mode_valid = drm_crtc->mode_valid,
|
||||
.drm_mode = drm_crtc->mode,
|
||||
};
|
||||
|
||||
read_gamma_state (crtc, impl_device, drm_crtc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -109,6 +152,18 @@ meta_kms_crtc_new (MetaKmsImplDevice *impl_device,
|
||||
return crtc;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_crtc_finalize (GObject *object)
|
||||
{
|
||||
MetaKmsCrtc *crtc = META_KMS_CRTC (object);
|
||||
|
||||
g_clear_pointer (&crtc->current_state.gamma.red, g_free);
|
||||
g_clear_pointer (&crtc->current_state.gamma.green, g_free);
|
||||
g_clear_pointer (&crtc->current_state.gamma.blue, g_free);
|
||||
|
||||
G_OBJECT_CLASS (meta_kms_crtc_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_crtc_init (MetaKmsCrtc *crtc)
|
||||
{
|
||||
@ -117,4 +172,7 @@ meta_kms_crtc_init (MetaKmsCrtc *crtc)
|
||||
static void
|
||||
meta_kms_crtc_class_init (MetaKmsCrtcClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_kms_crtc_finalize;
|
||||
}
|
||||
|
@ -36,6 +36,14 @@ typedef struct _MetaKmsCrtcState
|
||||
uint32_t common_possible_crtcs;
|
||||
uint32_t common_possible_clones;
|
||||
uint32_t encoder_device_idxs;
|
||||
|
||||
struct {
|
||||
uint16_t *red;
|
||||
uint16_t *green;
|
||||
uint16_t *blue;
|
||||
|
||||
int size;
|
||||
} gamma;
|
||||
} MetaKmsCrtcState;
|
||||
|
||||
#define META_TYPE_KMS_CRTC (meta_kms_crtc_get_type ())
|
||||
@ -43,6 +51,13 @@ G_DECLARE_FINAL_TYPE (MetaKmsCrtc, meta_kms_crtc,
|
||||
META, KMS_CRTC,
|
||||
GObject)
|
||||
|
||||
void meta_kms_crtc_set_gamma (MetaKmsCrtc *crtc,
|
||||
MetaKmsUpdate *update,
|
||||
int size,
|
||||
const uint16_t *red,
|
||||
const uint16_t *green,
|
||||
const uint16_t *blue);
|
||||
|
||||
MetaKmsDevice * meta_kms_crtc_get_device (MetaKmsCrtc *crtc);
|
||||
|
||||
const MetaKmsCrtcState * meta_kms_crtc_get_current_state (MetaKmsCrtc *crtc);
|
||||
|
@ -284,6 +284,35 @@ process_mode_set (MetaKmsImpl *impl,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_crtc_gamma (MetaKmsImpl *impl,
|
||||
MetaKmsCrtcGamma *gamma,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsCrtc *crtc = gamma->crtc;
|
||||
MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
|
||||
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_timestamp_earlier_than (uint64_t ts1,
|
||||
uint64_t ts2)
|
||||
@ -708,6 +737,14 @@ meta_kms_impl_simple_process_update (MetaKmsImpl *impl,
|
||||
goto discard_page_flips;
|
||||
}
|
||||
|
||||
for (l = meta_kms_update_get_crtc_gammas (update); l; l = l->next)
|
||||
{
|
||||
MetaKmsCrtcGamma *gamma = l->data;
|
||||
|
||||
if (!process_crtc_gamma (impl, gamma, error))
|
||||
goto discard_page_flips;
|
||||
}
|
||||
|
||||
for (l = meta_kms_update_get_page_flips (update); l; l = l->next)
|
||||
{
|
||||
MetaKmsPageFlip *page_flip = l->data;
|
||||
|
@ -59,6 +59,15 @@ typedef struct _MetaKmsConnectorProperty
|
||||
uint64_t value;
|
||||
} MetaKmsConnectorProperty;
|
||||
|
||||
typedef struct _MetaKmsCrtcGamma
|
||||
{
|
||||
MetaKmsCrtc *crtc;
|
||||
int size;
|
||||
uint16_t *red;
|
||||
uint16_t *green;
|
||||
uint16_t *blue;
|
||||
} MetaKmsCrtcGamma;
|
||||
|
||||
typedef struct _MetaKmsPageFlip
|
||||
{
|
||||
MetaKmsCrtc *crtc;
|
||||
@ -77,6 +86,13 @@ void meta_kms_update_set_connector_property (MetaKmsUpdate *update,
|
||||
uint32_t prop_id,
|
||||
uint64_t value);
|
||||
|
||||
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);
|
||||
|
||||
void meta_kms_plane_assignment_set_plane_property (MetaKmsPlaneAssignment *plane_assignment,
|
||||
uint32_t prop_id,
|
||||
uint64_t value);
|
||||
@ -89,6 +105,8 @@ GList * meta_kms_update_get_page_flips (MetaKmsUpdate *update);
|
||||
|
||||
GList * meta_kms_update_get_connector_properties (MetaKmsUpdate *update);
|
||||
|
||||
GList * meta_kms_update_get_crtc_gammas (MetaKmsUpdate *update);
|
||||
|
||||
gboolean meta_kms_update_has_mode_set (MetaKmsUpdate *update);
|
||||
|
||||
#endif /* META_KMS_UPDATE_PRIVATE_H */
|
||||
|
@ -34,6 +34,7 @@ struct _MetaKmsUpdate
|
||||
GList *plane_assignments;
|
||||
GList *page_flips;
|
||||
GList *connector_properties;
|
||||
GList *crtc_gammas;
|
||||
};
|
||||
|
||||
static MetaKmsProperty *
|
||||
@ -142,6 +143,39 @@ meta_kms_update_set_connector_property (MetaKmsUpdate *update,
|
||||
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,
|
||||
@ -225,6 +259,12 @@ 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;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_kms_update_has_mode_set (MetaKmsUpdate *update)
|
||||
{
|
||||
@ -258,6 +298,7 @@ meta_kms_update_free (MetaKmsUpdate *update)
|
||||
(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);
|
||||
}
|
||||
|
@ -367,20 +367,16 @@ meta_monitor_manager_kms_get_crtc_gamma (MetaMonitorManager *manager,
|
||||
unsigned short **green,
|
||||
unsigned short **blue)
|
||||
{
|
||||
MetaGpu *gpu = meta_crtc_get_gpu (crtc);
|
||||
int kms_fd = meta_gpu_kms_get_fd (META_GPU_KMS (gpu));
|
||||
drmModeCrtc *kms_crtc;
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
const MetaKmsCrtcState *crtc_state;
|
||||
|
||||
kms_crtc = drmModeGetCrtc (kms_fd, crtc->crtc_id);
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
|
||||
crtc_state = meta_kms_crtc_get_current_state (kms_crtc);
|
||||
|
||||
*size = kms_crtc->gamma_size;
|
||||
*red = g_new (unsigned short, *size);
|
||||
*green = g_new (unsigned short, *size);
|
||||
*blue = g_new (unsigned short, *size);
|
||||
|
||||
drmModeCrtcGetGamma (kms_fd, crtc->crtc_id, *size, *red, *green, *blue);
|
||||
|
||||
drmModeFreeCrtc (kms_crtc);
|
||||
*size = crtc_state->gamma.size;
|
||||
*red = g_memdup (crtc_state->gamma.red, *size * sizeof **red);
|
||||
*green = g_memdup (crtc_state->gamma.green, *size * sizeof **green);
|
||||
*blue = g_memdup (crtc_state->gamma.blue, *size * sizeof **blue);
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -453,20 +449,25 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
unsigned short *green,
|
||||
unsigned short *blue)
|
||||
{
|
||||
MetaGpu *gpu = meta_crtc_get_gpu (crtc);
|
||||
int kms_fd = meta_gpu_kms_get_fd (META_GPU_KMS (gpu));
|
||||
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
g_autofree char *gamma_ramp_string = NULL;
|
||||
int ret;
|
||||
MetaKmsUpdate *kms_update;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
|
||||
g_debug ("Setting CRTC (%ld) gamma to %s", crtc->crtc_id, gamma_ramp_string);
|
||||
|
||||
ret = drmModeCrtcSetGamma (kms_fd, crtc->crtc_id, size, red, green, blue);
|
||||
if (ret != 0)
|
||||
{
|
||||
g_warning ("Failed to set CRTC (%ld) Gamma: %s",
|
||||
crtc->crtc_id, g_strerror (-ret));
|
||||
}
|
||||
kms_update = meta_kms_ensure_pending_update (kms);
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc);
|
||||
meta_kms_crtc_set_gamma (kms_crtc, kms_update,
|
||||
size, red, green, blue);
|
||||
|
||||
if (!meta_kms_post_pending_update_sync (kms, &error))
|
||||
g_warning ("Failed to CRTC gamma: %s", error->message);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user