mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-21 22:52:20 +00:00
wlr_scene: Introduce wlr_scene_set_gamma_control_manager_v1
This commit is contained in:
parent
23202e192c
commit
515275ee72
@ -42,6 +42,7 @@ struct wlr_scene_output_layout;
|
|||||||
|
|
||||||
struct wlr_presentation;
|
struct wlr_presentation;
|
||||||
struct wlr_linux_dmabuf_v1;
|
struct wlr_linux_dmabuf_v1;
|
||||||
|
struct wlr_gamma_control_manager_v1;
|
||||||
struct wlr_output_state;
|
struct wlr_output_state;
|
||||||
|
|
||||||
typedef bool (*wlr_scene_buffer_point_accepts_input_func_t)(
|
typedef bool (*wlr_scene_buffer_point_accepts_input_func_t)(
|
||||||
@ -100,10 +101,13 @@ struct wlr_scene {
|
|||||||
|
|
||||||
// May be NULL
|
// May be NULL
|
||||||
struct wlr_linux_dmabuf_v1 *linux_dmabuf_v1;
|
struct wlr_linux_dmabuf_v1 *linux_dmabuf_v1;
|
||||||
|
struct wlr_gamma_control_manager_v1 *gamma_control_manager_v1;
|
||||||
|
|
||||||
// private state
|
// private state
|
||||||
|
|
||||||
struct wl_listener linux_dmabuf_v1_destroy;
|
struct wl_listener linux_dmabuf_v1_destroy;
|
||||||
|
struct wl_listener gamma_control_manager_v1_destroy;
|
||||||
|
struct wl_listener gamma_control_manager_v1_set_gamma;
|
||||||
|
|
||||||
enum wlr_scene_debug_damage_option debug_damage_option;
|
enum wlr_scene_debug_damage_option debug_damage_option;
|
||||||
bool direct_scanout;
|
bool direct_scanout;
|
||||||
@ -220,6 +224,9 @@ struct wlr_scene_output {
|
|||||||
uint8_t index;
|
uint8_t index;
|
||||||
bool prev_scanout;
|
bool prev_scanout;
|
||||||
|
|
||||||
|
bool gamma_lut_changed;
|
||||||
|
struct wlr_gamma_control_v1 *gamma_lut;
|
||||||
|
|
||||||
struct wl_listener output_commit;
|
struct wl_listener output_commit;
|
||||||
struct wl_listener output_damage;
|
struct wl_listener output_damage;
|
||||||
struct wl_listener output_needs_frame;
|
struct wl_listener output_needs_frame;
|
||||||
@ -326,6 +333,14 @@ struct wlr_scene *wlr_scene_create(void);
|
|||||||
void wlr_scene_set_linux_dmabuf_v1(struct wlr_scene *scene,
|
void wlr_scene_set_linux_dmabuf_v1(struct wlr_scene *scene,
|
||||||
struct wlr_linux_dmabuf_v1 *linux_dmabuf_v1);
|
struct wlr_linux_dmabuf_v1 *linux_dmabuf_v1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles gamma_control_v1 for all outputs in the scene.
|
||||||
|
*
|
||||||
|
* Asserts that a struct wlr_gamma_control_manager_v1 hasn't already been set
|
||||||
|
* for the scene.
|
||||||
|
*/
|
||||||
|
void wlr_scene_set_gamma_control_manager_v1(struct wlr_scene *scene,
|
||||||
|
struct wlr_gamma_control_manager_v1 *gamma_control);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a node displaying nothing but its children.
|
* Add a node displaying nothing but its children.
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
#include <wlr/types/wlr_damage_ring.h>
|
#include <wlr/types/wlr_damage_ring.h>
|
||||||
|
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||||
#include <wlr/types/wlr_presentation_time.h>
|
#include <wlr/types/wlr_presentation_time.h>
|
||||||
#include <wlr/types/wlr_scene.h>
|
#include <wlr/types/wlr_scene.h>
|
||||||
@ -136,6 +137,8 @@ void wlr_scene_node_destroy(struct wlr_scene_node *node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wl_list_remove(&scene->linux_dmabuf_v1_destroy.link);
|
wl_list_remove(&scene->linux_dmabuf_v1_destroy.link);
|
||||||
|
wl_list_remove(&scene->gamma_control_manager_v1_destroy.link);
|
||||||
|
wl_list_remove(&scene->gamma_control_manager_v1_set_gamma.link);
|
||||||
} else {
|
} else {
|
||||||
assert(node->parent);
|
assert(node->parent);
|
||||||
}
|
}
|
||||||
@ -169,6 +172,8 @@ struct wlr_scene *wlr_scene_create(void) {
|
|||||||
|
|
||||||
wl_list_init(&scene->outputs);
|
wl_list_init(&scene->outputs);
|
||||||
wl_list_init(&scene->linux_dmabuf_v1_destroy.link);
|
wl_list_init(&scene->linux_dmabuf_v1_destroy.link);
|
||||||
|
wl_list_init(&scene->gamma_control_manager_v1_destroy.link);
|
||||||
|
wl_list_init(&scene->gamma_control_manager_v1_set_gamma.link);
|
||||||
|
|
||||||
const char *debug_damage_options[] = {
|
const char *debug_damage_options[] = {
|
||||||
"none",
|
"none",
|
||||||
@ -1429,6 +1434,52 @@ void wlr_scene_set_linux_dmabuf_v1(struct wlr_scene *scene,
|
|||||||
wl_signal_add(&linux_dmabuf_v1->events.destroy, &scene->linux_dmabuf_v1_destroy);
|
wl_signal_add(&linux_dmabuf_v1->events.destroy, &scene->linux_dmabuf_v1_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void scene_handle_gamma_control_manager_v1_set_gamma(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
const struct wlr_gamma_control_manager_v1_set_gamma_event *event = data;
|
||||||
|
struct wlr_scene *scene =
|
||||||
|
wl_container_of(listener, scene, gamma_control_manager_v1_set_gamma);
|
||||||
|
struct wlr_scene_output *output = wlr_scene_get_scene_output(scene, event->output);
|
||||||
|
if (!output) {
|
||||||
|
// this scene might not own this output.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
output->gamma_lut_changed = true;
|
||||||
|
output->gamma_lut = event->control;
|
||||||
|
wlr_output_schedule_frame(output->output);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scene_handle_gamma_control_manager_v1_destroy(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct wlr_scene *scene =
|
||||||
|
wl_container_of(listener, scene, gamma_control_manager_v1_destroy);
|
||||||
|
wl_list_remove(&scene->gamma_control_manager_v1_destroy.link);
|
||||||
|
wl_list_init(&scene->gamma_control_manager_v1_destroy.link);
|
||||||
|
wl_list_remove(&scene->gamma_control_manager_v1_set_gamma.link);
|
||||||
|
wl_list_init(&scene->gamma_control_manager_v1_set_gamma.link);
|
||||||
|
scene->gamma_control_manager_v1 = NULL;
|
||||||
|
|
||||||
|
struct wlr_scene_output *output;
|
||||||
|
wl_list_for_each(output, &scene->outputs, link) {
|
||||||
|
output->gamma_lut_changed = false;
|
||||||
|
output->gamma_lut = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void wlr_scene_set_gamma_control_manager_v1(struct wlr_scene *scene,
|
||||||
|
struct wlr_gamma_control_manager_v1 *gamma_control) {
|
||||||
|
assert(scene->gamma_control_manager_v1 == NULL);
|
||||||
|
scene->gamma_control_manager_v1 = gamma_control;
|
||||||
|
|
||||||
|
scene->gamma_control_manager_v1_destroy.notify =
|
||||||
|
scene_handle_gamma_control_manager_v1_destroy;
|
||||||
|
wl_signal_add(&gamma_control->events.destroy, &scene->gamma_control_manager_v1_destroy);
|
||||||
|
scene->gamma_control_manager_v1_set_gamma.notify =
|
||||||
|
scene_handle_gamma_control_manager_v1_set_gamma;
|
||||||
|
wl_signal_add(&gamma_control->events.set_gamma, &scene->gamma_control_manager_v1_set_gamma);
|
||||||
|
}
|
||||||
|
|
||||||
static void scene_output_handle_destroy(struct wlr_addon *addon) {
|
static void scene_output_handle_destroy(struct wlr_addon *addon) {
|
||||||
struct wlr_scene_output *scene_output =
|
struct wlr_scene_output *scene_output =
|
||||||
wl_container_of(addon, scene_output, addon);
|
wl_container_of(addon, scene_output, addon);
|
||||||
@ -1496,6 +1547,13 @@ static void scene_output_handle_commit(struct wl_listener *listener, void *data)
|
|||||||
!wl_list_empty(&scene_output->damage_highlight_regions)) {
|
!wl_list_empty(&scene_output->damage_highlight_regions)) {
|
||||||
wlr_output_schedule_frame(scene_output->output);
|
wlr_output_schedule_frame(scene_output->output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Next time the output is enabled, try to re-apply the gamma LUT
|
||||||
|
if (scene_output->scene->gamma_control_manager_v1 &&
|
||||||
|
(state->committed & WLR_OUTPUT_STATE_ENABLED) &&
|
||||||
|
!scene_output->output->enabled) {
|
||||||
|
scene_output->gamma_lut_changed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scene_output_handle_damage(struct wl_listener *listener, void *data) {
|
static void scene_output_handle_damage(struct wl_listener *listener, void *data) {
|
||||||
@ -1820,7 +1878,7 @@ static bool scene_entry_try_direct_scanout(struct render_list_entry *entry,
|
|||||||
|
|
||||||
bool wlr_scene_output_needs_frame(struct wlr_scene_output *scene_output) {
|
bool wlr_scene_output_needs_frame(struct wlr_scene_output *scene_output) {
|
||||||
return scene_output->output->needs_frame || pixman_region32_not_empty(
|
return scene_output->output->needs_frame || pixman_region32_not_empty(
|
||||||
&scene_output->pending_commit_damage);
|
&scene_output->pending_commit_damage) || scene_output->gamma_lut_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_scene_output_commit(struct wlr_scene_output *scene_output,
|
bool wlr_scene_output_commit(struct wlr_scene_output *scene_output,
|
||||||
@ -1846,6 +1904,35 @@ out:
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void scene_output_state_attempt_gamma(struct wlr_scene_output *scene_output,
|
||||||
|
struct wlr_output_state *state) {
|
||||||
|
if (!scene_output->gamma_lut_changed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_output_state gamma_pending = {0};
|
||||||
|
if (!wlr_output_state_copy(&gamma_pending, state)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wlr_gamma_control_v1_apply(scene_output->gamma_lut, &gamma_pending)) {
|
||||||
|
wlr_output_state_finish(&gamma_pending);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scene_output->gamma_lut_changed = false;
|
||||||
|
if (!wlr_output_test_state(scene_output->output, &gamma_pending)) {
|
||||||
|
wlr_gamma_control_v1_send_failed_and_destroy(scene_output->gamma_lut);
|
||||||
|
|
||||||
|
scene_output->gamma_lut = NULL;
|
||||||
|
wlr_output_state_finish(&gamma_pending);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wlr_output_state_copy(state, &gamma_pending);
|
||||||
|
wlr_output_state_finish(&gamma_pending);
|
||||||
|
}
|
||||||
|
|
||||||
bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
||||||
struct wlr_output_state *state, const struct wlr_scene_output_state_options *options) {
|
struct wlr_output_state *state, const struct wlr_scene_output_state_options *options) {
|
||||||
struct wlr_scene_output_state_options default_options = {0};
|
struct wlr_scene_output_state_options default_options = {0};
|
||||||
@ -1982,6 +2069,8 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (scanout) {
|
if (scanout) {
|
||||||
|
scene_output_state_attempt_gamma(scene_output, state);
|
||||||
|
|
||||||
if (timer) {
|
if (timer) {
|
||||||
struct timespec end_time, duration;
|
struct timespec end_time, duration;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &end_time);
|
clock_gettime(CLOCK_MONOTONIC, &end_time);
|
||||||
@ -2141,6 +2230,8 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
|||||||
scene_output->in_point);
|
scene_output->in_point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scene_output_state_attempt_gamma(scene_output, state);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user