mirror of
https://github.com/mpv-player/mpv
synced 2024-12-23 07:12:39 +00:00
wayland/egl: rework resizing (again)
Moves a good chunk of the resizing code to wayland_common.c. This makes it possible to share it with future video drivers. It doesn't resizit it immediatly, it calcutlates the new position and size and then shedules a resizing event. This removes the ugly callback and void pointer from the wayland data structure.
This commit is contained in:
parent
c2cb85851f
commit
8fd274ea3b
@ -39,74 +39,42 @@ struct egl_context {
|
||||
} egl;
|
||||
};
|
||||
|
||||
static void egl_resize_func(struct vo_wayland_state *wl,
|
||||
uint32_t edges,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
void *user_data)
|
||||
static void egl_resize(struct vo_wayland_state *wl,
|
||||
struct egl_context *ctx)
|
||||
{
|
||||
struct egl_context *ctx = user_data;
|
||||
int32_t minimum_size = 150;
|
||||
int32_t x, y;
|
||||
float temp_aspect = width / (float) MPMAX(height, 1);
|
||||
int32_t x = wl->window.sh_x;
|
||||
int32_t y = wl->window.sh_y;
|
||||
int32_t width = wl->window.sh_width;
|
||||
int32_t height = wl->window.sh_height;
|
||||
|
||||
if (!ctx->egl_window)
|
||||
return;
|
||||
|
||||
/* get the real window size of the window */
|
||||
// get the real size of the window
|
||||
// this improves moving the window while resizing it
|
||||
wl_egl_window_get_attached_size(ctx->egl_window,
|
||||
&wl->window.width,
|
||||
&wl->window.height);
|
||||
|
||||
if (width < minimum_size)
|
||||
width = minimum_size;
|
||||
if (height < minimum_size)
|
||||
height = minimum_size;
|
||||
|
||||
/* if only the height is changed we have to calculate the width
|
||||
* in any other case we calculate the height */
|
||||
switch (edges) {
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM:
|
||||
width = wl->window.aspect * height;
|
||||
break;
|
||||
case WL_SHELL_SURFACE_RESIZE_LEFT:
|
||||
case WL_SHELL_SURFACE_RESIZE_RIGHT:
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: // just a preference
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
|
||||
height = (1 / wl->window.aspect) * width;
|
||||
break;
|
||||
default:
|
||||
if (wl->window.aspect < temp_aspect)
|
||||
width = wl->window.aspect * height;
|
||||
else
|
||||
height = (1 / wl->window.aspect) * width;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (edges & WL_SHELL_SURFACE_RESIZE_LEFT)
|
||||
x = wl->window.width - width;
|
||||
else
|
||||
x = 0;
|
||||
|
||||
if (edges & WL_SHELL_SURFACE_RESIZE_TOP)
|
||||
y = wl->window.height - height;
|
||||
else
|
||||
y = 0;
|
||||
|
||||
MP_VERBOSE(ctx, "resizing %dx%d -> %dx%d\n", wl->window.width,
|
||||
wl->window.height, width, height);
|
||||
wl->window.height,
|
||||
width,
|
||||
height);
|
||||
|
||||
if (x != 0)
|
||||
x = wl->window.width - width;
|
||||
|
||||
if (y != 0)
|
||||
y = wl->window.height - height;
|
||||
|
||||
wl_egl_window_resize(ctx->egl_window, width, height, x, y);
|
||||
|
||||
wl->window.width = width;
|
||||
wl->window.height = height;
|
||||
|
||||
/* set size for mplayer */
|
||||
wl->vo->dwidth = width;
|
||||
wl->vo->dheight = height;
|
||||
wl->vo->dwidth = wl->window.width;
|
||||
wl->vo->dheight = wl->window.height;
|
||||
|
||||
wl->vo->want_redraw = true;
|
||||
wl->window.events = 0;
|
||||
}
|
||||
|
||||
static bool egl_create_context(struct vo_wayland_state *wl,
|
||||
@ -217,9 +185,6 @@ static bool config_window_wayland(struct MPGLContext *ctx,
|
||||
|
||||
egl_ctx->log = mp_log_new(egl_ctx, wl->log, "EGL");
|
||||
|
||||
wl->window.resize_func = egl_resize_func;
|
||||
wl->window.resize_func_data = (void*) egl_ctx;
|
||||
|
||||
if (!vo_wayland_config(ctx->vo, d_width, d_height, flags))
|
||||
return false;
|
||||
|
||||
@ -262,7 +227,12 @@ static void releaseGlContext_wayland(MPGLContext *ctx)
|
||||
static void swapGlBuffers_wayland(MPGLContext *ctx)
|
||||
{
|
||||
struct egl_context * egl_ctx = ctx->priv;
|
||||
struct vo_wayland_state *wl = ctx->vo->wayland;
|
||||
|
||||
eglSwapBuffers(egl_ctx->egl.dpy, egl_ctx->egl_surface);
|
||||
|
||||
if (wl->window.events & VO_EVENT_RESIZE)
|
||||
egl_resize(wl, egl_ctx);
|
||||
}
|
||||
|
||||
void mpgl_set_backend_wayland(MPGLContext *ctx)
|
||||
|
@ -56,10 +56,10 @@ static int lookupkey(int key);
|
||||
|
||||
static void hide_cursor(struct vo_wayland_state * wl);
|
||||
static void show_cursor(struct vo_wayland_state * wl);
|
||||
static void resize_window(struct vo_wayland_state *wl,
|
||||
uint32_t edges,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
static void shedule_resize(struct vo_wayland_state *wl,
|
||||
uint32_t edges,
|
||||
int32_t width,
|
||||
int32_t height);
|
||||
|
||||
static void vo_wayland_fullscreen (struct vo *vo);
|
||||
|
||||
@ -127,7 +127,7 @@ static void ssurface_handle_configure(void *data,
|
||||
int32_t height)
|
||||
{
|
||||
struct vo_wayland_state *wl = data;
|
||||
resize_window(wl, edges, width, height);
|
||||
shedule_resize(wl, edges, width, height);
|
||||
}
|
||||
|
||||
static void ssurface_handle_popup_done(void *data,
|
||||
@ -545,20 +545,62 @@ static void show_cursor (struct vo_wayland_state *wl)
|
||||
wl_surface_commit(wl->cursor.surface);
|
||||
}
|
||||
|
||||
static void resize_window(struct vo_wayland_state *wl,
|
||||
uint32_t edges,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
static void shedule_resize(struct vo_wayland_state *wl,
|
||||
uint32_t edges,
|
||||
int32_t width,
|
||||
int32_t height)
|
||||
{
|
||||
MP_VERBOSE(wl, "resizing %dx%d -> %dx%d\n", wl->window.width,
|
||||
wl->window.height, width, height);
|
||||
if (wl->window.resize_func && wl->window.resize_func_data) {
|
||||
wl->window.resize_func(wl, edges, width, height,
|
||||
wl->window.resize_func_data);
|
||||
wl->window.events |= VO_EVENT_RESIZE;
|
||||
int32_t minimum_size = 150;
|
||||
int32_t x, y;
|
||||
float temp_aspect = width / (float) MPMAX(height, 1);
|
||||
|
||||
if (width < minimum_size)
|
||||
width = minimum_size;
|
||||
|
||||
if (height < minimum_size)
|
||||
height = minimum_size;
|
||||
|
||||
/* if only the height is changed we have to calculate the width
|
||||
* in any other case we calculate the height */
|
||||
switch (edges) {
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM:
|
||||
width = wl->window.aspect * height;
|
||||
break;
|
||||
case WL_SHELL_SURFACE_RESIZE_LEFT:
|
||||
case WL_SHELL_SURFACE_RESIZE_RIGHT:
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: // just a preference
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
|
||||
height = (1 / wl->window.aspect) * width;
|
||||
break;
|
||||
default:
|
||||
if (wl->window.aspect < temp_aspect)
|
||||
width = wl->window.aspect * height;
|
||||
else
|
||||
height = (1 / wl->window.aspect) * width;
|
||||
break;
|
||||
}
|
||||
|
||||
wl->vo->dwidth = width;
|
||||
wl->vo->dheight = height;
|
||||
|
||||
if (edges & WL_SHELL_SURFACE_RESIZE_LEFT)
|
||||
x = wl->window.width - width;
|
||||
else
|
||||
MP_WARN(wl, "no resizing possible\n");
|
||||
x = 0;
|
||||
|
||||
if (edges & WL_SHELL_SURFACE_RESIZE_TOP)
|
||||
y = wl->window.height - height;
|
||||
else
|
||||
y = 0;
|
||||
|
||||
wl->window.sh_width = width;
|
||||
wl->window.sh_height = height;
|
||||
wl->window.sh_x = x;
|
||||
wl->window.sh_y = y;
|
||||
wl->window.events |= VO_EVENT_RESIZE;
|
||||
}
|
||||
|
||||
|
||||
@ -747,7 +789,7 @@ static void vo_wayland_fullscreen (struct vo *vo)
|
||||
else {
|
||||
MP_VERBOSE(wl, "leaving fullscreen\n");
|
||||
wl_shell_surface_set_toplevel(wl->window.shell_surface);
|
||||
resize_window(wl, 0, wl->window.p_width, wl->window.p_height);
|
||||
shedule_resize(wl, 0, wl->window.p_width, wl->window.p_height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -755,7 +797,6 @@ static int vo_wayland_check_events (struct vo *vo)
|
||||
{
|
||||
struct vo_wayland_state *wl = vo->wayland;
|
||||
struct wl_display *dp = wl->display.display;
|
||||
int ret;
|
||||
|
||||
wl_display_dispatch_pending(dp);
|
||||
wl_display_flush(dp);
|
||||
@ -780,10 +821,8 @@ static int vo_wayland_check_events (struct vo *vo)
|
||||
wl_display_flush(dp);
|
||||
}
|
||||
|
||||
ret = wl->window.events;
|
||||
wl->window.events = 0;
|
||||
|
||||
return ret;
|
||||
// window events are reset by the resizing code
|
||||
return wl->window.events;
|
||||
}
|
||||
|
||||
static void vo_wayland_update_screeninfo (struct vo *vo)
|
||||
|
@ -65,24 +65,17 @@ struct vo_wayland_state {
|
||||
struct {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t p_width; // previous sizes for leaving fullscreen
|
||||
int32_t p_width; // previous sizes for leaving fullscreen
|
||||
int32_t p_height;
|
||||
int32_t sh_width; // sheduled width for resizing
|
||||
int32_t sh_height;
|
||||
int32_t sh_x; // x, y calculated with the drag edges for moving
|
||||
int32_t sh_y;
|
||||
float aspect;
|
||||
|
||||
struct wl_surface *surface;
|
||||
struct wl_shell_surface *shell_surface;
|
||||
int events; /* mplayer events (VO_EVENT_RESIZE) */
|
||||
|
||||
/* Because the egl windows have a special resize windw function we have to
|
||||
* register it first before doing any resizing.
|
||||
* This makes us independet from the output driver */
|
||||
void (*resize_func) (struct vo_wayland_state *wl,
|
||||
uint32_t edges,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
void *user_data);
|
||||
|
||||
void *resize_func_data;
|
||||
} window;
|
||||
|
||||
struct {
|
||||
|
Loading…
Reference in New Issue
Block a user