From cc1229e75e0c0c2cf5ae6d67bc7411c2631deb86 Mon Sep 17 00:00:00 2001 From: Vincent Vanlaer Date: Thu, 1 Feb 2018 20:27:35 +0100 Subject: Add atomic gamma setting --- backend/drm/atomic.c | 32 ++++++++++++++++++++++++++++++++ backend/drm/drm.c | 5 ++++- backend/drm/legacy.c | 8 ++++++++ backend/drm/properties.c | 1 + 4 files changed, 45 insertions(+), 1 deletion(-) (limited to 'backend') diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index 54024d86..a8003492 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -195,9 +196,40 @@ static bool atomic_crtc_move_cursor(struct wlr_drm_backend *drm, return atomic_end(drm->fd, &atom); } +static bool atomic_crtc_set_gamma(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, uint16_t *r, uint16_t *g, uint16_t *b, + uint32_t size) { + struct drm_color_lut *gamma = calloc(sizeof(struct drm_color_lut), size); + + for (uint32_t i = 0; i < size; i++) { + gamma[i].red = r[i]; + gamma[i].green = g[i]; + gamma[i].blue = b[i]; + } + + if (crtc->gamma_lut != 0) { + drmModeDestroyPropertyBlob(drm->fd, crtc->gamma_lut); + } + + if (drmModeCreatePropertyBlob(drm->fd, gamma, + sizeof(struct drm_color_lut) * size, &crtc->gamma_lut)) { + wlr_log_errno(L_ERROR, "Unable to create property blob"); + return false; + } + + free(gamma); + + struct atomic atom; + + atomic_begin(crtc, &atom); + atomic_add(&atom, crtc->id, crtc->props.gamma_lut, crtc->gamma_lut); + return atomic_end(drm->fd, &atom); +} + const struct wlr_drm_interface atomic_iface = { .conn_enable = atomic_conn_enable, .crtc_pageflip = atomic_crtc_pageflip, .crtc_set_cursor = atomic_crtc_set_cursor, .crtc_move_cursor = atomic_crtc_move_cursor, + .crtc_set_gamma = atomic_crtc_set_gamma, }; diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 08ced783..abcfcf8a 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -169,6 +169,9 @@ void wlr_drm_resources_free(struct wlr_drm_backend *drm) { if (crtc->mode_id) { drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id); } + if (crtc->gamma_lut) { + drmModeDestroyPropertyBlob(drm->fd, crtc->gamma_lut); + } } for (size_t i = 0; i < drm->num_planes; ++i) { struct wlr_drm_plane *plane = &drm->planes[i]; @@ -227,7 +230,7 @@ static void wlr_drm_connector_set_gamma(struct wlr_output *output, uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; - drmModeCrtcSetGamma(drm->fd, conn->crtc->id, size, r, g, b); + drm->iface->crtc_set_gamma(drm, conn->crtc, r, g, b, size); } static uint32_t wlr_drm_connector_get_gamma_size(struct wlr_output *output) { diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c index 61140cec..46911905 100644 --- a/backend/drm/legacy.c +++ b/backend/drm/legacy.c @@ -59,9 +59,17 @@ bool legacy_crtc_move_cursor(struct wlr_drm_backend *drm, return !drmModeMoveCursor(drm->fd, crtc->id, x, y); } +bool legacy_crtc_set_gamma(struct wlr_drm_backend *drm, + struct wlr_drm_crtc *crtc, uint16_t *r, uint16_t *g, uint16_t *b, + uint32_t size) { + return !drmModeCrtcSetGamma(drm->fd, crtc->id, size, r, g, b); +} + + const struct wlr_drm_interface legacy_iface = { .conn_enable = legacy_conn_enable, .crtc_pageflip = legacy_crtc_pageflip, .crtc_set_cursor = legacy_crtc_set_cursor, .crtc_move_cursor = legacy_crtc_move_cursor, + .crtc_set_gamma = legacy_crtc_set_gamma, }; diff --git a/backend/drm/properties.c b/backend/drm/properties.c index 5bec3243..c3efa96e 100644 --- a/backend/drm/properties.c +++ b/backend/drm/properties.c @@ -28,6 +28,7 @@ static const struct prop_info connector_info[] = { static const struct prop_info crtc_info[] = { #define INDEX(name) (offsetof(union wlr_drm_crtc_props, name) / sizeof(uint32_t)) { "ACTIVE", INDEX(active) }, + { "GAMMA_LUT", INDEX(gamma_lut) }, { "MODE_ID", INDEX(mode_id) }, { "rotation", INDEX(rotation) }, { "scaling mode", INDEX(scaling_mode) }, -- cgit v1.2.3