Bug 1460605 - Provide NS_NATIVE_EGL_WINDOW to get a native EGL window on Wayland, r=jhorak

Original patch author is Takuro Ashie <ashie@clear-code.com>

Provide ability to create native EGL window and provide it under NS_NATIVE_EGL_WINDOW
to GL code. The native EGL window is owned/managed by mozcontainer.

MozReview-Commit-ID: 4d0Kk6DRSaD

--HG--
extra : rebase_source : e4677ce51fbf918eb1b0257c66ca4b7220174bbb
This commit is contained in:
Martin Stransky 2018-05-10 16:04:20 +02:00
Родитель 5412f4e50b
Коммит 5fbefbfb2d
6 изменённых файлов: 82 добавлений и 0 удалений

Просмотреть файл

@ -1339,3 +1339,9 @@ if CONFIG['MOZ_SYSTEM_ICU']:
'unicode/ustring.h',
'unicode/utypes.h',
]
if CONFIG['MOZ_WAYLAND']:
system_headers += [
'wayland-client.h',
'wayland-egl.h',
]

Просмотреть файл

@ -10,6 +10,7 @@
#ifdef MOZ_WAYLAND
#include <gdk/gdkx.h>
#include <gdk/gdkwayland.h>
#include <wayland-egl.h>
#endif
#include <stdio.h>
#include <dlfcn.h>
@ -207,6 +208,11 @@ moz_container_init (MozContainer *container)
#if defined(MOZ_WAYLAND)
{
container->subcompositor = nullptr;
container->surface = nullptr;
container->subsurface = nullptr;
container->eglwindow = nullptr;
GdkDisplay *gdk_display = gtk_widget_get_display(GTK_WIDGET(container));
if (GDK_IS_WAYLAND_DISPLAY (gdk_display)) {
// Available as of GTK 3.8+
@ -289,6 +295,7 @@ moz_container_map_surface(MozContainer *container)
static void
moz_container_unmap_surface(MozContainer *container)
{
g_clear_pointer(&container->eglwindow, wl_egl_window_destroy);
g_clear_pointer(&container->subsurface, wl_subsurface_destroy);
g_clear_pointer(&container->surface, wl_surface_destroy);
}
@ -434,6 +441,11 @@ moz_container_size_allocate (GtkWidget *widget,
gdk_window_get_position(gtk_widget_get_window(widget), &x, &y);
wl_subsurface_set_position(container->subsurface, x, y);
}
if (container->eglwindow) {
wl_egl_window_resize(container->eglwindow,
allocation->width, allocation->height,
0, 0);
}
#endif
}
@ -559,4 +571,27 @@ moz_container_get_wl_surface(MozContainer *container)
return container->surface;
}
struct wl_egl_window *
moz_container_get_wl_egl_window(MozContainer *container)
{
if (!container->eglwindow) {
struct wl_surface *wlsurf = moz_container_get_wl_surface(container);
if (!wlsurf)
return nullptr;
GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container));
container->eglwindow
= wl_egl_window_create(wlsurf,
gdk_window_get_width(window),
gdk_window_get_height(window));
}
return container->eglwindow;
}
gboolean
moz_container_has_wl_egl_window(MozContainer *container)
{
return container->eglwindow ? true : false;
}
#endif

Просмотреть файл

@ -72,6 +72,7 @@ struct _MozContainer
struct wl_subcompositor *subcompositor;
struct wl_surface *surface;
struct wl_subsurface *subsurface;
struct wl_egl_window *eglwindow;
#endif
};
@ -95,6 +96,8 @@ void moz_container_move (MozContainer *container,
#ifdef MOZ_WAYLAND
struct wl_surface* moz_container_get_wl_surface(MozContainer *container);
struct wl_egl_window* moz_container_get_wl_egl_window(MozContainer *container);
gboolean moz_container_has_wl_egl_window(MozContainer *container);
#endif
#endif /* __MOZ_CONTAINER_H__ */

Просмотреть файл

@ -271,3 +271,21 @@ wl_log_set_handler_client(wl_log_func_t handler)
{
}
MOZ_EXPORT struct wl_egl_window *
wl_egl_window_create(struct wl_surface *surface,
int width, int height)
{
return NULL;
}
MOZ_EXPORT void
wl_egl_window_destroy(struct wl_egl_window *egl_window)
{
}
MOZ_EXPORT void
wl_egl_window_resize(struct wl_egl_window *egl_window,
int width, int height,
int dx, int dy)
{
}

Просмотреть файл

@ -1739,6 +1739,15 @@ nsWindow::GetNativeData(uint32_t aDataType)
case NS_NATIVE_COMPOSITOR_DISPLAY:
return gfxPlatformGtk::GetPlatform()->GetCompositorDisplay();
#endif // MOZ_X11
case NS_NATIVE_EGL_WINDOW: {
if (mIsX11Display)
return mGdkWindow ? (void*)GDK_WINDOW_XID(mGdkWindow) : nullptr;
#ifdef MOZ_WAYLAND
if (mContainer)
return moz_container_get_wl_egl_window(mContainer);
#endif
return nullptr;
}
default:
NS_WARNING("nsWindow::GetNativeData called with bad value");
return nullptr;
@ -4308,6 +4317,16 @@ nsWindow::NativeShow(bool aAction)
}
}
else {
#ifdef MOZ_WAYLAND
if (mContainer && moz_container_has_wl_egl_window(mContainer)) {
// Because wl_egl_window is destroyed on moz_container_unmap(),
// the current compositor cannot use it anymore. To avoid crash,
// destroy the compositor & recreate a new compositor on next
// expose event.
DestroyLayerManager();
}
#endif
if (mIsTopLevel) {
// Workaround window freezes on GTK versions before 3.21.2 by
// ensuring that configure events get dispatched to windows before

Просмотреть файл

@ -143,6 +143,7 @@ typedef void* nsNativeWidget;
#ifdef MOZ_X11
#define NS_NATIVE_COMPOSITOR_DISPLAY 105
#endif // MOZ_X11
#define NS_NATIVE_EGL_WINDOW 106
#endif
#ifdef MOZ_WIDGET_ANDROID
#define NS_JAVA_SURFACE 100