File indexing completed on 2024-05-19 05:31:36

0001 /*
0002     SPDX-FileCopyrightText: 2020 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "effect/globals.h"
0010 
0011 #include <QObject>
0012 
0013 namespace KWin
0014 {
0015 
0016 class RenderLoopPrivate;
0017 class SurfaceItem;
0018 class Item;
0019 class Output;
0020 
0021 /**
0022  * The RenderLoop class represents the compositing scheduler on a particular output.
0023  *
0024  * The RenderLoop class drives the compositing. The frameRequested() signal is emitted
0025  * when the loop wants a new frame to be rendered. The frameCompleted() signal is
0026  * emitted when a previously rendered frame has been presented on the screen. In case
0027  * you want the compositor to repaint the scene, call the scheduleRepaint() function.
0028  */
0029 class KWIN_EXPORT RenderLoop : public QObject
0030 {
0031     Q_OBJECT
0032 
0033 public:
0034     explicit RenderLoop(Output *output);
0035     ~RenderLoop() override;
0036 
0037     /**
0038      * Pauses the render loop. While the render loop is inhibited, scheduleRepaint()
0039      * requests are queued.
0040      *
0041      * Once the render loop is uninhibited, the pending schedule requests are going to
0042      * be re-applied.
0043      */
0044     void inhibit();
0045 
0046     /**
0047      * Uninhibits the render loop.
0048      */
0049     void uninhibit();
0050 
0051     /**
0052      * This function must be called before the Compositor sumbits the next
0053      * frame.
0054      */
0055     void prepareNewFrame();
0056 
0057     /**
0058      * This function must be called before the Compositor starts rendering the next
0059      * frame.
0060      */
0061     void beginPaint();
0062 
0063     /**
0064      * Returns the refresh rate at which the output is being updated, in millihertz.
0065      */
0066     int refreshRate() const;
0067 
0068     /**
0069      * Sets the refresh rate of this RenderLoop to @a refreshRate, in millihertz.
0070      */
0071     void setRefreshRate(int refreshRate);
0072 
0073     void setPresentationSafetyMargin(std::chrono::nanoseconds safetyMargin);
0074 
0075     /**
0076      * Schedules a compositing cycle at the next available moment.
0077      */
0078     void scheduleRepaint(Item *item = nullptr);
0079 
0080     /**
0081      * Returns the timestamp of the last frame that has been presented on the screen.
0082      * The returned timestamp is sourced from the monotonic clock.
0083      */
0084     std::chrono::nanoseconds lastPresentationTimestamp() const;
0085 
0086     /**
0087      * If a repaint has been scheduled, this function returns the expected time when
0088      * the next frame will be presented on the screen. The returned timestamp is sourced
0089      * from the monotonic clock.
0090      */
0091     std::chrono::nanoseconds nextPresentationTimestamp() const;
0092 
0093     void setPresentationMode(PresentationMode mode);
0094 
0095 Q_SIGNALS:
0096     /**
0097      * This signal is emitted when the refresh rate of this RenderLoop has changed.
0098      */
0099     void refreshRateChanged();
0100     /**
0101      * This signal is emitted when a frame has been actually presented on the screen.
0102      * @a timestamp indicates the time when it took place.
0103      */
0104     void framePresented(RenderLoop *loop, std::chrono::nanoseconds timestamp, PresentationMode mode);
0105 
0106     /**
0107      * This signal is emitted when the render loop wants a new frame to be composited.
0108      *
0109      * The Compositor should make a connection to this signal using Qt::DirectConnection.
0110      */
0111     void frameRequested(RenderLoop *loop);
0112 
0113 private:
0114     std::unique_ptr<RenderLoopPrivate> d;
0115     friend class RenderLoopPrivate;
0116 };
0117 
0118 } // namespace KWin