Commit graph

101 commits

Author SHA1 Message Date
Rose Hudson
9e8947e4d5 add render timer API
Based on five calls:
wlr_render_timer_create - creates a timer which can be reused across
  frames on the same renderer
wlr_renderer_begin_buffer_pass - now takes a timer so that backends can
  record when the rendering starts and finishes
wlr_render_timer_get_time - should be called as late as possible so that
  queries can make their way back from the GPU
wlr_render_timer_destroy - self-explanatory

The timer is exposed as an opaque `struct wlr_render_timer` so that
backends can store whatever they want in there.
2023-06-05 19:50:07 +00:00
Simon Ser
52b93f7eb4 output/cursor: fix scale and transform
Many issues here:

- wlr_output_cursor_set_buffer() takes a buffer already scaled for
  the output, not a buffer with scale=1.
- wlr_output_cursor.{width,height,hotspot_x,hotspot_y} are in output
  buffer coordinates.
- render_cursor_buffer() had hardcoded no-ops for scale and
  transform, instead of using the cursor surface's.

Fixes: b64e7e88bf ("output: add output_cursor_set_texture()")
2023-06-02 22:33:40 +00:00
Simon Ser
5bcd537ff4 output/cursor: use new rendering API 2023-05-30 16:18:19 +00:00
Simon Ser
93a6acae9f output: add wlr_output_begin_render_pass() 2023-05-30 16:18:19 +00:00
Simon Ser
2c6aeed7d6 output: use pending render format if any
If a modeset contains a render format change, use that instead of
the current one stored in wlr_output.render_format.

This fixes render_bit_depth configuration not being applied without
a second modeset in Sway.
2023-05-26 16:50:58 +00:00
Alexander Orzechowski
c4bed48fcc output_pick_format: Fail if no format could be chosen 2023-05-18 07:05:30 +00:00
Alexander Orzechowski
90d08f8f1c wlr_drm_format: Rework wlr_drm_format_intersect
Now it takes a reference to a destination format
2023-05-11 18:24:43 +02:00
Alexander Orzechowski
340700cb70 wlr_drm_format: Change wlr_drm_format_dup to copy 2023-05-11 18:24:43 +02:00
Alexander Orzechowski
e427e019c4 wlr_drm_format: Don't take double pointer in wlr_drm_format_add 2023-05-11 03:51:01 -04:00
Alexander Orzechowski
b45396c790 wlr_drm_format: Introduce drm_format_finish 2023-05-11 03:51:01 -04:00
Simon Ser
d933f5204b output: drop wlr_output_cursor_set_surface 2023-05-06 13:59:05 -04:00
Simon Ser
b64e7e88bf output: add output_cursor_set_texture() 2023-05-06 17:48:56 +00:00
Simon Ser
bf8ae8a036 output/cursor: fix buffer size when nested and scaled
The Wayland, X11 and headless backends don't really care about the
cursor size. We were picking a size identical to the texture size
in that case. This is incorrect for LoDPI cursor textures on HiDPI
outputs: in that case, we need to scale up the cursor texture.

Fixes the cursor being chopped off under the Wayland backend with
scale > 1.
2023-05-03 11:32:51 +02:00
Simon Ser
587852056c output: add wlr_output_add_software_cursors_to_render_pass()
Same as wlr_output_render_software_cursors(), but takes a
struct wlr_render_pass.
2023-04-25 17:26:34 +02:00
Simon Ser
44069dfd5e output-layer: add cropping support
Add a src_box state field. Use the SRC_* KMS props in the DRM
backend, reject the layers in the Wayland backend (for now, we can
support it later via viewporter).
2023-04-20 10:39:46 +02:00
Alexander Orzechowski
b1e38fc7ea output: Drop output_is_direct_scanout 2023-04-06 22:39:08 +02:00
Simon Ser
7abda952d0 output: drop direct scan-out check in output_basic_test()
wlr_output is not well-suited to checking whether direct scan-out
is happening or not. Compositors may want to use their own external
swapchains, for instance.

Additionally, ab7eabac84 ("output: leverage
wlr_output_configure_primary_swapchain()") makes it so
output_basic_test() is called before the output swapchain is
initialized, resulting in false positives.

References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3620
2023-04-06 21:46:45 +02:00
Simon Ser
079ff9e6fb output: add wlr_output_is_direct_scanout_allowed()
This lets compositors check whether direct scan-out is possible.
Compositors will soon be responsible for manually calling this
function.
2023-04-06 21:42:08 +02:00
Simon Ser
835208db98 output-layer: add support for scaling buffers
This allows callers to set a destination size different from the
buffer size to scale them.

The DRM backend supports this. The Wayland backend doesn't yet
(we'd need to wire up viewporter).
2023-04-04 19:39:38 +02:00
Simon Ser
e00c4cd7dc output-layer: cache current state
The will be used by the Wayland backend to figure out whether
updating sub-surface position is necessary.
2023-03-28 22:58:29 +00:00
Simon Ser
1b6fac4aa6 output-layer: require all layers in wlr_output_state.layers
- Simplifies the backends
- Avoids having two ways to do the same thing: previously one could
  disable a layer by either omitting it from wlr_output_state.layers,
  or by passing a NULL buffer
- We can change our mind in the future: we can allow users to omit
  some layers and define a meaning without breaking the API.

References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4017#note_1783997
2023-03-10 11:16:01 +00:00
Simon Ser
5079000e49 output: allow modeset with buffer while frame is pending
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3600
2023-02-26 18:42:31 +01:00
Simon Ser
ab7eabac84 output: leverage wlr_output_configure_primary_swapchain()
Replace our current logic to setup the primary swapchain with
wlr_output_configure_primary_swapchain().

- Removes some code, reducing duplication
- Stop overwriting wlr_output.swapchain with a yet-to-be-tested
  swapchain: remove the error_destroy_swapchain label.
2023-02-24 18:22:20 +00:00
Simon Ser
fef8ab22e3 output: introduce wlr_output_configure_primary_swapchain()
The goal is to simplify wlr_output by moving all of its rendering
API into separate helpers. Here is a first step to sunset
wlr_output_attach_render(). Instead, compositors call
wlr_output_configure_primary_swapchain(), wlr_swapchain_acquire(),
wlr_renderer_begin_with_buffer() and wlr_output_attach_buffer().

Note that compositors can supply a base struct wlr_output_state.
This is useful to allocate a buffer suitable for submission with
a modeset, for instance.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3079
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3197
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3984
2023-02-24 18:22:20 +00:00
Simon Ser
b33ab26fe7 render/swapchain: make public
We've had this struct for a while. It'd be useful for compositors
if they want to manage the swap chains themselves instead of being
forced to use wlr_output's. Some compositors might also want to use
a swapchain without an output.
2023-02-21 17:14:31 +01:00
Simon Ser
7215bd1e0f output: expose wlr_output_state_set_buffer() 2023-02-21 09:43:43 +00:00
Simon Ser
4629d0ef40 output: expose wlr_output_state_finish()
Same as the original function, but check for the bitfield before
calling pixman_region32_fini(), because that function expects an
initialized region.
2023-02-21 09:43:43 +00:00
Simon Ser
3e0ce761ad output: add wlr_output_set_layers() 2023-02-20 18:38:09 +01:00
Simon Ser
2f29b0c438 Add wlr_output_layer
This is based on previous work [1] [2].

This new API allows compositors to display buffers without needing to
perform rendering operations. This API can be implemented on Wayland
using subsurfaces and on DRM using KMS planes.

Compared to [1], this approach leverages wlr_addon_set to let backends
attach their own private state to layers, removes the pending
state (necessary for interop with wlr_output_commit_state()) and
enum wlr_output_layer_state_field.

[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/1985
[2]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3447
2023-02-20 18:38:09 +01:00
Simon Ser
92eedb84c1 output: don't attach buffer on first commit if disabled
In output_ensure_buffer() we create a swapchain and attach an empty
buffer to the output if necessary. We do that during the first commit.
This is fine when the first commit enables the output, however this breaks
when the first commit disables the output. A commit which disables an
output and has a buffer attached is invalid (see output_basic_test()), and
makes the DRM backend crash:

    00:00:00.780 [wlr] [backend/drm/drm.c:622] connector eDP-1: Turning off
    ../subprojects/wlroots/backend/drm/drm.c:652:44: runtime error: member access within null pointer of type 'struct wlr_drm_crtc'
    AddressSanitizer:DEADLYSIGNAL
    =================================================================
    ==2524==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f22e894afc1 bp 0x7ffe1d57c550 sp 0x7ffe1d57c420 T0)
    ==2524==The signal is caused by a READ memory access.
    ==2524==Hint: address points to the zero page.
        #0 0x7f22e894afc1 in drm_connector_commit_state ../subprojects/wlroots/backend/drm/drm.c:652
        #1 0x7f22e894b1f5 in drm_connector_commit ../subprojects/wlroots/backend/drm/drm.c:674
        #2 0x7f22e89e8da9 in wlr_output_commit_state ../subprojects/wlroots/types/output/output.c:756
        #3 0x555ab325624d in apply_output_config ../sway/config/output.c:517
        #4 0x555ab31a1aa1 in handle_new_output ../sway/desktop/output.c:974
        #5 0x7f22e9272f6d in wl_signal_emit_mutable (/usr/lib/libwayland-server.so.0+0x9f6d)
        #6 0x7f22e899b012 in new_output_reemit ../subprojects/wlroots/backend/multi/backend.c:161
        #7 0x7f22e9272f6d in wl_signal_emit_mutable (/usr/lib/libwayland-server.so.0+0x9f6d)
        #8 0x7f22e895a153 in scan_drm_connectors ../subprojects/wlroots/backend/drm/drm.c:1488
        #9 0x7f22e893c2e4 in backend_start ../subprojects/wlroots/backend/drm/backend.c:24
        #10 0x7f22e892ed00 in wlr_backend_start ../subprojects/wlroots/backend/backend.c:56
        #11 0x7f22e8999b83 in multi_backend_start ../subprojects/wlroots/backend/multi/backend.c:31
        #12 0x7f22e892ed00 in wlr_backend_start ../subprojects/wlroots/backend/backend.c:56
        #13 0x555ab317d5cc in server_start ../sway/server.c:316
        #14 0x555ab317748d in main ../sway/main.c:400
        #15 0x7f22e783c28f  (/usr/lib/libc.so.6+0x2328f)
        #16 0x7f22e783c349 in __libc_start_main (/usr/lib/libc.so.6+0x23349)
        #17 0x555ab3134c84 in _start (/home/simon/src/sway/build/sway/sway+0x377c84)

Fixes: 3be6658ee7 ("output: allocate swapchain on first commit")
Closes: https://github.com/swaywm/sway/issues/7373
2023-02-02 16:48:35 +00:00
bi4k8
790fb93794 cursor: compare to scaled coords 2022-12-20 20:01:56 +00:00
Simon Ser
c8eb24d30e output: drop enable/mode events
The backend no longer changes the output state behind the
compositor's back. Instead, compositors can listen to the "commit"
event and check for WLR_OUTPUT_STATE_ENABLED/WLR_OUTPUT_STATE_MODE.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/2300
2022-12-01 20:05:04 +00:00
Alexander Orzechowski
fe891ebd4e output_init_render: Allow re-initialization
This lets the compositor call this function after the fact to replace
the renderer/allocator after a renderer context lost.
2022-12-01 10:01:35 +00:00
Simon Ser
6c3d6be74b output: drop wlr_output_damage_whole()
This function is not used anymore. Backends have no good reason to
damage outputs.
2022-11-17 09:17:32 +00:00
Simon Ser
ef5e2cc5e3 output: call wlr_output_update_enabled() after commit
Backends no longer need to manually call wlr_output_update_enabled()
in their commit hook: wlr_output will take care of that.
2022-11-17 09:12:25 +00:00
Alexander Orzechowski
265439600e output: Initialize request_state 2022-11-15 12:00:47 -05:00
Simon Ser
45159f8708 output: check wlr_renderer_begin return value 2022-11-15 15:50:19 +00:00
Simon Ser
ff55663906 output: introduce request_state event
This allows backends to request the compositor to change the state
of an output.

References: https://github.com/swaywm/wlroots/issues/2300#issuecomment-761819673
2022-11-15 15:39:55 +00:00
Simon Ser
fe4225d5de output: constify damage APIs 2022-11-11 23:11:17 +00:00
Simon Ser
f0ee563416 output: try to use fixed mode in wlr_output_set_custom_mode()
If a fixed mode matching the user requirements is available, use
that. This avoids generating the mode with GTF or CVT in the DRM
backend, and instead uses mode timings advertised by the output.

References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3514
2022-10-20 09:49:16 +02:00
Simon Ser
650f955507 output: fix crash in output_test_with_back_buffer()
The output->impl->test check has been removed, but
output_test_with_back_buffer() hasn't been updated accordingly.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3506
Fixes: 3be6658ee7 ("output: allocate swapchain on first commit")
2022-10-10 12:08:06 +02:00
Simon Ser
3be6658ee7 output: allocate swapchain on first commit
On first commit, require a new buffer if the compositor called a
mode-setting function, even if the mode won't change. This makes it
so the swapchain is created now.

Stop trying to check whether the backend supports buffer-less modesets
because that makes everything more complicated. For instance, the
DRM backend doesn't need a new buffer if the previous DRM master left
the output enabled.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3499
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3502
2022-10-07 19:21:20 +00:00
Simon Ser
e92b272616 output/render: make output_ensure_buffer() no-op when missing renderer
Some compositors want to have full control over the buffers attached
to the output, and don't want to use the internal swapchain. Such
compositors include KWinFT (allocates its buffers on its own) and
gamescope (uses a headless output without any buffers).

Let's just make output_ensure_buffer() a no-op in that case.
2022-10-07 19:21:20 +00:00
Simon Ser
7d8284ec10 output/render: early return in output_ensure_buffer()
Slightly simplify the logic here.
2022-10-07 19:21:20 +00:00
Kirill Primak
ff9c52801f output: add a swapchain NULL check in wlr_output_commit_state()
Fixes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3504
2022-10-07 15:12:53 +00:00
Simon Ser
e40d492b78 output: fix typo in error message 2022-10-01 16:52:31 +02:00
Simon Ser
a0345f2854 output: add wlr_output_state.allow_artifacts
When starting up, the compositor might call wlr_output_set_mode()
with a mode which is already the current one. wlroots will detect
this and make the wlr_output_set_mode() call a no-op. During the
next wlr_output_commit() call, wlroots will perform an atomic
commit without the ALLOW_MODESET flag.

This is an issue, because some drivers need ALLOW_MODESET even if
the mode is the same. For instance, if the FB stride or modifier
changed, some drivers require a modeset.

Add a new flag "allow_artifacts" which is set when the compositor
calls mode-setting functions. Use this flag to figure out whether
we want to perform atomic commits with ALLOW_MODESET.

(The name "allow_artifacts" is picked because ALLOW_MODESET is a
misnomer, see [1].)

[1]: https://patchwork.freedesktop.org/patch/505107/

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3499
2022-09-30 10:58:17 +00:00
Simon Ser
8e8b9a7217 output: fix back buffer checks
The back buffer is no longer set at commit time since 0556aa0c59
("output: rejigger attach/clear for back buffer").

Instead, check whether the buffer belongs to the output swapchain.
This is more robust.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3496
2022-09-21 16:18:16 +02:00
Simon Ser
0556aa0c59 output: rejigger attach/clear for back buffer
In wlr_output_attach_render(), stop setting
wlr_output.pending.buffer. This removes one footgun: using the
wlr_buffer at that stage is invalid, because rendering operations
haven't been flushed to the GPU yet. We need to wait until
output_clear_back_buffer() for the wlr_buffer to be used safely.

Instead, set wlr_output.pending.buffer in wlr_output_test() and
wlr_output_commit().

Additionally, move the output_clear_back_buffer() from
wlr_output_commit_state() to wlr_output_commit(). This reduces the
number of calls in the failure path.
2022-09-19 10:46:26 +00:00
Simon Ser
0213da60bb output: drop back_buffer variable in wlr_output_commit_state()
We can just use pending.buffer instead. It's completely fine to
call wlr_swapchain_set_buffer_submitted() with a buffer which
doesn't come from the swapchain, in which case it's a no-op.
2022-09-19 10:46:26 +00:00