diff options
Diffstat (limited to 'mozilla-1587008.patch')
-rw-r--r-- | mozilla-1587008.patch | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/mozilla-1587008.patch b/mozilla-1587008.patch new file mode 100644 index 0000000..8daf72e --- /dev/null +++ b/mozilla-1587008.patch @@ -0,0 +1,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; + + |