author | stransky <stransky@redhat.com> |
Thu, 03 Sep 2020 09:02:44 +0000 | |
changeset 547651 | 915c19da6fceed6c61933b0458f216391e3ebe68 |
parent 547650 | dd2d6a667e9c3d7e8caf82840af3b622244413d6 |
child 547652 | e9d534d12e77469312104876f513cb749c25cce5 |
push id | 125672 |
push user | cbrindusan@mozilla.com |
push date | Thu, 03 Sep 2020 09:12:10 +0000 |
treeherder | autoland@e9d534d12e77 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jgilbert |
bugs | 1650583, 1478454 |
milestone | 82.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
gfx/gl/GLContextEGL.h | file | annotate | diff | comparison | revisions | |
gfx/gl/GLContextProviderEGL.cpp | file | annotate | diff | comparison | revisions |
--- a/gfx/gl/GLContextEGL.h +++ b/gfx/gl/GLContextEGL.h @@ -112,16 +112,21 @@ class GLContextEGL final : public GLCont const gfx::IntSize& size, nsACString* const out_FailureId); static RefPtr<GLContextEGL> CreateEGLPBufferOffscreenContextImpl( std::shared_ptr<EglDisplay>, const GLContextCreateDesc&, const gfx::IntSize& size, bool aUseGles, nsACString* const out_FailureId); static EGLSurface CreateEGLSurfaceForCompositorWidget( widget::CompositorWidget* aCompositorWidget, const EGLConfig aConfig); +#ifdef MOZ_X11 + static bool FindVisual(bool aUseWebRender, bool useAlpha, + int* const out_visualId); +#endif + protected: friend class GLContextProviderEGL; friend class GLContextEGLFactory; virtual void OnMarkDestroyed() override; public: const std::shared_ptr<EglDisplay> mEgl; @@ -151,16 +156,17 @@ class GLContextEGL final : public GLCont static EGLSurface CreateWaylandBufferSurface(EglDisplay&, EGLConfig, gfx::IntSize& pbsize); public: EGLSurface CreateCompatibleSurface(void* aWindow) const; }; // - - +// aVisual is used in Linux only to exactly match window and framebuffer +// visuals on NVIDIA drivers (Bug 1478454). bool CreateConfig(EglDisplay&, EGLConfig* aConfig, int32_t depth, - bool aEnableDepthBuffer, bool aUseGles); + bool aEnableDepthBuffer, bool aUseGles, int aVisual = 0); } // namespace gl } // namespace mozilla #endif // GLCONTEXTEGL_H_
--- a/gfx/gl/GLContextProviderEGL.cpp +++ b/gfx/gl/GLContextProviderEGL.cpp @@ -87,16 +87,25 @@ inline bool IsWaylandDisplay() { #ifdef MOZ_GTK_WAYLAND return gdk_display_get_default() && GDK_IS_WAYLAND_DISPLAY(gdk_display_get_default()); #else return false; #endif } +inline bool IsX11Display() { +#ifdef MOZ_WIDGET_GTK + return gdk_display_get_default() && + GDK_IS_X11_DISPLAY(gdk_display_get_default()); +#else + return false; +#endif +} + struct wl_egl_window; using namespace mozilla::gfx; namespace mozilla { namespace gl { using namespace mozilla::widget; @@ -125,17 +134,17 @@ void DeleteWaylandGLSurface(EGLSurface s entry.Remove(); } } } #endif static bool CreateConfigScreen(EglDisplay&, EGLConfig* const aConfig, const bool aEnableDepthBuffer, - const bool aUseGles); + const bool aUseGles, int aVisual = 0); // append three zeros at the end of attribs list to work around // EGL implementation bugs that iterate until they find 0, instead of // EGL_NONE. See bug 948406. #define EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS \ LOCAL_EGL_NONE, 0, 0, 0 static EGLint kTerminationAttribs[] = { @@ -251,47 +260,68 @@ already_AddRefed<GLContext> GLContextEGL } const auto egl = lib->CreateDisplay(true, &failureId); if (!egl) { gfxCriticalNote << "Failed[3] to create EGL library display: " << failureId.get(); return nullptr; } + int visualID = 0; + if (IsX11Display()) { +#ifdef MOZ_X11 + GdkDisplay* gdkDisplay = gdk_display_get_default(); + auto display = gdkDisplay ? GDK_DISPLAY_XDISPLAY(gdkDisplay) : nullptr; + if (display) { + XWindowAttributes windowAttrs; + if (!XGetWindowAttributes(display, (Window)aWindow, &windowAttrs)) { + NS_WARNING("[EGL] XGetWindowAttributes() failed"); + return nullptr; + } + visualID = XVisualIDFromVisual(windowAttrs.visual); + } +#endif + } + bool doubleBuffered = true; EGLConfig config; if (aWebRender && egl->mLib->IsANGLE()) { // Force enable alpha channel to make sure ANGLE use correct framebuffer // formart const int bpp = 32; const bool withDepth = true; if (!CreateConfig(*egl, &config, bpp, withDepth, aUseGles)) { gfxCriticalNote << "Failed to create EGLConfig for WebRender ANGLE!"; return nullptr; } } else { if (aDepth) { - if (!CreateConfig(*egl, &config, aDepth, aWebRender, aUseGles)) { + if (!CreateConfig(*egl, &config, aDepth, aWebRender, aUseGles, + visualID)) { gfxCriticalNote << "Failed to create EGLConfig for WebRender with depth!"; return nullptr; } } else { if (!CreateConfigScreen(*egl, &config, - /* aEnableDepthBuffer */ aWebRender, aUseGles)) { + /* aEnableDepthBuffer */ aWebRender, aUseGles, + visualID)) { gfxCriticalNote << "Failed to create EGLConfig!"; return nullptr; } } } EGLSurface surface = EGL_NO_SURFACE; if (aWindow) { surface = mozilla::gl::CreateSurfaceFromNativeWindow(*egl, aWindow, config); + if (!surface) { + return nullptr; + } } CreateContextFlags flags = CreateContextFlags::NONE; if (aWebRender && aUseGles) { flags |= CreateContextFlags::PREFER_ES3; } if (!aWebRender) { flags |= CreateContextFlags::REQUIRE_COMPAT_PROFILE; @@ -830,17 +860,17 @@ static const EGLint kEGLConfigAttribsRGB static const EGLint kEGLConfigAttribsRGBA32[] = { LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_WINDOW_BIT, LOCAL_EGL_RED_SIZE, 8, LOCAL_EGL_GREEN_SIZE, 8, LOCAL_EGL_BLUE_SIZE, 8, LOCAL_EGL_ALPHA_SIZE, 8}; bool CreateConfig(EglDisplay& egl, EGLConfig* aConfig, int32_t depth, - bool aEnableDepthBuffer, bool aUseGles) { + bool aEnableDepthBuffer, bool aUseGles, int aVisual) { EGLConfig configs[64]; std::vector<EGLint> attribs; EGLint ncfg = ArrayLength(configs); switch (depth) { case 16: for (const auto& cur : kEGLConfigAttribsRGB16) { attribs.push_back(cur); @@ -885,33 +915,44 @@ bool CreateConfig(EglDisplay& egl, EGLCo (depth == 32 && r == 8 && g == 8 && b == 8 && a == 8))) { EGLint z; if (aEnableDepthBuffer) { if (!egl.fGetConfigAttrib(config, LOCAL_EGL_DEPTH_SIZE, &z) || z != 24) { continue; } } +#if defined(MOZ_X11) + if (aVisual) { + int vis; + if (!egl.fGetConfigAttrib(config, LOCAL_EGL_NATIVE_VISUAL_ID, &vis) || + aVisual != vis) { + continue; + } + } +#endif *aConfig = config; return true; } } return false; } // Return true if a suitable EGLConfig was found and pass it out // through aConfig. Return false otherwise. // // NB: It's entirely legal for the returned EGLConfig to be valid yet // have the value null. +// aVisual is used in Linux only. static bool CreateConfigScreen(EglDisplay& egl, EGLConfig* const aConfig, const bool aEnableDepthBuffer, - const bool aUseGles) { + const bool aUseGles, int aVisual) { int32_t depth = gfxVars::ScreenDepth(); - if (CreateConfig(egl, aConfig, depth, aEnableDepthBuffer, aUseGles)) { + if (CreateConfig(egl, aConfig, depth, aEnableDepthBuffer, aUseGles, + aVisual)) { return true; } #ifdef MOZ_WIDGET_ANDROID // Bug 736005 // Android doesn't always support 16 bit so also try 24 bit if (depth == 16) { return CreateConfig(egl, aConfig, 24, aEnableDepthBuffer, aUseGles); } @@ -1040,16 +1081,42 @@ static EGLConfig ChooseConfig(EglDisplay foundConfigs == 0) { return EGL_NO_CONFIG; } EGLConfig config = configs[0]; return config; } +#ifdef MOZ_X11 +/* static */ +bool GLContextEGL::FindVisual(bool aUseWebRender, bool useAlpha, + int* const out_visualId) { + nsCString discardFailureId; + const auto egl = DefaultEglDisplay(&discardFailureId); + if (!egl) { + gfxCriticalNote + << "GLContextEGL::FindVisual(): Failed to load EGL library!"; + return false; + } + + EGLConfig config; + const int bpp = useAlpha ? 32 : 24; + if (!CreateConfig(*egl, &config, bpp, aUseWebRender, /* aUseGles */ false)) { + gfxCriticalNote + << "GLContextEGL::FindVisual(): Failed to create EGLConfig!"; + return false; + } + if (egl->fGetConfigAttrib(config, LOCAL_EGL_NATIVE_VISUAL_ID, out_visualId)) { + return true; + } + return false; +} +#endif + /*static*/ RefPtr<GLContextEGL> GLContextEGL::CreateEGLPBufferOffscreenContextImpl( const std::shared_ptr<EglDisplay> egl, const GLContextCreateDesc& desc, const mozilla::gfx::IntSize& size, const bool useGles, nsACString* const out_failureId) { const EGLConfig config = ChooseConfig(*egl, desc, useGles); if (config == EGL_NO_CONFIG) { *out_failureId = "FEATURE_FAILURE_EGL_NO_CONFIG"_ns;