mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
render: use single-pixel buffers for overlays, when possible
The unicode-mode, and flash overlays are single color buffers. This means we can use the single-pixel buffer protocol. It's undefined whether the compositor will release the buffer or not; to make things easier, simply destroy the buffer as soon as we've committed it. Note that since compositors don't necessarily release single-pixel buffers, we can't plug them into our own buffer interface. This means we can't use buffer pointers to check if we can re-use the previous buffer (i.e. we can skip comitting a new buffer), or if we have to create a new one. It's _almost_ enough to just check if the last overlay style is the same as the current one. Except that that doesn't take window resizes into account...
This commit is contained in:
parent
6944d5f901
commit
3c96d0b68e
5 changed files with 92 additions and 11 deletions
|
|
@ -159,6 +159,7 @@ wl_proto_xml = [
|
|||
wayland_protocols_datadir / 'staging/fractional-scale/fractional-scale-v1.xml',
|
||||
wayland_protocols_datadir / 'unstable/tablet/tablet-unstable-v2.xml', # required by cursor-shape-v1
|
||||
wayland_protocols_datadir / 'staging/cursor-shape/cursor-shape-v1.xml',
|
||||
wayland_protocols_datadir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml',
|
||||
]
|
||||
|
||||
foreach prot : wl_proto_xml
|
||||
|
|
|
|||
78
render.c
78
render.c
|
|
@ -1559,6 +1559,58 @@ render_ime_preedit(struct terminal *term, struct buffer *buf)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
render_overlay_single_pixel(struct terminal *term, enum overlay_style style,
|
||||
pixman_color_t color)
|
||||
{
|
||||
struct wayland *wayl = term->wl;
|
||||
struct wayl_sub_surface *overlay = &term->window->overlay;
|
||||
|
||||
/*
|
||||
* Note: we currently do *not* re-use the overlay buffer
|
||||
*
|
||||
* This means we'll re-create the buffer each time we render a new
|
||||
* frame. This shouldn't be a problem in any of the cases where we
|
||||
* use single-pixel buffers (unicode-input, and flash).
|
||||
*
|
||||
* Note: it's _almost_ enough to just check if
|
||||
* style' == last_overlay_style
|
||||
* except that doesn't take window resizes into account...
|
||||
*/
|
||||
|
||||
assert(style == OVERLAY_UNICODE_MODE || style == OVERLAY_FLASH);
|
||||
assert(wayl->single_pixel_manager != NULL);
|
||||
assert(overlay->surface.viewport != NULL);
|
||||
|
||||
struct wl_buffer *buf =
|
||||
wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer(
|
||||
term->wl->single_pixel_manager,
|
||||
(double)color.red / 0xffff * 0xffffffff,
|
||||
(double)color.green / 0xffff * 0xffffffff,
|
||||
(double)color.blue / 0xffff * 0xffffffff,
|
||||
(double)color.alpha / 0xffff * 0xffffffff);
|
||||
|
||||
wl_surface_set_buffer_scale(overlay->surface.surf, 1);
|
||||
wp_viewport_set_destination(
|
||||
overlay->surface.viewport,
|
||||
roundf(term->width / term->scale),
|
||||
roundf(term->height / term->scale));
|
||||
|
||||
quirk_weston_subsurface_desync_on(overlay->sub);
|
||||
|
||||
wl_subsurface_set_position(overlay->sub, 0, 0);
|
||||
wl_surface_attach(overlay->surface.surf, buf, 0, 0);
|
||||
|
||||
wl_surface_damage_buffer(
|
||||
overlay->surface.surf, 0, 0, term->width, term->height);
|
||||
|
||||
wl_surface_commit(overlay->surface.surf);
|
||||
quirk_weston_subsurface_desync_off(overlay->sub);
|
||||
|
||||
term->render.last_overlay_style = style;
|
||||
wl_buffer_destroy(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
render_overlay(struct terminal *term)
|
||||
{
|
||||
|
|
@ -1586,17 +1638,9 @@ render_overlay(struct terminal *term)
|
|||
return;
|
||||
}
|
||||
|
||||
struct buffer *buf = shm_get_buffer(
|
||||
term->render.chains.overlay, term->width, term->height, true);
|
||||
|
||||
pixman_image_set_clip_region32(buf->pix[0], NULL);
|
||||
|
||||
pixman_color_t color;
|
||||
|
||||
switch (style) {
|
||||
case OVERLAY_NONE:
|
||||
break;
|
||||
|
||||
case OVERLAY_SEARCH:
|
||||
case OVERLAY_UNICODE_MODE:
|
||||
color = (pixman_color_t){0, 0, 0, 0x7fff};
|
||||
|
|
@ -1607,8 +1651,26 @@ render_overlay(struct terminal *term)
|
|||
term->conf->colors.flash,
|
||||
term->conf->colors.flash_alpha);
|
||||
break;
|
||||
|
||||
case OVERLAY_NONE:
|
||||
xassert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
const bool single_pixel =
|
||||
(style == OVERLAY_UNICODE_MODE || style == OVERLAY_FLASH) &&
|
||||
term->wl->single_pixel_manager != NULL &&
|
||||
overlay->surface.viewport != NULL;
|
||||
|
||||
if (single_pixel) {
|
||||
render_overlay_single_pixel(term, style, color);
|
||||
return;
|
||||
}
|
||||
|
||||
struct buffer *buf = shm_get_buffer(
|
||||
term->render.chains.overlay, term->width, term->height, true);
|
||||
pixman_image_set_clip_region32(buf->pix[0], NULL);
|
||||
|
||||
/* Bounding rectangle of damaged areas - for wl_surface_damage_buffer() */
|
||||
pixman_box32_t damage_bounds;
|
||||
|
||||
|
|
|
|||
|
|
@ -2195,7 +2195,9 @@ term_font_size_reset(struct terminal *term)
|
|||
bool
|
||||
term_fractional_scaling(const struct terminal *term)
|
||||
{
|
||||
return term->wl->fractional_scale_manager != NULL && term->window->scale > 0.;
|
||||
return term->wl->fractional_scale_manager != NULL &&
|
||||
term->wl->viewporter != NULL &&
|
||||
term->window->scale > 0.;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
15
wayland.c
15
wayland.c
|
|
@ -1320,6 +1320,16 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
wayl->registry, name, &wp_cursor_shape_manager_v1_interface, required);
|
||||
}
|
||||
|
||||
else if (streq(interface, wp_single_pixel_buffer_manager_v1_interface.name)) {
|
||||
const uint32_t required = 1;
|
||||
if (!verify_iface_version(interface, version, required))
|
||||
return;
|
||||
|
||||
wayl->single_pixel_manager = wl_registry_bind(
|
||||
wayl->registry, name,
|
||||
&wp_single_pixel_buffer_manager_v1_interface, required);
|
||||
}
|
||||
|
||||
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||
else if (streq(interface, zwp_text_input_manager_v3_interface.name)) {
|
||||
const uint32_t required = 1;
|
||||
|
|
@ -1636,6 +1646,8 @@ wayl_destroy(struct wayland *wayl)
|
|||
zwp_text_input_manager_v3_destroy(wayl->text_input_manager);
|
||||
#endif
|
||||
|
||||
if (wayl->single_pixel_manager != NULL)
|
||||
wp_single_pixel_buffer_manager_v1_destroy(wayl->single_pixel_manager);
|
||||
if (wayl->fractional_scale_manager != NULL)
|
||||
wp_fractional_scale_manager_v1_destroy(wayl->fractional_scale_manager);
|
||||
if (wayl->viewporter != NULL)
|
||||
|
|
@ -2058,6 +2070,7 @@ surface_scale_explicit_width_height(
|
|||
}
|
||||
}
|
||||
|
||||
xassert(surf->viewport != NULL);
|
||||
wl_surface_set_buffer_scale(surf->surf, 1);
|
||||
wp_viewport_set_destination(
|
||||
surf->viewport, roundf(width / scale), roundf(height / scale));
|
||||
|
|
@ -2204,7 +2217,7 @@ wayl_win_subsurface_new_with_custom_parent(
|
|||
}
|
||||
|
||||
struct wp_viewport *viewport = NULL;
|
||||
if (wayl->fractional_scale_manager != NULL && wayl->viewporter != NULL) {
|
||||
if (wayl->viewporter != NULL) {
|
||||
viewport = wp_viewporter_get_viewport(wayl->viewporter, main_surface);
|
||||
if (viewport == NULL) {
|
||||
LOG_ERR("failed to instantiate viewport for sub-surface");
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <fractional-scale-v1.h>
|
||||
#include <presentation-time.h>
|
||||
#include <primary-selection-unstable-v1.h>
|
||||
#include <single-pixel-buffer-v1.h>
|
||||
#include <text-input-unstable-v3.h>
|
||||
#include <viewporter.h>
|
||||
#include <xdg-activation-v1.h>
|
||||
|
|
@ -439,10 +440,12 @@ struct wayland {
|
|||
|
||||
struct wp_cursor_shape_manager_v1 *cursor_shape_manager;
|
||||
|
||||
struct wp_single_pixel_buffer_manager_v1 *single_pixel_manager;
|
||||
|
||||
bool presentation_timings;
|
||||
struct wp_presentation *presentation;
|
||||
uint32_t presentation_clock_id;
|
||||
|
||||
|
||||
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
|
||||
struct zwp_text_input_manager_v3 *text_input_manager;
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue