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

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 "kwinglobals.h"
0010 #include "options.h"
0011 
0012 #include <QObject>
0013 
0014 namespace KWin
0015 {
0016 
0017 class RenderLoopPrivate;
0018 class Item;
0019 
0020 /**
0021  * The RenderLoop class represents the compositing scheduler on a particular output.
0022  *
0023  * The RenderLoop class drives the compositing. The frameRequested() signal is emitted
0024  * when the loop wants a new frame to be rendered. The frameCompleted() signal is
0025  * emitted when a previously rendered frame has been presented on the screen. In case
0026  * you want the compositor to repaint the scene, call the scheduleRepaint() function.
0027  */
0028 class KWIN_EXPORT RenderLoop : public QObject
0029 {
0030     Q_OBJECT
0031 
0032 public:
0033     explicit RenderLoop();
0034     ~RenderLoop() override;
0035 
0036     /**
0037      * Pauses the render loop. While the render loop is inhibited, scheduleRepaint()
0038      * requests are queued.
0039      *
0040      * Once the render loop is uninhibited, the pending schedule requests are going to
0041      * be re-applied.
0042      */
0043     void inhibit();
0044 
0045     /**
0046      * Uninhibits the render loop.
0047      */
0048     void uninhibit();
0049 
0050     /**
0051      * This function must be called before the Compositor starts rendering the next
0052      * frame.
0053      */
0054     void beginFrame();
0055 
0056     /**
0057      * This function must be called after the Compositor has finished rendering the
0058      * next frame.
0059      */
0060     void endFrame();
0061 
0062     /**
0063      * Returns the refresh rate at which the output is being updated, in millihertz.
0064      */
0065     int refreshRate() const;
0066 
0067     /**
0068      * Sets the refresh rate of this RenderLoop to @a refreshRate, in millihertz.
0069      */
0070     void setRefreshRate(int refreshRate);
0071 
0072     /**
0073      * Schedules a compositing cycle at the next available moment.
0074      */
0075     void scheduleRepaint(Item *item = nullptr);
0076 
0077     /**
0078      * Returns the timestamp of the last frame that has been presented on the screen.
0079      * The returned timestamp is sourced from the monotonic clock.
0080      */
0081     std::chrono::nanoseconds lastPresentationTimestamp() const;
0082 
0083     /**
0084      * If a repaint has been scheduled, this function returns the expected time when
0085      * the next frame will be presented on the screen. The returned timestamp is sourced
0086      * from the monotonic clock.
0087      */
0088     std::chrono::nanoseconds nextPresentationTimestamp() const;
0089 
0090     /**
0091      * Sets the surface that currently gets scanned out,
0092      * so that this RenderLoop can adjust its timing behavior to that surface
0093      */
0094     void setFullscreenSurface(Item *surface);
0095 
0096     enum class VrrPolicy : uint32_t {
0097         Never = 0,
0098         Always = 1,
0099         Automatic = 2,
0100     };
0101     Q_ENUM(VrrPolicy)
0102 
0103     /**
0104      * the current policy regarding the use of variable refresh rate
0105      */
0106     VrrPolicy vrrPolicy() const;
0107 
0108     /**
0109      * Set the policy regarding the use of variable refresh rate with RenderLoop
0110      */
0111     void setVrrPolicy(VrrPolicy vrrPolicy);
0112 
0113     /**
0114      * Returns the latency policy for this render loop.
0115      */
0116     LatencyPolicy latencyPolicy() const;
0117 
0118     /**
0119      * Sets the latecy policy of this render loop to @a policy. By default,
0120      * the latency policy of this render loop matches options->latencyPolicy().
0121      */
0122     void setLatencyPolicy(LatencyPolicy policy);
0123 
0124     /**
0125      * Resets the latency policy to the default value.
0126      */
0127     void resetLatencyPolicy();
0128 
0129 Q_SIGNALS:
0130     /**
0131      * This signal is emitted when the refresh rate of this RenderLoop has changed.
0132      */
0133     void refreshRateChanged();
0134     /**
0135      * This signal is emitted when a frame has been actually presented on the screen.
0136      * @a timestamp indicates the time when it took place.
0137      */
0138     void framePresented(RenderLoop *loop, std::chrono::nanoseconds timestamp);
0139 
0140     /**
0141      * This signal is emitted when the render loop wants a new frame to be composited.
0142      *
0143      * The Compositor should make a connection to this signal using Qt::DirectConnection.
0144      */
0145     void frameRequested(RenderLoop *loop);
0146 
0147 private:
0148     std::unique_ptr<RenderLoopPrivate> d;
0149     friend class RenderLoopPrivate;
0150 };
0151 
0152 } // namespace KWin