diff --git a/Source/WebCore/PlatformGTK.cmake b/Source/WebCore/PlatformGTK.cmake index 27b04aee02d4..76c08982c9b6 100644 --- a/Source/WebCore/PlatformGTK.cmake +++ b/Source/WebCore/PlatformGTK.cmake @@ -47,7 +47,9 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS platform/glib/ApplicationGLib.h - platform/graphics/egl/PlatformDisplayHeadless.h + platform/graphics/egl/PlatformDisplaySurfaceless.h + + platform/graphics/gbm/PlatformDisplayGBM.h platform/graphics/gtk/GdkCairoUtilities.h diff --git a/Source/WebCore/SourcesGTK.txt b/Source/WebCore/SourcesGTK.txt index 2042f2d6a177..58a73bf31a5b 100644 --- a/Source/WebCore/SourcesGTK.txt +++ b/Source/WebCore/SourcesGTK.txt @@ -74,7 +74,7 @@ platform/graphics/egl/GLContext.cpp @no-unify platform/graphics/egl/GLContextLibWPE.cpp @no-unify platform/graphics/egl/GLContextWayland.cpp @no-unify platform/graphics/egl/GLContextX11.cpp @no-unify -platform/graphics/egl/PlatformDisplayHeadless.cpp +platform/graphics/egl/PlatformDisplaySurfaceless.cpp platform/graphics/gbm/GBMBufferSwapchain.cpp platform/graphics/gbm/GBMDevice.cpp @@ -82,6 +82,7 @@ platform/graphics/gbm/GraphicsContextGLANGLELinux.cpp platform/graphics/gbm/GraphicsContextGLFallback.cpp platform/graphics/gbm/GraphicsContextGLGBM.cpp platform/graphics/gbm/GraphicsContextGLGBMTextureMapper.cpp +platform/graphics/gbm/PlatformDisplayGBM.cpp platform/graphics/gtk/ColorGtk.cpp platform/graphics/gtk/DisplayRefreshMonitorGtk.cpp diff --git a/Source/WebCore/platform/graphics/PlatformDisplay.cpp b/Source/WebCore/platform/graphics/PlatformDisplay.cpp index e5a48c9c0b52..cdd10a7d1351 100644 --- a/Source/WebCore/platform/graphics/PlatformDisplay.cpp +++ b/Source/WebCore/platform/graphics/PlatformDisplay.cpp @@ -80,6 +80,18 @@ #include #endif +#if USE(EGL) && USE(GBM) +#include +#include +#include +#include +#include +#include +#ifndef EGL_DRM_RENDER_NODE_FILE_EXT +#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377 +#endif +#endif + #if USE(ATSPI) #include #endif @@ -221,6 +233,10 @@ PlatformDisplay::~PlatformDisplay() #if PLATFORM(GTK) if (m_sharedDisplay) g_signal_handlers_disconnect_by_data(m_sharedDisplay.get(), this); +#endif +#if USE(EGL) && USE(GBM) + if (m_gbm.device.has_value() && m_gbm.device.value()) + gbm_device_destroy(m_gbm.device.value()); #endif if (s_sharedDisplayForCompositing == this) s_sharedDisplayForCompositing = nullptr; @@ -402,6 +418,107 @@ bool PlatformDisplay::destroyEGLImage(EGLImage image) const #endif } +#if USE(GBM) +EGLDeviceEXT PlatformDisplay::eglDevice() +{ + if (!GLContext::isExtensionSupported(eglQueryString(nullptr, EGL_EXTENSIONS), "EGL_EXT_device_query")) + return nullptr; + + if (!m_eglDisplayInitialized) + const_cast(this)->initializeEGLDisplay(); + + EGLDeviceEXT eglDevice; + if (eglQueryDisplayAttribEXT(m_eglDisplay, EGL_DEVICE_EXT, reinterpret_cast(&eglDevice))) + return eglDevice; + + return nullptr; +} + +const String& PlatformDisplay::drmDeviceFile() +{ + if (!m_drmDeviceFile.has_value()) { + if (EGLDeviceEXT device = eglDevice()) { + if (GLContext::isExtensionSupported(eglQueryDeviceStringEXT(device, EGL_EXTENSIONS), "EGL_EXT_device_drm")) { + m_drmDeviceFile = String::fromUTF8(eglQueryDeviceStringEXT(device, EGL_DRM_DEVICE_FILE_EXT)); + return m_drmDeviceFile.value(); + } + } + m_drmDeviceFile = String(); + } + + return m_drmDeviceFile.value(); +} + +static String drmRenderNodeFromPrimaryDeviceFile(const String& primaryDeviceFile) +{ + if (primaryDeviceFile.isEmpty()) + return { }; + + drmDevicePtr devices[64]; + memset(devices, 0, sizeof(devices)); + + int numDevices = drmGetDevices2(0, devices, std::size(devices)); + if (numDevices <= 0) + return { }; + + String renderNodeDeviceFile; + for (int i = 0; i < numDevices; ++i) { + drmDevice* device = devices[i]; + if (!(device->available_nodes & (1 << DRM_NODE_PRIMARY | 1 << DRM_NODE_RENDER))) + continue; + + if (String::fromUTF8(device->nodes[DRM_NODE_PRIMARY]) == primaryDeviceFile) { + renderNodeDeviceFile = String::fromUTF8(device->nodes[DRM_NODE_RENDER]); + break; + } + } + drmFreeDevices(devices, numDevices); + + return renderNodeDeviceFile; +} + +const String& PlatformDisplay::drmRenderNodeFile() +{ + if (!m_drmRenderNodeFile.has_value()) { + if (EGLDeviceEXT device = eglDevice()) { + if (GLContext::isExtensionSupported(eglQueryDeviceStringEXT(device, EGL_EXTENSIONS), "EGL_EXT_device_drm_render_node")) { + m_drmRenderNodeFile = String::fromUTF8(eglQueryDeviceStringEXT(device, EGL_DRM_RENDER_NODE_FILE_EXT)); + return m_drmRenderNodeFile.value(); + } + + // If EGL_EXT_device_drm_render_node is not present, try to get the render node using DRM API. + m_drmRenderNodeFile = drmRenderNodeFromPrimaryDeviceFile(drmDeviceFile()); + } else + m_drmRenderNodeFile = String(); + } + + return m_drmRenderNodeFile.value(); +} + +struct gbm_device* PlatformDisplay::gbmDevice() +{ + if (!m_gbm.device.has_value()) { + const char* envDeviceFile = getenv("WEBKIT_WEB_RENDER_DEVICE_FILE"); + String deviceFile = envDeviceFile && *envDeviceFile ? String::fromUTF8(envDeviceFile) : drmRenderNodeFile(); + if (!deviceFile.isEmpty()) { + m_gbm.deviceFD = UnixFileDescriptor { open(deviceFile.utf8().data(), O_RDWR | O_CLOEXEC), UnixFileDescriptor::Adopt }; + if (m_gbm.deviceFD) { + m_gbm.device = gbm_create_device(m_gbm.deviceFD.value()); + if (m_gbm.device.value()) + return m_gbm.device.value(); + + WTFLogAlways("Failed to create GBM device for render device: %s: %s", deviceFile.utf8().data(), safeStrerror(errno).data()); + m_gbm.deviceFD = { }; + } else + WTFLogAlways("Failed to open DRM render device %s: %s", deviceFile.utf8().data(), safeStrerror(errno).data()); + } + m_gbm.device = nullptr; + } + + return m_gbm.device.value(); +} +#endif + #endif // USE(EGL) #if USE(LCMS) diff --git a/Source/WebCore/platform/graphics/PlatformDisplay.h b/Source/WebCore/platform/graphics/PlatformDisplay.h index 28b5e9dfbfda..db3a51de0512 100644 --- a/Source/WebCore/platform/graphics/PlatformDisplay.h +++ b/Source/WebCore/platform/graphics/PlatformDisplay.h @@ -36,6 +36,11 @@ typedef void *EGLContext; typedef void *EGLDisplay; typedef void *EGLImage; typedef unsigned EGLenum; +#if USE(GBM) +#include +typedef void *EGLDeviceEXT; +struct gbm_device; +#endif #endif #if PLATFORM(GTK) @@ -80,7 +85,10 @@ class PlatformDisplay { WPE, #endif #if USE(EGL) - Headless, + Surfaceless, +#if USE(GBM) + GBM, +#endif #endif }; @@ -105,6 +113,11 @@ class PlatformDisplay { EGLImage createEGLImage(EGLContext, EGLenum target, EGLClientBuffer, const Vector&) const; bool destroyEGLImage(EGLImage) const; +#if USE(GBM) + const String& drmDeviceFile(); + const String& drmRenderNodeFile(); + struct gbm_device* gbmDevice(); +#endif #endif #if ENABLE(VIDEO) && USE(GSTREAMER_GL) @@ -138,10 +151,16 @@ class PlatformDisplay { virtual void initializeEGLDisplay(); EGLDisplay m_eglDisplay; -#endif - -#if USE(EGL) std::unique_ptr m_sharingGLContext; + +#if USE(GBM) + std::optional m_drmDeviceFile; + std::optional m_drmRenderNodeFile; + struct { + WTF::UnixFileDescriptor deviceFD; + std::optional device; + } m_gbm; +#endif #endif #if USE(LCMS) @@ -159,6 +178,9 @@ class PlatformDisplay { #if USE(EGL) void terminateEGLDisplay(); +#if USE(GBM) + EGLDeviceEXT eglDevice(); +#endif bool m_eglDisplayInitialized { false }; int m_eglMajorVersion { 0 }; diff --git a/Source/WebCore/platform/graphics/egl/GLContext.cpp b/Source/WebCore/platform/graphics/egl/GLContext.cpp index 35b29618a291..9ce78bd920e7 100644 --- a/Source/WebCore/platform/graphics/egl/GLContext.cpp +++ b/Source/WebCore/platform/graphics/egl/GLContext.cpp @@ -146,7 +146,7 @@ bool GLContext::getEGLConfig(PlatformDisplay& platformDisplay, EGLConfig* config switch (surfaceType) { case GLContext::Surfaceless: - if (platformDisplay.type() == PlatformDisplay::Type::Headless) + if (platformDisplay.type() == PlatformDisplay::Type::Surfaceless) attributeList[13] = EGL_PBUFFER_BIT; else attributeList[13] = EGL_WINDOW_BIT; @@ -270,7 +270,10 @@ std::unique_ptr GLContext::createWindowContext(GLNativeWindowType win surface = createWindowSurfaceWPE(display, config, window); break; #endif // USE(WPE_RENDERER) - case PlatformDisplay::Type::Headless: +#if USE(GBM) + case PlatformDisplay::Type::GBM: +#endif + case PlatformDisplay::Type::Surfaceless: RELEASE_ASSERT_NOT_REACHED(); } @@ -359,7 +362,7 @@ std::unique_ptr GLContext::create(GLNativeWindowType window, Platform } EGLContext eglSharingContext = platformDisplay.sharingGLContext() ? static_cast(platformDisplay.sharingGLContext())->m_context : EGL_NO_CONTEXT; - if (platformDisplay.type() == PlatformDisplay::Type::Headless) { + if (platformDisplay.type() == PlatformDisplay::Type::Surfaceless) { auto context = createSurfacelessContext(platformDisplay, eglSharingContext); if (!context) WTFLogAlways("Could not create EGL surfaceless context: %s.", lastErrorString()); @@ -386,7 +389,10 @@ std::unique_ptr GLContext::create(GLNativeWindowType window, Platform context = createWPEContext(platformDisplay, eglSharingContext); break; #endif - case PlatformDisplay::Type::Headless: +#if USE(GBM) + case PlatformDisplay::Type::GBM: +#endif + case PlatformDisplay::Type::Surfaceless: RELEASE_ASSERT_NOT_REACHED(); } } @@ -443,7 +449,10 @@ std::unique_ptr GLContext::createSharing(PlatformDisplay& platformDis context = createWPEContext(platformDisplay); break; #endif - case PlatformDisplay::Type::Headless: +#if USE(GBM) + case PlatformDisplay::Type::GBM: +#endif + case PlatformDisplay::Type::Surfaceless: break; } } diff --git a/Source/WebCore/platform/graphics/egl/PlatformDisplayHeadless.cpp b/Source/WebCore/platform/graphics/egl/PlatformDisplaySurfaceless.cpp similarity index 86% rename from Source/WebCore/platform/graphics/egl/PlatformDisplayHeadless.cpp rename to Source/WebCore/platform/graphics/egl/PlatformDisplaySurfaceless.cpp index 62ca6526c82c..bc2af43534da 100644 --- a/Source/WebCore/platform/graphics/egl/PlatformDisplayHeadless.cpp +++ b/Source/WebCore/platform/graphics/egl/PlatformDisplaySurfaceless.cpp @@ -24,7 +24,7 @@ */ #include "config.h" -#include "PlatformDisplayHeadless.h" +#include "PlatformDisplaySurfaceless.h" #if USE(EGL) #include "GLContext.h" @@ -32,12 +32,12 @@ namespace WebCore { -std::unique_ptr PlatformDisplayHeadless::create() +std::unique_ptr PlatformDisplaySurfaceless::create() { - return std::unique_ptr(new PlatformDisplayHeadless()); + return std::unique_ptr(new PlatformDisplaySurfaceless()); } -PlatformDisplayHeadless::PlatformDisplayHeadless() +PlatformDisplaySurfaceless::PlatformDisplaySurfaceless() { #if PLATFORM(GTK) PlatformDisplay::setSharedDisplayForCompositing(*this); @@ -52,7 +52,7 @@ PlatformDisplayHeadless::PlatformDisplayHeadless() PlatformDisplay::initializeEGLDisplay(); } -PlatformDisplayHeadless::~PlatformDisplayHeadless() +PlatformDisplaySurfaceless::~PlatformDisplaySurfaceless() { } diff --git a/Source/WebCore/platform/graphics/egl/PlatformDisplayHeadless.h b/Source/WebCore/platform/graphics/egl/PlatformDisplaySurfaceless.h similarity index 83% rename from Source/WebCore/platform/graphics/egl/PlatformDisplayHeadless.h rename to Source/WebCore/platform/graphics/egl/PlatformDisplaySurfaceless.h index 189dd71fc92f..920fb252c026 100644 --- a/Source/WebCore/platform/graphics/egl/PlatformDisplayHeadless.h +++ b/Source/WebCore/platform/graphics/egl/PlatformDisplaySurfaceless.h @@ -30,15 +30,15 @@ namespace WebCore { -class PlatformDisplayHeadless final : public PlatformDisplay { +class PlatformDisplaySurfaceless final : public PlatformDisplay { public: - static std::unique_ptr create(); + static std::unique_ptr create(); - virtual ~PlatformDisplayHeadless(); + virtual ~PlatformDisplaySurfaceless(); private: - PlatformDisplayHeadless(); + PlatformDisplaySurfaceless(); - Type type() const override { return PlatformDisplay::Type::Headless; } + Type type() const override { return PlatformDisplay::Type::Surfaceless; } }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/gbm/PlatformDisplayGBM.cpp b/Source/WebCore/platform/graphics/gbm/PlatformDisplayGBM.cpp new file mode 100644 index 000000000000..8bccfa61d057 --- /dev/null +++ b/Source/WebCore/platform/graphics/gbm/PlatformDisplayGBM.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2023 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PlatformDisplayGBM.h" + +#if USE(EGL) && USE(GBM) +#include "GLContext.h" +#include +#include +#include +#include +#include +#include +#include + +namespace WebCore { + +std::unique_ptr PlatformDisplayGBM::create(const String& deviceFile) +{ + auto fd = UnixFileDescriptor { open(deviceFile.utf8().data(), O_RDWR | O_CLOEXEC), UnixFileDescriptor::Adopt }; + if (!fd) { + WTFLogAlways("Failed to open DRM render device %s: %s", deviceFile.utf8().data(), safeStrerror(errno).data()); + return nullptr; + } + + auto* device = gbm_create_device(fd.value()); + if (!device) { + WTFLogAlways("Failed to create GBM device for render device: %s: %s", deviceFile.utf8().data(), safeStrerror(errno).data()); + return nullptr; + } + + return std::unique_ptr(new PlatformDisplayGBM(WTFMove(fd), device)); +} + +PlatformDisplayGBM::PlatformDisplayGBM(UnixFileDescriptor&& fd, struct gbm_device* device) +{ +#if PLATFORM(GTK) + PlatformDisplay::setSharedDisplayForCompositing(*this); +#endif + + m_gbm = { WTFMove(fd), device }; + + const char* extensions = eglQueryString(nullptr, EGL_EXTENSIONS); + if (GLContext::isExtensionSupported(extensions, "EGL_EXT_platform_base")) + m_eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, m_gbm.device.value(), nullptr); + else if (GLContext::isExtensionSupported(extensions, "EGL_KHR_platform_base")) + m_eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_GBM_KHR, m_gbm.device.value(), nullptr); + + PlatformDisplay::initializeEGLDisplay(); +} + +PlatformDisplayGBM::~PlatformDisplayGBM() +{ +} + +} // namespace WebCore + +#endif // USE(EGL) && USE(GBM) diff --git a/Source/WebCore/platform/graphics/gbm/PlatformDisplayGBM.h b/Source/WebCore/platform/graphics/gbm/PlatformDisplayGBM.h new file mode 100644 index 000000000000..e0a0049f4c6b --- /dev/null +++ b/Source/WebCore/platform/graphics/gbm/PlatformDisplayGBM.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#if USE(EGL) && USE(GBM) +#include "PlatformDisplay.h" + +namespace WebCore { + +class PlatformDisplayGBM final : public PlatformDisplay { +public: + static std::unique_ptr create(const String&); + + virtual ~PlatformDisplayGBM(); +private: + PlatformDisplayGBM(UnixFileDescriptor&&, struct gbm_device*); + + Type type() const override { return PlatformDisplay::Type::GBM; } +}; + +} // namespace WebCore + +#endif // USE(EGL) && USE(GBM) diff --git a/Source/WebKit/Shared/WebProcessCreationParameters.cpp b/Source/WebKit/Shared/WebProcessCreationParameters.cpp index 36c4a3a77906..aea41beabf8e 100644 --- a/Source/WebKit/Shared/WebProcessCreationParameters.cpp +++ b/Source/WebKit/Shared/WebProcessCreationParameters.cpp @@ -188,6 +188,7 @@ void WebProcessCreationParameters::encode(IPC::Encoder& encoder) const #if PLATFORM(GTK) encoder << useDMABufSurfaceForCompositing; + encoder << renderDeviceFile; encoder << useSystemAppearanceForScrollbars; encoder << gtkSettings; #endif @@ -526,6 +527,11 @@ bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreat if (!useDMABufSurfaceForCompositing) return false; parameters.useDMABufSurfaceForCompositing = WTFMove(*useDMABufSurfaceForCompositing); + std::optional renderDeviceFile; + decoder >> renderDeviceFile; + if (!renderDeviceFile) + return false; + parameters.renderDeviceFile = WTFMove(*renderDeviceFile); std::optional useSystemAppearanceForScrollbars; decoder >> useSystemAppearanceForScrollbars; if (!useSystemAppearanceForScrollbars) diff --git a/Source/WebKit/Shared/WebProcessCreationParameters.h b/Source/WebKit/Shared/WebProcessCreationParameters.h index b3d9560fba26..a8d59c1bcb8f 100644 --- a/Source/WebKit/Shared/WebProcessCreationParameters.h +++ b/Source/WebKit/Shared/WebProcessCreationParameters.h @@ -229,6 +229,7 @@ struct WebProcessCreationParameters { #if PLATFORM(GTK) bool useDMABufSurfaceForCompositing { false }; + String renderDeviceFile; bool useSystemAppearanceForScrollbars { false }; GtkSettingsState gtkSettings; #endif diff --git a/Source/WebKit/UIProcess/API/glib/WebKitProtocolHandler.cpp b/Source/WebKit/UIProcess/API/glib/WebKitProtocolHandler.cpp index b629cc6536bf..0750e0b544c9 100644 --- a/Source/WebKit/UIProcess/API/glib/WebKitProtocolHandler.cpp +++ b/Source/WebKit/UIProcess/API/glib/WebKitProtocolHandler.cpp @@ -58,9 +58,6 @@ #if USE(GBM) #include "AcceleratedBackingStoreDMABuf.h" -#ifndef EGL_DRM_RENDER_NODE_FILE_EXT -#define EGL_DRM_RENDER_NODE_FILE_EXT 0x3377 -#endif #endif #if PLATFORM(X11) @@ -281,22 +278,13 @@ void WebKitProtocolHandler::handleGPU(WebKitURISchemeRequest* request) addTableRow(hardwareAccelerationObject, "GL_VERSION"_s, makeString(reinterpret_cast(glGetString(GL_VERSION)))); addTableRow(hardwareAccelerationObject, "GL_SHADING_LANGUAGE_VERSION"_s, makeString(reinterpret_cast(glGetString(GL_SHADING_LANGUAGE_VERSION)))); - auto eglDisplay = PlatformDisplay::sharedDisplay().eglDisplay(); #if USE(GBM) - if (GLContext::isExtensionSupported(eglQueryString(nullptr, EGL_EXTENSIONS), "EGL_EXT_device_query")) { - EGLDeviceEXT eglDevice; - if (eglQueryDisplayAttribEXT(eglDisplay, EGL_DEVICE_EXT, reinterpret_cast(&eglDevice))) { - const char* deviceExtensions = eglQueryDeviceStringEXT(eglDevice, EGL_EXTENSIONS); - if (GLContext::isExtensionSupported(deviceExtensions, "EGL_EXT_device_drm")) { - if (const char* deviceFile = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_DEVICE_FILE_EXT)) - addTableRow(hardwareAccelerationObject, "DRM Device"_s, makeString(deviceFile)); - } - if (GLContext::isExtensionSupported(deviceExtensions, "EGL_EXT_device_drm_render_node")) { - if (const char* renderNode = eglQueryDeviceStringEXT(eglDevice, EGL_DRM_RENDER_NODE_FILE_EXT)) - addTableRow(hardwareAccelerationObject, "DRM Render Node"_s, makeString(renderNode)); - } - } - } + auto deviceFile = PlatformDisplay::sharedDisplay().drmDeviceFile(); + if (!deviceFile.isEmpty()) + addTableRow(hardwareAccelerationObject, "DRM Device"_s, deviceFile); + auto renderNode = PlatformDisplay::sharedDisplay().drmRenderNodeFile(); + if (!renderNode.isEmpty()) + addTableRow(hardwareAccelerationObject, "DRM Render Node"_s, renderNode); #endif #if USE(OPENGL_ES) @@ -313,6 +301,7 @@ void WebKitProtocolHandler::handleGPU(WebKitURISchemeRequest* request) addTableRow(hardwareAccelerationObject, "GL_EXTENSIONS"_s, extensionsBuilder.toString()); #endif + auto eglDisplay = PlatformDisplay::sharedDisplay().eglDisplay(); addTableRow(hardwareAccelerationObject, "EGL_VERSION"_s, makeString(eglQueryString(eglDisplay, EGL_VERSION))); addTableRow(hardwareAccelerationObject, "EGL_VENDOR"_s, makeString(eglQueryString(eglDisplay, EGL_VENDOR))); addTableRow(hardwareAccelerationObject, "EGL_EXTENSIONS"_s, makeString(eglQueryString(nullptr, EGL_EXTENSIONS), ' ', eglQueryString(eglDisplay, EGL_EXTENSIONS))); diff --git a/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp b/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp index 82feb4b26719..5abe94e29ad4 100644 --- a/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp +++ b/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp @@ -87,8 +87,10 @@ void WebProcessPool::platformInitializeWebProcess(const WebProcessProxy& process #endif #if PLATFORM(GTK) && USE(GBM) - if (AcceleratedBackingStoreDMABuf::checkRequirements()) + if (AcceleratedBackingStoreDMABuf::checkRequirements()) { parameters.useDMABufSurfaceForCompositing = true; + parameters.renderDeviceFile = WebCore::PlatformDisplay::sharedDisplay().drmRenderNodeFile(); + } #endif #if PLATFORM(WAYLAND) diff --git a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp index 3ed329cc9a86..bbdc911b0de2 100644 --- a/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp +++ b/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreDMABuf.cpp @@ -33,7 +33,6 @@ #include "WebPageProxy.h" #include "WebProcessProxy.h" #include -#include #include #include #include @@ -219,7 +218,12 @@ void AcceleratedBackingStoreDMABuf::Texture::paint(GtkWidget* widget, cairo_t* c AcceleratedBackingStoreDMABuf::Surface::Surface(const UnixFileDescriptor& backFD, const UnixFileDescriptor& frontFD, const WebCore::IntSize& size, uint32_t format, uint32_t offset, uint32_t stride, float deviceScaleFactor) : RenderSource(size, deviceScaleFactor) { - auto* device = WebCore::GBMDevice::singleton().device(); + auto* device = WebCore::PlatformDisplay::sharedDisplay().gbmDevice(); + if (!device) { + WTFLogAlways("Failed to get GBM device"); + return; + } + struct gbm_import_fd_data fdData = { backFD.value(), static_cast(m_size.width()), static_cast(m_size.height()), stride, format }; m_backBuffer = gbm_bo_import(device, GBM_BO_IMPORT_FD, &fdData, GBM_BO_USE_RENDERING); if (!m_backBuffer) { diff --git a/Source/WebKit/WebProcess/WebPage/AcceleratedSurface.cpp b/Source/WebKit/WebProcess/WebPage/AcceleratedSurface.cpp index 27f65723f70a..09cb12bb800f 100644 --- a/Source/WebKit/WebProcess/WebPage/AcceleratedSurface.cpp +++ b/Source/WebKit/WebProcess/WebPage/AcceleratedSurface.cpp @@ -47,7 +47,8 @@ using namespace WebCore; std::unique_ptr AcceleratedSurface::create(WebPage& webPage, Client& client) { #if USE(GBM) - if (PlatformDisplay::sharedDisplayForCompositing().type() == PlatformDisplay::Type::Headless) + if (PlatformDisplay::sharedDisplayForCompositing().type() == PlatformDisplay::Type::GBM + || PlatformDisplay::sharedDisplayForCompositing().type() == PlatformDisplay::Type::Surfaceless) return AcceleratedSurfaceDMABuf::create(webPage, client); #endif #if PLATFORM(WAYLAND) diff --git a/Source/WebKit/WebProcess/WebPage/gtk/AcceleratedSurfaceDMABuf.cpp b/Source/WebKit/WebProcess/WebPage/gtk/AcceleratedSurfaceDMABuf.cpp index 14a8631f3ed6..0300ea0b4436 100644 --- a/Source/WebKit/WebProcess/WebPage/gtk/AcceleratedSurfaceDMABuf.cpp +++ b/Source/WebKit/WebProcess/WebPage/gtk/AcceleratedSurfaceDMABuf.cpp @@ -32,7 +32,6 @@ #include "WebPage.h" #include "WebProcess.h" #include -#include #include #include #include @@ -48,7 +47,7 @@ std::unique_ptr AcceleratedSurfaceDMABuf::create(WebPa AcceleratedSurfaceDMABuf::AcceleratedSurfaceDMABuf(WebPage& webPage, Client& client) : AcceleratedSurface(webPage, client) - , m_isSoftwareRast(!WebCore::PlatformDisplay::sharedDisplayForCompositing().eglExtensions().EXT_image_dma_buf_import) + , m_isSoftwareRast(WebCore::PlatformDisplay::sharedDisplayForCompositing().type() == WebCore::PlatformDisplay::Type::Surfaceless) { } @@ -101,7 +100,12 @@ std::unique_ptr AcceleratedSurfaceDMABuf auto& display = WebCore::PlatformDisplay::sharedDisplayForCompositing(); auto createImage = [&]() -> std::pair { - auto* bo = gbm_bo_create(WebCore::GBMDevice::singleton().device(), size.width(), size.height(), uint32_t(WebCore::DMABufFormat::FourCC::ARGB8888), 0); + auto* device = display.gbmDevice(); + if (!device) { + WTFLogAlways("Failed to create GBM buffer of size %dx%d: no GBM device found", size.width(), size.height()); + return { }; + } + auto* bo = gbm_bo_create(device, size.width(), size.height(), uint32_t(WebCore::DMABufFormat::FourCC::ARGB8888), 0); if (!bo) { WTFLogAlways("Failed to create GBM buffer of size %dx%d: %s", size.width(), size.height(), safeStrerror(errno).data()); return { }; diff --git a/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp b/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp index 0b6108e29669..8a31082be1e5 100644 --- a/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp +++ b/Source/WebKit/WebProcess/glib/WebProcessGLib.cpp @@ -48,8 +48,9 @@ #include #endif -#if PLATFORM(GTK) && USE(EGL) -#include +#if PLATFORM(GTK) && USE(GBM) +#include +#include #endif #if PLATFORM(GTK) && !USE(GTK4) @@ -123,9 +124,13 @@ void WebProcess::platformInitializeWebProcess(WebProcessCreationParameters& para } #endif -#if PLATFORM(GTK) && USE(EGL) - if (parameters.useDMABufSurfaceForCompositing) - m_displayForCompositing = WebCore::PlatformDisplayHeadless::create(); +#if PLATFORM(GTK) && USE(GBM) + if (parameters.useDMABufSurfaceForCompositing) { + if (!parameters.renderDeviceFile.isEmpty()) + m_displayForCompositing = WebCore::PlatformDisplayGBM::create(parameters.renderDeviceFile); + else + m_displayForCompositing = WebCore::PlatformDisplaySurfaceless::create(); + } #endif #if PLATFORM(WAYLAND)