From 92e16f9069e32c692765fface7cfc01813c81bf9 Mon Sep 17 00:00:00 2001 From: Martin Stransky Date: Tue, 14 Jun 2022 14:33:53 +0200 Subject: Added more VA-API and WebGL fixes --- D148946.diff | 250 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ D149238.diff | 100 ++++++++++++++++++++++++ firefox.spec | 9 ++- 3 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 D148946.diff create mode 100644 D149238.diff diff --git a/D148946.diff b/D148946.diff new file mode 100644 index 0000000..e4d9aa4 --- /dev/null +++ b/D148946.diff @@ -0,0 +1,250 @@ +diff -up firefox-101.0.1/gfx/gl/GLContextProviderEGL.cpp.D148946.diff firefox-101.0.1/gfx/gl/GLContextProviderEGL.cpp +--- firefox-101.0.1/gfx/gl/GLContextProviderEGL.cpp.D148946.diff 2022-06-14 14:25:07.290229683 +0200 ++++ firefox-101.0.1/gfx/gl/GLContextProviderEGL.cpp 2022-06-14 14:25:07.313230450 +0200 +@@ -1190,42 +1190,16 @@ RefPtr GLContextEGL::Creat + } + + /*static*/ +-RefPtr GLContextEGL::CreateEGLSurfacelessContext( +- const std::shared_ptr display, const GLContextCreateDesc& desc, +- nsACString* const out_failureId) { +- const EGLConfig config = {}; +- auto fullDesc = GLContextDesc{desc}; +- fullDesc.isOffscreen = true; +- RefPtr gl = GLContextEGL::CreateGLContext( +- display, fullDesc, config, EGL_NO_SURFACE, false, out_failureId); +- if (!gl) { +- NS_WARNING("Failed to create surfaceless GL context"); +- return nullptr; +- } +- return gl; +-} +- +-/*static*/ + already_AddRefed GLContextProviderEGL::CreateHeadless( + const GLContextCreateDesc& desc, nsACString* const out_failureId) { + const auto display = DefaultEglDisplay(out_failureId); + if (!display) { + return nullptr; + } +- RefPtr gl; +-#ifdef MOZ_WAYLAND +- if (!gdk_display_get_default() && +- display->IsExtensionSupported(EGLExtension::MESA_platform_surfaceless)) { +- gl = +- GLContextEGL::CreateEGLSurfacelessContext(display, desc, out_failureId); +- } else +-#endif +- { +- mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16); +- gl = GLContextEGL::CreateEGLPBufferOffscreenContext( +- display, desc, dummySize, out_failureId); +- } +- return gl.forget(); ++ mozilla::gfx::IntSize dummySize = mozilla::gfx::IntSize(16, 16); ++ auto ret = GLContextEGL::CreateEGLPBufferOffscreenContext( ++ display, desc, dummySize, out_failureId); ++ return ret.forget(); + } + + // Don't want a global context on Android as 1) share groups across 2 threads +diff -up firefox-101.0.1/gfx/gl/GLDefs.h.D148946.diff firefox-101.0.1/gfx/gl/GLDefs.h +--- firefox-101.0.1/gfx/gl/GLDefs.h.D148946.diff 2022-06-14 14:25:07.290229683 +0200 ++++ firefox-101.0.1/gfx/gl/GLDefs.h 2022-06-14 14:25:07.313230450 +0200 +@@ -104,9 +104,6 @@ bool CheckContextLost(const GLContext* g + // EGL_ANGLE_image_d3d11_texture + #define LOCAL_EGL_D3D11_TEXTURE_ANGLE 0x3484 + +-// EGL_MESA_platform_surfaceless +-#define LOCAL_EGL_PLATFORM_SURFACELESS_MESA 0x31DD +- + // clang-format on + + #endif +diff -up firefox-101.0.1/gfx/gl/GLLibraryEGL.cpp.D148946.diff firefox-101.0.1/gfx/gl/GLLibraryEGL.cpp +--- firefox-101.0.1/gfx/gl/GLLibraryEGL.cpp.D148946.diff 2022-06-14 14:25:07.307230250 +0200 ++++ firefox-101.0.1/gfx/gl/GLLibraryEGL.cpp 2022-06-14 14:27:03.477110994 +0200 +@@ -53,9 +53,15 @@ StaticRefPtr GLLibraryEGL: + + // should match the order of EGLExtensions, and be null-terminated. + static const char* sEGLLibraryExtensionNames[] = { +- "EGL_ANDROID_get_native_client_buffer", "EGL_ANGLE_device_creation", +- "EGL_ANGLE_device_creation_d3d11", "EGL_ANGLE_platform_angle", +- "EGL_ANGLE_platform_angle_d3d", "EGL_EXT_device_query"}; ++ "EGL_ANDROID_get_native_client_buffer", ++ "EGL_ANGLE_device_creation", ++ "EGL_ANGLE_device_creation_d3d11", ++ "EGL_ANGLE_platform_angle", ++ "EGL_ANGLE_platform_angle_d3d", ++ "EGL_EXT_device_enumeration", ++ "EGL_EXT_device_query", ++ "EGL_EXT_platform_device", ++ "EGL_MESA_platform_surfaceless"}; + + // should match the order of EGLExtensions, and be null-terminated. + static const char* sEGLExtensionNames[] = { +@@ -83,7 +89,6 @@ static const char* sEGLExtensionNames[] + "EGL_EXT_buffer_age", + "EGL_KHR_partial_update", + "EGL_NV_robustness_video_memory_purge", +- "EGL_MESA_platform_surfaceless", + "EGL_EXT_image_dma_buf_import", + "EGL_EXT_image_dma_buf_import_modifiers", + "EGL_MESA_image_dma_buf_export"}; +@@ -156,8 +161,52 @@ static std::shared_ptr GetAn + } + + #ifdef MOZ_WAYLAND ++static std::shared_ptr GetAndInitDeviceDisplay( ++ GLLibraryEGL& egl, const StaticMutexAutoLock& aProofOfLock) { ++ nsAutoCString drmRenderDevice(gfx::gfxVars::DrmRenderDevice()); ++ if (drmRenderDevice.IsEmpty() || ++ !egl.IsExtensionSupported(EGLLibExtension::EXT_platform_device) || ++ !egl.IsExtensionSupported(EGLLibExtension::EXT_device_enumeration)) { ++ return nullptr; ++ } ++ ++ EGLint maxDevices; ++ if (!egl.fQueryDevicesEXT(0, nullptr, &maxDevices)) { ++ return nullptr; ++ } ++ ++ std::vector devices(maxDevices); ++ EGLint numDevices; ++ if (!egl.fQueryDevicesEXT(devices.size(), devices.data(), &numDevices)) { ++ return nullptr; ++ } ++ devices.resize(numDevices); ++ ++ EGLDisplay display = EGL_NO_DISPLAY; ++ for (const auto& device : devices) { ++ const char* renderNodeString = ++ egl.fQueryDeviceStringEXT(device, LOCAL_EGL_DRM_RENDER_NODE_FILE_EXT); ++ if (renderNodeString && ++ strcmp(renderNodeString, drmRenderDevice.get()) == 0) { ++ const EGLAttrib attrib_list[] = {LOCAL_EGL_NONE}; ++ display = egl.fGetPlatformDisplay(LOCAL_EGL_PLATFORM_DEVICE_EXT, device, ++ attrib_list); ++ break; ++ } ++ } ++ if (!display) { ++ return nullptr; ++ } ++ ++ return EglDisplay::Create(egl, display, true, aProofOfLock); ++} ++ + static std::shared_ptr GetAndInitSurfacelessDisplay( + GLLibraryEGL& egl, const StaticMutexAutoLock& aProofOfLock) { ++ if (!egl.IsExtensionSupported(EGLLibExtension::MESA_platform_surfaceless)) { ++ return nullptr; ++ } ++ + const EGLAttrib attrib_list[] = {LOCAL_EGL_NONE}; + const EGLDisplay display = egl.fGetPlatformDisplay( + LOCAL_EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, attrib_list); +@@ -610,9 +659,9 @@ bool GLLibraryEGL::Init(nsACString* cons + (void)fnLoadSymbols(symbols); + } + { +- const SymLoadStruct symbols[] = {SYMBOL(QueryDisplayAttribEXT), +- SYMBOL(QueryDeviceAttribEXT), +- END_OF_SYMBOLS}; ++ const SymLoadStruct symbols[] = { ++ SYMBOL(QueryDisplayAttribEXT), SYMBOL(QueryDeviceAttribEXT), ++ SYMBOL(QueryDeviceStringEXT), END_OF_SYMBOLS}; + (void)fnLoadSymbols(symbols); + } + { +@@ -657,6 +706,10 @@ bool GLLibraryEGL::Init(nsACString* cons + END_OF_SYMBOLS}; + (void)fnLoadSymbols(symbols); + } ++ { ++ const SymLoadStruct symbols[] = {SYMBOL(QueryDevicesEXT), END_OF_SYMBOLS}; ++ (void)fnLoadSymbols(symbols); ++ } + + return true; + } +@@ -835,7 +888,10 @@ std::shared_ptr GLLibraryEGL + // Some drivers doesn't support EGL_DEFAULT_DISPLAY + GdkDisplay* gdkDisplay = gdk_display_get_default(); + if (!gdkDisplay) { +- ret = GetAndInitSurfacelessDisplay(*this, aProofOfLock); ++ ret = GetAndInitDeviceDisplay(*this, aProofOfLock); ++ if (!ret) { ++ ret = GetAndInitSurfacelessDisplay(*this, aProofOfLock); ++ } + } else if (widget::GdkIsWaylandDisplay(gdkDisplay)) { + nativeDisplay = widget::WaylandDisplayGetWLDisplay(gdkDisplay); + if (!nativeDisplay) { +diff -up firefox-101.0.1/gfx/gl/GLLibraryEGL.h.D148946.diff firefox-101.0.1/gfx/gl/GLLibraryEGL.h +--- firefox-101.0.1/gfx/gl/GLLibraryEGL.h.D148946.diff 2022-06-14 14:25:07.307230250 +0200 ++++ firefox-101.0.1/gfx/gl/GLLibraryEGL.h 2022-06-14 14:25:07.313230450 +0200 +@@ -71,7 +71,10 @@ enum class EGLLibExtension { + ANGLE_device_creation_d3d11, + ANGLE_platform_angle, + ANGLE_platform_angle_d3d, ++ EXT_device_enumeration, + EXT_device_query, ++ EXT_platform_device, ++ MESA_platform_surfaceless, + Max + }; + +@@ -107,7 +110,6 @@ enum class EGLExtension { + EXT_buffer_age, + KHR_partial_update, + NV_robustness_video_memory_purge, +- MESA_platform_surfaceless, + EXT_image_dma_buf_import, + EXT_image_dma_buf_import_modifiers, + MESA_image_dma_buf_export, +@@ -436,6 +438,10 @@ class GLLibraryEGL final { + WRAP(fQueryDeviceAttribEXT(device, attribute, value)); + } + ++ const char* fQueryDeviceStringEXT(EGLDeviceEXT device, EGLint name) { ++ WRAP(fQueryDeviceStringEXT(device, name)); ++ } ++ + private: + // NV_stream_consumer_gltexture_yuv + EGLBoolean fStreamConsumerGLTextureExternalAttribsNV( +@@ -478,6 +484,13 @@ class GLLibraryEGL final { + WRAP(fExportDMABUFImageMESA(dpy, image, fds, strides, offsets)); + } + ++ public: ++ // EGL_EXT_device_enumeration ++ EGLBoolean fQueryDevicesEXT(EGLint max_devices, EGLDeviceEXT* devices, ++ EGLint* num_devices) { ++ WRAP(fQueryDevicesEXT(max_devices, devices, num_devices)); ++ } ++ + #undef WRAP + + #undef WRAP +@@ -586,6 +599,9 @@ class GLLibraryEGL final { + EGLBoolean(GLAPIENTRY* fQueryDeviceAttribEXT)(EGLDeviceEXT device, + EGLint attribute, + EGLAttrib* value); ++ const char*(GLAPIENTRY* fQueryDeviceStringEXT)(EGLDeviceEXT device, ++ EGLint name); ++ + // NV_stream_consumer_gltexture_yuv + EGLBoolean(GLAPIENTRY* fStreamConsumerGLTextureExternalAttribsNV)( + EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list); +@@ -623,6 +639,10 @@ class GLLibraryEGL final { + EGLint* strides, + EGLint* offsets); + ++ EGLBoolean(GLAPIENTRY* fQueryDevicesEXT)(EGLint max_devices, ++ EGLDeviceEXT* devices, ++ EGLint* num_devices); ++ + } mSymbols = {}; + }; + diff --git a/D149238.diff b/D149238.diff new file mode 100644 index 0000000..290c536 --- /dev/null +++ b/D149238.diff @@ -0,0 +1,100 @@ +diff -up firefox-101.0.1/gfx/config/gfxVars.h.D149238.diff firefox-101.0.1/gfx/config/gfxVars.h +--- firefox-101.0.1/gfx/config/gfxVars.h.D149238.diff 2022-06-14 14:28:15.301514131 +0200 ++++ firefox-101.0.1/gfx/config/gfxVars.h 2022-06-14 14:29:32.221087732 +0200 +@@ -91,7 +91,8 @@ class gfxVarReceiver; + _(AllowWebGPU, bool, false) \ + _(UseVP8HwDecode, bool, false) \ + _(UseVP9HwDecode, bool, false) \ +- _(HwDecodedVideoNoCopy, bool, false) ++ _(HwDecodedVideoNoCopy, bool, false) \ ++ _(UseDMABufSurfaceExport, bool, true) + + /* Add new entries above this line. */ + +diff -up firefox-101.0.1/gfx/gl/SharedSurfaceDMABUF.cpp.D149238.diff firefox-101.0.1/gfx/gl/SharedSurfaceDMABUF.cpp +--- firefox-101.0.1/gfx/gl/SharedSurfaceDMABUF.cpp.D149238.diff 2022-06-14 14:28:15.297513997 +0200 ++++ firefox-101.0.1/gfx/gl/SharedSurfaceDMABUF.cpp 2022-06-14 14:28:15.301514131 +0200 +@@ -9,6 +9,7 @@ + #include "GLContextEGL.h" + #include "MozFramebuffer.h" + #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc ++#include "mozilla/gfx/gfxVars.h" + + namespace mozilla::gl { + +@@ -27,22 +28,39 @@ UniquePtr SharedSu + const auto& context = gle->mContext; + const auto& egl = *(gle->mEgl); + +- if (!HasDmaBufExtensions(gle)) { +- return nullptr; +- } +- +- auto fb = MozFramebuffer::Create(desc.gl, desc.size, 0, false); +- if (!fb) return nullptr; +- +- const auto buffer = reinterpret_cast(fb->ColorTex()); +- const auto image = +- egl.fCreateImage(context, LOCAL_EGL_GL_TEXTURE_2D, buffer, nullptr); +- if (!image) return nullptr; +- +- const RefPtr surface = DMABufSurfaceRGBA::CreateDMABufSurface( +- desc.gl, image, desc.size.width, desc.size.height); +- if (!surface) return nullptr; ++ RefPtr surface; ++ UniquePtr fb; + ++ if (!HasDmaBufExtensions(gle) || !gfx::gfxVars::UseDMABufSurfaceExport()) { ++ // Use MESA_image_dma_buf_export is not supported or it's broken. ++ // Create dmabuf surface directly via. GBM and create ++ // EGLImage/framebuffer over it. ++ const auto flags = static_cast( ++ DMABUF_TEXTURE | DMABUF_USE_MODIFIERS | DMABUF_ALPHA); ++ surface = DMABufSurfaceRGBA::CreateDMABufSurface(desc.size.width, ++ desc.size.height, flags); ++ if (!surface || !surface->CreateTexture(desc.gl)) { ++ return nullptr; ++ } ++ const auto tex = surface->GetTexture(); ++ fb = MozFramebuffer::CreateForBacking(desc.gl, desc.size, 0, false, ++ LOCAL_GL_TEXTURE_2D, tex); ++ if (!fb) return nullptr; ++ } else { ++ // Use MESA_image_dma_buf_export so create EGLImage/framebuffer directly ++ // and derive dmabuf from it. ++ fb = MozFramebuffer::Create(desc.gl, desc.size, 0, false); ++ if (!fb) return nullptr; ++ ++ const auto buffer = reinterpret_cast(fb->ColorTex()); ++ const auto image = ++ egl.fCreateImage(context, LOCAL_EGL_GL_TEXTURE_2D, buffer, nullptr); ++ if (!image) return nullptr; ++ ++ surface = DMABufSurfaceRGBA::CreateDMABufSurface( ++ desc.gl, image, desc.size.width, desc.size.height); ++ if (!surface) return nullptr; ++ } + return AsUnique(new SharedSurface_DMABUF(desc, std::move(fb), surface)); + } + +diff -up firefox-101.0.1/gfx/thebes/gfxPlatform.cpp.D149238.diff firefox-101.0.1/gfx/thebes/gfxPlatform.cpp +--- firefox-101.0.1/gfx/thebes/gfxPlatform.cpp.D149238.diff 2022-06-08 23:06:36.000000000 +0200 ++++ firefox-101.0.1/gfx/thebes/gfxPlatform.cpp 2022-06-14 14:28:15.302514165 +0200 +@@ -2851,6 +2851,17 @@ void gfxPlatform::InitWebGLConfig() { + gfxVars::SetAllowEglRbab(false); + } + } ++ ++ if (kIsWayland || kIsX11) { ++ // Disable EGL_MESA_image_dma_buf_export on mesa/radeonsi due to ++ // https://gitlab.freedesktop.org/mesa/mesa/-/issues/6666 ++ nsString adapterDriverVendor; ++ gfxInfo->GetAdapterDriverVendor(adapterDriverVendor); ++ if (adapterDriverVendor.Find("mesa") != -1 && ++ adapterDriverVendor.Find("radeonsi") != -1) { ++ gfxVars::SetUseDMABufSurfaceExport(false); ++ } ++ } + } + + void gfxPlatform::InitWebGPUConfig() { diff --git a/firefox.spec b/firefox.spec index 1f412f8..80f2a2d 100644 --- a/firefox.spec +++ b/firefox.spec @@ -163,7 +163,7 @@ ExcludeArch: aarch64 Summary: Mozilla Firefox Web browser Name: firefox Version: 101.0.1 -Release: 2%{?pre_tag}%{?dist} +Release: 4%{?pre_tag}%{?dist} URL: https://www.mozilla.org/firefox/ License: MPLv1.1 or GPLv2+ or LGPLv2+ Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz @@ -268,6 +268,8 @@ Patch440: D147635.diff Patch441: D147636.diff Patch442: D147637.diff Patch443: D149135.diff +Patch444: D148946.diff +Patch445: D149238.diff # PGO/LTO patches Patch600: pgo.patch @@ -537,6 +539,8 @@ This package contains results of tests executed during build. # More VA-API fixes %patch422 -p1 -b .D147720.diff +%patch444 -p1 -b .D148946.diff +%patch445 -p1 -b .D149238.diff # PGO patches %if %{build_with_pgo} @@ -1110,6 +1114,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Tue Jun 14 2022 Martin Stransky - 101.0.1-3 +- Added fixes for mozbz#1773377 and mozbz#1774075 + * Mon Jun 13 2022 Martin Stransky - 101.0.1-2 - Fix WebGL mem leaks (mzbz#1773968) -- cgit