File indexing completed on 2024-11-10 04:56:33
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 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #include "virtual_qpainter_backend.h" 0010 #include "core/graphicsbufferview.h" 0011 #include "core/shmgraphicsbufferallocator.h" 0012 #include "platformsupport/scenes/qpainter/qpainterswapchain.h" 0013 #include "utils/softwarevsyncmonitor.h" 0014 #include "virtual_backend.h" 0015 #include "virtual_output.h" 0016 0017 #include <drm_fourcc.h> 0018 0019 namespace KWin 0020 { 0021 0022 VirtualQPainterLayer::VirtualQPainterLayer(Output *output, VirtualQPainterBackend *backend) 0023 : m_output(output) 0024 , m_backend(backend) 0025 { 0026 } 0027 0028 VirtualQPainterLayer::~VirtualQPainterLayer() 0029 { 0030 } 0031 0032 std::optional<OutputLayerBeginFrameInfo> VirtualQPainterLayer::beginFrame() 0033 { 0034 const QSize nativeSize(m_output->modeSize()); 0035 if (!m_swapchain || m_swapchain->size() != nativeSize) { 0036 m_swapchain = std::make_unique<QPainterSwapchain>(m_backend->graphicsBufferAllocator(), nativeSize, DRM_FORMAT_XRGB8888); 0037 } 0038 0039 m_current = m_swapchain->acquire(); 0040 if (!m_current) { 0041 return std::nullopt; 0042 } 0043 0044 m_renderStart = std::chrono::steady_clock::now(); 0045 return OutputLayerBeginFrameInfo{ 0046 .renderTarget = RenderTarget(m_current->view()->image()), 0047 .repaint = m_output->rect(), 0048 }; 0049 } 0050 0051 bool VirtualQPainterLayer::endFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) 0052 { 0053 m_renderTime = std::chrono::steady_clock::now() - m_renderStart; 0054 return true; 0055 } 0056 0057 QImage *VirtualQPainterLayer::image() 0058 { 0059 return m_current->view()->image(); 0060 } 0061 0062 std::chrono::nanoseconds VirtualQPainterLayer::queryRenderTime() const 0063 { 0064 return m_renderTime; 0065 } 0066 0067 VirtualQPainterBackend::VirtualQPainterBackend(VirtualBackend *backend) 0068 : m_allocator(std::make_unique<ShmGraphicsBufferAllocator>()) 0069 { 0070 connect(backend, &VirtualBackend::outputAdded, this, &VirtualQPainterBackend::addOutput); 0071 connect(backend, &VirtualBackend::outputRemoved, this, &VirtualQPainterBackend::removeOutput); 0072 0073 const auto outputs = backend->outputs(); 0074 for (Output *output : outputs) { 0075 addOutput(output); 0076 } 0077 } 0078 0079 VirtualQPainterBackend::~VirtualQPainterBackend() = default; 0080 0081 void VirtualQPainterBackend::addOutput(Output *output) 0082 { 0083 m_outputs[output] = std::make_unique<VirtualQPainterLayer>(output, this); 0084 } 0085 0086 void VirtualQPainterBackend::removeOutput(Output *output) 0087 { 0088 m_outputs.erase(output); 0089 } 0090 0091 GraphicsBufferAllocator *VirtualQPainterBackend::graphicsBufferAllocator() const 0092 { 0093 return m_allocator.get(); 0094 } 0095 0096 void VirtualQPainterBackend::present(Output *output, const std::shared_ptr<OutputFrame> &frame) 0097 { 0098 static_cast<VirtualOutput *>(output)->present(frame); 0099 } 0100 0101 VirtualQPainterLayer *VirtualQPainterBackend::primaryLayer(Output *output) 0102 { 0103 return m_outputs[output].get(); 0104 } 0105 } 0106 0107 #include "moc_virtual_qpainter_backend.cpp"