File indexing completed on 2024-05-19 16:34:47

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 "scene/surfaceitem_internal.h"
0008 #include "composite.h"
0009 #include "core/renderbackend.h"
0010 #include "deleted.h"
0011 #include "internalwindow.h"
0012 
0013 #include <QOpenGLFramebufferObject>
0014 
0015 namespace KWin
0016 {
0017 
0018 SurfaceItemInternal::SurfaceItemInternal(InternalWindow *window, Scene *scene, Item *parent)
0019     : SurfaceItem(scene, parent)
0020     , m_window(window)
0021 {
0022     connect(window, &Window::bufferGeometryChanged,
0023             this, &SurfaceItemInternal::handleBufferGeometryChanged);
0024     connect(window, &Window::windowClosed,
0025             this, &SurfaceItemInternal::handleWindowClosed);
0026 
0027     setSize(window->bufferGeometry().size());
0028 
0029     // The device pixel ratio of the internal window is static.
0030     QMatrix4x4 surfaceToBufferMatrix;
0031     surfaceToBufferMatrix.scale(window->bufferScale());
0032     setSurfaceToBufferMatrix(surfaceToBufferMatrix);
0033 }
0034 
0035 Window *SurfaceItemInternal::window() const
0036 {
0037     return m_window;
0038 }
0039 
0040 QVector<QRectF> SurfaceItemInternal::shape() const
0041 {
0042     return {rect()};
0043 }
0044 
0045 std::unique_ptr<SurfacePixmap> SurfaceItemInternal::createPixmap()
0046 {
0047     return std::make_unique<SurfacePixmapInternal>(this);
0048 }
0049 
0050 void SurfaceItemInternal::handleBufferGeometryChanged(Window *window, const QRectF &old)
0051 {
0052     if (window->bufferGeometry().size() != old.size()) {
0053         discardPixmap();
0054     }
0055     setSize(window->bufferGeometry().size());
0056 }
0057 
0058 void SurfaceItemInternal::handleWindowClosed(Window *original, Deleted *deleted)
0059 {
0060     m_window = deleted;
0061 }
0062 
0063 SurfacePixmapInternal::SurfacePixmapInternal(SurfaceItemInternal *item, QObject *parent)
0064     : SurfacePixmap(Compositor::self()->backend()->createSurfaceTextureInternal(this), parent)
0065     , m_item(item)
0066 {
0067 }
0068 
0069 QOpenGLFramebufferObject *SurfacePixmapInternal::fbo() const
0070 {
0071     return m_fbo.get();
0072 }
0073 
0074 QImage SurfacePixmapInternal::image() const
0075 {
0076     return m_rasterBuffer;
0077 }
0078 
0079 void SurfacePixmapInternal::create()
0080 {
0081     update();
0082 }
0083 
0084 void SurfacePixmapInternal::update()
0085 {
0086     const Window *window = m_item->window();
0087 
0088     if (window->internalFramebufferObject()) {
0089         m_fbo = window->internalFramebufferObject();
0090         m_size = m_fbo->size();
0091         m_hasAlphaChannel = true;
0092     } else if (!window->internalImageObject().isNull()) {
0093         m_rasterBuffer = window->internalImageObject();
0094         m_size = m_rasterBuffer.size();
0095         m_hasAlphaChannel = m_rasterBuffer.hasAlphaChannel();
0096     }
0097 }
0098 
0099 bool SurfacePixmapInternal::isValid() const
0100 {
0101     return m_fbo != nullptr || !m_rasterBuffer.isNull();
0102 }
0103 
0104 } // namespace KWin