1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
diff -up firefox-67.0/widget/gtk/mozcontainer.cpp.mozilla-1535567 firefox-67.0/widget/gtk/mozcontainer.cpp
--- firefox-67.0/widget/gtk/mozcontainer.cpp.mozilla-1535567 2019-05-14 01:08:37.000000000 +0200
+++ firefox-67.0/widget/gtk/mozcontainer.cpp 2019-05-15 15:56:19.645336209 +0200
@@ -157,6 +157,7 @@ void moz_container_init(MozContainer *co
container->subsurface = nullptr;
container->eglwindow = nullptr;
container->frame_callback_handler = nullptr;
+ container->frame_callback_handler_surface_id = -1;
// We can draw to x11 window any time.
container->ready_to_draw = GDK_IS_X11_DISPLAY(gdk_display_get_default());
container->surface_needs_clear = true;
@@ -165,6 +166,11 @@ void moz_container_init(MozContainer *co
}
#if defined(MOZ_WAYLAND)
+void moz_container_set_initial_draw_callback(
+ MozContainer *container, std::function<void(void)> inital_draw_cb) {
+ container->inital_draw_cb = inital_draw_cb;
+}
+
static wl_surface *moz_container_get_gtk_container_surface(
MozContainer *container) {
static auto sGdkWaylandWindowGetWlSurface = (wl_surface * (*)(GdkWindow *))
@@ -178,37 +184,61 @@ static void frame_callback_handler(void
uint32_t time) {
MozContainer *container = MOZ_CONTAINER(data);
g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
+ container->frame_callback_handler_surface_id = -1;
if (!container->ready_to_draw && container->inital_draw_cb) {
container->inital_draw_cb();
}
container->ready_to_draw = true;
}
-void moz_container_set_initial_draw_callback(
- MozContainer *container, std::function<void(void)> inital_draw_cb) {
- container->inital_draw_cb = inital_draw_cb;
-}
-
static const struct wl_callback_listener frame_listener = {
frame_callback_handler};
-static gboolean moz_container_map_wayland(GtkWidget *widget,
- GdkEventAny *event) {
- MozContainer *container = MOZ_CONTAINER(widget);
-
- if (container->ready_to_draw || container->frame_callback_handler) {
- return FALSE;
- }
-
+static void moz_container_request_parent_frame_callback(
+ MozContainer *container) {
wl_surface *gtk_container_surface =
moz_container_get_gtk_container_surface(container);
+ int gtk_container_surface_id =
+ gtk_container_surface
+ ? wl_proxy_get_id((struct wl_proxy *)gtk_container_surface)
+ : -1;
+
+ LOG(
+ ("%s [%p] frame_callback_handler %p "
+ "frame_callback_handler_surface_id %d\n",
+ __FUNCTION__, (void *)container, container->frame_callback_handler,
+ container->frame_callback_handler_surface_id));
+
+ if (container->frame_callback_handler &&
+ container->frame_callback_handler_surface_id ==
+ gtk_container_surface_id) {
+ return;
+ }
+
+ // If there's pending frame callback, delete it.
+ if (container->frame_callback_handler) {
+ g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
+ }
if (gtk_container_surface) {
+ container->frame_callback_handler_surface_id = gtk_container_surface_id;
container->frame_callback_handler = wl_surface_frame(gtk_container_surface);
wl_callback_add_listener(container->frame_callback_handler, &frame_listener,
container);
+ } else {
+ container->frame_callback_handler_surface_id = -1;
+ }
+}
+
+static gboolean moz_container_map_wayland(GtkWidget *widget,
+ GdkEventAny *event) {
+ MozContainer *container = MOZ_CONTAINER(widget);
+
+ if (container->ready_to_draw) {
+ return FALSE;
}
+ moz_container_request_parent_frame_callback(MOZ_CONTAINER(widget));
return FALSE;
}
@@ -217,6 +247,7 @@ static void moz_container_unmap_wayland(
g_clear_pointer(&container->subsurface, wl_subsurface_destroy);
g_clear_pointer(&container->surface, wl_surface_destroy);
g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy);
+ container->frame_callback_handler_surface_id = -1;
container->surface_needs_clear = true;
container->ready_to_draw = false;
@@ -329,6 +360,10 @@ void moz_container_realize(GtkWidget *wi
: gtk_widget_get_visual(widget);
window = gdk_window_new(parent, &attributes, attributes_mask);
+
+ LOG(("moz_container_realize() [%p] GdkWindow %p\n", (void *)container,
+ (void *)window));
+
gdk_window_set_user_data(window, widget);
} else {
window = parent;
@@ -498,6 +533,7 @@ static void moz_container_add(GtkContain
struct wl_surface *moz_container_get_wl_surface(MozContainer *container) {
if (!container->surface) {
if (!container->ready_to_draw) {
+ moz_container_request_parent_frame_callback(container);
return nullptr;
}
GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container));
diff -up firefox-67.0/widget/gtk/mozcontainer.h.mozilla-1535567 firefox-67.0/widget/gtk/mozcontainer.h
--- firefox-67.0/widget/gtk/mozcontainer.h.mozilla-1535567 2019-05-14 01:08:37.000000000 +0200
+++ firefox-67.0/widget/gtk/mozcontainer.h 2019-05-15 15:50:59.440570372 +0200
@@ -77,6 +77,7 @@ struct _MozContainer {
struct wl_subsurface *subsurface;
struct wl_egl_window *eglwindow;
struct wl_callback *frame_callback_handler;
+ int frame_callback_handler_surface_id;
gboolean surface_needs_clear;
gboolean ready_to_draw;
std::function<void(void)> inital_draw_cb;
|