mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-05-13 16:37:27 +00:00
Use single pixel buffer protocol for more efficient temp buffer creation
This commit is contained in:
parent
d3b5e86f30
commit
b4bba99678
4 changed files with 57 additions and 23 deletions
|
|
@ -81,6 +81,7 @@
|
|||
"unstable/tablet/tablet-unstable-v2.xml",
|
||||
"staging/cursor-shape/cursor-shape-v1.xml",
|
||||
"staging/fractional-scale/fractional-scale-v1.xml",
|
||||
"staging/single-pixel-buffer/single-pixel-buffer-v1.xml",
|
||||
|
||||
"kwin-blur-v1.xml",
|
||||
"wlr-layer-shell-unstable-v1.xml"
|
||||
|
|
|
|||
5
glfw/wl_init.c
vendored
5
glfw/wl_init.c
vendored
|
|
@ -724,6 +724,9 @@ static void registryHandleGlobal(void* data UNUSED,
|
|||
_glfwSetupWaylandPrimarySelectionDevice();
|
||||
}
|
||||
}
|
||||
else if (is(wp_single_pixel_buffer_manager_v1)) {
|
||||
_glfw.wl.wp_single_pixel_buffer_manager_v1 = wl_registry_bind(registry, name, &wp_single_pixel_buffer_manager_v1_interface, 1);
|
||||
}
|
||||
else if (is(xdg_activation_v1)) {
|
||||
_glfw.wl.xdg_activation_v1 = wl_registry_bind(registry, name, &xdg_activation_v1_interface, 1);
|
||||
}
|
||||
|
|
@ -992,6 +995,8 @@ void _glfwPlatformTerminate(void)
|
|||
zwp_primary_selection_device_manager_v1_destroy(_glfw.wl.primarySelectionDeviceManager);
|
||||
if (_glfw.wl.xdg_activation_v1)
|
||||
xdg_activation_v1_destroy(_glfw.wl.xdg_activation_v1);
|
||||
if (_glfw.wl.wp_single_pixel_buffer_manager_v1)
|
||||
wp_single_pixel_buffer_manager_v1_destroy(_glfw.wl.wp_single_pixel_buffer_manager_v1);
|
||||
if (_glfw.wl.wp_cursor_shape_manager_v1)
|
||||
wp_cursor_shape_manager_v1_destroy(_glfw.wl.wp_cursor_shape_manager_v1);
|
||||
if (_glfw.wl.wp_viewporter)
|
||||
|
|
|
|||
2
glfw/wl_platform.h
vendored
2
glfw/wl_platform.h
vendored
|
|
@ -64,6 +64,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
|||
#include "wayland-viewporter-client-protocol.h"
|
||||
#include "wayland-kwin-blur-v1-client-protocol.h"
|
||||
#include "wayland-wlr-layer-shell-unstable-v1-client-protocol.h"
|
||||
#include "wayland-single-pixel-buffer-v1-client-protocol.h"
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
|
|
@ -308,6 +309,7 @@ typedef struct _GLFWlibraryWayland
|
|||
struct wp_viewporter *wp_viewporter;
|
||||
struct org_kde_kwin_blur_manager *org_kde_kwin_blur_manager;
|
||||
struct zwlr_layer_shell_v1* zwlr_layer_shell_v1; uint32_t zwlr_layer_shell_v1_version;
|
||||
struct wp_single_pixel_buffer_manager_v1 *wp_single_pixel_buffer_manager_v1;
|
||||
|
||||
int compositorVersion;
|
||||
int seatVersion;
|
||||
|
|
|
|||
72
glfw/wl_window.c
vendored
72
glfw/wl_window.c
vendored
|
|
@ -752,28 +752,23 @@ apply_xdg_configure_changes(_GLFWwindow *window) {
|
|||
commit_window_surface_if_safe(window);
|
||||
window->wl.pending_state = 0;
|
||||
}
|
||||
typedef union pixel {
|
||||
struct {
|
||||
uint8_t blue, green, red, alpha;
|
||||
};
|
||||
uint32_t value;
|
||||
} pixel;
|
||||
|
||||
static bool
|
||||
attach_temp_buffer_during_window_creation(_GLFWwindow *window) {
|
||||
int width, height;
|
||||
_glfwPlatformGetFramebufferSize(window, &width, &height);
|
||||
static struct wl_buffer*
|
||||
create_single_color_buffer(int width, int height, pixel color) {
|
||||
int shm_format = color.alpha == 0xff ? WL_SHM_FORMAT_XRGB8888 : WL_SHM_FORMAT_ARGB8888;
|
||||
const size_t size = 4 * width * height;
|
||||
int fd = createAnonymousFile(size);
|
||||
if (fd < 0) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: failed to create anonymous file");
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
uint32_t *shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
union {
|
||||
struct {
|
||||
uint8_t blue, green, red, alpha;
|
||||
};
|
||||
uint32_t value;
|
||||
} color;
|
||||
color.value = _glfw.hints.window.wl.bgcolor;
|
||||
int shm_format = WL_SHM_FORMAT_ARGB8888;
|
||||
if (!window->wl.transparent) { color.alpha = 0xff; shm_format = WL_SHM_FORMAT_XRGB8888; }
|
||||
else if (color.alpha == 0) color.value = 0; // fully transparent blends best with black and we can use memset
|
||||
// convert to pre-multiplied alpha
|
||||
float alpha = color.alpha / 255.f; color.red = (uint8_t)(alpha * color.red); color.green = (uint8_t)(alpha * color.green); color.blue = (uint8_t)(alpha * color.blue);
|
||||
if (color.value) for (size_t i = 0; i < size/4; i++) shm_data[i] = color.value;
|
||||
|
|
@ -781,25 +776,56 @@ attach_temp_buffer_during_window_creation(_GLFWwindow *window) {
|
|||
if (!shm_data) {
|
||||
close(fd);
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: failed to mmap anonymous file");
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
struct wl_shm_pool *pool = wl_shm_create_pool(_glfw.wl.shm, fd, size);
|
||||
if (!pool) {
|
||||
close(fd); munmap(shm_data, size);
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: failed to create wl_shm_pool of size: %zu", size);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
struct wl_buffer *buffer = wl_shm_pool_create_buffer(pool, 0, width, height, width * 4, shm_format);
|
||||
wl_shm_pool_destroy(pool); munmap(shm_data, size); close(fd);
|
||||
if (!buffer) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: failed to create wl_buffer of size: %zu", size);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
if (window->wl.temp_buffer_used_during_window_creation) wl_buffer_destroy(window->wl.temp_buffer_used_during_window_creation);
|
||||
window->wl.temp_buffer_used_during_window_creation = buffer;
|
||||
wl_surface_set_buffer_scale(window->wl.surface, window->wl.fractional_scale ? 1: _glfwWaylandIntegerWindowScale(window));
|
||||
wl_surface_attach(window->wl.surface, buffer, 0, 0);
|
||||
if (window->wl.wp_viewport) wp_viewport_set_destination(window->wl.wp_viewport, window->wl.width, window->wl.height);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static bool
|
||||
attach_temp_buffer_during_window_creation(_GLFWwindow *window) {
|
||||
pixel color;
|
||||
color.value = _glfw.hints.window.wl.bgcolor;
|
||||
if (!window->wl.transparent) color.alpha = 0xff;
|
||||
else if (color.alpha == 0) color.value = 0; // fully transparent blends best with black and we can use memset
|
||||
|
||||
if (window->wl.temp_buffer_used_during_window_creation) {
|
||||
wl_buffer_destroy(window->wl.temp_buffer_used_during_window_creation);
|
||||
window->wl.temp_buffer_used_during_window_creation = NULL;
|
||||
}
|
||||
int width, height;
|
||||
_glfwPlatformGetFramebufferSize(window, &width, &height);
|
||||
|
||||
if (window->wl.wp_viewport) {
|
||||
if (_glfw.wl.wp_single_pixel_buffer_manager_v1) {
|
||||
window->wl.temp_buffer_used_during_window_creation = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer(_glfw.wl.wp_single_pixel_buffer_manager_v1, color.red, color.green, color.blue, color.alpha);
|
||||
if (!window->wl.temp_buffer_used_during_window_creation) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: failed to create single pixel buffer");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
window->wl.temp_buffer_used_during_window_creation = create_single_color_buffer(1, 1, color);
|
||||
if (!window->wl.temp_buffer_used_during_window_creation) return false;
|
||||
}
|
||||
wl_surface_set_buffer_scale(window->wl.surface, 1);
|
||||
wp_viewport_set_destination(window->wl.wp_viewport, window->wl.width, window->wl.height);
|
||||
} else {
|
||||
window->wl.temp_buffer_used_during_window_creation = create_single_color_buffer(1, 1, color);
|
||||
if (!window->wl.temp_buffer_used_during_window_creation) return false;
|
||||
wl_surface_set_buffer_scale(window->wl.surface, window->wl.fractional_scale ? 1: _glfwWaylandIntegerWindowScale(window));
|
||||
}
|
||||
wl_surface_attach(window->wl.surface, window->wl.temp_buffer_used_during_window_creation, 0, 0);
|
||||
wl_surface_commit(window->wl.surface);
|
||||
debug("Attached temp buffer during window creation of size: %dx%d\n", width, height);
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue