mtasaka / rpms / firefox

Forked from rpms/firefox 4 years ago
Clone
Blob Blame History Raw
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;