summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Preisinger <alexander.preisinger@gmail.com>2014-08-18 22:00:39 +0200
committerAlexander Preisinger <alexander.preisinger@gmail.com>2014-08-18 22:00:39 +0200
commit752dce9284e7af0b1c791220433a4157dfff20b5 (patch)
tree65f4d3f42b98ec8acaddc33063cd0c77df2edb4d
parent39b8b0a41f6b8aae0eec86d5e59bae3609bd7a1f (diff)
downloadmpv-752dce9284e7af0b1c791220433a4157dfff20b5.tar.bz2
mpv-752dce9284e7af0b1c791220433a4157dfff20b5.tar.xz
wayland: dynamically report display fps
Only reports the most recently entered output if the window is displayed on 2 or more outputs. Should be changed to the lowest fps of all outputs the window is visible. Until no one complains this will have to wait. Look for the VO framedropping for more information on this topic.
-rw-r--r--video/out/wayland_common.c78
-rw-r--r--video/out/wayland_common.h3
2 files changed, 60 insertions, 21 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 36c6fc0d4b..4af9f46929 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -183,6 +183,7 @@ static void output_handle_mode(void *data,
output->width = width;
output->height = height;
output->flags = flags;
+ output->refresh_rate = refresh;
}
static const struct wl_output_listener output_listener = {
@@ -190,6 +191,40 @@ static const struct wl_output_listener output_listener = {
output_handle_mode
};
+
+/* SURFACE LISTENER */
+
+static void surface_handle_enter(void *data,
+ struct wl_surface *wl_surface,
+ struct wl_output *output)
+{
+ struct vo_wayland_state *wl = data;
+ wl->display.current_output = NULL;
+
+ struct vo_wayland_output *o;
+ wl_list_for_each(o, &wl->display.output_list, link) {
+ if (o->output == output) {
+ wl->display.current_output = o;
+ break;
+ }
+ }
+}
+
+static void surface_handle_leave(void *data,
+ struct wl_surface *wl_surface,
+ struct wl_output *output)
+{
+ // window can be displayed at 2 output, but we only use the most recently
+ // entered and discard the previous one even if a part of the window is
+ // still visible on the previous entered output.
+ // Don't bother with a "leave" logic
+}
+
+static const struct wl_surface_listener surface_listener = {
+ surface_handle_enter,
+ surface_handle_leave
+};
+
/* KEYBOARD LISTENER */
static void keyboard_handle_keymap(void *data,
struct wl_keyboard *wl_keyboard,
@@ -738,7 +773,7 @@ static bool create_display (struct vo_wayland_state *wl)
wl->display.registry = wl_display_get_registry(wl->display.display);
wl_registry_add_listener(wl->display.registry, &registry_listener, wl);
- wl_display_dispatch(wl->display.display);
+ wl_display_roundtrip(wl->display.display);
wl->display.display_fd = wl_display_get_fd(wl->display.display);
@@ -784,6 +819,9 @@ static bool create_window (struct vo_wayland_state *wl)
wl->window.video_surface =
wl_compositor_create_surface(wl->display.compositor);
+ wl_surface_add_listener(wl->window.video_surface,
+ &surface_listener, wl);
+
if (wl->display.shell) {
wl->window.shell_surface = wl_shell_get_shell_surface(wl->display.shell,
wl->window.video_surface);
@@ -1047,7 +1085,6 @@ static void vo_wayland_update_screeninfo(struct vo *vo, struct mp_rect *screenrc
{
struct vo_wayland_state *wl = vo->wayland;
struct mp_vo_opts *opts = vo->opts;
- bool mode_received = false;
wl_display_roundtrip(wl->display.display);
@@ -1059,24 +1096,16 @@ static void vo_wayland_update_screeninfo(struct vo *vo, struct mp_rect *screenrc
struct vo_wayland_output *first_output = NULL;
struct vo_wayland_output *fsscreen_output = NULL;
- wl_list_for_each_reverse(output, &wl->display.output_list, link) {
- if (!output || !output->width)
- continue;
-
- mode_received = true;
+ if (opts->fsscreen_id >= 0) {
+ wl_list_for_each_reverse(output, &wl->display.output_list, link) {
+ if (!output || !output->width)
+ continue;
- if (opts->fsscreen_id == screen_id)
- fsscreen_output = output;
-
- if (!first_output)
- first_output = output;
-
- screen_id++;
- }
+ if (opts->fsscreen_id == screen_id)
+ fsscreen_output = output;
- if (!mode_received) {
- MP_ERR(wl, "no output mode detected\n");
- return;
+ screen_id++;
+ }
}
if (fsscreen_output) {
@@ -1088,8 +1117,8 @@ static void vo_wayland_update_screeninfo(struct vo *vo, struct mp_rect *screenrc
wl->display.fs_output = NULL; /* current output is always 0 */
if (first_output) {
- screenrc->x1 = first_output->width;
- screenrc->y1 = first_output->height;
+ screenrc->x1 = wl->display.current_output->width;
+ screenrc->y1 = wl->display.current_output->height;
}
}
@@ -1138,6 +1167,15 @@ int vo_wayland_control (struct vo *vo, int *events, int request, void *arg)
case VOCTRL_UPDATE_WINDOW_TITLE:
window_set_title(wl, (char*) arg);
return VO_TRUE;
+ case VOCTRL_GET_DISPLAY_FPS: {
+ if (!wl->display.current_output)
+ break;
+
+ // refresh rate is stored in milli-Hertz (mHz)
+ double fps = wl->display.current_output->refresh_rate / 1000;
+ *(double*) arg = fps;
+ return VO_TRUE;
+ }
}
return VO_NOTIMPL;
}
diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h
index dc446bc6f3..5702372731 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -41,6 +41,7 @@ struct vo_wayland_output {
uint32_t flags;
int32_t width;
int32_t height;
+ int32_t refresh_rate; // fps (mHz)
struct wl_list link;
};
@@ -72,7 +73,7 @@ struct vo_wayland_state {
struct wl_list output_list;
struct wl_output *fs_output; /* fullscreen output */
- int output_mode_received;
+ struct vo_wayland_output *current_output;
int display_fd;