mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-25 00:22:25 +00:00
output: add wlr_output_state_init()
This changes the semantics of wlr_output_state. Instead of having fields with uninitialized memory when missing from the committed bitflag, all fields are always initialized (and maybe NULL/empty), just like we do in wlr_surface_state. This reduces the chances of footguns when reading a field, and removes the need to check for the committed bitfield everywhere. A new wlr_output_state_init() function takes care of initializing the Pixman region.
This commit is contained in:
parent
8a5b5e6f28
commit
be05097968
@ -121,22 +121,21 @@ static void handle_session_active(struct wl_listener *listener, void *data) {
|
|||||||
struct wlr_drm_connector *conn;
|
struct wlr_drm_connector *conn;
|
||||||
wl_list_for_each(conn, &drm->connectors, link) {
|
wl_list_for_each(conn, &drm->connectors, link) {
|
||||||
struct wlr_output_mode *mode = NULL;
|
struct wlr_output_mode *mode = NULL;
|
||||||
uint32_t committed = WLR_OUTPUT_STATE_ENABLED;
|
|
||||||
if (conn->status != DRM_MODE_DISCONNECTED && conn->output.enabled
|
if (conn->status != DRM_MODE_DISCONNECTED && conn->output.enabled
|
||||||
&& conn->output.current_mode != NULL) {
|
&& conn->output.current_mode != NULL) {
|
||||||
committed |= WLR_OUTPUT_STATE_MODE;
|
|
||||||
mode = conn->output.current_mode;
|
mode = conn->output.current_mode;
|
||||||
}
|
}
|
||||||
struct wlr_output_state state = {
|
|
||||||
.committed = committed,
|
struct wlr_output_state state;
|
||||||
.allow_artifacts = true,
|
wlr_output_state_init(&state);
|
||||||
.enabled = mode != NULL,
|
wlr_output_state_set_enabled(&state, mode != NULL);
|
||||||
.mode_type = WLR_OUTPUT_STATE_MODE_FIXED,
|
if (mode != NULL) {
|
||||||
.mode = mode,
|
wlr_output_state_set_mode(&state, mode);
|
||||||
};
|
}
|
||||||
if (!drm_connector_commit_state(conn, &state)) {
|
if (!drm_connector_commit_state(conn, &state)) {
|
||||||
wlr_drm_conn_log(conn, WLR_ERROR, "Failed to restore state after VT switch");
|
wlr_drm_conn_log(conn, WLR_ERROR, "Failed to restore state after VT switch");
|
||||||
}
|
}
|
||||||
|
wlr_output_state_finish(&state);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
wlr_log(WLR_INFO, "DRM fd paused");
|
wlr_log(WLR_INFO, "DRM fd paused");
|
||||||
|
@ -1155,16 +1155,15 @@ static void dealloc_crtc(struct wlr_drm_connector *conn) {
|
|||||||
wlr_drm_conn_log(conn, WLR_DEBUG, "De-allocating CRTC %" PRIu32,
|
wlr_drm_conn_log(conn, WLR_DEBUG, "De-allocating CRTC %" PRIu32,
|
||||||
conn->crtc->id);
|
conn->crtc->id);
|
||||||
|
|
||||||
struct wlr_output_state state = {
|
struct wlr_output_state state;
|
||||||
.committed = WLR_OUTPUT_STATE_ENABLED,
|
wlr_output_state_init(&state);
|
||||||
.allow_artifacts = true,
|
wlr_output_state_set_enabled(&state, false);
|
||||||
.enabled = false,
|
|
||||||
};
|
|
||||||
if (!drm_connector_commit_state(conn, &state)) {
|
if (!drm_connector_commit_state(conn, &state)) {
|
||||||
// On GPU unplug, disabling the CRTC can fail with EPERM
|
// On GPU unplug, disabling the CRTC can fail with EPERM
|
||||||
wlr_drm_conn_log(conn, WLR_ERROR, "Failed to disable CRTC %"PRIu32,
|
wlr_drm_conn_log(conn, WLR_ERROR, "Failed to disable CRTC %"PRIu32,
|
||||||
conn->crtc->id);
|
conn->crtc->id);
|
||||||
}
|
}
|
||||||
|
wlr_output_state_finish(&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void realloc_crtcs(struct wlr_drm_backend *drm,
|
static void realloc_crtcs(struct wlr_drm_backend *drm,
|
||||||
|
@ -703,12 +703,11 @@ static void xdg_toplevel_handle_configure(void *data,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_output_state state = {
|
struct wlr_output_state state;
|
||||||
.committed = WLR_OUTPUT_STATE_MODE,
|
wlr_output_state_init(&state);
|
||||||
.mode_type = WLR_OUTPUT_STATE_MODE_CUSTOM,
|
wlr_output_state_set_custom_mode(&state, width, height, 0);
|
||||||
.custom_mode = { .width = width, .height = height },
|
|
||||||
};
|
|
||||||
wlr_output_send_request_state(&output->wlr_output, &state);
|
wlr_output_send_request_state(&output->wlr_output, &state);
|
||||||
|
wlr_output_state_finish(&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xdg_toplevel_handle_close(void *data,
|
static void xdg_toplevel_handle_close(void *data,
|
||||||
|
@ -623,12 +623,11 @@ void handle_x11_configure_notify(struct wlr_x11_output *output,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_output_state state = {
|
struct wlr_output_state state;
|
||||||
.committed = WLR_OUTPUT_STATE_MODE,
|
wlr_output_state_init(&state);
|
||||||
.mode_type = WLR_OUTPUT_STATE_MODE_CUSTOM,
|
wlr_output_state_set_custom_mode(&state, ev->width, ev->height, 0);
|
||||||
.custom_mode = { .width = ev->width, .height = ev->height },
|
|
||||||
};
|
|
||||||
wlr_output_send_request_state(&output->wlr_output, &state);
|
wlr_output_send_request_state(&output->wlr_output, &state);
|
||||||
|
wlr_output_state_finish(&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_output_is_x11(struct wlr_output *wlr_output) {
|
bool wlr_output_is_x11(struct wlr_output *wlr_output) {
|
||||||
|
@ -89,7 +89,8 @@ static void output_handle_frame(struct wl_listener *listener, void *data) {
|
|||||||
int width, height;
|
int width, height;
|
||||||
wlr_output_effective_resolution(output->wlr_output, &width, &height);
|
wlr_output_effective_resolution(output->wlr_output, &width, &height);
|
||||||
|
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
struct wlr_render_pass *pass = wlr_output_begin_render_pass(output->wlr_output, &state, NULL,
|
struct wlr_render_pass *pass = wlr_output_begin_render_pass(output->wlr_output, &state, NULL,
|
||||||
NULL);
|
NULL);
|
||||||
if (pass == NULL) {
|
if (pass == NULL) {
|
||||||
@ -166,7 +167,8 @@ static void server_handle_new_output(struct wl_listener *listener, void *data) {
|
|||||||
|
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
|
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
|
||||||
if (mode != NULL) {
|
if (mode != NULL) {
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_mode(&state, mode);
|
wlr_output_state_set_mode(&state, mode);
|
||||||
wlr_output_commit_state(wlr_output, &state);
|
wlr_output_commit_state(wlr_output, &state);
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
|
@ -82,7 +82,8 @@ static void output_handle_frame(struct wl_listener *listener, void *data) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_output_state output_state = {0};
|
struct wlr_output_state output_state;
|
||||||
|
wlr_output_state_init(&output_state);
|
||||||
wlr_output_state_set_layers(&output_state, layers_arr.data,
|
wlr_output_state_set_layers(&output_state, layers_arr.data,
|
||||||
layers_arr.size / sizeof(struct wlr_output_layer_state));
|
layers_arr.size / sizeof(struct wlr_output_layer_state));
|
||||||
|
|
||||||
@ -175,7 +176,8 @@ static void server_handle_new_output(struct wl_listener *listener, void *data) {
|
|||||||
|
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
|
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
|
||||||
if (mode != NULL) {
|
if (mode != NULL) {
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_mode(&state, mode);
|
wlr_output_state_set_mode(&state, mode);
|
||||||
wlr_output_commit_state(wlr_output, &state);
|
wlr_output_commit_state(wlr_output, &state);
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
|
@ -114,7 +114,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
|||||||
struct sample_state *sample = output->sample;
|
struct sample_state *sample = output->sample;
|
||||||
struct wlr_output *wlr_output = output->output;
|
struct wlr_output *wlr_output = output->output;
|
||||||
|
|
||||||
struct wlr_output_state output_state = {0};
|
struct wlr_output_state output_state;
|
||||||
|
wlr_output_state_init(&output_state);
|
||||||
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
||||||
|
|
||||||
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
||||||
@ -178,7 +179,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
|||||||
|
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
||||||
if (mode != NULL) {
|
if (mode != NULL) {
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_mode(&state, mode);
|
wlr_output_state_set_mode(&state, mode);
|
||||||
wlr_output_commit_state(output, &state);
|
wlr_output_commit_state(output, &state);
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
|
@ -101,7 +101,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
|||||||
struct wlr_renderer *renderer = state->renderer;
|
struct wlr_renderer *renderer = state->renderer;
|
||||||
assert(renderer);
|
assert(renderer);
|
||||||
|
|
||||||
struct wlr_output_state output_state = {0};
|
struct wlr_output_state output_state;
|
||||||
|
wlr_output_state_init(&output_state);
|
||||||
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
||||||
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
||||||
.box = { .width = wlr_output->width, .height = wlr_output->height },
|
.box = { .width = wlr_output->width, .height = wlr_output->height },
|
||||||
@ -280,7 +281,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
|||||||
|
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
||||||
if (mode != NULL) {
|
if (mode != NULL) {
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_mode(&state, mode);
|
wlr_output_state_set_mode(&state, mode);
|
||||||
wlr_output_commit_state(output, &state);
|
wlr_output_commit_state(output, &state);
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
|
@ -59,7 +59,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
|||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
wlr_output_effective_resolution(wlr_output, &width, &height);
|
wlr_output_effective_resolution(wlr_output, &width, &height);
|
||||||
|
|
||||||
struct wlr_output_state output_state = {0};
|
struct wlr_output_state output_state;
|
||||||
|
wlr_output_state_init(&output_state);
|
||||||
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
||||||
|
|
||||||
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
||||||
@ -122,7 +123,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
|||||||
sample_output->x_offs = sample_output->y_offs = 0;
|
sample_output->x_offs = sample_output->y_offs = 0;
|
||||||
sample_output->x_vel = sample_output->y_vel = 128;
|
sample_output->x_vel = sample_output->y_vel = 128;
|
||||||
|
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_transform(&state, sample->transform);
|
wlr_output_state_set_transform(&state, sample->transform);
|
||||||
|
|
||||||
sample_output->output = output;
|
sample_output->output = output;
|
||||||
|
@ -83,7 +83,8 @@ static void server_handle_new_output(struct wl_listener *listener, void *data) {
|
|||||||
|
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
|
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
|
||||||
if (mode != NULL) {
|
if (mode != NULL) {
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_mode(&state, mode);
|
wlr_output_state_set_mode(&state, mode);
|
||||||
wlr_output_commit_state(wlr_output, &state);
|
wlr_output_commit_state(wlr_output, &state);
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
|
@ -62,7 +62,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
|||||||
sample->dec = inc;
|
sample->dec = inc;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &state, NULL, NULL);
|
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &state, NULL, NULL);
|
||||||
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
||||||
.box = { .width = wlr_output->width, .height = wlr_output->height },
|
.box = { .width = wlr_output->width, .height = wlr_output->height },
|
||||||
@ -107,7 +108,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
|||||||
|
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
||||||
if (mode != NULL) {
|
if (mode != NULL) {
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_mode(&state, mode);
|
wlr_output_state_set_mode(&state, mode);
|
||||||
wlr_output_commit_state(sample_output->output, &state);
|
wlr_output_commit_state(sample_output->output, &state);
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
|
@ -87,7 +87,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
|||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
wlr_output_effective_resolution(wlr_output, &width, &height);
|
wlr_output_effective_resolution(wlr_output, &width, &height);
|
||||||
|
|
||||||
struct wlr_output_state output_state = {0};
|
struct wlr_output_state output_state;
|
||||||
|
wlr_output_state_init(&output_state);
|
||||||
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
||||||
|
|
||||||
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
||||||
@ -285,7 +286,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
|||||||
|
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
||||||
if (mode != NULL) {
|
if (mode != NULL) {
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_mode(&state, mode);
|
wlr_output_state_set_mode(&state, mode);
|
||||||
wlr_output_commit_state(output, &state);
|
wlr_output_commit_state(output, &state);
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
|
@ -76,7 +76,8 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {
|
|||||||
int32_t width, height;
|
int32_t width, height;
|
||||||
wlr_output_effective_resolution(wlr_output, &width, &height);
|
wlr_output_effective_resolution(wlr_output, &width, &height);
|
||||||
|
|
||||||
struct wlr_output_state output_state = {0};
|
struct wlr_output_state output_state;
|
||||||
|
wlr_output_state_init(&output_state);
|
||||||
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
struct wlr_render_pass *pass = wlr_output_begin_render_pass(wlr_output, &output_state, NULL, NULL);
|
||||||
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
wlr_render_pass_add_rect(pass, &(struct wlr_render_rect_options){
|
||||||
.box = { .width = width, .height = height },
|
.box = { .width = width, .height = height },
|
||||||
@ -184,7 +185,8 @@ static void new_output_notify(struct wl_listener *listener, void *data) {
|
|||||||
|
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
struct wlr_output_mode *mode = wlr_output_preferred_mode(output);
|
||||||
if (mode != NULL) {
|
if (mode != NULL) {
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_mode(&state, mode);
|
wlr_output_state_set_mode(&state, mode);
|
||||||
wlr_output_commit_state(output, &state);
|
wlr_output_commit_state(output, &state);
|
||||||
wlr_output_state_finish(&state);
|
wlr_output_state_finish(&state);
|
||||||
|
@ -88,10 +88,8 @@ struct wlr_output_state {
|
|||||||
uint32_t render_format;
|
uint32_t render_format;
|
||||||
enum wl_output_subpixel subpixel;
|
enum wl_output_subpixel subpixel;
|
||||||
|
|
||||||
// only valid if WLR_OUTPUT_STATE_BUFFER
|
|
||||||
struct wlr_buffer *buffer;
|
struct wlr_buffer *buffer;
|
||||||
|
|
||||||
// only valid if WLR_OUTPUT_STATE_MODE
|
|
||||||
enum wlr_output_state_mode_type mode_type;
|
enum wlr_output_state_mode_type mode_type;
|
||||||
struct wlr_output_mode *mode;
|
struct wlr_output_mode *mode;
|
||||||
struct {
|
struct {
|
||||||
@ -99,11 +97,9 @@ struct wlr_output_state {
|
|||||||
int32_t refresh; // mHz, may be zero
|
int32_t refresh; // mHz, may be zero
|
||||||
} custom_mode;
|
} custom_mode;
|
||||||
|
|
||||||
// only valid if WLR_OUTPUT_STATE_GAMMA_LUT
|
|
||||||
uint16_t *gamma_lut;
|
uint16_t *gamma_lut;
|
||||||
size_t gamma_lut_size;
|
size_t gamma_lut_size;
|
||||||
|
|
||||||
// only valid if WLR_OUTPUT_STATE_LAYERS
|
|
||||||
struct wlr_output_layer_state *layers;
|
struct wlr_output_layer_state *layers;
|
||||||
size_t layers_len;
|
size_t layers_len;
|
||||||
};
|
};
|
||||||
@ -567,6 +563,10 @@ bool wlr_output_cursor_move(struct wlr_output_cursor *cursor,
|
|||||||
double x, double y);
|
double x, double y);
|
||||||
void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor);
|
void wlr_output_cursor_destroy(struct wlr_output_cursor *cursor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize an output state.
|
||||||
|
*/
|
||||||
|
void wlr_output_state_init(struct wlr_output_state *state);
|
||||||
/**
|
/**
|
||||||
* Releases all resources associated with an output state.
|
* Releases all resources associated with an output state.
|
||||||
*/
|
*/
|
||||||
|
@ -603,7 +603,8 @@ static void server_new_output(struct wl_listener *listener, void *data) {
|
|||||||
* would let the user configure it. */
|
* would let the user configure it. */
|
||||||
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
|
struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
|
||||||
if (mode != NULL) {
|
if (mode != NULL) {
|
||||||
struct wlr_output_state state = {0};
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
wlr_output_state_set_mode(&state, mode);
|
wlr_output_state_set_mode(&state, mode);
|
||||||
wlr_output_state_set_enabled(&state, true);
|
wlr_output_state_set_enabled(&state, true);
|
||||||
if (!wlr_output_commit_state(wlr_output, &state)) {
|
if (!wlr_output_commit_state(wlr_output, &state)) {
|
||||||
|
@ -319,15 +319,10 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
|||||||
wlr_output_destroy_global(output);
|
wlr_output_destroy_global(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_state_init(struct wlr_output_state *state) {
|
|
||||||
memset(state, 0, sizeof(*state));
|
|
||||||
pixman_region32_init(&state->damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void output_state_move(struct wlr_output_state *dst,
|
static void output_state_move(struct wlr_output_state *dst,
|
||||||
struct wlr_output_state *src) {
|
struct wlr_output_state *src) {
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
output_state_init(src);
|
wlr_output_state_init(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
||||||
@ -359,7 +354,7 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend,
|
|||||||
wl_signal_init(&output->events.description);
|
wl_signal_init(&output->events.description);
|
||||||
wl_signal_init(&output->events.request_state);
|
wl_signal_init(&output->events.request_state);
|
||||||
wl_signal_init(&output->events.destroy);
|
wl_signal_init(&output->events.destroy);
|
||||||
output_state_init(&output->pending);
|
wlr_output_state_init(&output->pending);
|
||||||
|
|
||||||
output->software_cursor_locks = env_parse_bool("WLR_NO_HARDWARE_CURSORS");
|
output->software_cursor_locks = env_parse_bool("WLR_NO_HARDWARE_CURSORS");
|
||||||
if (output->software_cursor_locks) {
|
if (output->software_cursor_locks) {
|
||||||
|
@ -3,21 +3,20 @@
|
|||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "types/wlr_output.h"
|
#include "types/wlr_output.h"
|
||||||
|
|
||||||
|
void wlr_output_state_init(struct wlr_output_state *state) {
|
||||||
|
*state = (struct wlr_output_state){0};
|
||||||
|
pixman_region32_init(&state->damage);
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_output_state_finish(struct wlr_output_state *state) {
|
void wlr_output_state_finish(struct wlr_output_state *state) {
|
||||||
if (state->committed & WLR_OUTPUT_STATE_BUFFER) {
|
|
||||||
wlr_buffer_unlock(state->buffer);
|
wlr_buffer_unlock(state->buffer);
|
||||||
// struct wlr_buffer is ref'counted, so the pointer may remain valid after
|
// struct wlr_buffer is ref'counted, so the pointer may remain valid after
|
||||||
// wlr_buffer_unlock(). Reset the field to NULL to ensure nobody mistakenly
|
// wlr_buffer_unlock(). Reset the field to NULL to ensure nobody mistakenly
|
||||||
// reads it after output_state_finish().
|
// reads it after output_state_finish().
|
||||||
state->buffer = NULL;
|
state->buffer = NULL;
|
||||||
}
|
|
||||||
if (state->committed & WLR_OUTPUT_STATE_DAMAGE) {
|
|
||||||
pixman_region32_fini(&state->damage);
|
pixman_region32_fini(&state->damage);
|
||||||
}
|
|
||||||
if (state->committed & WLR_OUTPUT_STATE_GAMMA_LUT) {
|
|
||||||
free(state->gamma_lut);
|
free(state->gamma_lut);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void wlr_output_state_set_enabled(struct wlr_output_state *state,
|
void wlr_output_state_set_enabled(struct wlr_output_state *state,
|
||||||
bool enabled) {
|
bool enabled) {
|
||||||
@ -75,23 +74,14 @@ void wlr_output_state_set_subpixel(struct wlr_output_state *state,
|
|||||||
|
|
||||||
void wlr_output_state_set_buffer(struct wlr_output_state *state,
|
void wlr_output_state_set_buffer(struct wlr_output_state *state,
|
||||||
struct wlr_buffer *buffer) {
|
struct wlr_buffer *buffer) {
|
||||||
if (state->committed & WLR_OUTPUT_STATE_BUFFER) {
|
|
||||||
wlr_buffer_unlock(state->buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
state->committed |= WLR_OUTPUT_STATE_BUFFER;
|
state->committed |= WLR_OUTPUT_STATE_BUFFER;
|
||||||
|
wlr_buffer_unlock(state->buffer);
|
||||||
state->buffer = wlr_buffer_lock(buffer);
|
state->buffer = wlr_buffer_lock(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_output_state_set_damage(struct wlr_output_state *state,
|
void wlr_output_state_set_damage(struct wlr_output_state *state,
|
||||||
const pixman_region32_t *damage) {
|
const pixman_region32_t *damage) {
|
||||||
if (state->committed & WLR_OUTPUT_STATE_DAMAGE) {
|
|
||||||
pixman_region32_fini(&state->damage);
|
|
||||||
}
|
|
||||||
|
|
||||||
state->committed |= WLR_OUTPUT_STATE_DAMAGE;
|
state->committed |= WLR_OUTPUT_STATE_DAMAGE;
|
||||||
|
|
||||||
pixman_region32_init(&state->damage);
|
|
||||||
pixman_region32_copy(&state->damage, damage);
|
pixman_region32_copy(&state->damage, damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,11 +89,7 @@ bool wlr_output_state_set_gamma_lut(struct wlr_output_state *state,
|
|||||||
size_t ramp_size, const uint16_t *r, const uint16_t *g, const uint16_t *b) {
|
size_t ramp_size, const uint16_t *r, const uint16_t *g, const uint16_t *b) {
|
||||||
uint16_t *gamma_lut = NULL;
|
uint16_t *gamma_lut = NULL;
|
||||||
if (ramp_size > 0) {
|
if (ramp_size > 0) {
|
||||||
if (state->committed & WLR_OUTPUT_STATE_GAMMA_LUT) {
|
|
||||||
gamma_lut = realloc(state->gamma_lut, 3 * ramp_size * sizeof(uint16_t));
|
gamma_lut = realloc(state->gamma_lut, 3 * ramp_size * sizeof(uint16_t));
|
||||||
} else {
|
|
||||||
gamma_lut = malloc(3 * ramp_size * sizeof(uint16_t));
|
|
||||||
}
|
|
||||||
if (gamma_lut == NULL) {
|
if (gamma_lut == NULL) {
|
||||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||||
return false;
|
return false;
|
||||||
@ -112,10 +98,8 @@ bool wlr_output_state_set_gamma_lut(struct wlr_output_state *state,
|
|||||||
memcpy(gamma_lut + ramp_size, g, ramp_size * sizeof(uint16_t));
|
memcpy(gamma_lut + ramp_size, g, ramp_size * sizeof(uint16_t));
|
||||||
memcpy(gamma_lut + 2 * ramp_size, b, ramp_size * sizeof(uint16_t));
|
memcpy(gamma_lut + 2 * ramp_size, b, ramp_size * sizeof(uint16_t));
|
||||||
} else {
|
} else {
|
||||||
if (state->committed & WLR_OUTPUT_STATE_GAMMA_LUT) {
|
|
||||||
free(state->gamma_lut);
|
free(state->gamma_lut);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
state->committed |= WLR_OUTPUT_STATE_GAMMA_LUT;
|
state->committed |= WLR_OUTPUT_STATE_GAMMA_LUT;
|
||||||
state->gamma_lut_size = ramp_size;
|
state->gamma_lut_size = ramp_size;
|
||||||
@ -136,6 +120,10 @@ bool wlr_output_state_copy(struct wlr_output_state *dst,
|
|||||||
copy.committed &= ~(WLR_OUTPUT_STATE_BUFFER |
|
copy.committed &= ~(WLR_OUTPUT_STATE_BUFFER |
|
||||||
WLR_OUTPUT_STATE_DAMAGE |
|
WLR_OUTPUT_STATE_DAMAGE |
|
||||||
WLR_OUTPUT_STATE_GAMMA_LUT);
|
WLR_OUTPUT_STATE_GAMMA_LUT);
|
||||||
|
copy.buffer = NULL;
|
||||||
|
pixman_region32_init(©.damage);
|
||||||
|
copy.gamma_lut = NULL;
|
||||||
|
copy.gamma_lut_size = 0;
|
||||||
|
|
||||||
if (src->committed & WLR_OUTPUT_STATE_BUFFER) {
|
if (src->committed & WLR_OUTPUT_STATE_BUFFER) {
|
||||||
wlr_output_state_set_buffer(©, src->buffer);
|
wlr_output_state_set_buffer(©, src->buffer);
|
||||||
@ -146,21 +134,18 @@ bool wlr_output_state_copy(struct wlr_output_state *dst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (src->committed & WLR_OUTPUT_STATE_GAMMA_LUT) {
|
if (src->committed & WLR_OUTPUT_STATE_GAMMA_LUT) {
|
||||||
size_t gamma_buffer_size = 3 * src->gamma_lut_size * sizeof(uint16_t);
|
const uint16_t *r = src->gamma_lut;
|
||||||
copy.gamma_lut = malloc(gamma_buffer_size);
|
const uint16_t *g = src->gamma_lut + src->gamma_lut_size;
|
||||||
if (!copy.gamma_lut) {
|
const uint16_t *b = src->gamma_lut + 2 * src->gamma_lut_size;
|
||||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
if (!wlr_output_state_set_gamma_lut(©, src->gamma_lut_size, r, g, b)) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy.committed |= WLR_OUTPUT_STATE_GAMMA_LUT;
|
|
||||||
memcpy(copy.gamma_lut, src->gamma_lut, gamma_buffer_size);
|
|
||||||
copy.gamma_lut_size = src->gamma_lut_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_output_state_finish(dst);
|
wlr_output_state_finish(dst);
|
||||||
*dst = copy;
|
*dst = copy;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
wlr_output_state_finish(©);
|
wlr_output_state_finish(©);
|
||||||
return false;
|
return false;
|
||||||
|
@ -65,8 +65,9 @@ static bool test_swapchain(struct wlr_output *output,
|
|||||||
|
|
||||||
bool wlr_output_configure_primary_swapchain(struct wlr_output *output,
|
bool wlr_output_configure_primary_swapchain(struct wlr_output *output,
|
||||||
const struct wlr_output_state *state, struct wlr_swapchain **swapchain_ptr) {
|
const struct wlr_output_state *state, struct wlr_swapchain **swapchain_ptr) {
|
||||||
const struct wlr_output_state empty_state = {0};
|
struct wlr_output_state empty_state;
|
||||||
if (state == NULL) {
|
if (state == NULL) {
|
||||||
|
wlr_output_state_init(&empty_state);
|
||||||
state = &empty_state;
|
state = &empty_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1534,7 +1534,8 @@ static bool scene_buffer_can_consider_direct_scanout(struct wlr_scene_buffer *bu
|
|||||||
|
|
||||||
static bool scene_buffer_try_direct_scanout(struct wlr_scene_buffer *buffer,
|
static bool scene_buffer_try_direct_scanout(struct wlr_scene_buffer *buffer,
|
||||||
struct wlr_scene_output *scene_output, struct wlr_output_state *state) {
|
struct wlr_scene_output *scene_output, struct wlr_output_state *state) {
|
||||||
struct wlr_output_state pending = {0};
|
struct wlr_output_state pending;
|
||||||
|
wlr_output_state_init(&pending);
|
||||||
if (!wlr_output_state_copy(&pending, state)) {
|
if (!wlr_output_state_copy(&pending, state)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1564,19 +1565,23 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_output_state state = {0};
|
bool ok = false;
|
||||||
|
struct wlr_output_state state;
|
||||||
|
wlr_output_state_init(&state);
|
||||||
if (!wlr_scene_output_build_state(scene_output, &state)) {
|
if (!wlr_scene_output_build_state(scene_output, &state)) {
|
||||||
return false;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = wlr_output_commit_state(scene_output->output, &state);
|
ok = wlr_output_commit_state(scene_output->output, &state);
|
||||||
wlr_output_state_finish(&state);
|
if (!ok) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (success) {
|
|
||||||
wlr_damage_ring_rotate(&scene_output->damage_ring);
|
wlr_damage_ring_rotate(&scene_output->damage_ring);
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
out:
|
||||||
|
wlr_output_state_finish(&state);
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
|
||||||
|
Loading…
Reference in New Issue
Block a user