Bug 1587008 - [Wayland] Get wl_egl_window size from compositor by nsWindow::SetEGLNativeWindowSize, r=jhorak

We can't set wl_egl_window from widget code as it must match GL rendering pipeline,
so let compositor to set the egl window size.

Depends on D49136

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Martin Stransky 2019-10-15 19:25:47 +00:00
parent 5a403b0cdd
commit 0595546bfc
4 changed files with 79 additions and 51 deletions

View File

@ -141,6 +141,43 @@ void moz_container_put(MozContainer* container, GtkWidget* child_widget, gint x,
}
/* 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;
}
void moz_container_move(MozContainer* container, int dx, int dy) {
if (container->subsurface) {
wl_subsurface_set_position(container->subsurface, dx, dy);
}
}
void moz_container_scale_update(MozContainer* container) {
if (container->surface) {
gint scale = moz_container_get_scale(container);
wl_surface_set_buffer_scale(container->surface, scale);
}
}
// This is called from layout/compositor code only with
// size equal to GL rendering context. Otherwise there are
// rendering artifacts as wl_egl_window size does not match
// GL rendering pipeline setup.
void moz_container_egl_window_set_size(MozContainer* container, int width,
int height) {
if (container->eglwindow) {
wl_egl_window_resize(container->eglwindow, width, height, 0, 0);
}
}
#endif
void moz_container_class_init(MozContainerClass* klass) {
/*GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@ -290,43 +327,17 @@ static void moz_container_unmap_wayland(MozContainer* container) {
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));
LOG(("moz_container_scale_changed [%p] surface %p eglwindow %p\n",
(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_scale_update(container);
}
#endif
@ -421,8 +432,8 @@ void moz_container_size_allocate(GtkWidget* widget, GtkAllocation* allocation) {
g_return_if_fail(IS_MOZ_CONTAINER(widget));
LOG(("%s [%p] %d %d %d %d\n", __FUNCTION__, (void*)widget, allocation->x,
allocation->y, allocation->width, allocation->height));
LOG(("moz_container_size_allocate [%p] %d,%d -> %d x %d\n", (void*)widget,
allocation->x, allocation->y, allocation->width, allocation->height));
/* short circuit if you can */
container = MOZ_CONTAINER(widget);
@ -450,23 +461,14 @@ void moz_container_size_allocate(GtkWidget* widget, GtkAllocation* allocation) {
gdk_window_move_resize(gtk_widget_get_window(widget), allocation->x,
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);
}
// We need to position our subsurface according to GdkWindow
// when offset changes (GdkWindow is maximized for instance).
// see gtk-clutter-embed.c for reference.
moz_container_move(MOZ_CONTAINER(widget), allocation->x, allocation->y);
moz_container_scale_update(MOZ_CONTAINER(widget));
#endif
}
}
void moz_container_remove(GtkContainer* container, GtkWidget* child_widget) {

View File

@ -105,6 +105,10 @@ void moz_container_scale_changed(MozContainer* container,
GtkAllocation* aAllocation);
void moz_container_set_initial_draw_callback(
MozContainer* container, std::function<void(void)> inital_draw_cb);
void moz_container_move_resize(MozContainer* container, int dx, int dy,
int width, int height);
void moz_container_egl_window_set_size(MozContainer* container, int width,
int height);
#endif
#endif /* __MOZ_CONTAINER_H__ */

View File

@ -1088,6 +1088,9 @@ void nsWindow::Resize(double aWidth, double aHeight, bool aRepaint) {
void nsWindow::Resize(double aX, double aY, double aWidth, double aHeight,
bool aRepaint) {
LOG(("nsWindow::Resize [%p] %f %f repaint %d\n", (void*)this, aWidth, aHeight,
aRepaint));
double scale =
BoundsUseDesktopPixels() ? GetDesktopToDeviceScale().scale : 1.0;
int32_t width = NSToIntRound(scale * aWidth);
@ -1644,8 +1647,12 @@ LayoutDeviceIntRect nsWindow::GetScreenBounds() {
// frame bounds, but mBounds.Size() is returned here for consistency
// with Resize.
rect.SizeTo(mBounds.Size());
LOG(("GetScreenBounds %d,%d | %dx%d\n", rect.x, rect.y, rect.width,
rect.height));
#if MOZ_LOGGING
gint scale = GdkScaleFactor();
LOG(("GetScreenBounds %d,%d -> %d x %d, unscaled %d,%d -> %d x %d\n", rect.x,
rect.y, rect.width, rect.height, rect.x / scale, rect.y / scale,
rect.width / scale, rect.height / scale));
#endif
return rect;
}
@ -2511,8 +2518,9 @@ void nsWindow::OnContainerUnrealize() {
}
void nsWindow::OnSizeAllocate(GtkAllocation* aAllocation) {
LOG(("size_allocate [%p] %d %d %d %d\n", (void*)this, aAllocation->x,
aAllocation->y, aAllocation->width, aAllocation->height));
LOG(("nsWindow::OnSizeAllocate [%p] %d,%d -> %d x %d\n", (void*)this,
aAllocation->x, aAllocation->y, aAllocation->width,
aAllocation->height));
LayoutDeviceIntSize size = GdkRectToDevicePixels(*aAllocation).Size();
@ -7370,3 +7378,13 @@ void nsWindow::LockAspectRatio(bool aShouldLock) {
(void*)this));
}
}
#ifdef MOZ_WAYLAND
void nsWindow::SetEGLNativeWindowSize(
const LayoutDeviceIntSize& aEGLWindowSize) {
if (mContainer && !mIsX11Display) {
moz_container_egl_window_set_size(mContainer, aEGLWindowSize.width,
aEGLWindowSize.height);
}
}
#endif

View File

@ -226,6 +226,10 @@ class nsWindow final : public nsBaseWidget {
void SetProgress(unsigned long progressPercent);
#ifdef MOZ_WAYLAND
void SetEGLNativeWindowSize(const LayoutDeviceIntSize& aEGLWindowSize);
#endif
private:
void UpdateAlpha(mozilla::gfx::SourceSurface* aSourceSurface,
nsIntRect aBoundsRect);