mirror of
https://gitlab.freedesktop.org/wayland/weston
synced 2024-10-15 05:53:17 +00:00
clients/simple-egl: Implement fractional-scale protocol support
Fractional scale is increasingly common in the Wayland ecosystem. Thus, given simple-egl's role as egl example client, implement support for the new protocol - even though Weston itself does not support it yet. Together with buffer_scale and buffer_transform this ensures simple-egl provides optimally sized and oriented buffers. Signed-off-by: Robert Mader <robert.mader@collabora.com>
This commit is contained in:
parent
1d2feda5aa
commit
9337d42741
|
@ -128,8 +128,12 @@ simple_clients = [
|
||||||
'name': 'egl',
|
'name': 'egl',
|
||||||
'sources': [
|
'sources': [
|
||||||
'simple-egl.c',
|
'simple-egl.c',
|
||||||
|
fractional_scale_v1_client_protocol_h,
|
||||||
|
fractional_scale_v1_protocol_c,
|
||||||
tearing_control_v1_client_protocol_h,
|
tearing_control_v1_client_protocol_h,
|
||||||
tearing_control_v1_protocol_c,
|
tearing_control_v1_protocol_c,
|
||||||
|
viewporter_client_protocol_h,
|
||||||
|
viewporter_protocol_c,
|
||||||
xdg_shell_client_protocol_h,
|
xdg_shell_client_protocol_h,
|
||||||
xdg_shell_protocol_c,
|
xdg_shell_protocol_c,
|
||||||
ivi_application_client_protocol_h,
|
ivi_application_client_protocol_h,
|
||||||
|
|
|
@ -42,6 +42,8 @@
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
#include <EGL/eglext.h>
|
#include <EGL/eglext.h>
|
||||||
|
|
||||||
|
#include "fractional-scale-v1-client-protocol.h"
|
||||||
|
#include "viewporter-client-protocol.h"
|
||||||
#include "xdg-shell-client-protocol.h"
|
#include "xdg-shell-client-protocol.h"
|
||||||
#include "tearing-control-v1-client-protocol.h"
|
#include "tearing-control-v1-client-protocol.h"
|
||||||
|
|
||||||
|
@ -71,6 +73,8 @@ struct display {
|
||||||
struct wl_cursor *default_cursor;
|
struct wl_cursor *default_cursor;
|
||||||
struct wl_surface *cursor_surface;
|
struct wl_surface *cursor_surface;
|
||||||
struct wp_tearing_control_manager_v1 *tearing_manager;
|
struct wp_tearing_control_manager_v1 *tearing_manager;
|
||||||
|
struct wp_viewporter *viewporter;
|
||||||
|
struct wp_fractional_scale_manager_v1 *fractional_scale_manager;
|
||||||
struct {
|
struct {
|
||||||
EGLDisplay dpy;
|
EGLDisplay dpy;
|
||||||
EGLContext ctx;
|
EGLContext ctx;
|
||||||
|
@ -93,6 +97,7 @@ struct window {
|
||||||
struct geometry logical_size;
|
struct geometry logical_size;
|
||||||
struct geometry buffer_size;
|
struct geometry buffer_size;
|
||||||
int32_t buffer_scale;
|
int32_t buffer_scale;
|
||||||
|
double fractional_buffer_scale;
|
||||||
enum wl_output_transform buffer_transform;
|
enum wl_output_transform buffer_transform;
|
||||||
bool needs_buffer_geometry_update;
|
bool needs_buffer_geometry_update;
|
||||||
|
|
||||||
|
@ -112,6 +117,8 @@ struct window {
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
int fullscreen, maximized, opaque, buffer_bpp, frame_sync, delay;
|
int fullscreen, maximized, opaque, buffer_bpp, frame_sync, delay;
|
||||||
struct wp_tearing_control_v1 *tear_control;
|
struct wp_tearing_control_v1 *tear_control;
|
||||||
|
struct wp_viewport *viewport;
|
||||||
|
struct wp_fractional_scale_v1 *fractional_scale_obj;
|
||||||
bool tearing, toggled_tearing, tear_enabled;
|
bool tearing, toggled_tearing, tear_enabled;
|
||||||
bool vertical_bar;
|
bool vertical_bar;
|
||||||
bool fullscreen_ratio;
|
bool fullscreen_ratio;
|
||||||
|
@ -326,8 +333,8 @@ static void
|
||||||
update_buffer_geometry(struct window *window)
|
update_buffer_geometry(struct window *window)
|
||||||
{
|
{
|
||||||
enum wl_output_transform new_buffer_transform;
|
enum wl_output_transform new_buffer_transform;
|
||||||
int32_t new_buffer_scale;
|
|
||||||
struct geometry new_buffer_size;
|
struct geometry new_buffer_size;
|
||||||
|
struct geometry new_viewport_dest_size;
|
||||||
|
|
||||||
new_buffer_transform = compute_buffer_transform(window);
|
new_buffer_transform = compute_buffer_transform(window);
|
||||||
if (window->buffer_transform != new_buffer_transform) {
|
if (window->buffer_transform != new_buffer_transform) {
|
||||||
|
@ -336,13 +343,6 @@ update_buffer_geometry(struct window *window)
|
||||||
window->buffer_transform);
|
window->buffer_transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_buffer_scale = compute_buffer_scale(window);
|
|
||||||
if (window->buffer_scale != new_buffer_scale) {
|
|
||||||
window->buffer_scale = new_buffer_scale;
|
|
||||||
wl_surface_set_buffer_scale(window->surface,
|
|
||||||
window->buffer_scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (window->buffer_transform) {
|
switch (window->buffer_transform) {
|
||||||
case WL_OUTPUT_TRANSFORM_NORMAL:
|
case WL_OUTPUT_TRANSFORM_NORMAL:
|
||||||
case WL_OUTPUT_TRANSFORM_180:
|
case WL_OUTPUT_TRANSFORM_180:
|
||||||
|
@ -360,14 +360,47 @@ update_buffer_geometry(struct window *window)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window->fractional_buffer_scale > 0.0) {
|
||||||
|
if (window->buffer_scale > 1) {
|
||||||
|
window->buffer_scale = 1;
|
||||||
|
wl_surface_set_buffer_scale(window->surface,
|
||||||
|
window->buffer_scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
new_buffer_size.width = ceil(new_buffer_size.width *
|
||||||
|
window->fractional_buffer_scale);
|
||||||
|
new_buffer_size.height = ceil(new_buffer_size.height *
|
||||||
|
window->fractional_buffer_scale);
|
||||||
|
} else {
|
||||||
|
int32_t new_buffer_scale;
|
||||||
|
|
||||||
|
new_buffer_scale = compute_buffer_scale(window);
|
||||||
|
if (window->buffer_scale != new_buffer_scale) {
|
||||||
|
window->buffer_scale = new_buffer_scale;
|
||||||
|
wl_surface_set_buffer_scale(window->surface,
|
||||||
|
window->buffer_scale);
|
||||||
|
}
|
||||||
|
|
||||||
new_buffer_size.width *= window->buffer_scale;
|
new_buffer_size.width *= window->buffer_scale;
|
||||||
new_buffer_size.height *= window->buffer_scale;
|
new_buffer_size.height *= window->buffer_scale;
|
||||||
|
}
|
||||||
|
|
||||||
if (window->fullscreen && window->fullscreen_ratio) {
|
if (window->fullscreen && window->fullscreen_ratio) {
|
||||||
int new_buffer_size_min = MIN(new_buffer_size.width,
|
int new_buffer_size_min;
|
||||||
|
int new_viewport_dest_size_min;
|
||||||
|
|
||||||
|
new_buffer_size_min = MIN(new_buffer_size.width,
|
||||||
new_buffer_size.height);
|
new_buffer_size.height);
|
||||||
new_buffer_size.width = new_buffer_size_min;
|
new_buffer_size.width = new_buffer_size_min;
|
||||||
new_buffer_size.height = new_buffer_size_min;
|
new_buffer_size.height = new_buffer_size_min;
|
||||||
|
|
||||||
|
new_viewport_dest_size_min = MIN(window->logical_size.width,
|
||||||
|
window->logical_size.height);
|
||||||
|
new_viewport_dest_size.width = new_viewport_dest_size_min;
|
||||||
|
new_viewport_dest_size.height = new_viewport_dest_size_min;
|
||||||
|
} else {
|
||||||
|
new_viewport_dest_size.width = window->logical_size.width;
|
||||||
|
new_viewport_dest_size.height = window->logical_size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window->buffer_size.width != new_buffer_size.width ||
|
if (window->buffer_size.width != new_buffer_size.width ||
|
||||||
|
@ -379,10 +412,14 @@ update_buffer_geometry(struct window *window)
|
||||||
window->buffer_size.height, 0, 0);
|
window->buffer_size.height, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (window->fractional_buffer_scale > 0.0)
|
||||||
|
wp_viewport_set_destination(window->viewport,
|
||||||
|
new_viewport_dest_size.width,
|
||||||
|
new_viewport_dest_size.height);
|
||||||
|
|
||||||
window->needs_buffer_geometry_update = false;
|
window->needs_buffer_geometry_update = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_gl(struct window *window)
|
init_gl(struct window *window)
|
||||||
{
|
{
|
||||||
|
@ -686,6 +723,19 @@ static const struct wl_surface_listener surface_listener = {
|
||||||
surface_leave
|
surface_leave
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void fractional_scale_handle_preferred_scale(void *data,
|
||||||
|
struct wp_fractional_scale_v1 *info,
|
||||||
|
uint32_t wire_scale) {
|
||||||
|
struct window *window = data;
|
||||||
|
|
||||||
|
window->fractional_buffer_scale = wire_scale / 120.0;
|
||||||
|
window->needs_buffer_geometry_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
|
||||||
|
.preferred_scale = fractional_scale_handle_preferred_scale,
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
create_surface(struct window *window)
|
create_surface(struct window *window)
|
||||||
{
|
{
|
||||||
|
@ -720,6 +770,17 @@ create_surface(struct window *window)
|
||||||
else if (window->maximized)
|
else if (window->maximized)
|
||||||
xdg_toplevel_set_maximized(window->xdg_toplevel);
|
xdg_toplevel_set_maximized(window->xdg_toplevel);
|
||||||
|
|
||||||
|
if (display->viewporter && display->fractional_scale_manager) {
|
||||||
|
window->viewport = wp_viewporter_get_viewport(display->viewporter,
|
||||||
|
window->surface);
|
||||||
|
window->fractional_scale_obj =
|
||||||
|
wp_fractional_scale_manager_v1_get_fractional_scale(display->fractional_scale_manager,
|
||||||
|
window->surface);
|
||||||
|
wp_fractional_scale_v1_add_listener(window->fractional_scale_obj,
|
||||||
|
&fractional_scale_listener,
|
||||||
|
window);
|
||||||
|
}
|
||||||
|
|
||||||
window->wait_for_configure = true;
|
window->wait_for_configure = true;
|
||||||
wl_surface_commit(window->surface);
|
wl_surface_commit(window->surface);
|
||||||
}
|
}
|
||||||
|
@ -740,6 +801,10 @@ destroy_surface(struct window *window)
|
||||||
xdg_toplevel_destroy(window->xdg_toplevel);
|
xdg_toplevel_destroy(window->xdg_toplevel);
|
||||||
if (window->xdg_surface)
|
if (window->xdg_surface)
|
||||||
xdg_surface_destroy(window->xdg_surface);
|
xdg_surface_destroy(window->xdg_surface);
|
||||||
|
if (window->viewport)
|
||||||
|
wp_viewport_destroy(window->viewport);
|
||||||
|
if (window->fractional_scale_obj)
|
||||||
|
wp_fractional_scale_v1_destroy(window->fractional_scale_obj);
|
||||||
wl_surface_destroy(window->surface);
|
wl_surface_destroy(window->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1178,6 +1243,15 @@ registry_handle_global(void *data, struct wl_registry *registry,
|
||||||
d->tearing_manager = wl_registry_bind(registry, name,
|
d->tearing_manager = wl_registry_bind(registry, name,
|
||||||
&wp_tearing_control_manager_v1_interface,
|
&wp_tearing_control_manager_v1_interface,
|
||||||
1);
|
1);
|
||||||
|
} else if (strcmp(interface, wp_viewporter_interface.name) == 0) {
|
||||||
|
d->viewporter = wl_registry_bind(registry, name,
|
||||||
|
&wp_viewporter_interface,
|
||||||
|
1);
|
||||||
|
} else if (strcmp(interface, wp_fractional_scale_manager_v1_interface.name) == 0) {
|
||||||
|
d->fractional_scale_manager =
|
||||||
|
wl_registry_bind(registry, name,
|
||||||
|
&wp_fractional_scale_manager_v1_interface,
|
||||||
|
1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1352,6 +1426,12 @@ out_no_xdg_shell:
|
||||||
if (display.compositor)
|
if (display.compositor)
|
||||||
wl_compositor_destroy(display.compositor);
|
wl_compositor_destroy(display.compositor);
|
||||||
|
|
||||||
|
if (display.viewporter)
|
||||||
|
wp_viewporter_destroy(display.viewporter);
|
||||||
|
|
||||||
|
if (display.fractional_scale_manager)
|
||||||
|
wp_fractional_scale_manager_v1_destroy(display.fractional_scale_manager);
|
||||||
|
|
||||||
wl_registry_destroy(display.registry);
|
wl_registry_destroy(display.registry);
|
||||||
wl_display_flush(display.display);
|
wl_display_flush(display.display);
|
||||||
wl_display_disconnect(display.display);
|
wl_display_disconnect(display.display);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
dep_scanner = dependency('wayland-scanner', native: true)
|
dep_scanner = dependency('wayland-scanner', native: true)
|
||||||
prog_scanner = find_program(dep_scanner.get_variable(pkgconfig: 'wayland_scanner'))
|
prog_scanner = find_program(dep_scanner.get_variable(pkgconfig: 'wayland_scanner'))
|
||||||
|
|
||||||
dep_wp = dependency('wayland-protocols', version: '>= 1.30',
|
dep_wp = dependency('wayland-protocols', version: '>= 1.31',
|
||||||
fallback: ['wayland-protocols', 'wayland_protocols'])
|
fallback: ['wayland-protocols', 'wayland_protocols'])
|
||||||
dir_wp_base = dep_wp.get_variable(pkgconfig: 'pkgdatadir', internal: 'pkgdatadir')
|
dir_wp_base = dep_wp.get_variable(pkgconfig: 'pkgdatadir', internal: 'pkgdatadir')
|
||||||
|
|
||||||
|
@ -16,11 +16,12 @@ install_data(
|
||||||
)
|
)
|
||||||
|
|
||||||
generated_protocols = [
|
generated_protocols = [
|
||||||
|
[ 'fullscreen-shell', 'unstable', 'v1' ],
|
||||||
|
[ 'fractional-scale', 'staging', 'v1' ],
|
||||||
[ 'input-method', 'unstable', 'v1' ],
|
[ 'input-method', 'unstable', 'v1' ],
|
||||||
[ 'input-timestamps', 'unstable', 'v1' ],
|
[ 'input-timestamps', 'unstable', 'v1' ],
|
||||||
[ 'ivi-application', 'internal' ],
|
[ 'ivi-application', 'internal' ],
|
||||||
[ 'ivi-hmi-controller', 'internal' ],
|
[ 'ivi-hmi-controller', 'internal' ],
|
||||||
[ 'fullscreen-shell', 'unstable', 'v1' ],
|
|
||||||
[ 'linux-dmabuf', 'unstable', 'v1' ],
|
[ 'linux-dmabuf', 'unstable', 'v1' ],
|
||||||
[ 'linux-explicit-synchronization', 'unstable', 'v1' ],
|
[ 'linux-explicit-synchronization', 'unstable', 'v1' ],
|
||||||
[ 'presentation-time', 'stable' ],
|
[ 'presentation-time', 'stable' ],
|
||||||
|
|
Loading…
Reference in a new issue