File indexing completed on 2024-11-10 04:57:07

0001 /*
0002     SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "windowscreencastsource.h"
0008 #include "screencastutils.h"
0009 
0010 #include "compositor.h"
0011 #include "core/output.h"
0012 #include "core/renderloop.h"
0013 #include "core/rendertarget.h"
0014 #include "core/renderviewport.h"
0015 #include "effect/effect.h"
0016 #include "opengl/gltexture.h"
0017 #include "opengl/glutils.h"
0018 #include "scene/itemrenderer.h"
0019 #include "scene/windowitem.h"
0020 #include "scene/workspacescene.h"
0021 #include <drm_fourcc.h>
0022 
0023 namespace KWin
0024 {
0025 
0026 WindowScreenCastSource::WindowScreenCastSource(Window *window, QObject *parent)
0027     : ScreenCastSource(parent)
0028     , m_window(window)
0029     , m_offscreenRef(window)
0030 {
0031     connect(m_window, &Window::closed, this, &ScreenCastSource::closed);
0032 }
0033 
0034 quint32 WindowScreenCastSource::drmFormat() const
0035 {
0036     return DRM_FORMAT_ARGB8888;
0037 }
0038 
0039 bool WindowScreenCastSource::hasAlphaChannel() const
0040 {
0041     return true;
0042 }
0043 
0044 QSize WindowScreenCastSource::textureSize() const
0045 {
0046     return m_window->clientGeometry().size().toSize();
0047 }
0048 
0049 void WindowScreenCastSource::render(spa_data *spa, spa_video_format format)
0050 {
0051     const auto offscreenTexture = GLTexture::allocate(hasAlphaChannel() ? GL_RGBA8 : GL_RGB8, textureSize());
0052     if (!offscreenTexture) {
0053         return;
0054     }
0055     GLFramebuffer offscreenTarget(offscreenTexture.get());
0056 
0057     render(&offscreenTarget);
0058     grabTexture(offscreenTexture.get(), spa, format);
0059 }
0060 
0061 void WindowScreenCastSource::render(GLFramebuffer *target)
0062 {
0063     const QRectF geometry = m_window->clientGeometry();
0064     QMatrix4x4 projectionMatrix;
0065     projectionMatrix.scale(1, -1);
0066     projectionMatrix.ortho(geometry);
0067 
0068     WindowPaintData data;
0069     data.setProjectionMatrix(projectionMatrix);
0070 
0071     RenderTarget renderTarget(target);
0072     RenderViewport viewport(geometry, 1, renderTarget);
0073     GLFramebuffer::pushFramebuffer(target);
0074     glClearColor(0.0, 0.0, 0.0, 0.0);
0075     glClear(GL_COLOR_BUFFER_BIT);
0076     Compositor::self()->scene()->renderer()->renderItem(renderTarget, viewport, m_window->windowItem(), Scene::PAINT_WINDOW_TRANSFORMED, infiniteRegion(), data);
0077     GLFramebuffer::popFramebuffer();
0078 }
0079 
0080 std::chrono::nanoseconds WindowScreenCastSource::clock() const
0081 {
0082     return m_window->output()->renderLoop()->lastPresentationTimestamp();
0083 }
0084 
0085 uint WindowScreenCastSource::refreshRate() const
0086 {
0087     return m_window->output()->refreshRate();
0088 }
0089 
0090 } // namespace KWin
0091 
0092 #include "moc_windowscreencastsource.cpp"