Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libnvidia-egl-wayland for openSUSE:Factory checked in at 2023-11-14 21:41:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libnvidia-egl-wayland (Old) and /work/SRC/openSUSE:Factory/.libnvidia-egl-wayland.new.17445 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libnvidia-egl-wayland" Tue Nov 14 21:41:37 2023 rev:9 rq:1125472 version:1.1.13 Changes: -------- --- /work/SRC/openSUSE:Factory/libnvidia-egl-wayland/libnvidia-egl-wayland.changes 2023-06-12 15:25:33.698736153 +0200 +++ /work/SRC/openSUSE:Factory/.libnvidia-egl-wayland.new.17445/libnvidia-egl-wayland.changes 2023-11-14 21:41:40.869618413 +0100 @@ -1,0 +2,13 @@ +Sun Nov 12 18:57:54 UTC 2023 - Florian "spirit" <packag...@sp1rit.anonaddy.me> + +- update to version 1.1.13: + * Fixed a bug where PRIME render-offload was not working with KDE + * Fixed some more warnings from libwayland-client.so when closing + applications + * Fixed a bug that was causing intermittent segfaults in + wlEglDestroyFormatSet (notably affecting Firefox) + * Avoid unnecessarily calling eglQueryDeviceEXT during application + start-up on PRIME systems. This was both slow and would turn on + the dGPU wasting power. + +------------------------------------------------------------------- Old: ---- egl-wayland-1.1.12.tar.gz New: ---- egl-wayland-1.1.13.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libnvidia-egl-wayland.spec ++++++ --- /var/tmp/diff_new_pack.cM8q5v/_old 2023-11-14 21:41:41.345636033 +0100 +++ /var/tmp/diff_new_pack.cM8q5v/_new 2023-11-14 21:41:41.345636033 +0100 @@ -20,7 +20,7 @@ %define lname libnvidia-egl-wayland%{so_ver} %define rname egl-wayland Name: libnvidia-egl-wayland -Version: 1.1.12 +Version: 1.1.13 Release: 0 Summary: The EGLStream-based Wayland external platform License: MIT ++++++ egl-wayland-1.1.12.tar.gz -> egl-wayland-1.1.13.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/egl-wayland-1.1.12/Makefile.am new/egl-wayland-1.1.13/Makefile.am --- old/egl-wayland-1.1.12/Makefile.am 2023-06-02 01:27:32.000000000 +0200 +++ new/egl-wayland-1.1.13/Makefile.am 2023-10-18 20:00:18.000000000 +0200 @@ -14,6 +14,7 @@ $(PTHREAD_CFLAGS) \ $(EGL_EXTERNAL_PLATFORM_CFLAGS) \ $(WAYLAND_CFLAGS) \ + $(LIBDRM_CFLAGS) \ $(COMPILER_FLAG_VISIBILITY_HIDDEN) # Make sure we don't use deprecated stuff @@ -24,6 +25,7 @@ -shared \ -Wl,-Bsymbolic \ $(WAYLAND_LIBS) \ + $(LIBDRM_LIBS) \ -version-number $(WAYLAND_EXTERNAL_MAJOR_VERSION):$(WAYLAND_EXTERNAL_MINOR_VERSION):$(WAYLAND_EXTERNAL_MICRO_VERSION) \ $(LINKER_FLAG_NO_UNDEFINED) @@ -40,6 +42,21 @@ src/wayland-drm.c \ src/wayland-external-exports.c +libnvidia_egl_wayland_la_SOURCES += \ + include/wayland-drm.h \ + include/wayland-egldevice.h \ + include/wayland-egldisplay.h \ + include/wayland-eglhandle.h \ + include/wayland-eglstream.h \ + include/wayland-eglstream-server.h \ + include/wayland-eglsurface.h \ + include/wayland-eglsurface-internal.h \ + include/wayland-eglswap.h \ + include/wayland-eglutils.h \ + include/wayland-external-exports.h \ + include/wayland-thread.h \ + wayland-egl/wayland-egl-ext.h + libnvidia_egl_wayland_la_built_public_protocols = \ wayland-eglstream/wayland-eglstream-controller-protocol.c \ wayland-drm/wayland-drm-protocol.c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/egl-wayland-1.1.12/configure.ac new/egl-wayland-1.1.13/configure.ac --- old/egl-wayland-1.1.12/configure.ac 2023-06-02 01:27:32.000000000 +0200 +++ new/egl-wayland-1.1.13/configure.ac 2023-10-18 20:00:18.000000000 +0200 @@ -2,7 +2,7 @@ m4_define([wayland_eglstream_major_version], [1]) m4_define([wayland_eglstream_minor_version], [1]) -m4_define([wayland_eglstream_micro_version], [12]) +m4_define([wayland_eglstream_micro_version], [13]) m4_define([wayland_eglstream_version], [wayland_eglstream_major_version.wayland_eglstream_minor_version.wayland_eglstream_micro_version]) @@ -63,6 +63,7 @@ AX_PTHREAD() PKG_CHECK_MODULES([EGL_EXTERNAL_PLATFORM], [eglexternalplatform >= ${EGL_EXTERNAL_PLATFORM_MIN_VERSION} eglexternalplatform < ${EGL_EXTERNAL_PLATFORM_MAX_VERSION}]) PKG_CHECK_MODULES([WAYLAND], [wayland-server wayland-client wayland-egl-backend >= 3]) +PKG_CHECK_MODULES([LIBDRM], [libdrm]) # Checks for header files. AC_CHECK_HEADERS([arpa/inet.h stddef.h stdint.h stdlib.h string.h sys/socket.h unistd.h]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/egl-wayland-1.1.12/include/wayland-egldisplay.h new/egl-wayland-1.1.13/include/wayland-egldisplay.h --- old/egl-wayland-1.1.12/include/wayland-egldisplay.h 2023-06-02 01:27:32.000000000 +0200 +++ new/egl-wayland-1.1.13/include/wayland-egldisplay.h 2023-10-18 20:00:18.000000000 +0200 @@ -186,6 +186,7 @@ } WlEventQueue; int WlEglRegisterFeedback(WlEglDmaBufFeedback *feedback); +void wlEglDestroyFeedback(WlEglDmaBufFeedback *feedback); EGLBoolean wlEglIsValidNativeDisplayExport(void *data, void *nativeDpy); EGLBoolean wlEglBindDisplaysHook(void *data, EGLDisplay dpy, void *nativeDpy); EGLBoolean wlEglUnbindDisplaysHook(EGLDisplay dpy, void *nativeDpy); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/egl-wayland-1.1.12/include/wayland-external-exports.h new/egl-wayland-1.1.13/include/wayland-external-exports.h --- old/egl-wayland-1.1.12/include/wayland-external-exports.h 2023-06-02 01:27:32.000000000 +0200 +++ new/egl-wayland-1.1.13/include/wayland-external-exports.h 2023-10-18 20:00:18.000000000 +0200 @@ -53,7 +53,7 @@ #define WAYLAND_EXTERNAL_VERSION_MINOR 0 #endif -#define WAYLAND_EXTERNAL_VERSION_MICRO 12 +#define WAYLAND_EXTERNAL_VERSION_MICRO 13 #define EGL_EXTERNAL_PLATFORM_VERSION_MAJOR WAYLAND_EXTERNAL_VERSION_MAJOR diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/egl-wayland-1.1.12/meson.build new/egl-wayland-1.1.13/meson.build --- old/egl-wayland-1.1.12/meson.build 2023-06-02 01:27:32.000000000 +0200 +++ new/egl-wayland-1.1.13/meson.build 2023-10-18 20:00:18.000000000 +0200 @@ -1,5 +1,5 @@ project('wayland-eglstream', 'c', - version : '1.1.12', + version : '1.1.13', default_options : [ 'buildtype=debugoptimized', 'c_std=gnu99', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/egl-wayland-1.1.12/src/meson.build new/egl-wayland-1.1.13/src/meson.build --- old/egl-wayland-1.1.12/src/meson.build 2023-06-02 01:27:32.000000000 +0200 +++ new/egl-wayland-1.1.13/src/meson.build 2023-10-18 20:00:18.000000000 +0200 @@ -9,6 +9,7 @@ endif wl_protos = dependency('wayland-protocols', version: '>= 1.8') +libdrm = dependency('libdrm') wl_protos_dir = wl_protos.get_pkgconfig_variable('pkgdatadir') wl_dmabuf_xml = join_paths(wl_protos_dir, 'unstable', 'linux-dmabuf', 'linux-dmabuf-unstable-v1.xml') wp_presentation_time_xml = join_paths(wl_protos_dir, 'stable', 'presentation-time', 'presentation-time.xml') @@ -66,6 +67,7 @@ wayland_client, wayland_egl_backend, threads, + libdrm, ], include_directories : inc, version : meson.project_version(), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/egl-wayland-1.1.12/src/wayland-egldisplay.c new/egl-wayland-1.1.13/src/wayland-egldisplay.c --- old/egl-wayland-1.1.12/src/wayland-egldisplay.c 2023-06-02 01:27:32.000000000 +0200 +++ new/egl-wayland-1.1.13/src/wayland-egldisplay.c 2023-10-18 20:00:18.000000000 +0200 @@ -38,6 +38,7 @@ #include <unistd.h> #include <fcntl.h> #include <sys/mman.h> +#include <xf86drm.h> typedef struct WlServerProtocolsRec { EGLBoolean hasEglStream; @@ -144,7 +145,7 @@ typedef void *pointer_t; #endif -static void +void wlEglDestroyFeedback(WlEglDmaBufFeedback *feedback) { wlEglFeedbackResetTranches(feedback); @@ -619,6 +620,9 @@ * destroy the display connection itself */ wlEglDestroyAllSurfaces(display); + wlEglDestroyFormatSet(&display->formatSet); + wlEglDestroyFeedback(&display->defaultFeedback); + if (!globalTeardown || display->ownNativeDpy) { if (display->wlRegistry) { wl_registry_destroy(display->wlRegistry); @@ -636,19 +640,17 @@ wp_presentation_destroy(display->wpPresentation); display->wpPresentation = NULL; } - if (display->wlEventQueue) { - wl_event_queue_destroy(display->wlEventQueue); - display->wlEventQueue = NULL; - } if (display->wlDmaBuf) { zwp_linux_dmabuf_v1_destroy(display->wlDmaBuf); display->wlDmaBuf = NULL; } + /* all proxies using the queue must be destroyed first! */ + if (display->wlEventQueue) { + wl_event_queue_destroy(display->wlEventQueue); + display->wlEventQueue = NULL; + } } - wlEglDestroyFormatSet(&display->formatSet); - wlEglDestroyFeedback(&display->defaultFeedback); - return EGL_TRUE; } @@ -712,6 +714,70 @@ } } +static EGLBoolean checkNvidiaDrmDevice(WlServerProtocols *protocols) +{ + int fd = -1; + EGLBoolean result = EGL_FALSE; + drmVersion *version = NULL; + drmDevice *dev = NULL; + + if (protocols->drm_name == NULL) { + goto done; + } + + fd = open(protocols->drm_name, O_RDWR); + if (fd < 0) { + goto done; + } + + if (drmGetDevice(fd, &dev) == 0) { + if (dev->available_nodes & (1 << DRM_NODE_RENDER)) { + // Make sure that drm_name is the path to the render node, which is + // what wlEglGetPlatformDisplayExport checks for. + if (strcmp(protocols->drm_name, dev->nodes[DRM_NODE_RENDER]) != 0) { + free(protocols->drm_name); + protocols->drm_name = strdup(dev->nodes[DRM_NODE_RENDER]); + if (protocols->drm_name == NULL) { + goto done; + } + } + } + + /* + * Since we've already called drmGetDevice anyway, if this is a PCI + * device, then check if the vendor ID is for NVIDIA. If this is a + * Tegra device, though, then it won't be a PCI device, so we'll need + * to call drmGetVesion and look at the driver name instead. + */ + if (dev->bustype == DRM_BUS_PCI && dev->deviceinfo.pci->vendor_id == 0x10de) { + result = EGL_TRUE; + } + } + + if (!result) { + version = drmGetVersion(fd); + if (version != NULL && version->name != NULL) { + if (strcmp(version->name, "nvidia-drm") == 0 + || strcmp(version->name, "tegra-udrm") == 0 + || strcmp(version->name, "tegra") == 0) { + result = EGL_TRUE; + } + } + } + +done: + if (version != NULL) { + drmFreeVersion(version); + } + if (dev != NULL) { + drmFreeDevice(&dev); + } + if (fd >= 0) { + close(fd); + } + return result; +} + EGLDisplay wlEglGetPlatformDisplayExport(void *data, EGLenum platform, void *nativeDpy, @@ -730,6 +796,7 @@ EGLDeviceEXT serverDevice = EGL_NO_DEVICE_EXT; EGLDeviceEXT requestedDevice = EGL_NO_DEVICE_EXT; EGLBoolean usePrimeRenderOffload = EGL_FALSE; + EGLBoolean isServerNV; if (platform != EGL_PLATFORM_WAYLAND_EXT) { wlEglSetError(data, EGL_BAD_PARAMETER); @@ -802,6 +869,11 @@ wl_display_dispatch_pending(display->nativeDpy); } + primeRenderOffloadStr = getenv("__NV_PRIME_RENDER_OFFLOAD"); + if (primeRenderOffloadStr && !strcmp(primeRenderOffloadStr, "1")) { + usePrimeRenderOffload = EGL_TRUE; + } + /* * This is where we check the supported protocols on the compositor, * and bind to wl_drm to get the device name. @@ -809,6 +881,23 @@ */ getServerProtocolsInfo(display->nativeDpy, &protocols); + // Check if the server is running on an NVIDIA device. This will also make + // sure that the device node that we're looking at is a render node, + // regardless of which node the server sends back. + isServerNV = checkNvidiaDrmDevice(&protocols); + if (!usePrimeRenderOffload && requestedDevice == EGL_NO_DEVICE_EXT) { + /* + * We're not configured to use any sort of GPU offloading, so we only + * support this display if the server is running on an NVIDIA GPU. Do + * this early, before we call eglQueryDevicesEXT. eglQueryDevicesEXT + * might have to power on the GPU's, which can be very slow. + */ + if (!isServerNV) { + err = EGL_SUCCESS; + goto fail; + } + } + if (!protocols.hasDrm || (!protocols.hasEglStream && !protocols.hasDmaBuf)) { goto fail; } @@ -833,11 +922,6 @@ goto fail; } - primeRenderOffloadStr = getenv("__NV_PRIME_RENDER_OFFLOAD"); - if (primeRenderOffloadStr && !strcmp(primeRenderOffloadStr, "1")) { - usePrimeRenderOffload = EGL_TRUE; - } - // Try to find the device that the compositor is running on. if (protocols.drm_name) { for (i = 0; i < numDevices; i++) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/egl-wayland-1.1.12/src/wayland-eglsurface.c new/egl-wayland-1.1.13/src/wayland-eglsurface.c --- old/egl-wayland-1.1.12/src/wayland-eglsurface.c 2023-06-02 01:27:32.000000000 +0200 +++ new/egl-wayland-1.1.13/src/wayland-eglsurface.c 2023-10-18 20:00:18.000000000 +0200 @@ -1265,12 +1265,18 @@ } static WlEglDmaBufFormatSet * -WlEglGetFormatSetForDev(WlEglDmaBufFeedback *feedback, dev_t dev) +WlEglGetFormatSetForDev(WlEglDmaBufFeedback *feedback, dev_t dev, uint32_t format) { /* find the dev_t in our feedback's list of tranches */ for (int i = 0; i < (int)feedback->numTranches; i++) { if (feedback->tranches[i].drmDev == dev) { - return &feedback->tranches[i].formatSet; + /* check if this tranche contains our format */ + WlEglDmaBufFormatSet *formatSet = &feedback->tranches[i].formatSet; + for (int j = 0; j < (int)formatSet->numFormats; ++j) { + if (formatSet->dmaBufFormats[j].format == format) { + return formatSet; + } + } } } @@ -1354,16 +1360,10 @@ EGLint err = EGL_SUCCESS; EGLint numModifiers = 0; EGLuint64KHR *modifiers = NULL; - EGLint format; + uint32_t format; WlEglDmaBufFormatSet *formatSet = NULL; WlEglDmaBufFeedback *feedback = NULL; - /* First do a roundtrip to get the tranches in case the compositor resent them */ - if (wl_display_roundtrip_queue(display->nativeDpy, display->wlEventQueue) < 0) { - err = EGL_BAD_ACCESS; - goto fail; - } - /* * Vulkan surfaces will not have an eglConfig set. We will need to address them * separately. @@ -1395,10 +1395,10 @@ feedback = &display->defaultFeedback; } - formatSet = WlEglGetFormatSetForDev(feedback, display->devDpy->dev); + formatSet = WlEglGetFormatSetForDev(feedback, display->devDpy->dev, format); if (!formatSet) { /* try again and see if there is a matching tranche for the render node */ - formatSet = WlEglGetFormatSetForDev(feedback, display->devDpy->renderNode); + formatSet = WlEglGetFormatSetForDev(feedback, display->devDpy->renderNode, format); } /* @@ -1407,14 +1407,14 @@ * us to check if the main device supports the linear modifier. */ if (!formatSet && display->primeRenderOffload) { - formatSet = WlEglGetFormatSetForDev(feedback, feedback->mainDev); + formatSet = WlEglGetFormatSetForDev(feedback, feedback->mainDev, format); } } /* grab the modifier array */ if (formatSet) { for (int i = 0; i < (int)formatSet->numFormats; i++) { - if (formatSet->dmaBufFormats[i].format == (uint32_t)format) { + if (formatSet->dmaBufFormats[i].format == format) { modifiers = formatSet->dmaBufFormats[i].modifiers; numModifiers = formatSet->dmaBufFormats[i].numModifiers; break; @@ -2149,6 +2149,8 @@ free(surface->attribs); } + wlEglDestroyFeedback(&surface->feedback); + if (surface->presentFeedbackQueue != NULL) { wl_event_queue_destroy(surface->presentFeedbackQueue); surface->presentFeedbackQueue = NULL; @@ -2157,6 +2159,8 @@ wl_callback_destroy(surface->throttleCallback); surface->throttleCallback = NULL; } + + /* all proxies using the queue must be destroyed first! */ if (surface->wlEventQueue != NULL) { wl_event_queue_destroy(surface->wlEventQueue); surface->wlEventQueue = NULL; @@ -2338,8 +2342,13 @@ * hints about which modifiers to use. */ if (display->dmaBufProtocolVersion >= 4) { + struct zwp_linux_dmabuf_v1 *wrapper = wl_proxy_create_wrapper(display->wlDmaBuf); + wl_proxy_set_queue((struct wl_proxy *)wrapper, surface->wlEventQueue); + surface->feedback.wlDmaBufFeedback = - zwp_linux_dmabuf_v1_get_surface_feedback(display->wlDmaBuf, surface->wlSurface); + zwp_linux_dmabuf_v1_get_surface_feedback(wrapper, surface->wlSurface); + + wl_proxy_wrapper_destroy(wrapper); if (!surface->feedback.wlDmaBufFeedback || WlEglRegisterFeedback(&surface->feedback)) { @@ -2347,7 +2356,7 @@ goto fail; } /* Do a roundtrip to get the tranches before calling create_surface_context */ - if (wl_display_roundtrip_queue(display->nativeDpy, display->wlEventQueue) < 0) { + if (wl_display_roundtrip_queue(display->nativeDpy, surface->wlEventQueue) < 0) { err = EGL_BAD_ALLOC; goto fail; }