The current buffer allocator allocates a buffer that is either the
minimum stage span, the requested size times two, or the largest current
allocation times two.
Imagine needing a miniscule allocation. We currently have 1M, 8M and 16M
buffers, but the 1M buffer is full or not available. The last rule would
cause us to request a 32M buffer, rather than a more appropriate 2M
buffer to fill the bucket sequence.
Make two adjustments to this logic:
1. Round the requested size up to the nearest power of two to avoid odd
bucket sizes.
2. Look through the available buffers and find a hole in the bucket
sequence to fill, which is made easy by the power of two rule above
as we can just iterate until the buffer we are looking at is more
than 2x our current target.
The buffer we create is inserted into the middle of the list of buffers
as needed to maintain the size order.
We expect the render buffers to be ordered largest to smallest, with the
allocator using a reverse iteration to fill smallest buffers first.
Buffers that had been borrowed by a command buffer would just be
inserted at the end of the list, and would not maintain ordering with
any buffers already in that list.
Use a sorted insert to ensure that buffers remain ordered.
This avoids processing events which we're not interested in.
Specifically, this fixes a case where output_commit() could be
indirectly called from itself either from import_dmabuf() or while
waiting for a configure event when enabling the output.
Remove unneeded includes of wlr_output.h from wlr_compositor.h and
wlr_cursor.h (unneeded now that we forward-declare struct wlr_surface)
and put the actually-required includes in the right places.
wlr_compositor.h contains references to `struct wlr_surface` in function
arguments before it actually defines it. This generally works because
wlr_compositor.h includes wlr_output.h which contains a
forward-declaration for `struct wlr_surface` (despite not actually
referencing it).
This is all pretty weird, and gives very confusing errors if you manage
to end up with wlr_output.h including wlr_compositor.h (eg. via an
indirect route) so make it less weird.
The surface's buffer dimensions were used to scale the clip's x/y
offset. If a surface had a larger buffer than src_box, the calculations
to scale the x/y portion of the clip would be incorrect, yielding
graphical glitches.
This was noticed with Chromium in sway, which during resize uses a
viewport with a src_box to avoid immediate buffer reallocation. While
the viewport was in use, the surface would be shifted so that too much
content was cropped in the upper left, and damage glitching was visible
in the lower right.
Use the buffer source box dimensions instead.
Otherwise the number of touch points goes up constantly and d'n'd via
touch can't work as validation always fails.
Fixes 75ecba44 ("seat: add serials to touch up events")
Signed-off-by: Guido Günther <agx@sigxcpu.org>
Creating a renderer results in lots of logs. Make it clear that
the logs belong to a multi-GPU renderer (as opposed to a primary
renderer created by the compositor).
Replace them with pixman_region32_empty(), which avoids using a
double-negative when checking if a region is empty. Also use that
new function when checking for non-empty regions so that only one
variant of the Pixman API is used.
The old approach of using a signal is fundamentally broken for a common
usecase: When the waiter is ready, it's common to immediately finish and
free any resources associated with it.
Because of the semantics of wl_signal_emit_mutable() this is UB.
wl_signal_emit_mutable() always excepts that the waiter hasn't been freed
until the signal has finished being emitted.
Instead of over engineering the solution, let's just add a callback required
by wlr_drm_syncobj_timeline_waiter_init(). In this callback, the implementation
is free to finish() or free() any resource it likes.
This fixes a problem where an outdated surface input region was used to
compute the effective confinement region.
Additionally, this commit fixes a bug in pointer_constraint_create()
which caused the initial region to not be applied immediately.
This is a breaking change: set_region is now emitted before the role
commit hook is called, and it's not emitted if the region hasn't
actually changed.