#pragma once #ifdef ENABLE_WAYLAND #include #include #include #include #include #include #include "WallpaperEngine/Application/ApplicationContext.h" #include "WallpaperEngine/Application/WallpaperApplication.h" #include "WallpaperEngine/Input/Drivers/WaylandMouseInput.h" #include "WallpaperEngine/Render/Drivers/Detectors/WaylandFullScreenDetector.h" #include "WallpaperEngine/Render/Drivers/Output/WaylandOutput.h" #include "WallpaperEngine/Render/Drivers/Output/WaylandOutputViewport.h" #include "WallpaperEngine/Render/Drivers/VideoDriver.h" namespace WallpaperEngine::Application { class ApplicationContext; class WallpaperApplication; } // namespace WallpaperEngine::Application struct zwlr_layer_shell_v1; struct zwlr_layer_surface_v1; struct zxdg_output_manager_v1; struct wp_color_manager_v1; struct wp_image_description_v1; #ifdef ENABLE_KDE_FEATURES struct org_kde_plasma_shell; #endif namespace WallpaperEngine::Render::Drivers { using namespace WallpaperEngine::Application; using namespace WallpaperEngine::Input::Drivers; class WaylandOpenGLDriver; namespace Output { class WaylandOutputViewport; class WaylandOutput; } // namespace Output class WaylandOpenGLDriver final : public VideoDriver { friend class Output::WaylandOutput; friend class CWaylandMouseInput; public: struct SEGLContext { EGLDisplay display = nullptr; EGLConfig config = nullptr; EGLContext context = nullptr; PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = nullptr; }; struct WaylandContext { wl_display* display = nullptr; wl_registry* registry = nullptr; wl_compositor* compositor = nullptr; wl_shm* shm = nullptr; zwlr_layer_shell_v1* layerShell = nullptr; wl_seat* seat = nullptr; zxdg_output_manager_v1* xdgOutputManager = nullptr; /** Only bound with --hdr */ wp_color_manager_v1* colorManager = nullptr; #ifdef ENABLE_KDE_FEATURES org_kde_plasma_shell* plasmaShell = nullptr; #endif }; /** What wp_color_manager_v1 advertised, only these three matter for PQ output */ struct ColorSupport { bool parametric = false; bool pq = false; bool bt2020 = false; }; explicit WaylandOpenGLDriver (ApplicationContext& context, WallpaperApplication& app); ~WaylandOpenGLDriver (); [[nodiscard]] Output::Output& getOutput () override; float getRenderTime () const override; bool closeRequested () override; void resizeWindow (glm::ivec2 size) override; void resizeWindow (glm::ivec4 sizeandpos) override; void showWindow () override; void hideWindow () override; glm::ivec2 getFramebufferSize () const override; uint32_t getFrameCounter () const override; void dispatchEventQueue () override; [[nodiscard]] void* getProcAddress (const char* name) const override; [[nodiscard]] void* getWaylandDisplay () const override; [[nodiscard]] bool isHDRAvailable () const override; /** PQ with BT.2020 primaries (and the PQ default luminances, 203 nits reference white), shared by every HDR surface */ [[nodiscard]] wp_image_description_v1* getHDRDescription () const; void onLayerClose (Output::WaylandOutputViewport*); Output::WaylandOutputViewport* surfaceToViewport (const wl_surface*) const; Output::WaylandOutputViewport* viewportInFocus = nullptr; [[nodiscard]] SEGLContext* getEGLContext (); [[nodiscard]] WaylandContext* getWaylandContext (); std::vector m_screens = {}; ColorSupport colorSupport = {}; bool hdrDescriptionReady = false; private: Output::WaylandOutput m_output; SEGLContext m_eglContext = {}; WaylandContext m_waylandContext = {}; mutable bool m_requestedExit; void initWaylandRegistry (); void setupOutputLayerSurfaces (); void initEGL (); void initGLEW (); void finishEGL () const; void initColorManagement (); wp_image_description_v1* m_hdrDescription = nullptr; uint32_t m_frameCounter = 0; ApplicationContext& m_context; WaylandMouseInput m_mouseInput; std::chrono::high_resolution_clock::time_point renderStart = std::chrono::high_resolution_clock::now (); }; } // namespace WallpaperEngine::Render::Drivers #endif /* ENABLE_WAYLAND */