firefox/mozilla-1587008.patch

190 lines
7.0 KiB
Diff

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;