Commit Graph

325 Commits

Author SHA1 Message Date
Simon Ser 2a6dc0059f output: detach buffer from renderer before commit
Right now we rely entirely on implicit sync for synchronizing
access to GPU buffers. Implicit sync works by setting
synchronization points on the buffer in writers, and letting
readers wait on these sync points before accessing the buffer.

With OpenGL, sync points are created using functions such as
eglSwapBuffers or glFlush. If none of these special functions
are called, no sync point will be created and readers will
potentially access a buffer that hasn't finished rendering yet.

In the context of wlroots, OpenGL is the writer and the backend
(KMS or parent Wayland/X11 session) is the reader. After we're
done rendering a frame, and before passing that frame to the
backend, we need to call glFlush.

glFlush is called when the buffer is detached from the renderer.
This is a task done by output_clear_back_buffer. So let's call
this function before invoking the impl->commit hook, instead of
calling it after.

All of this is maybe a little tricky to get right with the
current renderer_bind_buffer API. The new
wlr_renderer_begin_with_buffer API is much better, because glFlush
is called on wlr_renderer_end, so it's more intuitive.

Closes: https://github.com/swaywm/wlroots/issues/3020
(cherry picked from commit c2bd63c186)
2021-07-07 19:24:47 +02:00
Simon Ser 6259fd23fb output: reset back buffer on failed commit
On commit failure, we need to unbind the back buffer from the
renderer.

This fixes assertions triggered on commits following a failed commit
where the compositor called wlr_output_attach_render.
2021-06-13 13:17:30 +02:00
Simon Ser b2f6db3533 render: drop wlr_ prefix from wlr_renderer_bind_buffer
Make it clear this function is a private wlroots API and will stay
that way.
2021-06-09 10:26:09 +02:00
Simon Ser fbadadf36f output: use wlr_renderer_begin_with_buffer for cursor 2021-06-09 10:26:09 +02:00
Simon Ser 1a06ea7750 output: make attach_render and rollback_render optional
If these aren't provided by the backend, allocate a swapchain for the
output.
2021-06-07 15:42:38 +02:00
Simon Ser 233a2617cf output: split output_pick_cursor_format
Introduce output_pick_format that can be re-used for the primary
buffer too.
2021-06-07 15:42:38 +02:00
Simon Ser 2b0a1aeed5 output: take a wlr_buffer in set_cursor
Instead of passing a wlr_texture to the backend, directly pass a
wlr_buffer. Use get_cursor_size and get_cursor_formats to create
a wlr_buffer that can be used as a cursor.

We don't want to pass a wlr_texture because we want to remove as
many rendering bits from the backend as possible.
2021-06-02 11:08:52 +02:00
Simon Ser 6622cd3277 output: correctly handle outputs without a test() impl
This fixes a crash when calling wlr_output_test() on a headless
output.

Closes: https://github.com/swaywm/sway/issues/6213
2021-04-21 08:52:50 +02:00
Simon Ser 44fa2c4b49 output: fix transform matrix for 90/270 rotations
We need to adjust the second translation depending on the transform
we applied.

Fixes: 9601a2abf0 ("output: improve transform matrix calculation"
Closes: https://github.com/swaywm/wlroots/issues/2774
2021-03-11 22:52:38 +01:00
Simon Zeni 9601a2abf0 output: improve transform matrix calculation
Compute only the transform matrix in the output. The projection matrix
will be calculated inside the gles2 renderer when we start rendering.

The goal is to help the pixman rendering process.
2021-03-10 15:33:36 +01:00
Simon Ser 675bc39658 Fix wl_shm_format passed to wlr_texture_from_pixels
Fixes: 27fba3df43 ("render: use DRM formats in wlr_texture_from_pixels")
2021-02-23 17:36:32 +01:00
Simon Ser 00bf6674b3 output: use DRM format in wlr_output_preferred_read_format 2021-02-23 16:09:26 +01:00
Simon Ser b3e76d6678 output: send commit event after pending state is cleared
References: https://github.com/swaywm/wlroots/issues/2098
2021-01-16 09:06:27 +01:00
Simon Ser cc56b4f073 output: remove scale/transform events
Instead, the commit event should be used.
2021-01-15 10:18:56 +01:00
Simon Ser 768131e488 output: stop assuming a frame is pending in init
- The DRM backend initially doesn't have a frame scheduled initially.
  However the compositor is expected to set a mode to start the
  rendering loop (frame_pending is set to true in drm_crtc_pageflip).
- The headless and X11 backends have a timer to schedule frames, so they
  ignore this hint completely.
- The Wayland backend renders a fake frame to start the rendering loop.
  It's the only case where a frame is pending on init, move the
  assumption there.
2020-12-13 12:16:28 +01:00
Simon Ser e9c1f0f7d3
output: improve basic test logging 2020-12-09 22:20:24 +01:00
Kenny Levinsen ebecc5404b surface: Make send_enter store entered outputs
wlr_surface_send_enter now stores outputs that have been entered.
Combined with a new 'bind' event on wlr_output, this allows us to delay
enter events as necessary until the respective wl_output global has been
bound.

Closes: https://github.com/swaywm/wlroots/issues/2466
2020-11-23 10:58:50 +01:00
Simon Ser 8c8164c4a6 output: add when field to wlr_output_event_commit
Similar to the one already present in wlr_output_event_precommit.
2020-11-05 09:43:42 +01:00
Simon Ser c674241ec0 output: introduce wlr_output_event_commit
This event contains a `committed` bitfield, which allows callers to know
which output fields changed during the commit.

This allows users to setup a single atomic commit listener, instead of
setting up one listener for each event (mode, scale, transform, and so
on).

References: https://github.com/swaywm/wlroots/issues/2098
2020-08-27 13:54:19 -06:00
Ilia Bozhinov 0032954c75 make sure to fail setting gamma on disabled outputs 2020-08-03 12:05:35 +02:00
Simon Ser 155d57b01d output: fix dangling renderer context after wlr_output_preferred_read_format
attach_render was called without un-setting the current rendering
context afterwards.

Closes: https://github.com/swaywm/wlroots/issues/2164
2020-06-19 11:50:42 -06:00
Simon Ser 3c5dbfd97c output: make rollback_render mandatory
If the output backend provides attach_render, assert it also provides a
way to revert it via rollback_render.
2020-06-19 11:50:42 -06:00
Simon Ser bf93d2e67c output: rename impl->rollback to rollback_render
The output backend API is now mostly state-less thanks to the atomic
hooks (commit and test). There is one exception though: attach_render.
This function makes the rendering context current. However sometimes the
compositor might decide not to render after attach_render (e.g. when
there's nothing new to render to the back buffer). Thus
wlr_output_rollback has been introduced to revert the pending state.

Because the output backend API is mostly state-less, the only thing
wlr_output_impl.rollback needs to do is revert the current rendering
context. Rename the function to rollback_render to make this clear. Add
a check in the common wlr_output code to only call rollback_render when
attach_buffer has been previously called.

On the long term, we'll be able to remove attach_render and
rollback_render together.
2020-06-19 11:50:42 -06:00
Simon Ser 347bdb6d9a output: make wlr_output_set_gamma atomic
wlr_output_set_gamma is now double-buffered and applies the gamma LUT on
the next output commit.
2020-05-14 20:09:28 +02:00
Simon Ser 0281b58d2f output: fix maybe-uninitialized warning
GCC is complaining about a maybe-uninitialized variable when doing a
release build. Even if that can't actually happen because all enum
values are handled, add an abort call to silence the warning.
2020-04-10 17:05:00 +02:00
Simon Ser 50ade3671f output: check for buffer size compatibility in common code
Instead of checking for buffer size compatibility in each backend,
centralize the check in wlr_output itself.
2020-04-10 15:52:20 +02:00
Simon Ser 5f092c55d1 output: fix blurred hw cursors with fractional scaling
The scaling factor was being implicitly cast to an int.

Closes: https://github.com/swaywm/sway/issues/4927
2020-04-10 15:10:12 +02:00
Simon Ser 507d9bc19e Add wlr_output_impl.rollback
Most of the pending output state is not forwarded to the backend prior
to an output commit. For instance, wlr_output_set_mode just stashes the
mode without calling any wlr_output_impl function.
wlr_output_impl.commit is responsible for applying the pending mode.

However, there are exceptions to this rule. The first one is
wlr_output_attach_render. It won't go away before renderer v6 is
complete, because it needs to set the current EGL surface.

The second one is wlr_output_attach_buffer.
wlr_output_impl.attach_buffer is removed in [1].

When wlr_output_rollback is called, all pending state is supposed to be
cleared. This works for all the state except the two exceptions
mentionned above. To fix this, introduce wlr_output_impl.rollback.

Right now, the backend resets the current EGL surface. This prevents GL
commands from affecting the output after wlr_output_rollback.

This patch is required for FBO-based outputs to work properly. The
compositor might be using FBOs for its own purposes [2], having leftover
FBO state can have bad consequences.

[1]: https://github.com/swaywm/wlroots/pull/2097
[2]: https://github.com/swaywm/wlroots/pull/2063#issuecomment-597614312
2020-04-08 17:33:00 +02:00
Simon Ser 6977f3a843 output: check buffer in wlr_output_test
Check that buffer can be scanned out in wlr_output_test instead of
wlr_output_attach_buffer. This allows the backend to have access to the
whole pending state when performing the check.

This brings the wlr_output API more in line with the KMS API.

This removes the need for wlr_output_attach_buffer to return a value,
and for wlr_output_impl.attach_buffer.
2020-04-08 16:31:21 +02:00
Simon Ser e041158988 output: introduce wlr_output_test 2020-04-08 16:31:21 +02:00
Simon Ser 6595db6409 buffer: add a release event
Consumers call wlr_buffer_lock. Once all consumers are done with the
buffer, only the producer should have a reference to the buffer. In this
case, we can release the buffer (and let the producer re-use it).
2020-04-02 15:03:43 +02:00
Simon Ser e0bbafc253 output: replace wlr_output.damage with a damage event
This patch disambiguates the needs_frame event by uncoupling it from
damage. A new separate damage event is emitted when the backend damages
the output (this happens e.g. VT is changed or software cursors are
used). The event specifies the damaged region.

The wlr_output.damage field is removed. wlr_output is no longer
responsible for tracking its own damage, this is wlr_output_damage's
job.

This is a breaking change, but wlr_output_damage users shouldn't need an
update.

Bugs fixed:

- Screen flashes on VT switch
- Cursor damage issues on the X11 and headless backends

Closes: https://github.com/swaywm/sway/issues/5086
2020-03-12 22:47:59 +01:00
Simon Ser 07737e85cc output: add comment about needs_frame in wlr_output_schedule_frame
Add a comment to not forget why this call is necessary.

References: https://github.com/swaywm/wlroots/pull/2053
2020-03-12 15:01:09 +01:00
Simon Ser 7bce056f1d output: don't send a needs_frame event if already sent 2020-03-06 21:35:00 +01:00
Simon Ser a4c7c6db09 output: make wlr_output_schedule_frame set output->needs_frame
This way, wlr_output_schedule_frame will always be followed by a
wlr_output_commit. This forces the compositor to render an extra
frame before stopping the rendering loop.

To test, run wleird's frame-callback [1], make sure it's the only
visible client on the output and check the interval between frame
events is the output's refresh period instead of zero.

[1]: https://github.com/emersion/wleird/blob/master/frame-callback.c

Closes: https://github.com/swaywm/wlroots/issues/2051
2020-03-06 21:35:00 +01:00
Simon Ser 7017fa95b8 output: add adaptive_sync_enabled property 2020-03-06 21:32:58 +01:00
Simon Ser 348f52b5fc output: remove wlr_output_impl.schedule_frame
This function allowed backends to provide a custom function for frame
scheduling. Before resuming the rendering loop, the DRM and Wayland
backends would wait for vsync.

There isn't a clear benefit of doing this. The only upside is that we
get more stable timings: the delay between two repaints doesn't change too
much and is close to a mutliple of the refresh rate.

However this introduces latency, especially when a client misses a
frame. For instance a fullscreen game missing vblank will need to wait
more than a whole frame before being able to display new content. This
worst case scenario happens as follows:

- Client is still rendering its frame and cannot submit it in time
- Deadline is reached
- Compositor decides to stop the rendering loop since nothing changed on
  screen
- Client finally manages to render its frame, submits it
- Compositor calls wlr_output_schedule_frame
- DRM backend waits for next vblank
- The wlr_output frame event is fired, compositor draws new content on screen
- On the second next vblank, the new content reaches the screen

With this patch, the wlr_output frame event is fired immediately when
the client submits its late frame.

This change also makes it easier to support variable refresh rate, since
VRR is all about being able to present too-late frames earlier.

References: https://github.com/swaywm/wlroots/issues/1925
2020-03-04 03:22:19 +01:00
Manuel Stoeckl 2fddec56e8 output: fix output transform compositions
This change ensures that wlr_output_transform_compose correctly composes
transforms when the first transform includes a rotation and the second
transform includes a flip.
2020-02-17 21:43:05 +01:00
Simon Ser e63b70263a output: don't destroy global immediately
Closes: https://github.com/swaywm/sway/issues/3625
2020-02-17 20:52:37 +01:00
Simon Ser ff29843d87 output: only advertise current mode
- Regular clients shouldn't care about modes
- Modes exposed are missing metadata such as aspect-ratio, interleaved, etc
- Modes exposed cannot be pruned [1]
- wlr-output-management provides a better API for privileged clients

[1]: https://gitlab.freedesktop.org/wayland/wayland/issues/92

Closes: https://github.com/swaywm/wlroots/issues/1099
2019-12-30 14:25:33 -07:00
Simon Ser 8fc16890c7 output: refuse to commit a buffer or modeset a disabled output
References: https://github.com/swaywm/wlroots/issues/1780#issuecomment-518938390
2019-12-30 11:21:11 -07:00
Simon Ser b5597f5b44 output: clear pending bit if pending == current
In case the pending value is the same as the current value, clear the
bit from pending.committed.
2019-12-30 11:21:11 -07:00
Simon Ser 5d1ba0f446 output: re-introduce atomic mode, enabled, scale and transform
This reverts commit 01f903874b and re-applies
commit ee5f98ad49.

Updates: https://github.com/swaywm/wlroots/issues/1640 (Atomic output updates issue)
See also: https://github.com/swaywm/wlroots/pull/1762 (Atomic output updates original PR)
See also: https://github.com/swaywm/wlroots/issues/1780 (Issue caused by atomic output updates)
See also: https://github.com/swaywm/sway/issues/4419 (Issue caused by atomic output updates)
See also: https://github.com/swaywm/wlroots/pull/1781 (Revert PR)
2019-12-30 11:21:11 -07:00
Simon Ser 4da4a15d6b output: add description
wlr_output.description is a string containing a human-readable string
identifying the output. Compositors can customise it via
wlr_output_set_description, for instance to make the name more
user-friendly.

References: https://github.com/swaywm/wlroots/issues/1623
2019-12-29 12:35:22 -05:00
Simon Ser 98cd11c019 output: fix wlr_output_preferred_mode fallback
`mode` points to an invalid pointer (head of the list) when the loop
stops.

Closes: https://github.com/swaywm/sway/issues/4717
2019-12-16 01:24:28 +00:00
Manuel Stoeckl 8a5e4768e1 output: fix cursor wl_surface.{enter,leave} tracking
This change ensures that wl_surface.leave is sent when a surface
associated with the cursor is disassociated (when the cursor is
reset).
2019-12-09 15:58:18 +01:00
Simon Ser dc6ef658b6 Revert "output: add block_idle_frame"
This reverts commit cbb2781fed.

In [1], we found issues with block_idle_frame and replaced it with
frame_pending. block_idle_frame is now unused.

[1]: https://github.com/swaywm/sway/pull/4772
2019-12-01 10:25:34 -05:00
Simon Ser 3084cee7bc output: fix off-by-one wlr_output_event_present.commit_seq
Backends not supporting presentation feedback call
wlr_output_send_present with a NULL event in their commit handler. Since
the commit hasn't been applied yet, commit_seq still has its old value.
We need to increment it.

An alternative would be to move commit_seq in wlr_output_state. This
would allow to have a pending and a current commit_seq.
wlr_output_send_present could take the pending commit_seq when called
with a NULL event.
2019-11-21 11:03:43 -05:00
Simon Ser 2d9661f189 output: set wlr_output.commit_seq before firing the commit event
This allows listeners to read the commit sequence number.
2019-11-21 11:03:43 -05:00
Simon Ser 6c649bab53 output: add wlr_output_event_present.commit_seq
This is set to the value of wlr_output.commit_seq when the frame has
been submitted. This allows tracking presentation with more then 1 full
frame of latency.

References: https://github.com/swaywm/wlroots/issues/1917
2019-11-17 00:12:59 +01:00