File indexing completed on 2024-11-10 04:57:06
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org> 0006 SPDX-FileCopyrightText: 2019 Vlad Zahorodnii <vlad.zahorodnii@kde.org> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 // this needs to be on top, epoxy has an error if you include it after GL/gl.h, 0011 // which Qt does include 0012 #include "utils/drm_format_helper.h" 0013 0014 #include "compositor.h" 0015 #include "core/renderbackend.h" 0016 #include "core/shmgraphicsbufferallocator.h" 0017 #include "internalwindow.h" 0018 #include "swapchain.h" 0019 #include "window.h" 0020 0021 #include <logging.h> 0022 0023 #include <libdrm/drm_fourcc.h> 0024 #include <qpa/qwindowsysteminterface.h> 0025 0026 namespace KWin 0027 { 0028 namespace QPA 0029 { 0030 static quint32 s_windowId = 0; 0031 0032 Window::Window(QWindow *window) 0033 : QPlatformWindow(window) 0034 , m_windowId(++s_windowId) 0035 , m_scale(kwinApp()->devicePixelRatio()) 0036 { 0037 Q_ASSERT(!window->property("_KWIN_WINDOW_IS_OFFSCREEN").toBool()); 0038 } 0039 0040 Window::~Window() 0041 { 0042 unmap(); 0043 } 0044 0045 Swapchain *Window::swapchain(const QHash<uint32_t, QList<uint64_t>> &formats) 0046 { 0047 const QSize nativeSize = geometry().size() * devicePixelRatio(); 0048 if (!m_swapchain || m_swapchain->size() != nativeSize 0049 || !formats.contains(m_swapchain->format()) 0050 || m_swapchain->modifiers() != formats[m_swapchain->format()]) { 0051 const bool software = window()->surfaceType() == QSurface::RasterSurface; // RasterGLSurface is unsupported by us 0052 0053 GraphicsBufferAllocator *allocator; 0054 if (software) { 0055 static ShmGraphicsBufferAllocator shmAllocator; 0056 allocator = &shmAllocator; 0057 } else { 0058 allocator = Compositor::self()->backend()->graphicsBufferAllocator(); 0059 } 0060 0061 for (auto it = formats.begin(); it != formats.end(); it++) { 0062 if (auto info = FormatInfo::get(it.key()); info && info->bitsPerColor == 8 && info->alphaBits == 8) { 0063 const auto options = GraphicsBufferOptions{ 0064 .size = nativeSize, 0065 .format = it.key(), 0066 .modifiers = it.value(), 0067 .software = software, 0068 }; 0069 auto buffer = allocator->allocate(options); 0070 if (!buffer) { 0071 continue; 0072 } 0073 m_swapchain = std::make_unique<Swapchain>(allocator, options, buffer); 0074 break; 0075 } 0076 } 0077 } 0078 return m_swapchain.get(); 0079 } 0080 0081 void Window::invalidateSurface() 0082 { 0083 m_swapchain.reset(); 0084 } 0085 0086 void Window::setVisible(bool visible) 0087 { 0088 if (visible) { 0089 map(); 0090 } else { 0091 unmap(); 0092 } 0093 0094 QPlatformWindow::setVisible(visible); 0095 } 0096 0097 QSurfaceFormat Window::format() const 0098 { 0099 return m_format; 0100 } 0101 0102 void Window::requestActivateWindow() 0103 { 0104 #if QT_VERSION < QT_VERSION_CHECK(6, 7, 0) 0105 QWindowSystemInterface::handleWindowActivated(window()); 0106 #else 0107 QWindowSystemInterface::handleFocusWindowChanged(window()); 0108 #endif 0109 } 0110 0111 void Window::setGeometry(const QRect &rect) 0112 { 0113 const QRect oldGeometry = geometry(); 0114 QPlatformWindow::setGeometry(rect); 0115 0116 if (window()->isVisible() && rect.isValid()) { 0117 QWindowSystemInterface::handleGeometryChange(window(), geometry()); 0118 } 0119 0120 if (isExposed() && oldGeometry.size() != rect.size()) { 0121 QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), rect.size())); 0122 } 0123 } 0124 0125 WId Window::winId() const 0126 { 0127 return m_windowId; 0128 } 0129 0130 qreal Window::devicePixelRatio() const 0131 { 0132 return m_scale; 0133 } 0134 0135 InternalWindow *Window::internalWindow() const 0136 { 0137 return m_handle; 0138 } 0139 0140 void Window::map() 0141 { 0142 if (m_handle) { 0143 return; 0144 } 0145 0146 m_handle = new InternalWindow(window()); 0147 } 0148 0149 void Window::unmap() 0150 { 0151 if (!m_handle) { 0152 return; 0153 } 0154 0155 m_handle->destroyWindow(); 0156 m_handle = nullptr; 0157 0158 invalidateSurface(); 0159 } 0160 0161 } 0162 }