mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-02-04 04:06:09 -05:00
Merge branch 'color-pipeline' into 'master'
Draft: Apply output color transform in KMS See merge request wlroots/wlroots!5083
This commit is contained in:
commit
7b02490f00
12 changed files with 290 additions and 20 deletions
|
|
@ -6,6 +6,7 @@
|
|||
#include <wlr/util/box.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include "backend/drm/color.h"
|
||||
#include "backend/drm/drm.h"
|
||||
#include "backend/drm/fb.h"
|
||||
#include "backend/drm/iface.h"
|
||||
|
|
@ -153,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;
|
||||
|
|
@ -331,28 +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;
|
||||
if (state->base->color_transform != NULL) {
|
||||
struct wlr_color_transform_lut_3x1d *tr =
|
||||
color_transform_lut_3x1d_from_base(state->base->color_transform);
|
||||
dim = tr->dim;
|
||||
lut = tr->lut_3x1d;
|
||||
const float *matrix = NULL;
|
||||
if (state->crtc_color_transform != NULL) {
|
||||
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;
|
||||
|
|
@ -395,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;
|
||||
|
|
@ -414,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 ?
|
||||
|
|
@ -440,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);
|
||||
|
|
@ -544,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);
|
||||
}
|
||||
|
|
|
|||
177
backend/drm/color.c
Normal file
177
backend/drm/color.c
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "backend/drm/color.h"
|
||||
#include "backend/drm/drm.h"
|
||||
#include "render/color.h"
|
||||
#include "util/matrix.h"
|
||||
|
||||
enum wlr_drm_crtc_color_transform_stage {
|
||||
WLR_DRM_CRTC_COLOR_TRANSFORM_MATRIX,
|
||||
WLR_DRM_CRTC_COLOR_TRANSFORM_LUT_3X1D,
|
||||
};
|
||||
|
||||
static struct wlr_color_transform_lut_3x1d *create_identity_3x1dlut(size_t dim) {
|
||||
if (dim == 0) {
|
||||
return NULL;
|
||||
}
|
||||
uint16_t *lut = malloc(dim * sizeof(lut[0]));
|
||||
if (lut == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for (size_t i = 0; i < dim; i++) {
|
||||
float x = (float)i / (dim - 1);
|
||||
lut[i] = (uint16_t)roundf(UINT16_MAX * x);
|
||||
}
|
||||
struct wlr_color_transform *out = wlr_color_transform_init_lut_3x1d(dim, lut, lut, lut);
|
||||
free(lut);
|
||||
return color_transform_lut_3x1d_from_base(out);
|
||||
}
|
||||
|
||||
static bool set_stage(enum wlr_drm_crtc_color_transform_stage *current,
|
||||
enum wlr_drm_crtc_color_transform_stage next) {
|
||||
// Enforce that we fill the pipeline in order: first CTM then GAMMA_LUT
|
||||
if (*current > next) {
|
||||
return false;
|
||||
}
|
||||
*current = next;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool drm_crtc_color_transform_init_lut_3x1d(struct wlr_drm_crtc_color_transform *out,
|
||||
enum wlr_drm_crtc_color_transform_stage *stage, size_t dim) {
|
||||
if (!set_stage(stage, WLR_DRM_CRTC_COLOR_TRANSFORM_LUT_3X1D)) {
|
||||
return false;
|
||||
}
|
||||
if (out->lut_3x1d != NULL) {
|
||||
return true;
|
||||
}
|
||||
out->lut_3x1d = create_identity_3x1dlut(dim);
|
||||
return out->lut_3x1d != NULL;
|
||||
}
|
||||
|
||||
static bool drm_crtc_color_transform_convert(struct wlr_drm_crtc_color_transform *out,
|
||||
struct wlr_color_transform *in, enum wlr_drm_crtc_color_transform_stage *stage,
|
||||
size_t lut_3x1d_dim) {
|
||||
switch (in->type) {
|
||||
case COLOR_TRANSFORM_INVERSE_EOTF:;
|
||||
struct wlr_color_transform_inverse_eotf *inv_eotf =
|
||||
wlr_color_transform_inverse_eotf_from_base(in);
|
||||
|
||||
if (!drm_crtc_color_transform_init_lut_3x1d(out, stage, lut_3x1d_dim)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
for (size_t j = 0; j < lut_3x1d_dim; j++) {
|
||||
size_t offset = i * lut_3x1d_dim + j;
|
||||
float v = (float)out->lut_3x1d->lut_3x1d[offset] / UINT16_MAX;
|
||||
v = wlr_color_transfer_function_eval_inverse_eotf(inv_eotf->tf, v);
|
||||
out->lut_3x1d->lut_3x1d[offset] = (uint16_t)roundf(UINT16_MAX * v);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
case COLOR_TRANSFORM_LUT_3X1D:;
|
||||
struct wlr_color_transform_lut_3x1d *lut_3x1d =
|
||||
color_transform_lut_3x1d_from_base(in);
|
||||
if (lut_3x1d->dim != lut_3x1d_dim) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!drm_crtc_color_transform_init_lut_3x1d(out, stage, lut_3x1d_dim)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: we loose precision when the input color transform is a lone 3×1D LUT
|
||||
for (size_t i = 0; i < 3 * lut_3x1d->dim; i++) {
|
||||
out->lut_3x1d->lut_3x1d[i] *= lut_3x1d->lut_3x1d[i];
|
||||
}
|
||||
|
||||
return true;
|
||||
case COLOR_TRANSFORM_MATRIX:;
|
||||
struct wlr_color_transform_matrix *matrix = wl_container_of(in, matrix, base);
|
||||
if (!set_stage(stage, WLR_DRM_CRTC_COLOR_TRANSFORM_MATRIX)) {
|
||||
return false;
|
||||
}
|
||||
wlr_matrix_multiply(out->matrix, matrix->matrix, out->matrix);
|
||||
out->has_matrix = true;
|
||||
return true;
|
||||
case COLOR_TRANSFORM_LCMS2:
|
||||
return false; // unsupported
|
||||
case COLOR_TRANSFORM_PIPELINE:;
|
||||
struct wlr_color_transform_pipeline *pipeline = wl_container_of(in, pipeline, base);
|
||||
|
||||
for (size_t i = 0; i < pipeline->len; i++) {
|
||||
if (!drm_crtc_color_transform_convert(out, pipeline->transforms[i], stage, lut_3x1d_dim)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
abort(); // unreachable
|
||||
}
|
||||
|
||||
static void addon_destroy(struct wlr_addon *addon) {
|
||||
struct wlr_drm_crtc_color_transform *tr = wl_container_of(addon, tr, addon);
|
||||
if (tr->lut_3x1d != NULL) {
|
||||
wlr_color_transform_unref(&tr->lut_3x1d->base);
|
||||
}
|
||||
free(tr);
|
||||
}
|
||||
|
||||
static const struct wlr_addon_interface addon_impl = {
|
||||
.name = "wlr_drm_crtc_color_transform",
|
||||
.destroy = addon_destroy,
|
||||
};
|
||||
|
||||
static struct wlr_drm_crtc_color_transform *drm_crtc_color_transform_create(
|
||||
struct wlr_drm_backend *backend, struct wlr_drm_crtc *crtc,
|
||||
struct wlr_color_transform *base) {
|
||||
struct wlr_drm_crtc_color_transform *tr = calloc(1, sizeof(*tr));
|
||||
if (tr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tr->base = base;
|
||||
wlr_addon_init(&tr->addon, &base->addons, crtc, &addon_impl);
|
||||
wlr_matrix_identity(tr->matrix);
|
||||
|
||||
size_t lut_3x1d_dim = drm_crtc_get_gamma_lut_size(backend, crtc);
|
||||
enum wlr_drm_crtc_color_transform_stage stage = WLR_DRM_CRTC_COLOR_TRANSFORM_MATRIX;
|
||||
tr->failed = !drm_crtc_color_transform_convert(tr, base, &stage, lut_3x1d_dim);
|
||||
|
||||
return tr;
|
||||
}
|
||||
|
||||
struct wlr_drm_crtc_color_transform *drm_crtc_color_transform_import(
|
||||
struct wlr_drm_backend *backend, struct wlr_drm_crtc *crtc,
|
||||
struct wlr_color_transform *base) {
|
||||
struct wlr_drm_crtc_color_transform *tr;
|
||||
struct wlr_addon *addon = wlr_addon_find(&base->addons, crtc, &addon_impl);
|
||||
if (addon != NULL) {
|
||||
tr = wl_container_of(addon, tr, addon);
|
||||
} else {
|
||||
tr = drm_crtc_color_transform_create(backend, crtc, base);
|
||||
if (tr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (tr->failed) {
|
||||
// We failed to convert the color transform to a 3×1D LUT. Keep the
|
||||
// addon attached so that we remember that this color transform cannot
|
||||
// be imported next time a commit contains it.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlr_color_transform_ref(tr->base);
|
||||
return tr;
|
||||
}
|
||||
|
||||
void drm_crtc_color_transform_unref(struct wlr_drm_crtc_color_transform *tr) {
|
||||
if (tr == NULL) {
|
||||
return;
|
||||
}
|
||||
wlr_color_transform_unref(tr->base);
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
#include <wlr/util/transform.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include "backend/drm/color.h"
|
||||
#include "backend/drm/drm.h"
|
||||
#include "backend/drm/fb.h"
|
||||
#include "backend/drm/iface.h"
|
||||
|
|
@ -390,6 +391,9 @@ void finish_drm_resources(struct wlr_drm_backend *drm) {
|
|||
if (crtc->gamma_lut) {
|
||||
drmModeDestroyPropertyBlob(drm->fd, crtc->gamma_lut);
|
||||
}
|
||||
if (crtc->ctm) {
|
||||
drmModeDestroyPropertyBlob(drm->fd, crtc->ctm);
|
||||
}
|
||||
}
|
||||
|
||||
free(drm->crtcs);
|
||||
|
|
@ -707,6 +711,7 @@ static void drm_connector_state_finish(struct wlr_drm_connector_state *state) {
|
|||
drm_fb_clear(&state->primary_fb);
|
||||
drm_fb_clear(&state->cursor_fb);
|
||||
wlr_drm_syncobj_timeline_unref(state->wait_timeline);
|
||||
drm_crtc_color_transform_unref(state->crtc_color_transform);
|
||||
}
|
||||
|
||||
static bool drm_connector_state_update_primary_fb(struct wlr_drm_connector *conn,
|
||||
|
|
@ -858,11 +863,15 @@ static bool drm_connector_prepare(struct wlr_drm_connector_state *conn_state, bo
|
|||
}
|
||||
}
|
||||
|
||||
if ((state->committed & WLR_OUTPUT_STATE_COLOR_TRANSFORM) && state->color_transform != NULL &&
|
||||
state->color_transform->type != COLOR_TRANSFORM_LUT_3X1D) {
|
||||
wlr_drm_conn_log(conn, WLR_DEBUG,
|
||||
"Only 3x1D LUT color transforms are supported");
|
||||
return false;
|
||||
if ((state->committed & WLR_OUTPUT_STATE_COLOR_TRANSFORM) && state->color_transform != NULL) {
|
||||
assert(conn_state->crtc_color_transform == NULL);
|
||||
conn_state->crtc_color_transform = drm_crtc_color_transform_import(conn->backend,
|
||||
conn->crtc, state->color_transform);
|
||||
if (conn_state->crtc_color_transform == NULL) {
|
||||
wlr_drm_conn_log(conn, WLR_DEBUG,
|
||||
"Failed to import color transform");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((state->committed & WLR_OUTPUT_STATE_IMAGE_DESCRIPTION) &&
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <wlr/util/log.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
#include "backend/drm/color.h"
|
||||
#include "backend/drm/drm.h"
|
||||
#include "backend/drm/fb.h"
|
||||
#include "backend/drm/iface.h"
|
||||
|
|
@ -128,11 +129,9 @@ static bool legacy_crtc_commit(const struct wlr_drm_connector_state *state,
|
|||
if (state->base->committed & WLR_OUTPUT_STATE_COLOR_TRANSFORM) {
|
||||
size_t dim = 0;
|
||||
uint16_t *lut = NULL;
|
||||
if (state->base->color_transform != NULL) {
|
||||
struct wlr_color_transform_lut_3x1d *tr =
|
||||
color_transform_lut_3x1d_from_base(state->base->color_transform);
|
||||
dim = tr->dim;
|
||||
lut = tr->lut_3x1d;
|
||||
if (state->crtc_color_transform != NULL) {
|
||||
dim = state->crtc_color_transform->lut_3x1d->dim;
|
||||
lut = state->crtc_color_transform->lut_3x1d->lut_3x1d;
|
||||
}
|
||||
|
||||
if (!drm_legacy_crtc_set_gamma(drm, crtc, dim, lut)) {
|
||||
|
|
|
|||
|
|
@ -328,6 +328,9 @@ static bool add_connector(drmModeAtomicReq *req,
|
|||
if (crtc->props.gamma_lut != 0) {
|
||||
ok = ok && add_prop(req, crtc->id, crtc->props.gamma_lut, state->gamma_lut);
|
||||
}
|
||||
if (crtc->props.ctm != 0) {
|
||||
ok = ok && add_prop(req, crtc->id, crtc->props.ctm, state->ctm);
|
||||
}
|
||||
if (crtc->props.vrr_enabled != 0) {
|
||||
ok = ok && add_prop(req, crtc->id, crtc->props.vrr_enabled, state->vrr_enabled);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ wlr_files += pnpids_c
|
|||
wlr_files += files(
|
||||
'atomic.c',
|
||||
'backend.c',
|
||||
'color.c',
|
||||
'drm.c',
|
||||
'fb.c',
|
||||
'legacy.c',
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ static const struct prop_info connector_info[] = {
|
|||
static const struct prop_info crtc_info[] = {
|
||||
#define INDEX(name) (offsetof(struct wlr_drm_crtc_props, name) / sizeof(uint32_t))
|
||||
{ "ACTIVE", INDEX(active) },
|
||||
{ "CTM", INDEX(ctm) },
|
||||
{ "GAMMA_LUT", INDEX(gamma_lut) },
|
||||
{ "GAMMA_LUT_SIZE", INDEX(gamma_lut_size) },
|
||||
{ "MODE_ID", INDEX(mode_id) },
|
||||
|
|
|
|||
25
include/backend/drm/color.h
Normal file
25
include/backend/drm/color.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef BACKEND_DRN_COLOR_H
|
||||
#define BACKEND_DRN_COLOR_H
|
||||
|
||||
#include <wlr/util/addon.h>
|
||||
|
||||
struct wlr_drm_backend;
|
||||
struct wlr_drm_crtc;
|
||||
struct wlr_color_transform;
|
||||
|
||||
struct wlr_drm_crtc_color_transform {
|
||||
struct wlr_color_transform *base;
|
||||
struct wlr_addon addon; // wlr_color_transform.addons
|
||||
bool failed;
|
||||
struct wlr_color_transform_lut_3x1d *lut_3x1d;
|
||||
float matrix[9];
|
||||
bool has_matrix;
|
||||
};
|
||||
|
||||
struct wlr_drm_crtc_color_transform *drm_crtc_color_transform_import(
|
||||
struct wlr_drm_backend *backend, struct wlr_drm_crtc *crtc,
|
||||
struct wlr_color_transform *base);
|
||||
|
||||
void drm_crtc_color_transform_unref(struct wlr_drm_crtc_color_transform *tr);
|
||||
|
||||
#endif
|
||||
|
|
@ -15,6 +15,8 @@
|
|||
#include "backend/drm/properties.h"
|
||||
#include "backend/drm/renderer.h"
|
||||
|
||||
struct wlr_drm_crtc_color_transform;
|
||||
|
||||
struct wlr_drm_viewport {
|
||||
struct wlr_fbox src_box;
|
||||
struct wlr_box dst_box;
|
||||
|
|
@ -74,6 +76,7 @@ struct wlr_drm_crtc {
|
|||
bool own_mode_id;
|
||||
uint32_t mode_id;
|
||||
uint32_t gamma_lut;
|
||||
uint32_t ctm;
|
||||
|
||||
// Legacy only
|
||||
int legacy_gamma_size;
|
||||
|
|
@ -152,9 +155,12 @@ struct wlr_drm_connector_state {
|
|||
struct wlr_drm_syncobj_timeline *wait_timeline;
|
||||
uint64_t wait_point;
|
||||
|
||||
struct wlr_drm_crtc_color_transform *crtc_color_transform;
|
||||
|
||||
// used by atomic
|
||||
uint32_t mode_id;
|
||||
uint32_t gamma_lut;
|
||||
uint32_t ctm;
|
||||
uint32_t fb_damage_clips;
|
||||
int primary_in_fence_fd, out_fence_fd;
|
||||
bool vrr_enabled;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ struct wlr_drm_crtc_props {
|
|||
uint32_t vrr_enabled;
|
||||
uint32_t gamma_lut;
|
||||
uint32_t gamma_lut_size;
|
||||
uint32_t ctm;
|
||||
|
||||
// atomic-modesetting only
|
||||
|
||||
|
|
|
|||
|
|
@ -108,4 +108,9 @@ void wlr_color_primaries_to_xyz(const struct wlr_color_primaries *primaries, flo
|
|||
void wlr_color_transfer_function_get_default_luminance(enum wlr_color_transfer_function tf,
|
||||
struct wlr_color_luminances *lum);
|
||||
|
||||
/**
|
||||
* Apply a color transfer function's EOTF⁻¹ operation.
|
||||
*/
|
||||
float wlr_color_transfer_function_eval_inverse_eotf(enum wlr_color_transfer_function tf, float x);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ static float bt1886_eval_inverse_eotf(float x) {
|
|||
return powf(x / a, 1.0 / 2.4) - b;
|
||||
}
|
||||
|
||||
static float transfer_function_eval_inverse_eotf(
|
||||
float wlr_color_transfer_function_eval_inverse_eotf(
|
||||
enum wlr_color_transfer_function tf, float x) {
|
||||
switch (tf) {
|
||||
case WLR_COLOR_TRANSFER_FUNCTION_SRGB:
|
||||
|
|
@ -209,7 +209,7 @@ static void color_transform_inverse_eotf_eval(
|
|||
struct wlr_color_transform_inverse_eotf *tr,
|
||||
float out[static 3], const float in[static 3]) {
|
||||
for (size_t i = 0; i < 3; i++) {
|
||||
out[i] = transfer_function_eval_inverse_eotf(tr->tf, in[i]);
|
||||
out[i] = wlr_color_transfer_function_eval_inverse_eotf(tr->tf, in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue