190 lines
7.0 KiB
Diff
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;
|
|
|
|
|