#52618·electron

OSR useSharedTexture: details.texture is always null on Linux with the NVIDIA proprietary driver

Author: sdkv2Created Aug 3, 2026Updated Sep 16, 2026
Labelsplatform/linuxbug :beetle:has-repro-gist43-x-y
### Preflight Checklist - [x] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project. - [x] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to. - [x] I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a bug report that matches the one I want to file, without success. ### Electron Version 43.2.0 ### What operating system(s) are you using? Ubuntu ### Operating System Version Ubuntu 22.04.5 and Ubuntu 24.04.4, X11 (kernel 6.8.0-136) ### What arch are you using? x64 ### Last Known Working Electron version _No response_ ### Does the issue also appear in Chromium / Google Chrome? I don't know how to test ### Expected Behavior With `webPreferences.offscreen.useSharedTexture: true`, the `paint` event should provide `details.texture` as an `OffscreenSharedTexture`, with `textureInfo.handle.nativePixmap.planes[].fd` on Linux. ### Actual Behavior `details.texture` is always `null` on Linux with the NVIDIA proprietary driver. The `paint` event fires normally, but every frame silently falls back to the CPU bitmap path, so the GPU-accelerated capture mode is unusable. There is no error thrown and no warning — the only way to notice is checking `details.texture` yourself. The same code returns a shared texture on Windows and macOS. ### Testcase Gist URL https://gist.github.com/sdkv2/94dec53fa8397ef82cd2e218dfdf9a36 ### Additional Information Reproduced on **Electron 43.2.0 and 40.10.6**, on four separate machines (RTX 3060), across both Ubuntu versions, three NVIDIA driver versions (575.51.03, 575.57.08, 580.95.05), two libgbm versions (23.2.1 and 25.2.8), and three X server setups (Xvfb, hand-configured Xorg with `nvidia_drv.so`, and a full SDDM/KDE session). Result was identical in every combination. `--enable-features=Vulkan` is often suggested as the NVIDIA workaround. It did not produce a shared texture in any configuration I tried, and it additionally disabled WebGL2 entirely — for an app using OSR to capture WebGL content, that trade is not usable. Note for anyone else testing this: Xvfb provides no DRI3, so it can never work — but hardware GL still reports a real GPU renderer string under it, which makes it look like a working setup. In-depth investigation

`details.texture` is explicitly `null` rather than `undefined` (verified by dumping the whole paint callback: `arg[0] = { texture: null, preventDefault: …, defaultPrevented: false }`), so `offscreen_use_shared_texture_` is being set correctly in C++ — viz simply never delivers a usable frame to `OnFrameCaptured`. With `--enable-logging=stderr --v=1`, ANGLE reports: ``` ERROR:ui/gl/egl_util.cc:92] EGL Driver message (Error) : Internal Vulkan error (-8): A requested feature is not supported, in third_party/angle/src/libANGLE/renderer/vulkan/linux/DmaBufImageSiblingVkLinux.cpp, initImpl:616. ``` `-8` is `VK_ERROR_FEATURE_NOT_PRESENT`. (Line is `initImpl:616` on Electron 43.2.0 and `initImpl:614` on 40.10.6 — same function.) The likely cause is what the capture pool asks GBM for. `RenderableGpuMemoryBufferVideoFramePool` allocates with `requires_cpu_access = true` → `SCANOUT_CPU_READ_WRITE` → `GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING`, notably *without* `GBM_BO_USE_RENDERING` (`ui/gfx/linux/gbm_util.cc`). Chromium's own comment in `media/video/renderable_gpu_memory_buffer_video_frame_pool.cc` predicts this failure and names the vendor: > "On Linux, `GBM_BO_USE_LINEAR` (implied by `SCANOUT_CPU_READ_WRITE`) can prevent GPU rendering on some drivers, notably NVIDIA's GBM driver, because it disables `GBM_BO_USE_RENDERING`." So the buffer is allocated, but NVIDIA's Vulkan will not import a LINEAR/SCANOUT dma-buf as a renderable image sibling. Verified present on the failing hosts, so these are not the cause: - `nvidia-drm.modeset = Y`; `/dev/dri/card0` + `renderD128` present - X server exposes DRI2 + DRI3 - `nvidia-drm_gbm.so` GBM backend (`libnvidia-allocator`) - EGL: `EGL_EXT_image_dma_buf_import`, `EGL_EXT_image_dma_buf_import_modifiers`, `EGL_MESA_image_dma_buf_export` - Vulkan: `VK_EXT_image_drm_format_modifier` (rev 2), `VK_EXT_external_memory_dma_buf`, `VK_EXT_queue_family_foreign`, `VK_KHR_external_memory_fd` - `app.getGPUFeatureStatus()` at paint time: `gpu_compositing=enabled vulkan=enabled_on webgl=enabled opengl=enabled_on rasterization=enabled_force` Ruled out: - All four `sharedTexturePixelFormat` values (`argb`, `nv12`, `rgba`, `bgra`) — identical result. - `--enable-native-gpu-memory-buffers` — no effect; it gates the client-side mmap path (`ui/gfx/linux/client_native_pixmap_dmabuf.cc`), while the viz capture pool uses `always_create_native_gmb_handle=true` and never consults it. - `--use-angle=gl` vs `--use-angle=vulkan` — no effect (both report the same ANGLE/Vulkan renderer on these hosts). - Initially-hidden window — `paintWhenInitiallyHidden: true` is set and `paint` does fire. The Linux `NativePixmapHandle` branch in `shell/browser/osr/osr_video_consumer.cc` looks correct, so this does not appear to be missing Electron code — the mismatch is upstream, between what the capture pool requests and what NVIDIA's GBM/Vulkan will import. Filing here because this is where it surfaces and because `docs/api/structures/shared-texture-handle.md` lists `nativePixmap` as Linux-supported without noting it does not work on the NVIDIA proprietary driver. Possibly related: #49247.