summaryrefslogtreecommitdiff
path: root/mozilla-1587008.patch
blob: 8daf72edf1aae5862cf8eb6639d8da392f19e06a (plain)
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
changeset:   498019:9961a0e4d424
tag:         tip
parent:      498006:3fa65bda1e50
user:        Martin Stransky <stransky@redhat.com>
date:        Tue Oct 08 13:32:37 2019 +0200
files:       widget/gtk/mozcontainer.cpp
description:
Bug 1587008 - [Wayland/GL] Fixed visual glitches with gl compositor during window resize, r=jhorak

Recently we update egl_window size only in moz_container_size_allocate() which is leads
to visible visual glitches as moz_container_size_allocate() is not called during window resize but
after it.

We need to update egl_window size faster which is done in configure-event callback.

Differential Revision: https://phabricator.services.mozilla.com/D48526


diff --git a/widget/gtk/mozcontainer.cpp b/widget/gtk/mozcontainer.cpp
--- a/widget/gtk/mozcontainer.cpp
+++ b/widget/gtk/mozcontainer.cpp
@@ -136,16 +136,60 @@ void moz_container_put(MozContainer* con
   container->children = g_list_append(container->children, child);
 
   /* we assume that the caller of this function will have already set
      the parent GdkWindow because we can have many anonymous children. */
   gtk_widget_set_parent(child_widget, GTK_WIDGET(container));
 }
 
 /* static methods */
+#if defined(MOZ_WAYLAND)
+static gint moz_container_get_scale(MozContainer* container) {
+  static auto sGdkWindowGetScaleFactorPtr =
+      (gint(*)(GdkWindow*))dlsym(RTLD_DEFAULT, "gdk_window_get_scale_factor");
+
+  if (sGdkWindowGetScaleFactorPtr) {
+    GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
+    return (*sGdkWindowGetScaleFactorPtr)(window);
+  }
+
+  return 1;
+}
+
+static void moz_container_resize(MozContainer* container, int width,
+                                 int height) {
+  // Set correct scaled/unscaled mozcontainer offset
+  // especially when wl_egl is used but we don't recreate it as Gtk+ does.
+  if (container->subsurface) {
+    gint x, y;
+    gdk_window_get_position(gtk_widget_get_window(GTK_WIDGET(container)), &x,
+                            &y);
+    wl_subsurface_set_position(container->subsurface, x, y);
+  }
+
+  // Try to only resize wl_egl_window on scale factor change.
+  // It's a bit risky as Gtk+ recreates it at that event.
+  if (container->eglwindow) {
+    gint scale = moz_container_get_scale(container);
+    if (container->surface) {
+      wl_surface_set_buffer_scale(container->surface, scale);
+    }
+    wl_egl_window_resize(container->eglwindow, width * scale, height * scale, 0,
+                         0);
+  }
+}
+
+static gboolean moz_container_configure_event_cb(GtkWidget* widget,
+                                                 GdkEventConfigure* event) {
+  LOG(("moz_container_egl_window_configure_event_cb [%p] %d %d %d %d\n",
+       (void*)widget, event->x, event->y, event->width, event->height));
+  moz_container_resize(MOZ_CONTAINER(widget), event->width, event->height);
+  return FALSE;
+}
+#endif
 
 void moz_container_class_init(MozContainerClass* klass) {
   /*GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); */
   GtkContainerClass* container_class = GTK_CONTAINER_CLASS(klass);
   GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(klass);
 
   widget_class->map = moz_container_map;
@@ -173,16 +217,21 @@ 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;
   container->inital_draw_cb = nullptr;
+
+  // We need faster resize response in mozcontainer to avoid visual glitches
+  // during window resize.
+  g_signal_connect(container, "configure_event",
+                   G_CALLBACK(moz_container_configure_event_cb), nullptr);
 #endif
 
   LOG(("%s [%p]\n", __FUNCTION__, (void*)container));
 }
 
 #if defined(MOZ_WAYLAND)
 void moz_container_set_initial_draw_callback(
     MozContainer* container, std::function<void(void)> inital_draw_cb) {
@@ -285,53 +334,26 @@ static void moz_container_unmap_wayland(
   container->frame_callback_handler_surface_id = -1;
 
   container->surface_needs_clear = true;
   container->ready_to_draw = false;
 
   LOGWAYLAND(("%s [%p]\n", __FUNCTION__, (void*)container));
 }
 
-static gint moz_container_get_scale(MozContainer* container) {
-  static auto sGdkWindowGetScaleFactorPtr =
-      (gint(*)(GdkWindow*))dlsym(RTLD_DEFAULT, "gdk_window_get_scale_factor");
-
-  if (sGdkWindowGetScaleFactorPtr) {
-    GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(container));
-    return (*sGdkWindowGetScaleFactorPtr)(window);
-  }
-
-  return 1;
-}
-
 void moz_container_scale_changed(MozContainer* container,
                                  GtkAllocation* aAllocation) {
   LOGWAYLAND(("%s [%p] surface %p eglwindow %p\n", __FUNCTION__,
               (void*)container, (void*)container->surface,
               (void*)container->eglwindow));
 
   if (!container->surface) {
     return;
   }
-
-  // Set correct scaled/unscaled mozcontainer offset
-  // especially when wl_egl is used but we don't recreate it as Gtk+ does.
-  gint x, y;
-  gdk_window_get_position(gtk_widget_get_window(GTK_WIDGET(container)), &x, &y);
-  wl_subsurface_set_position(container->subsurface, x, y);
-
-  // Try to only resize wl_egl_window on scale factor change.
-  // It's a bit risky as Gtk+ recreates it at that event.
-  if (container->eglwindow) {
-    gint scale = moz_container_get_scale(container);
-    wl_surface_set_buffer_scale(container->surface,
-                                moz_container_get_scale(container));
-    wl_egl_window_resize(container->eglwindow, aAllocation->width * scale,
-                         aAllocation->height * scale, 0, 0);
-  }
+  moz_container_resize(container, aAllocation->width, aAllocation->height);
 }
 #endif
 
 void moz_container_map(GtkWidget* widget) {
   MozContainer* container;
   GList* tmp_list;
   GtkWidget* tmp_child;
 
@@ -451,26 +473,18 @@ void moz_container_size_allocate(GtkWidg
                            allocation->y, allocation->width,
                            allocation->height);
   }
 
 #if defined(MOZ_WAYLAND)
   // We need to position our subsurface according to GdkWindow
   // when offset changes (GdkWindow is maximized for instance).
   // see gtk-clutter-embed.c for reference.
-  if (container->subsurface) {
-    gint x, y;
-    gdk_window_get_position(gtk_widget_get_window(widget), &x, &y);
-    wl_subsurface_set_position(container->subsurface, x, y);
-  }
-  if (container->eglwindow) {
-    gint scale = moz_container_get_scale(container);
-    wl_egl_window_resize(container->eglwindow, allocation->width * scale,
-                         allocation->height * scale, 0, 0);
-  }
+  moz_container_resize(MOZ_CONTAINER(widget), allocation->width,
+                       allocation->height);
 #endif
 }
 
 void moz_container_remove(GtkContainer* container, GtkWidget* child_widget) {
   MozContainerChild* child;
   MozContainer* moz_container;
   GdkWindow* parent_window;
 

bgstack15