184 lines
6.4 KiB
Diff
184 lines
6.4 KiB
Diff
|
diff -up firefox-60.0.1/gfx/gl/GLContextEGL.h.mozilla-1462642 firefox-60.0.1/gfx/gl/GLContextEGL.h
|
||
|
--- firefox-60.0.1/gfx/gl/GLContextEGL.h.mozilla-1462642 2018-05-16 07:38:29.000000000 +0200
|
||
|
+++ firefox-60.0.1/gfx/gl/GLContextEGL.h 2018-05-25 10:54:09.271902218 +0200
|
||
|
@@ -133,6 +133,10 @@ protected:
|
||
|
static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
|
||
|
EGLenum bindToTextureFormat,
|
||
|
gfx::IntSize& pbsize);
|
||
|
+#if defined(MOZ_WAYLAND)
|
||
|
+ static EGLSurface CreateWaylandBufferSurface(EGLConfig config,
|
||
|
+ gfx::IntSize& pbsize);
|
||
|
+#endif
|
||
|
#if defined(MOZ_WIDGET_ANDROID)
|
||
|
public:
|
||
|
EGLSurface CreateCompatibleSurface(void* aWindow);
|
||
|
diff -up firefox-60.0.1/gfx/gl/GLContextProviderEGL.cpp.mozilla-1462642 firefox-60.0.1/gfx/gl/GLContextProviderEGL.cpp
|
||
|
--- firefox-60.0.1/gfx/gl/GLContextProviderEGL.cpp.mozilla-1462642 2018-05-25 10:54:09.258902265 +0200
|
||
|
+++ firefox-60.0.1/gfx/gl/GLContextProviderEGL.cpp 2018-05-25 10:55:57.634553279 +0200
|
||
|
@@ -63,6 +63,17 @@
|
||
|
#include "ScopedGLHelpers.h"
|
||
|
#include "TextureImageEGL.h"
|
||
|
|
||
|
+#if defined(MOZ_WAYLAND)
|
||
|
+#include "nsAutoPtr.h"
|
||
|
+#include "nsDataHashtable.h"
|
||
|
+
|
||
|
+#include <gtk/gtk.h>
|
||
|
+#include <gdk/gdkx.h>
|
||
|
+#include <gdk/gdkwayland.h>
|
||
|
+#include <wayland-egl.h>
|
||
|
+#include <dlfcn.h>
|
||
|
+#endif
|
||
|
+
|
||
|
using namespace mozilla::gfx;
|
||
|
|
||
|
namespace mozilla {
|
||
|
@@ -70,6 +81,35 @@ namespace gl {
|
||
|
|
||
|
using namespace mozilla::widget;
|
||
|
|
||
|
+#if defined(MOZ_WAYLAND)
|
||
|
+class WaylandGLSurface {
|
||
|
+public:
|
||
|
+ WaylandGLSurface(struct wl_surface *aWaylandSurface,
|
||
|
+ struct wl_egl_window *aEGLWindow);
|
||
|
+ ~WaylandGLSurface();
|
||
|
+private:
|
||
|
+ struct wl_surface *mWaylandSurface;
|
||
|
+ struct wl_egl_window *mEGLWindow;
|
||
|
+};
|
||
|
+
|
||
|
+static nsDataHashtable<nsPtrHashKey<void>, WaylandGLSurface*>
|
||
|
+ sWaylandGLSurface;
|
||
|
+
|
||
|
+void
|
||
|
+DeleteWaylandGLSurface(EGLSurface surface)
|
||
|
+{
|
||
|
+ // We're running on Wayland which means our EGLSurface may
|
||
|
+ // have attached Wayland backend data which must be released.
|
||
|
+ if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
|
||
|
+ auto entry = sWaylandGLSurface.Lookup(surface);
|
||
|
+ if (entry) {
|
||
|
+ delete entry.Data();
|
||
|
+ entry.Remove();
|
||
|
+ }
|
||
|
+ }
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
#define ADD_ATTR_2(_array, _k, _v) do { \
|
||
|
(_array).AppendElement(_k); \
|
||
|
(_array).AppendElement(_v); \
|
||
|
@@ -125,6 +165,9 @@ DestroySurface(EGLSurface oldSurface) {
|
||
|
EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||
|
EGL_NO_CONTEXT);
|
||
|
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), oldSurface);
|
||
|
+#if defined(MOZ_WAYLAND)
|
||
|
+ DeleteWaylandGLSurface(oldSurface);
|
||
|
+#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -588,6 +631,52 @@ TRY_AGAIN_POWER_OF_TWO:
|
||
|
return surface;
|
||
|
}
|
||
|
|
||
|
+#if defined(MOZ_WAYLAND)
|
||
|
+WaylandGLSurface::WaylandGLSurface(struct wl_surface *aWaylandSurface,
|
||
|
+ struct wl_egl_window *aEGLWindow)
|
||
|
+ : mWaylandSurface(aWaylandSurface)
|
||
|
+ , mEGLWindow(aEGLWindow)
|
||
|
+{
|
||
|
+}
|
||
|
+
|
||
|
+WaylandGLSurface::~WaylandGLSurface()
|
||
|
+{
|
||
|
+ wl_egl_window_destroy(mEGLWindow);
|
||
|
+ wl_surface_destroy(mWaylandSurface);
|
||
|
+}
|
||
|
+
|
||
|
+EGLSurface
|
||
|
+GLContextEGL::CreateWaylandBufferSurface(EGLConfig config,
|
||
|
+ mozilla::gfx::IntSize& pbsize)
|
||
|
+{
|
||
|
+ // Available as of GTK 3.8+
|
||
|
+ static auto sGdkWaylandDisplayGetWlCompositor =
|
||
|
+ (wl_compositor *(*)(GdkDisplay *))
|
||
|
+ dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_compositor");
|
||
|
+
|
||
|
+ if (!sGdkWaylandDisplayGetWlCompositor)
|
||
|
+ return nullptr;
|
||
|
+
|
||
|
+ struct wl_compositor *compositor =
|
||
|
+ sGdkWaylandDisplayGetWlCompositor(gdk_display_get_default());
|
||
|
+ struct wl_surface *wlsurface = wl_compositor_create_surface(compositor);
|
||
|
+ struct wl_egl_window *eglwindow =
|
||
|
+ wl_egl_window_create(wlsurface, pbsize.width, pbsize.height);
|
||
|
+
|
||
|
+ EGLSurface surface =
|
||
|
+ sEGLLibrary.fCreateWindowSurface(EGL_DISPLAY(), config, eglwindow, 0);
|
||
|
+
|
||
|
+ if (surface) {
|
||
|
+ WaylandGLSurface* waylandData =
|
||
|
+ new WaylandGLSurface(wlsurface, eglwindow);
|
||
|
+ auto entry = sWaylandGLSurface.LookupForAdd(surface);
|
||
|
+ entry.OrInsert([&waylandData](){ return waylandData; });
|
||
|
+ }
|
||
|
+
|
||
|
+ return surface;
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
static const EGLint kEGLConfigAttribsOffscreenPBuffer[] = {
|
||
|
LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PBUFFER_BIT,
|
||
|
LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
|
||
|
@@ -807,7 +896,17 @@ FillContextAttribs(bool alpha, bool dept
|
||
|
bool es3, nsTArray<EGLint>* out)
|
||
|
{
|
||
|
out->AppendElement(LOCAL_EGL_SURFACE_TYPE);
|
||
|
+#if defined(MOZ_WAYLAND)
|
||
|
+ if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
|
||
|
+ // Wayland on desktop does not support PBuffer or FBO.
|
||
|
+ // We create a dummy wl_egl_window instead.
|
||
|
+ out->AppendElement(LOCAL_EGL_WINDOW_BIT);
|
||
|
+ } else {
|
||
|
+ out->AppendElement(LOCAL_EGL_PBUFFER_BIT);
|
||
|
+ }
|
||
|
+#else
|
||
|
out->AppendElement(LOCAL_EGL_PBUFFER_BIT);
|
||
|
+#endif
|
||
|
|
||
|
out->AppendElement(LOCAL_EGL_RENDERABLE_TYPE);
|
||
|
if (es3) {
|
||
|
@@ -926,9 +1025,17 @@ GLContextEGL::CreateEGLPBufferOffscreenC
|
||
|
}
|
||
|
|
||
|
mozilla::gfx::IntSize pbSize(size);
|
||
|
- EGLSurface surface = GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(config,
|
||
|
- LOCAL_EGL_NONE,
|
||
|
- pbSize);
|
||
|
+ EGLSurface surface = nullptr;
|
||
|
+#if defined(MOZ_WAYLAND)
|
||
|
+ if (GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default())) {
|
||
|
+ surface = GLContextEGL::CreateWaylandBufferSurface(config, pbSize);
|
||
|
+ } else
|
||
|
+#endif
|
||
|
+ {
|
||
|
+ surface = GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo(config,
|
||
|
+ LOCAL_EGL_NONE,
|
||
|
+ pbSize);
|
||
|
+ }
|
||
|
if (!surface) {
|
||
|
*out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_EGL_POT");
|
||
|
NS_WARNING("Failed to create PBuffer for context!");
|
||
|
@@ -941,6 +1048,9 @@ GLContextEGL::CreateEGLPBufferOffscreenC
|
||
|
if (!gl) {
|
||
|
NS_WARNING("Failed to create GLContext from PBuffer");
|
||
|
sEGLLibrary.fDestroySurface(sEGLLibrary.Display(), surface);
|
||
|
+#if defined(MOZ_WAYLAND)
|
||
|
+ DeleteWaylandGLSurface(surface);
|
||
|
+#endif
|
||
|
return nullptr;
|
||
|
}
|
||
|
|