scene.h 24.6 KB
Newer Older
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
1 2 3
/*
    KWin - the KDE window manager
    This file is part of the KDE project.
4

Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
5
    SPDX-FileCopyrightText: 2006 Lubos Lunak <l.lunak@kde.org>
6

Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
7 8
    SPDX-License-Identifier: GPL-2.0-or-later
*/
9 10 11 12 13 14 15 16

#ifndef KWIN_SCENE_H
#define KWIN_SCENE_H

#include "toplevel.h"
#include "utils.h"
#include "kwineffects.h"

17
#include <QElapsedTimer>
18
#include <QMatrix4x4>
19

20 21
class QOpenGLFramebufferObject;

22
namespace KWaylandServer
23 24
{
class BufferInterface;
25
class SubSurfaceInterface;
26 27
}

28 29 30
namespace KWin
{

31 32 33 34 35 36
namespace Decoration
{
class DecoratedClientImpl;
class Renderer;
}

37
class AbstractThumbnailItem;
38
class Deleted;
39
class EffectFrameImpl;
40
class EffectWindowImpl;
41
class OverlayWindow;
42
class Shadow;
43
class WindowPixmap;
44 45
class GLTexture;
class AbstractOutput;
46
class SubSurfaceMonitor;
47 48

// The base class for compositing backends.
49
class KWIN_EXPORT Scene : public QObject
50
{
51
    Q_OBJECT
52
public:
53
    explicit Scene(QObject *parent = nullptr);
54
    ~Scene() override = 0;
55 56 57 58 59 60
    class EffectFrame;
    class Window;

    // Returns true if the ctor failed to properly initialize.
    virtual bool initFailed() const = 0;
    virtual CompositingType compositingType() const = 0;
61

62 63
    // Repaints the given screen areas, windows provides the stacking order.
    // The entry point for the main part of the painting pass.
64 65
    // returns the time since the last vblank signal - if there's one
    // ie. "what of this frame is lost to painting"
66 67
    virtual void paint(int screenId, const QRegion &damage, const QList<Toplevel *> &windows,
                       std::chrono::milliseconds presentTime) = 0;
68

69 70 71 72 73 74 75 76
    /**
     * Adds the Toplevel to the Scene.
     *
     * If the toplevel gets deleted, then the scene will try automatically
     * to re-bind an underlying scene window to the corresponding Deleted.
     *
     * @param toplevel The window to be added.
     * @note You can add a toplevel to scene only once.
77
     */
78 79 80 81 82 83 84
    void addToplevel(Toplevel *toplevel);

    /**
     * Removes the Toplevel from the Scene.
     *
     * @param toplevel The window to be removed.
     * @note You can remove a toplevel from the scene only once.
85
     */
86
    void removeToplevel(Toplevel *toplevel);
87

88 89 90 91
    /**
     * @brief Creates the Scene backend of an EffectFrame.
     *
     * @param frame The EffectFrame this Scene::EffectFrame belongs to.
92
     */
93
    virtual Scene::EffectFrame *createEffectFrame(EffectFrameImpl *frame) = 0;
94 95 96 97 98 99 100
    /**
     * @brief Creates the Scene specific Shadow subclass.
     *
     * An implementing class has to create a proper instance. It is not allowed to
     * return @c null.
     *
     * @param toplevel The Toplevel for which the Shadow needs to be created.
101
     */
102
    virtual Shadow *createShadow(Toplevel *toplevel) = 0;
103 104 105 106 107
    /**
     * Method invoked when the screen geometry is changed.
     * Reimplementing classes should also invoke the parent method
     * as it takes care of resizing the overlay window.
     * @param size The new screen geometry size
108
     */
109
    virtual void screenGeometryChanged(const QSize &size);
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
    // Flags controlling how painting is done.
    enum {
        // Window (or at least part of it) will be painted opaque.
        PAINT_WINDOW_OPAQUE         = 1 << 0,
        // Window (or at least part of it) will be painted translucent.
        PAINT_WINDOW_TRANSLUCENT    = 1 << 1,
        // Window will be painted with transformed geometry.
        PAINT_WINDOW_TRANSFORMED    = 1 << 2,
        // Paint only a region of the screen (can be optimized, cannot
        // be used together with TRANSFORMED flags).
        PAINT_SCREEN_REGION         = 1 << 3,
        // Whole screen will be painted with transformed geometry.
        PAINT_SCREEN_TRANSFORMED    = 1 << 4,
        // At least one window will be painted with transformed geometry.
        PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS = 1 << 5,
        // Clear whole background as the very first step, without optimizing it
        PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6,
127
        // PAINT_DECORATION_ONLY = 1 << 7 has been removed
128
        // Window will be painted with a lanczos filter.
Laurent Montel's avatar
Laurent Montel committed
129
        PAINT_WINDOW_LANCZOS = 1 << 8
130
        // PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_WITHOUT_FULL_REPAINTS = 1 << 9 has been removed
131
    };
132 133 134
    // types of filtering available
    enum ImageFilterType { ImageFilterFast, ImageFilterGood };
    // there's nothing to paint (adjust time_diff later)
135
    void idle();
136
    virtual bool syncsToVBlank() const;
137
    virtual OverlayWindow* overlayWindow() const = 0;
138 139 140

    virtual bool makeOpenGLContextCurrent();
    virtual void doneOpenGLContextCurrent();
141
    virtual bool supportsSurfacelessContext() const;
142
    virtual bool supportsNativeFence() const;
143

144 145
    virtual QMatrix4x4 screenProjectionMatrix() const;

146 147
    /**
     * Whether the Scene uses an X11 overlay window to perform compositing.
148
     */
149
    virtual bool usesOverlayWindow() const = 0;
150

151
    virtual void triggerFence();
152

153 154
    virtual Decoration::Renderer *createDecorationRenderer(Decoration::DecoratedClientImpl *) = 0;

155 156 157 158 159
    /**
     * Whether the Scene is able to drive animations.
     * This is used as a hint to the effects system which effects can be supported.
     * If the Scene performs software rendering it is supposed to return @c false,
     * if rendering is hardware accelerated it should return @c true.
160
     */
161 162
    virtual bool animationsSupported() const = 0;

163 164 165
    /**
     * The render buffer used by an XRender based compositor scene.
     * Default implementation returns XCB_RENDER_PICTURE_NONE
166
     */
167 168
    virtual xcb_render_picture_t xrenderBufferPicture() const;

169 170 171
    /**
     * The QPainter used by a QPainter based compositor scene.
     * Default implementation returns @c nullptr;
172
     */
173 174
    virtual QPainter *scenePainter() const;

175 176 177
    /**
     * The render buffer used by a QPainter based compositor.
     * Default implementation returns @c nullptr.
178
     */
179
    virtual QImage *qpainterRenderBuffer(int screenId) const;
180

181 182 183 184 185 186
    /**
     * The backend specific extensions (e.g. EGL/GLX extensions).
     *
     * Not the OpenGL (ES) extension!
     *
     * Default implementation returns empty list
187
     */
188 189
    virtual QVector<QByteArray> openGLPlatformInterfaceExtensions() const;

190 191 192 193 194
    virtual QSharedPointer<GLTexture> textureForOutput(AbstractOutput *output) const {
        Q_UNUSED(output);
        return {};
    }

195 196
Q_SIGNALS:
    void frameRendered();
197
    void resetCompositing();
198

199
public Q_SLOTS:
200
    // a window has been closed
201
    void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted);
202
protected:
203
    virtual Window *createWindow(Toplevel *toplevel) = 0;
204
    void createStackingOrder(const QList<Toplevel *> &toplevels);
205
    void clearStackingOrder();
206
    // shared implementation, starts painting the screen
207
    void paintScreen(int *mask, const QRegion &damage, const QRegion &repaint,
208 209 210 211
                     QRegion *updateRegion, QRegion *validRegion,
                     std::chrono::milliseconds presentTime,
                     const QMatrix4x4 &projection = QMatrix4x4(),
                     const QRect &outputGeometry = QRect(), qreal screenScale = 1.0);
212
    // Render cursor texture in case hardware cursor is disabled/non-applicable
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
213
    virtual void paintCursor(const QRegion &region) = 0;
214 215
    friend class EffectsHandlerImpl;
    // called after all effects had their paintScreen() called
216
    void finalPaintScreen(int mask, const QRegion &region, ScreenPaintData& data);
217 218
    // shared implementation of painting the screen in the generic
    // (unoptimized) way
219
    virtual void paintGenericScreen(int mask, const ScreenPaintData &data);
220
    // shared implementation of painting the screen in an optimized way
221
    virtual void paintSimpleScreen(int mask, const QRegion &region);
222
    // paint the background (not the desktop background - the whole background)
223
    virtual void paintBackground(const QRegion &region) = 0;
224 225 226 227 228 229

    /**
     * Notifies about starting to paint.
     *
     * @p damage contains the reported damage as suggested by windows and effects on prepaint calls.
     */
230
    virtual void aboutToStartPainting(int screenId, const QRegion &damage);
231
    // called after all effects had their paintWindow() called
232
    void finalPaintWindow(EffectWindowImpl* w, int mask, const QRegion &region, WindowPaintData& data);
233
    // shared implementation, starts painting the window
234
    virtual void paintWindow(Window* w, int mask, const QRegion &region, const WindowQuadList &quads);
235
    // called after all effects had their drawWindow() called
236
    virtual void finalDrawWindow(EffectWindowImpl* w, int mask, const QRegion &region, WindowPaintData& data);
237 238 239
    // let the scene decide whether it's better to paint more of the screen, eg. in order to allow a buffer swap
    // the default is NOOP
    virtual void extendPaintRegion(QRegion &region, bool opaqueFullscreen);
240
    virtual void paintDesktop(int desktop, int mask, const QRegion &region, ScreenPaintData &data);
241 242 243

    virtual void paintEffectQuickView(EffectQuickView *w) = 0;

244 245
    // saved data for 2nd pass of optimized screen painting
    struct Phase2Data {
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
246
        Window *window = nullptr;
247 248
        QRegion region;
        QRegion clip;
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
249
        int mask = 0;
250 251 252 253 254 255 256 257
        WindowQuadList quads;
    };
    // The region which actually has been painted by paintScreen() and should be
    // copied from the buffer to the screen. I.e. the region returned from Scene::paintScreen().
    // Since prePaintWindow() can extend areas to paint, these changes would have to propagate
    // up all the way from paintSimpleScreen() up to paintScreen(), so save them here rather
    // than propagate them up in arguments.
    QRegion painted_region;
258 259 260 261
    // Additional damage that needs to be repaired to bring a reused back buffer up to date
    QRegion repaint_region;
    // The dirty region before it was unioned with repaint_region
    QRegion damaged_region;
262 263
    // The screen that is being currently painted
    int painted_screen = -1;
264
private:
265
    void paintWindowThumbnails(Scene::Window *w, const QRegion &region, qreal opacity, qreal brightness, qreal saturation);
266
    void paintDesktopThumbnails(Scene::Window *w);
267
    std::chrono::milliseconds m_expectedPresentTimestamp = std::chrono::milliseconds::zero();
268 269 270
    QHash< Toplevel*, Window* > m_windows;
    // windows in their stacking order
    QVector< Window* > stacking_order;
271 272
    // how many times finalPaintScreen() has been called
    int m_paintScreenCount = 0;
273
};
274

275 276
/**
 * Factory class to create a Scene. Needs to be implemented by the plugins.
277
 */
278 279 280 281
class KWIN_EXPORT SceneFactory : public QObject
{
    Q_OBJECT
public:
282
    ~SceneFactory() override;
283 284 285

    /**
     * @returns The created Scene, may be @c nullptr.
286
     */
287 288 289 290 291 292
    virtual Scene *create(QObject *parent = nullptr) const = 0;

protected:
    explicit SceneFactory(QObject *parent);
};

293
// The base class for windows representations in composite backends
294
class Scene::Window : public QObject
295
{
296 297
    Q_OBJECT

298
public:
299 300
    explicit Window(Toplevel *client, QObject *parent = nullptr);
    ~Window() override;
301
    // perform the actual painting of the window
302
    virtual void performPaint(int mask, const QRegion &region, const WindowPaintData &data) = 0;
303
    // do any cleanup needed when the window's composite pixmap is discarded
304 305
    void discardPixmap();
    void updatePixmap();
306 307 308 309 310 311 312 313 314 315
    int x() const;
    int y() const;
    int width() const;
    int height() const;
    QRect geometry() const;
    QPoint pos() const;
    QSize size() const;
    QRect rect() const;
    // access to the internal window class
    // TODO eventually get rid of this
316
    Toplevel* window() const;
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
    // should the window be painted
    bool isPaintingEnabled() const;
    void resetPaintingEnabled();
    // Flags explaining why painting should be disabled
    enum {
        // Window will not be painted
        PAINT_DISABLED                 = 1 << 0,
        // Window will not be painted because it is deleted
        PAINT_DISABLED_BY_DELETE       = 1 << 1,
        // Window will not be painted because of which desktop it's on
        PAINT_DISABLED_BY_DESKTOP      = 1 << 2,
        // Window will not be painted because it is minimized
        PAINT_DISABLED_BY_MINIMIZE     = 1 << 3,
        // Window will not be painted because it's not on the current activity
        PAINT_DISABLED_BY_ACTIVITY     = 1 << 5
332
    };
333 334 335 336 337 338
    void enablePainting(int reason);
    void disablePainting(int reason);
    // is the window visible at all
    bool isVisible() const;
    // is the window fully opaque
    bool isOpaque() const;
339 340
    // is the window shaded
    bool isShaded() const;
341
    // shape of the window
342
    QRegion bufferShape() const;
343
    QRegion clientShape() const;
344 345
    QRegion decorationShape() const;
    QPoint bufferOffset() const;
346
    void discardShape();
347
    void updateToplevel(Deleted *deleted);
348 349
    // creates initial quad list for the window
    virtual WindowQuadList buildQuads(bool force = false) const;
350 351 352
    void updateShadow(Shadow* shadow);
    const Shadow* shadow() const;
    Shadow* shadow();
353 354
    void referencePreviousPixmap();
    void unreferencePreviousPixmap();
355
    void discardQuads();
356
    void preprocess();
357 358 359 360 361
    void addRepaint(const QRegion &region);
    void addLayerRepaint(const QRegion &region);
    QRegion repaints(int screen) const;
    void resetRepaints(int screen);
    bool wantsRepaint() const;
362 363 364 365 366

    virtual QSharedPointer<GLTexture> windowTexture() {
        return {};
    }

367 368 369
    /**
     * @brief Returns the WindowPixmap for this Window.
     *
Yuri Chornoivan's avatar
Yuri Chornoivan committed
370
     * If the WindowPixmap does not yet exist, this method will invoke createWindowPixmap.
371 372 373
     * If the WindowPixmap is not valid it tries to create it, in case this succeeds the WindowPixmap is
     * returned. In case it fails, the previous (and still valid) WindowPixmap is returned.
     *
Yuri Chornoivan's avatar
Yuri Chornoivan committed
374
     * @note This method can return @c NULL as there might neither be a valid previous nor current WindowPixmap
375 376 377 378 379 380
     * around.
     *
     * The WindowPixmap gets casted to the type passed in as a template parameter. That way this class does not
     * need to know the actual WindowPixmap subclass used by the concrete Scene implementations.
     *
     * @return The WindowPixmap casted to T* or @c NULL if there is no valid window pixmap.
381
     */
382 383
    template<typename T> T *windowPixmap() const;
    template<typename T> T *previousWindowPixmap() const;
384 385

protected:
386
    WindowQuadList makeDecorationQuads(const QRect *rects, const QRegion &region) const;
387
    WindowQuadList makeContentsQuads() const;
388 389 390 391
    /**
     * @brief Factory method to create a WindowPixmap.
     *
     * The inheriting classes need to implement this method to create a new instance of their WindowPixmap subclass.
Yuri Chornoivan's avatar
Yuri Chornoivan committed
392
     * @note Do not use WindowPixmap::create on the created instance. The Scene will take care of that.
393
     */
394
    virtual WindowPixmap *createWindowPixmap() = 0;
395 396
    Toplevel* toplevel;
    ImageFilterType filter;
397
    Shadow *m_shadow;
398
private:
399 400
    void reallocRepaints();

401 402
    QScopedPointer<WindowPixmap> m_currentPixmap;
    QScopedPointer<WindowPixmap> m_previousPixmap;
403 404
    QVector<QRegion> m_repaints;
    QVector<QRegion> m_layerRepaints;
405
    SubSurfaceMonitor *m_subsurfaceMonitor = nullptr;
406
    int m_referencePixmapCounter;
407
    int disable_painting;
408 409
    mutable QRegion m_bufferShape;
    mutable bool m_bufferShapeIsValid = false;
Kevin Funk's avatar
Kevin Funk committed
410
    mutable QScopedPointer<WindowQuadList> cached_quad_list;
411 412
    Q_DISABLE_COPY(Window)
};
413

414
/**
Yuri Chornoivan's avatar
Yuri Chornoivan committed
415
 * @brief Wrapper for a pixmap of the Scene::Window.
416 417
 *
 * This class encapsulates the functionality to get the pixmap for a window. When initialized the pixmap is not yet
Yuri Chornoivan's avatar
Yuri Chornoivan committed
418 419
 * mapped to the window and isValid will return @c false. The pixmap mapping to the window can be established
 * through @ref create. If it succeeds isValid will return @c true, otherwise it will keep in the non valid
420 421 422 423 424
 * state and it can be tried to create the pixmap mapping again (e.g. in the next frame).
 *
 * This class is not intended to be updated when the pixmap is no longer valid due to e.g. resizing the window.
 * Instead a new instance of this class should be instantiated. The idea behind this is that a valid pixmap does not
 * get destroyed, but can continue to be used. To indicate that a newer pixmap should in generally be around, one can
Yuri Chornoivan's avatar
Yuri Chornoivan committed
425
 * use markAsDiscarded.
426 427 428
 *
 * This class is intended to be inherited for the needs of the compositor backends which need further mapping from
 * the native pixmap to the respective rendering format.
429
 */
430
class KWIN_EXPORT WindowPixmap : public QObject
431
{
432
    Q_OBJECT
433 434 435 436 437
public:
    virtual ~WindowPixmap();
    /**
     * @brief Tries to create the mapping between the Window and the pixmap.
     *
Yuri Chornoivan's avatar
Yuri Chornoivan committed
438
     * In case this method succeeds in creating the pixmap for the window, isValid will return @c true otherwise
439 440 441 442
     * @c false.
     *
     * Inheriting classes should re-implement this method in case they need to add further functionality for mapping the
     * native pixmap to the rendering format.
443
     */
444
    virtual void create();
445 446 447 448
    /**
     * @brief Recursively updates the mapping between the WindowPixmap and the buffer.
     */
    virtual void update();
449 450
    /**
     * @return @c true if the pixmap has been created and is valid, @c false otherwise
451
     */
452
    virtual bool isValid() const;
453 454 455 456
    /**
     * Returns @c true if this is the root window pixmap; otherwise returns @c false.
     */
    bool isRoot() const;
457 458
    /**
     * @return The native X11 pixmap handle
459
     */
460
    xcb_pixmap_t pixmap() const;
461 462
    /**
     * @return The Wayland BufferInterface for this WindowPixmap.
463
     */
464
    KWaylandServer::BufferInterface *buffer() const;
465
    const QSharedPointer<QOpenGLFramebufferObject> &fbo() const;
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
466
    QImage internalImage() const;
467 468 469 470 471 472
    /**
     * @brief Whether this WindowPixmap is considered as discarded. This means the window has changed in a way that a new
     * WindowPixmap should have been created already.
     *
     * @return @c true if this WindowPixmap is considered as discarded, @c false otherwise.
     * @see markAsDiscarded
473
     */
474 475
    bool isDiscarded() const;
    /**
Yuri Chornoivan's avatar
Yuri Chornoivan committed
476
     * @brief Marks this WindowPixmap as discarded. From now on isDiscarded will return @c true. This method should
477 478 479
     * only be used by the Window when it changes in a way that a new pixmap is required.
     *
     * @see isDiscarded
480
     */
481
    void markAsDiscarded();
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
    /**
     * Returns the position of the WindowPixmap relative to the upper left corner of the parent.
     *
     * This method returns the position of the WindowPixmap relative to the upper left corner
     * of the window pixmap if parent() is @c null.
     *
     * The upper left corner of the parent window pixmap corresponds to (0, 0).
     */
    QPoint position() const;
    /**
     * Returns the position of the WindowPixmap relative to the upper left corner of the window
     * frame. Note that position() returns the position relative to the parent WindowPixmap.
     *
     * The upper left corner of the window frame corresponds to (0, 0).
     */
    QPoint framePosition() const;
498 499
    /**
     * The size of the pixmap.
500
     */
501
    const QSize &size() const;
502 503 504 505 506 507 508 509 510 511 512 513
    /**
     * Returns the device pixel ratio for the attached buffer. This is the ratio between device
     * pixels and logical pixels.
     */
    qreal scale() const;
    /**
     * Returns the region that specifies the area inside the attached buffer with the actual
     * client's contents.
     *
     * The upper left corner of the attached buffer corresponds to (0, 0).
     */
    QRegion shape() const;
514 515 516 517 518 519
    /**
     * Returns the region that specifies the opaque area inside the attached buffer.
     *
     * The upper left corner of the attached buffer corresponds to (0, 0).
     */
    QRegion opaque() const;
520 521 522 523 524 525
    /**
     * The geometry of the Client's content inside the pixmap. In case of a decorated Client the
     * pixmap also contains the decoration which is not rendered into this pixmap, though. This
     * contentsRect tells where inside the complete pixmap the real content is.
     */
    const QRect &contentsRect() const;
526 527 528
    /**
     * @brief Returns the Toplevel this WindowPixmap belongs to.
     * Note: the Toplevel can change over the lifetime of the WindowPixmap in case the Toplevel is copied to Deleted.
529
     */
530
    Toplevel *toplevel() const;
531 532 533 534
    /**
     * Returns @c true if the attached buffer has an alpha channel; otherwise returns @c false.
     */
    bool hasAlphaChannel() const;
535 536 537 538 539 540 541 542
    /**
     * Maps the specified @a point from the window pixmap coordinates to the window local coordinates.
     */
    QPointF mapToWindow(const QPointF &point) const;
    /**
     * Maps the specified @a point from the window pixmap coordinates to the buffer pixel coordinates.
     */
    QPointF mapToBuffer(const QPointF &point) const;
543 544 545 546
    /**
     * Maps the specified @a region from the window pixmap coordinates to the global screen coordinates.
     */
    QRegion mapToGlobal(const QRegion &region) const;
547

548 549
    /**
     * @returns the parent WindowPixmap in the sub-surface tree
550
     */
551 552 553 554 555 556
    WindowPixmap *parent() const {
        return m_parent;
    }

    /**
     * @returns the current sub-surface tree
557
     */
558 559 560 561 562 563
    QVector<WindowPixmap*> children() const {
        return m_children;
    }

    /**
     * @returns the subsurface this WindowPixmap is for if it is not for a root window
564
     */
565
    KWaylandServer::SubSurfaceInterface *subSurface() const;
566

567 568
    /**
     * @returns the surface this WindowPixmap references, might be @c null.
569
     */
570
    KWaylandServer::SurfaceInterface *surface() const;
571

572 573
protected:
    explicit WindowPixmap(Scene::Window *window);
574 575
    explicit WindowPixmap(KWaylandServer::SubSurfaceInterface *subSurface, WindowPixmap *parent);
    virtual WindowPixmap *createChild(KWaylandServer::SubSurfaceInterface *subSurface);
576 577
    /**
     * @return The Window this WindowPixmap belongs to
578
     */
579
    Scene::Window *window();
580

581 582
    /**
     * Sets the sub-surface tree to @p children.
583
     */
584 585 586 587
    void setChildren(const QVector<WindowPixmap*> &children) {
        m_children = children;
    }

588
private:
589 590 591
    void setBuffer(KWaylandServer::BufferInterface *buffer);
    void clear();

592 593 594 595
    Scene::Window *m_window;
    xcb_pixmap_t m_pixmap;
    QSize m_pixmapSize;
    bool m_discarded;
596
    QRect m_contentsRect;
597
    KWaylandServer::BufferInterface *m_buffer = nullptr;
598
    QSharedPointer<QOpenGLFramebufferObject> m_fbo;
Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
599
    QImage m_internalImage;
600 601
    WindowPixmap *m_parent = nullptr;
    QVector<WindowPixmap*> m_children;
602
    QPointer<KWaylandServer::SubSurfaceInterface> m_subSurface;
603 604
};

605
class Scene::EffectFrame
606 607 608 609
{
public:
    EffectFrame(EffectFrameImpl* frame);
    virtual ~EffectFrame();
610
    virtual void render(const QRegion &region, double opacity, double frameOpacity) = 0;
611 612 613 614 615 616 617 618 619 620
    virtual void free() = 0;
    virtual void freeIconFrame() = 0;
    virtual void freeTextFrame() = 0;
    virtual void freeSelection() = 0;
    virtual void crossFadeIcon() = 0;
    virtual void crossFadeText() = 0;

protected:
    EffectFrameImpl* m_effectFrame;
};
621

622 623
inline
int Scene::Window::x() const
624
{
625
    return toplevel->x();
626 627
}

628 629
inline
int Scene::Window::y() const
630
{
631
    return toplevel->y();
632
}
633 634 635

inline
int Scene::Window::width() const
636
{
637
    return toplevel->width();
638 639
}

640 641
inline
int Scene::Window::height() const
642
{
643
    return toplevel->height();
644
}
645 646 647

inline
QRect Scene::Window::geometry() const
648
{
649
    return toplevel->frameGeometry();
650
}
651 652 653

inline
QSize Scene::Window::size() const
654
{
655
    return toplevel->size();
656 657
}

658 659
inline
QPoint Scene::Window::pos() const
660
{
661
    return toplevel->pos();
662 663
}

664 665
inline
QRect Scene::Window::rect() const
666
{
667
    return toplevel->rect();
668
}
669 670

inline
671
Toplevel* Scene::Window::window() const
672
{
673
    return toplevel;
674
}
675

676 677 678 679 680 681 682 683 684 685 686 687
inline
const Shadow* Scene::Window::shadow() const
{
    return m_shadow;
}

inline
Shadow* Scene::Window::shadow()
{
    return m_shadow;
}

688
inline
689
KWaylandServer::BufferInterface *WindowPixmap::buffer() const
690
{
691
    return m_buffer;
692 693
}

694 695 696 697 698 699
inline
const QSharedPointer<QOpenGLFramebufferObject> &WindowPixmap::fbo() const
{
    return m_fbo;
}

Vlad Zahorodnii's avatar
Vlad Zahorodnii committed
700 701 702 703 704 705
inline
QImage WindowPixmap::internalImage() const
{
    return m_internalImage;
}

706 707
template <typename T>
inline
708
T *Scene::Window::windowPixmap() const
709
{
710
    if (m_currentPixmap && m_currentPixmap->isValid()) {
711
        return static_cast<T*>(m_currentPixmap.data());
712 713
    }
    if (m_previousPixmap && m_previousPixmap->isValid()) {
714 715
        return static_cast<T*>(m_previousPixmap.data());
    }
716
    return nullptr;
717 718
}

719 720
template <typename T>
inline
721
T *Scene::Window::previousWindowPixmap() const
722 723 724 725
{
    return static_cast<T*>(m_previousPixmap.data());
}

726
inline
727
Toplevel* WindowPixmap::toplevel() const
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750
{
    return m_window->window();
}

inline
xcb_pixmap_t WindowPixmap::pixmap() const
{
    return m_pixmap;
}

inline
bool WindowPixmap::isDiscarded() const
{
    return m_discarded;
}

inline
void WindowPixmap::markAsDiscarded()
{
    m_discarded = true;
    m_window->referencePreviousPixmap();
}

751 752 753 754 755 756
inline
const QRect &WindowPixmap::contentsRect() const
{
    return m_contentsRect;
}

757 758 759 760 761 762
inline
const QSize &WindowPixmap::size() const
{
    return m_pixmapSize;
}

763 764
} // namespace

765 766
Q_DECLARE_INTERFACE(KWin::SceneFactory, "org.kde.kwin.Scene")

767
#endif