mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-15 22:05:31 -05:00
backend/drm: add support for CTM
This commit is contained in:
parent
92ba6ffdf8
commit
2db00a9872
8 changed files with 96 additions and 12 deletions
|
|
@ -154,6 +154,31 @@ static bool create_gamma_lut_blob(struct wlr_drm_backend *drm,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool create_ctm_blob(struct wlr_drm_backend *drm,
|
||||
const float *matrix, uint32_t *blob_id) {
|
||||
if (matrix == NULL) {
|
||||
*blob_id = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Convert to S31.32 sign-magnitude fixed floating-point encoding
|
||||
struct drm_color_ctm ctm = {0};
|
||||
for (size_t i = 0; i < 9; i++) {
|
||||
uint64_t v = fabs(matrix[i]) * ((uint64_t)1 << 32);
|
||||
if (matrix[i] < 0) {
|
||||
v |= (uint64_t)1 << 63;
|
||||
}
|
||||
ctm.matrix[i] = v;
|
||||
}
|
||||
|
||||
if (drmModeCreatePropertyBlob(drm->fd, &ctm, sizeof(ctm), blob_id) != 0) {
|
||||
wlr_log_errno(WLR_ERROR, "Unable to create CTM property blob");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool create_fb_damage_clips_blob(struct wlr_drm_backend *drm,
|
||||
int width, int height, const pixman_region32_t *damage, uint32_t *blob_id) {
|
||||
pixman_region32_t clipped;
|
||||
|
|
@ -332,26 +357,39 @@ bool drm_atomic_connector_prepare(struct wlr_drm_connector_state *state, bool mo
|
|||
}
|
||||
|
||||
uint32_t gamma_lut = crtc->gamma_lut;
|
||||
uint32_t ctm = crtc->ctm;
|
||||
if (state->base->committed & WLR_OUTPUT_STATE_COLOR_TRANSFORM) {
|
||||
size_t dim = 0;
|
||||
size_t lut_dim = 0;
|
||||
uint16_t *lut = NULL;
|
||||
const float *matrix = NULL;
|
||||
if (state->crtc_color_transform != NULL) {
|
||||
dim = state->crtc_color_transform->lut_3x1d->dim;
|
||||
lut_dim = state->crtc_color_transform->lut_3x1d->dim;
|
||||
lut = state->crtc_color_transform->lut_3x1d->lut_3x1d;
|
||||
if (state->crtc_color_transform->has_matrix) {
|
||||
matrix = state->crtc_color_transform->matrix;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to legacy gamma interface when gamma properties are not
|
||||
// available (can happen on older Intel GPUs that support gamma but not
|
||||
// degamma).
|
||||
if (crtc->props.gamma_lut == 0) {
|
||||
if (!drm_legacy_crtc_set_gamma(drm, crtc, dim, lut)) {
|
||||
if (!drm_legacy_crtc_set_gamma(drm, crtc, lut_dim, lut)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!create_gamma_lut_blob(drm, dim, lut, &gamma_lut)) {
|
||||
if (!create_gamma_lut_blob(drm, lut_dim, lut, &gamma_lut)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (matrix != NULL && crtc->props.ctm == 0) {
|
||||
wlr_log(WLR_DEBUG, "CRTC %"PRIu32" doesn't support CTM", crtc->id);
|
||||
return false;
|
||||
}
|
||||
if (!create_ctm_blob(drm, matrix, &ctm)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t fb_damage_clips = 0;
|
||||
|
|
@ -394,6 +432,7 @@ bool drm_atomic_connector_prepare(struct wlr_drm_connector_state *state, bool mo
|
|||
|
||||
state->mode_id = mode_id;
|
||||
state->gamma_lut = gamma_lut;
|
||||
state->ctm = ctm;
|
||||
state->fb_damage_clips = fb_damage_clips;
|
||||
state->primary_in_fence_fd = in_fence_fd;
|
||||
state->vrr_enabled = vrr_enabled;
|
||||
|
|
@ -413,6 +452,7 @@ void drm_atomic_connector_apply_commit(struct wlr_drm_connector_state *state) {
|
|||
crtc->own_mode_id = true;
|
||||
commit_blob(drm, &crtc->mode_id, state->mode_id);
|
||||
commit_blob(drm, &crtc->gamma_lut, state->gamma_lut);
|
||||
commit_blob(drm, &crtc->ctm, state->ctm);
|
||||
commit_blob(drm, &conn->hdr_output_metadata, state->hdr_output_metadata);
|
||||
|
||||
conn->output.adaptive_sync_status = state->vrr_enabled ?
|
||||
|
|
@ -439,6 +479,7 @@ void drm_atomic_connector_rollback_commit(struct wlr_drm_connector_state *state)
|
|||
|
||||
rollback_blob(drm, &crtc->mode_id, state->mode_id);
|
||||
rollback_blob(drm, &crtc->gamma_lut, state->gamma_lut);
|
||||
rollback_blob(drm, &crtc->ctm, state->ctm);
|
||||
rollback_blob(drm, &conn->hdr_output_metadata, state->hdr_output_metadata);
|
||||
|
||||
destroy_blob(drm, state->fb_damage_clips);
|
||||
|
|
@ -543,6 +584,9 @@ static void atomic_connector_add(struct atomic *atom,
|
|||
if (crtc->props.gamma_lut != 0) {
|
||||
atomic_add(atom, crtc->id, crtc->props.gamma_lut, state->gamma_lut);
|
||||
}
|
||||
if (crtc->props.ctm != 0) {
|
||||
atomic_add(atom, crtc->id, crtc->props.ctm, state->ctm);
|
||||
}
|
||||
if (crtc->props.vrr_enabled != 0) {
|
||||
atomic_add(atom, crtc->id, crtc->props.vrr_enabled, state->vrr_enabled);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue