[gtk+/wip/alexl/broadway4: 95/96] broadway: Roundtrip each update to rate limit redraw
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/alexl/broadway4: 95/96] broadway: Roundtrip each update to rate limit redraw
- Date: Thu, 23 Nov 2017 09:54:15 +0000 (UTC)
commit cfb76fedb641a58d41efa01edf20ca480029030a
Author: Alexander Larsson <alexl redhat com>
Date: Thu Nov 23 10:22:23 2017 +0100
broadway: Roundtrip each update to rate limit redraw
gdk/broadway/broadway-output.c | 10 ++++
gdk/broadway/broadway-output.h | 3 +
gdk/broadway/broadway-protocol.h | 20 +++++++-
gdk/broadway/broadway-server.c | 100 ++++++++++++++++++++++++++++++++++-
gdk/broadway/broadway-server.h | 3 +
gdk/broadway/broadway.js | 11 ++++
gdk/broadway/broadwayd.c | 7 +++
gdk/broadway/gdkbroadway-server.c | 16 +++++-
gdk/broadway/gdkbroadway-server.h | 3 +
gdk/broadway/gdkeventsource.c | 7 +++
gdk/broadway/gdkprivate-broadway.h | 5 +-
gdk/broadway/gdkwindow-broadway.c | 46 ++++++++++++----
12 files changed, 211 insertions(+), 20 deletions(-)
---
diff --git a/gdk/broadway/broadway-output.c b/gdk/broadway/broadway-output.c
index 193d68e..036f71b 100644
--- a/gdk/broadway/broadway-output.c
+++ b/gdk/broadway/broadway-output.c
@@ -238,6 +238,16 @@ broadway_output_destroy_surface(BroadwayOutput *output, int id)
}
void
+broadway_output_roundtrip (BroadwayOutput *output,
+ int id,
+ guint32 tag)
+{
+ write_header (output, BROADWAY_OP_ROUNDTRIP);
+ append_uint16 (output, id);
+ append_uint32 (output, tag);
+}
+
+void
broadway_output_set_show_keyboard (BroadwayOutput *output,
gboolean show)
{
diff --git a/gdk/broadway/broadway-output.h b/gdk/broadway/broadway-output.h
index 024df8e..bf35be2 100644
--- a/gdk/broadway/broadway-output.h
+++ b/gdk/broadway/broadway-output.h
@@ -42,6 +42,9 @@ void broadway_output_lower_surface (BroadwayOutput *output,
int id);
void broadway_output_destroy_surface (BroadwayOutput *output,
int id);
+void broadway_output_roundtrip (BroadwayOutput *output,
+ int id,
+ guint32 tag);
void broadway_output_move_resize_surface (BroadwayOutput *output,
int id,
gboolean has_pos,
diff --git a/gdk/broadway/broadway-protocol.h b/gdk/broadway/broadway-protocol.h
index 7e8a37c..41861ef 100644
--- a/gdk/broadway/broadway-protocol.h
+++ b/gdk/broadway/broadway-protocol.h
@@ -37,7 +37,8 @@ typedef enum {
BROADWAY_EVENT_CONFIGURE_NOTIFY = 'w',
BROADWAY_EVENT_DELETE_NOTIFY = 'W',
BROADWAY_EVENT_SCREEN_SIZE_CHANGED = 'd',
- BROADWAY_EVENT_FOCUS = 'f'
+ BROADWAY_EVENT_FOCUS = 'f',
+ BROADWAY_EVENT_ROUNDTRIP_NOTIFY = 'F',
} BroadwayEventType;
typedef enum {
@@ -60,6 +61,7 @@ typedef enum {
BROADWAY_OP_UPLOAD_TEXTURE = 't',
BROADWAY_OP_RELEASE_TEXTURE = 'T',
BROADWAY_OP_SET_NODES = 'n',
+ BROADWAY_OP_ROUNDTRIP = 'F',
} BroadwayOpType;
typedef struct {
@@ -130,6 +132,13 @@ typedef struct {
typedef struct {
BroadwayInputBaseMsg base;
+ gint32 id;
+ guint32 tag;
+ guint32 local;
+} BroadwayInputRoundtripNotify;
+
+typedef struct {
+ BroadwayInputBaseMsg base;
guint32 width;
guint32 height;
} BroadwayInputScreenResizeNotify;
@@ -155,6 +164,7 @@ typedef union {
BroadwayInputKeyMsg key;
BroadwayInputGrabReply grab_reply;
BroadwayInputConfigureNotify configure_notify;
+ BroadwayInputRoundtripNotify roundtrip_notify;
BroadwayInputDeleteNotify delete_notify;
BroadwayInputScreenResizeNotify screen_resize_notify;
BroadwayInputFocusMsg focus;
@@ -177,6 +187,7 @@ typedef enum {
BROADWAY_REQUEST_UPLOAD_TEXTURE,
BROADWAY_REQUEST_RELEASE_TEXTURE,
BROADWAY_REQUEST_SET_NODES,
+ BROADWAY_REQUEST_ROUNDTRIP,
} BroadwayRequestType;
typedef struct {
@@ -193,6 +204,12 @@ typedef struct {
typedef struct {
BroadwayRequestBase base;
guint32 id;
+ guint32 tag;
+} BroadwayRequestRoundtrip;
+
+typedef struct {
+ BroadwayRequestBase base;
+ guint32 id;
guint32 parent;
} BroadwayRequestSetTransientFor;
@@ -257,6 +274,7 @@ typedef union {
BroadwayRequestNewWindow new_window;
BroadwayRequestFlush flush;
BroadwayRequestSync sync;
+ BroadwayRequestRoundtrip roundtrip;
BroadwayRequestQueryMouse query_mouse;
BroadwayRequestDestroyWindow destroy_window;
BroadwayRequestShowWindow show_window;
diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c
index 859fa68..3f9dfeb 100644
--- a/gdk/broadway/broadway-server.c
+++ b/gdk/broadway/broadway-server.c
@@ -35,6 +35,12 @@
#include <string.h>
#endif
+
+typedef struct {
+ int id;
+ guint32 tag;
+} BroadwayOutstandingRoundtrip;
+
typedef struct BroadwayInput BroadwayInput;
typedef struct BroadwayWindow BroadwayWindow;
struct _BroadwayServer {
@@ -81,6 +87,8 @@ struct _BroadwayServer {
int future_root_y;
guint32 future_state;
int future_mouse_in_toplevel;
+
+ GList *outstanding_roundtrips;
};
struct _BroadwayServerClass
@@ -122,6 +130,7 @@ struct BroadwayWindow {
};
static void broadway_server_resync_windows (BroadwayServer *server);
+static void send_outstanding_roundtrips (BroadwayServer *server);
static GType broadway_server_get_type (void);
@@ -288,6 +297,8 @@ update_event_state (BroadwayServer *server,
window->y = message->configure_notify.y;
}
break;
+ case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
+ break;
case BROADWAY_EVENT_DELETE_NOTIFY:
break;
case BROADWAY_EVENT_SCREEN_SIZE_CHANGED:
@@ -430,12 +441,19 @@ update_future_pointer_info (BroadwayServer *server, BroadwayInputPointerMsg *dat
}
static void
+queue_input_message (BroadwayServer *server, BroadwayInputMsg *msg)
+{
+ server->input_messages = g_list_append (server->input_messages, g_memdup (msg, sizeof (BroadwayInputMsg)));
+}
+
+static void
parse_input_message (BroadwayInput *input, const unsigned char *message)
{
BroadwayServer *server = input->server;
BroadwayInputMsg msg;
guint32 *p;
gint64 time_;
+ GList *l;
memset (&msg, 0, sizeof (msg));
@@ -512,6 +530,26 @@ parse_input_message (BroadwayInput *input, const unsigned char *message)
msg.configure_notify.height = ntohl (*p++);
break;
+ case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
+ msg.roundtrip_notify.id = ntohl (*p++);
+ msg.roundtrip_notify.tag = ntohl (*p++);
+ msg.roundtrip_notify.local = FALSE;
+
+ /* Remove matched outstanding roundtrips */
+ for (l = server->outstanding_roundtrips; l != NULL; l = l->next)
+ {
+ BroadwayOutstandingRoundtrip *rt = l->data;
+
+ if (rt->id == msg.roundtrip_notify.id &&
+ rt->tag == msg.roundtrip_notify.tag)
+ {
+ server->outstanding_roundtrips = g_list_delete_link (server->outstanding_roundtrips, l);
+ g_free (rt);
+ break;
+ }
+ }
+ break;
+
case BROADWAY_EVENT_DELETE_NOTIFY:
msg.delete_notify.id = ntohl (*p++);
break;
@@ -526,8 +564,7 @@ parse_input_message (BroadwayInput *input, const unsigned char *message)
break;
}
- server->input_messages = g_list_append (server->input_messages, g_memdup (&msg, sizeof (msg)));
-
+ queue_input_message (server, &msg);
}
static inline void
@@ -697,7 +734,11 @@ broadway_server_read_all_input_nonblocking (BroadwayInput *input)
}
if (input->server->input == input)
- input->server->input = NULL;
+ {
+ send_outstanding_roundtrips (input->server);
+
+ input->server->input = NULL;
+ }
broadway_input_free (input);
if (res < 0)
{
@@ -758,6 +799,23 @@ broadway_server_get_screen_size (BroadwayServer *server,
*height = server->root->height;
}
+static void
+broadway_server_fake_roundtrip_reply (BroadwayServer *server,
+ gint id,
+ guint32 tag)
+{
+ BroadwayInputMsg msg;
+
+ msg.base.type = BROADWAY_EVENT_ROUNDTRIP_NOTIFY;
+ msg.base.serial = 0;
+ msg.base.time = server->last_seen_time;
+ msg.roundtrip_notify.id = id;
+ msg.roundtrip_notify.tag = tag;
+ msg.roundtrip_notify.local = 1;
+
+ queue_input_message (server, &msg);
+ queue_process_input_at_idle (server);
+}
void
broadway_server_flush (BroadwayServer *server)
@@ -768,9 +826,28 @@ broadway_server_flush (BroadwayServer *server)
server->saved_serial = broadway_output_get_next_serial (server->output);
broadway_output_free (server->output);
server->output = NULL;
+ send_outstanding_roundtrips (server);
}
}
+void
+broadway_server_roundtrip (BroadwayServer *server,
+ gint id,
+ guint32 tag)
+{
+ if (server->output)
+ {
+ BroadwayOutstandingRoundtrip *rt = g_new0 (BroadwayOutstandingRoundtrip, 1);
+ rt->id = id;
+ rt->tag = tag;
+ server->outstanding_roundtrips = g_list_prepend (server->outstanding_roundtrips, rt);
+
+ broadway_output_roundtrip (server->output, id, tag);
+ }
+ else
+ broadway_server_fake_roundtrip_reply (server, id, tag);
+}
+
#if 0
/* TODO: This is not used atm, is it needed? */
/* Note: This may be called while handling a message (i.e. sorta recursively) */
@@ -1001,6 +1078,21 @@ start_input (HttpRequest *request)
}
static void
+send_outstanding_roundtrips (BroadwayServer *server)
+{
+ GList *l;
+
+ for (l = server->outstanding_roundtrips; l != NULL; l = l->next)
+ {
+ BroadwayOutstandingRoundtrip *rt = l->data;
+ broadway_server_fake_roundtrip_reply (server, rt->id, rt->tag);
+ }
+
+ g_list_free_full (server->outstanding_roundtrips, g_free);
+ server->outstanding_roundtrips = NULL;
+}
+
+static void
start (BroadwayInput *input)
{
BroadwayServer *server;
@@ -1011,12 +1103,14 @@ start (BroadwayInput *input)
if (server->output)
{
+ send_outstanding_roundtrips (server);
broadway_output_disconnected (server->output);
broadway_output_flush (server->output);
}
if (server->input != NULL)
{
+ send_outstanding_roundtrips (server);
broadway_input_free (server->input);
server->input = NULL;
}
diff --git a/gdk/broadway/broadway-server.h b/gdk/broadway/broadway-server.h
index 4bc81a7..d120261 100644
--- a/gdk/broadway/broadway-server.h
+++ b/gdk/broadway/broadway-server.h
@@ -29,6 +29,9 @@ BroadwayServer *broadway_server_on_unix_socket_new (char *
gboolean broadway_server_has_client (BroadwayServer *server);
void broadway_server_flush (BroadwayServer *server);
void broadway_server_sync (BroadwayServer *server);
+void broadway_server_roundtrip (BroadwayServer *server,
+ gint id,
+ guint32 tag);
void broadway_server_get_screen_size (BroadwayServer *server,
guint32 *width,
guint32 *height);
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index 9f9ca23..acbd80d 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -245,6 +245,11 @@ function cmdDeleteSurface(id)
delete surfaces[id];
}
+function cmdRoundtrip(id, tag)
+{
+ sendInput("F", [id, tag]);
+}
+
function cmdMoveResizeSurface(id, has_pos, x, y, has_size, w, h)
{
var surface = surfaces[id];
@@ -737,6 +742,12 @@ function handleCommands(cmd)
cmdDeleteSurface(id);
break;
+ case 'F': // RoundTrip
+ id = cmd.get_16();
+ var tag = cmd.get_32();
+ cmdRoundtrip(id, tag);
+ break;
+
case 'm': // Move a surface
id = cmd.get_16();
var ops = cmd.get_flags();
diff --git a/gdk/broadway/broadwayd.c b/gdk/broadway/broadwayd.c
index 50d71f5..638b7f9 100644
--- a/gdk/broadway/broadwayd.c
+++ b/gdk/broadway/broadwayd.c
@@ -325,6 +325,11 @@ client_handle_request (BroadwayClient *client,
send_reply (client, request, (BroadwayReply *)&reply_sync, sizeof (reply_sync),
BROADWAY_REPLY_SYNC);
break;
+ case BROADWAY_REQUEST_ROUNDTRIP:
+ broadway_server_roundtrip (server,
+ request->roundtrip.id,
+ request->roundtrip.tag);
+ break;
case BROADWAY_REQUEST_QUERY_MOUSE:
broadway_server_query_mouse (server,
&reply_query_mouse.toplevel,
@@ -728,6 +733,8 @@ get_event_size (int type)
return sizeof (BroadwayInputGrabReply);
case BROADWAY_EVENT_CONFIGURE_NOTIFY:
return sizeof (BroadwayInputConfigureNotify);
+ case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
+ return sizeof (BroadwayInputRoundtripNotify);
case BROADWAY_EVENT_DELETE_NOTIFY:
return sizeof (BroadwayInputDeleteNotify);
case BROADWAY_EVENT_SCREEN_SIZE_CHANGED:
diff --git a/gdk/broadway/gdkbroadway-server.c b/gdk/broadway/gdkbroadway-server.c
index 28959a7..fa24e08 100644
--- a/gdk/broadway/gdkbroadway-server.c
+++ b/gdk/broadway/gdkbroadway-server.c
@@ -48,7 +48,6 @@ struct _GdkBroadwayServer {
guint process_input_idle;
GList *incomming;
-
};
struct _GdkBroadwayServerClass
@@ -422,7 +421,7 @@ _gdk_broadway_server_sync (GdkBroadwayServer *server)
BroadwayReply *reply;
serial = gdk_broadway_server_send_message (server, msg,
- BROADWAY_REQUEST_SYNC);
+ BROADWAY_REQUEST_SYNC);
reply = gdk_broadway_server_wait_for_reply (server, serial);
g_assert (reply->base.type == BROADWAY_REPLY_SYNC);
@@ -433,6 +432,19 @@ _gdk_broadway_server_sync (GdkBroadwayServer *server)
}
void
+_gdk_broadway_server_roundtrip (GdkBroadwayServer *server,
+ gint32 id,
+ guint32 tag)
+{
+ BroadwayRequestRoundtrip msg;
+
+ msg.id = id;
+ msg.tag = tag;
+ gdk_broadway_server_send_message (server, msg,
+ BROADWAY_REQUEST_ROUNDTRIP);
+}
+
+void
_gdk_broadway_server_query_mouse (GdkBroadwayServer *server,
guint32 *toplevel,
gint32 *root_x,
diff --git a/gdk/broadway/gdkbroadway-server.h b/gdk/broadway/gdkbroadway-server.h
index 8ff26eb..aec5669 100644
--- a/gdk/broadway/gdkbroadway-server.h
+++ b/gdk/broadway/gdkbroadway-server.h
@@ -18,6 +18,9 @@ GdkBroadwayServer *_gdk_broadway_server_new (const char
GError **error);
void _gdk_broadway_server_flush (GdkBroadwayServer *server);
void _gdk_broadway_server_sync (GdkBroadwayServer *server);
+void _gdk_broadway_server_roundtrip (GdkBroadwayServer *server,
+ gint32 id,
+ guint32 tag);
gulong _gdk_broadway_server_get_next_serial (GdkBroadwayServer *server);
guint32 _gdk_broadway_server_get_last_seen_time (GdkBroadwayServer *server);
gboolean _gdk_broadway_server_lookahead_event (GdkBroadwayServer *server,
diff --git a/gdk/broadway/gdkeventsource.c b/gdk/broadway/gdkeventsource.c
index 0935cc9..2f51212 100644
--- a/gdk/broadway/gdkeventsource.c
+++ b/gdk/broadway/gdkeventsource.c
@@ -21,6 +21,7 @@
#include "gdkdevicemanager-broadway.h"
#include "gdkinternals.h"
+#include "gdkframeclockprivate.h"
#include <stdlib.h>
@@ -336,6 +337,12 @@ _gdk_broadway_events_got_input (BroadwayInputMsg *message)
}
break;
+ case BROADWAY_EVENT_ROUNDTRIP_NOTIFY:
+ window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->roundtrip_notify.id));
+ if (window)
+ _gdk_broadway_roundtrip_notify (window, message->roundtrip_notify.tag,
message->roundtrip_notify.local);
+ break;
+
case BROADWAY_EVENT_DELETE_NOTIFY:
window = g_hash_table_lookup (display_broadway->id_ht, GINT_TO_POINTER (message->delete_notify.id));
if (window)
diff --git a/gdk/broadway/gdkprivate-broadway.h b/gdk/broadway/gdkprivate-broadway.h
index 146ff37..3d8faaa 100644
--- a/gdk/broadway/gdkprivate-broadway.h
+++ b/gdk/broadway/gdkprivate-broadway.h
@@ -79,8 +79,9 @@ gboolean _gdk_broadway_moveresize_handle_event (GdkDisplay *display,
BroadwayInputMsg *msg);
gboolean _gdk_broadway_moveresize_configure_done (GdkDisplay *display,
GdkWindow *window);
-
-
+void _gdk_broadway_roundtrip_notify (GdkWindow *window,
+ guint32 tag,
+ gboolean local_reply);
void _gdk_broadway_selection_window_destroyed (GdkWindow *window);
void _gdk_broadway_window_grab_check_destroy (GdkWindow *window);
void _gdk_broadway_window_grab_check_unmap (GdkWindow *window,
diff --git a/gdk/broadway/gdkwindow-broadway.c b/gdk/broadway/gdkwindow-broadway.c
index 4b71b45..9eb8173 100644
--- a/gdk/broadway/gdkwindow-broadway.c
+++ b/gdk/broadway/gdkwindow-broadway.c
@@ -37,6 +37,7 @@
#include "gdkdeviceprivate.h"
#include "gdkeventsource.h"
#include <gdk/gdktextureprivate.h>
+#include <gdk/gdkframeclockprivate.h>
#include <stdlib.h>
#include <stdio.h>
@@ -96,17 +97,6 @@ find_broadway_display (void)
return display;
}
-static void
-update_dirty_windows_and_sync (void)
-{
- GdkBroadwayDisplay *display;
-
- display = GDK_BROADWAY_DISPLAY (find_broadway_display ());
- g_assert (display != NULL);
-
- gdk_display_flush (GDK_DISPLAY (display));
-}
-
static guint flush_id = 0;
static gboolean
@@ -165,11 +155,43 @@ gdk_window_impl_broadway_finalize (GObject *object)
G_OBJECT_CLASS (gdk_window_impl_broadway_parent_class)->finalize (object);
}
+static gboolean
+thaw_clock_cb (GdkFrameClock *clock)
+{
+ _gdk_frame_clock_thaw (clock);
+ g_object_unref (clock);
+ return G_SOURCE_REMOVE;
+}
+
+void
+_gdk_broadway_roundtrip_notify (GdkWindow *window,
+ guint32 tag,
+ gboolean local_reply)
+{
+ GdkFrameClock *clock = gdk_window_get_frame_clock (window);
+
+ /* If there is no remove web client, rate limit update to once a second */
+ if (local_reply)
+ g_timeout_add_seconds (1, (GSourceFunc)thaw_clock_cb, g_object_ref (clock));
+ else
+ _gdk_frame_clock_thaw (clock);
+}
+
static void
on_frame_clock_after_paint (GdkFrameClock *clock,
GdkWindow *window)
{
- update_dirty_windows_and_sync ();
+ GdkDisplay *display = gdk_window_get_display (window);
+ GdkWindowImplBroadway *impl = GDK_WINDOW_IMPL_BROADWAY (window->impl);
+ GdkBroadwayDisplay *broadway_display;
+
+ _gdk_frame_clock_freeze (gdk_window_get_frame_clock (window));
+
+ broadway_display = GDK_BROADWAY_DISPLAY (display);
+
+ _gdk_broadway_server_roundtrip (broadway_display->server, impl->id, _gdk_display_get_next_serial
(display));
+
+ gdk_display_flush (display);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]