output: trigger frame/present events on all commits on enabled output

Up until now, frame/present events were only triggered when the
user submitted a buffer. Change the wlr_output API so that these
events are triggered when any commit is applied on an enabled
output.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3708
master
Simon Ser 1 year ago committed by Alexander Orzechowski
parent 462f04db9e
commit e5fc8cd4c7

@ -715,12 +715,10 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn,
} }
} }
uint32_t flags = 0;
if (pending.base->committed & WLR_OUTPUT_STATE_BUFFER) { if (pending.base->committed & WLR_OUTPUT_STATE_BUFFER) {
if (!drm_connector_state_update_primary_fb(conn, &pending)) { if (!drm_connector_state_update_primary_fb(conn, &pending)) {
goto out; goto out;
} }
flags |= DRM_MODE_PAGE_FLIP_EVENT;
// wlr_drm_interface.crtc_commit will perform either a non-blocking // wlr_drm_interface.crtc_commit will perform either a non-blocking
// page-flip, either a blocking modeset. When performing a blocking modeset // page-flip, either a blocking modeset. When performing a blocking modeset
@ -732,9 +730,6 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn,
goto out; goto out;
} }
} }
if (pending.modeset && pending.active) {
flags |= DRM_MODE_PAGE_FLIP_EVENT;
}
if (pending.base->committed & WLR_OUTPUT_STATE_LAYERS) { if (pending.base->committed & WLR_OUTPUT_STATE_LAYERS) {
if (!drm_connector_set_pending_layer_fbs(conn, pending.base)) { if (!drm_connector_set_pending_layer_fbs(conn, pending.base)) {
return false; return false;
@ -751,6 +746,8 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn,
} }
} }
uint32_t flags = pending.active ? DRM_MODE_PAGE_FLIP_EVENT : 0;
ok = drm_crtc_commit(conn, &pending, flags, false); ok = drm_crtc_commit(conn, &pending, flags, false);
if (!ok) { if (!ok) {
goto out; goto out;

@ -5,6 +5,7 @@
#include <wlr/types/wlr_output_layer.h> #include <wlr/types/wlr_output_layer.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "backend/headless.h" #include "backend/headless.h"
#include "types/wlr_output.h"
static const uint32_t SUPPORTED_OUTPUT_STATE = static const uint32_t SUPPORTED_OUTPUT_STATE =
WLR_OUTPUT_STATE_BACKEND_OPTIONAL | WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
@ -65,7 +66,7 @@ static bool output_commit(struct wlr_output *wlr_output,
output_update_refresh(output, state->custom_mode.refresh); output_update_refresh(output, state->custom_mode.refresh);
} }
if (state->committed & WLR_OUTPUT_STATE_BUFFER) { if (output_pending_enabled(wlr_output, state)) {
struct wlr_output_event_present present_event = { struct wlr_output_event_present present_event = {
.commit_seq = wlr_output->commit_seq + 1, .commit_seq = wlr_output->commit_seq + 1,
.presented = true, .presented = true,

@ -19,6 +19,7 @@
#include "backend/wayland.h" #include "backend/wayland.h"
#include "render/pixel_format.h" #include "render/pixel_format.h"
#include "render/wlr_renderer.h" #include "render/wlr_renderer.h"
#include "types/wlr_output.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h" #include "linux-dmabuf-unstable-v1-client-protocol.h"
#include "presentation-time-client-protocol.h" #include "presentation-time-client-protocol.h"
@ -555,7 +556,7 @@ static bool output_commit(struct wlr_output *wlr_output,
return false; return false;
} }
if (state->committed & (WLR_OUTPUT_STATE_BUFFER | WLR_OUTPUT_STATE_LAYERS)) { if (output_pending_enabled(wlr_output, state)) {
if (output->frame_callback != NULL) { if (output->frame_callback != NULL) {
wl_callback_destroy(output->frame_callback); wl_callback_destroy(output->frame_callback);
} }

@ -22,6 +22,7 @@
#include "backend/x11.h" #include "backend/x11.h"
#include "util/time.h" #include "util/time.h"
#include "types/wlr_output.h"
static const uint32_t SUPPORTED_OUTPUT_STATE = static const uint32_t SUPPORTED_OUTPUT_STATE =
WLR_OUTPUT_STATE_BACKEND_OPTIONAL | WLR_OUTPUT_STATE_BACKEND_OPTIONAL |
@ -375,6 +376,10 @@ static bool output_commit(struct wlr_output *wlr_output,
if (!output_commit_buffer(output, state)) { if (!output_commit_buffer(output, state)) {
return false; return false;
} }
} else if (output_pending_enabled(wlr_output, state)) {
uint32_t serial = output->wlr_output.commit_seq;
uint64_t target_msc = output->last_msc ? output->last_msc + 1 : 0;
xcb_present_notify_msc(x11->xcb, output->win, serial, target_msc, 0, 0);
} }
xcb_flush(x11->xcb); xcb_flush(x11->xcb);

@ -6,6 +6,8 @@
void output_pending_resolution(struct wlr_output *output, void output_pending_resolution(struct wlr_output *output,
const struct wlr_output_state *state, int *width, int *height); const struct wlr_output_state *state, int *width, int *height);
bool output_pending_enabled(struct wlr_output *output,
const struct wlr_output_state *state);
bool output_pick_format(struct wlr_output *output, bool output_pick_format(struct wlr_output *output,
const struct wlr_drm_format_set *display_formats, const struct wlr_drm_format_set *display_formats,

@ -170,7 +170,8 @@ struct wlr_output {
struct wl_signal precommit; // struct wlr_output_event_precommit struct wl_signal precommit; // struct wlr_output_event_precommit
// Emitted right after commit // Emitted right after commit
struct wl_signal commit; // struct wlr_output_event_commit struct wl_signal commit; // struct wlr_output_event_commit
// Emitted right after the buffer has been presented to the user // Emitted right after a commit has been presented to the user for
// enabled outputs
struct wl_signal present; // struct wlr_output_event_present struct wl_signal present; // struct wlr_output_event_present
// Emitted after a client bound the wl_output global // Emitted after a client bound the wl_output global
struct wl_signal bind; // struct wlr_output_event_bind struct wl_signal bind; // struct wlr_output_event_bind

@ -319,7 +319,7 @@ static void output_apply_state(struct wlr_output *output,
output->cursor_swapchain = NULL; output->cursor_swapchain = NULL;
} }
if (state->committed & WLR_OUTPUT_STATE_BUFFER) { if (output_pending_enabled(output, state)) {
output->frame_pending = true; output->frame_pending = true;
output->needs_frame = false; output->needs_frame = false;
} }
@ -592,6 +592,14 @@ void output_pending_resolution(struct wlr_output *output,
} }
} }
bool output_pending_enabled(struct wlr_output *output,
const struct wlr_output_state *state) {
if (state->committed & WLR_OUTPUT_STATE_ENABLED) {
return state->enabled;
}
return output->enabled;
}
/** /**
* Compare a struct wlr_output_state with the current state of a struct * Compare a struct wlr_output_state with the current state of a struct
* wlr_output. * wlr_output.

Loading…
Cancel
Save