When a wlr_gamma_control client calls set_gamma, we allocate a LUT based
on the value returned from wlr_output_get_gamma_size at the time of the
call.
If the output is off and has no CRTC, such as if gamma changes in the
background while a display is disabled for idle reasons,
wlr_output_get_gamma_size returns 0. This leads to a zero-sized table,
which the drm backend interprets as a request to reset gamma tables to
their default.
Store the gamma size when the gamma control was created. Even if the
size changes, this is the size the client was sent and uses to create
the LUTs it sends.
Per comments in util/box.h, the width and height of a wlr_box are
exclusive; that is, for a 100x100 box at (0,0), the point (99,99) is
inside it while the point (100,100) is outside it.
Thus mathematically, there exists no single closest point to the
bottom-right corner of the box while remaining inside it. You can
construct an infinite series approaching the limit, such as {(99,99),
(99.9,99.9), (99.99,99.99)...}, but since the intervals are half-open,
there is no "last" point.
wlr_box_closest_point() must therefore define an arbitrary "closest"
point. For points below and to the right of the box, the current
implementation returns (box.x + width - 1, box.y + height - 1). Let's
continue to do this.
However, the current implementation is non-linear: with the example
100x100 box, it will return an input point of (99.9,99.9) unchanged, but
for an input point (100.1,100.1) the returned point will jump back to
(99.0,99.0).
In practice, this non-linearity results in strange behaviors when
driving the mouse cursor to a screen corner. On a 1920x1080 display for
example, driving the cursor quickly to the bottom-left corner results in
a position of exactly (0,1079). Continuing to slowly nudge the cursor
downward results in the position jumping between (0,1079) and other,
fractional coordinates such as (0,1079.88).
The fractional coordinates expose some client/toolkit-side bugs (which,
to be clear, should be fixed on the client side), but IMHO the wlroots
behavior is also inconsistent and wrong -- when I drive the mouse cursor
into the corner of the screen, it should come to a stop at a fixed
position, not jitter around.
The surface argument is only used to obtain a wlr_seat_client and
semantically makes no sense. The wl_touch.cancel event applies to all
touch points and all surfaces of a client.
I decided to make the functions accept a wlr_seat_client rather than a
wl_client as it is directly available in the wlr_touch_point struct and
simplifies the implementation.
Previously, cases when a viewport source box was updated without attaching
a buffer weren't checked for correctness properly because the state's buffer
would be NULL. Use wlr_surface_state_has_buffer() instead.
This is worth doing despite wl_client_get_destroy_listener() incorrectly
accepting a mutable wl_client pointer since this lookup_client()
function will primarily be used with a wl_display_global_filter_func_t
which only provides a const wl_client pointer.
Work around this libwayland API wart in wlroots so compositors don't
have to.
I wish to use a allowlist of globals for my security context
implementation rather than a blocklist, which means I need access to
the wp_single_pixel_buffer_manager_v1 global in order to allowlist it.
I think using a allowlist will make it harder for me to accidentally
expose globals to a security context that were meant to be restricted.
I wish to use a allowlist of globals for my security context
implementation rather than a blocklist, which means I need access to
the ext_idle_notifier_v1 global in order to allowlist it.
I think using a allowlist will make it harder for me to accidentally
expose globals to a security context that were meant to be restricted.
I wish to use a allowlist of globals for my security context
implementation rather than a blocklist, which means I need access to
the wl_shm global in order to allowlist it.
I think using a allowlist will make it harder for me to accidentally
expose globals to a security context that were meant to be restricted.
This new helper assists compositors in allocating buffers for
modesets. It degrades to different allocation parameters as
needed, and should help with screens not turning on when multiple
outputs are connected on some hardware (e.g. Intel).
For simplicity, the old logic to try allocating with explicit
modifiers first and then fallback to implicit modifiers later is
left as-is. We'll probably want to have more complicated logic
instead in the future: try the fallback on one output at a time,
and try dropping modifiers one by one instead of using implicit
modifiers (at the cost of some combinatorial explosion).
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/1873
Co-authored-by: Kenny Levinsen <kl@kl.wtf>
When a compositors submits a wlr_output_state with
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED set and
adaptive_sync_enabled = false on an output which doesn't support
adaptive sync, we'd fail the commit. Fix this.
This bug was previously hidden because wlr_output_commit() drops
no-op changes from wlr_output_state.committed.
After disabling a connector, we need to cleanup the connector to
teardown the surfaces and unlock the FBs.
Move this logic into drm_connector_apply_commit() so that it's
applied when drm_commit() is called from somewhere else than
drm_connector_commit_state().
There is some duplicated logic between these two functions.
The commit codepath was calling the test function before doing the
real commit, so this also saves an unnecessary test-only commit
when performing a real commit.
This centralizes logic common for both the atomic and libliftoff
backends. Additionally, a struct will make it easier to implement
multi-connector commits (since it can be stored in an array).
This allows us to remove the renderer destroy listener. The
listener was buggy: compositors can't destroy surface resources on
their own.
The wlr_compositor will always outlive the wlr_surface, so no need
for a destroy listener.
If we hit this case, we effectively failed to render something, this might
be because a texture failed to upload or the texture is momentarily
unavailable after a GPU reset. If we fail to render, we have to continue
to track damage for the next frame in hopes that the texture becomes
available then.
An alternative approach would be to fail the commit completely if we
find this case, but in the case of gpu resets, clients may not commit
a new buffer for a while, and a frozen display does not help.
This fixes damage tracking issues after a gpu reset.
The spec for GL_EXT_disjoint_timer_query says
> The GetInteger64vEXT command is required only if OpenGL ES 3.0 or later
> is not supported.
Some GLES 3.2 implementations like the proprietary mali driver on the
rk3566 based OrangePi advertise GL_EXT_disjoint_timer_query but lack
glGetInteger64vEXT. Use glGetInteger64v instead.
We will soon support custom swapchains. In order to track output damage
we should instead use the damage_ring which will hold all the buffers
we are currently tracking anyway across an arbitrary amount of swapchains.