KiCad PCB EDA Suite
Loading...
Searching...
No Matches
rhi_present_mode.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#ifndef RHI_PRESENT_MODE_H
21#define RHI_PRESENT_MODE_H
22
23#include <algorithm>
24#include <chrono>
25#include <cstdint>
26#include <optional>
27#include <string>
28#include <vector>
29
30
34constexpr int RHI_PRESENTS_IN_FLIGHT = 2;
35
36
40enum class RHI_PRESENT_MODE : uint8_t
41{
45};
46
47
59inline RHI_PRESENT_MODE RhiChoosePresentMode( const std::vector<RHI_PRESENT_MODE>& aOffered, bool aComposited,
60 bool aImmediateUnderCompositor = false )
61{
62 auto offered = [&]( RHI_PRESENT_MODE aMode )
63 {
64 return std::find( aOffered.begin(), aOffered.end(), aMode ) != aOffered.end();
65 };
66
67 if( aComposited && aImmediateUnderCompositor && offered( RHI_PRESENT_MODE::IMMEDIATE ) )
69
70 if( offered( RHI_PRESENT_MODE::MAILBOX ) )
72
73 if( aComposited && offered( RHI_PRESENT_MODE::IMMEDIATE ) )
75
77}
78
79
90template <typename TIME_POINT>
91TIME_POINT RhiNextFrameAt( TIME_POINT aFrameStart, double aRefreshHz, std::optional<TIME_POINT> aVblank )
92{
93 using DURATION = typename TIME_POINT::duration;
94
95 const DURATION period = std::chrono::round<DURATION>( std::chrono::duration<double>( 1.0 / aRefreshHz ) );
96
97 if( !aVblank || period <= DURATION::zero() )
98 return aFrameStart + period;
99
100 const DURATION since = aFrameStart - *aVblank;
101 auto refreshes = since / period;
102
106 if( since < DURATION::zero() && refreshes * period != since )
107 --refreshes;
108
109 return *aVblank + ( refreshes + 1 ) * period;
110}
111
112
113#endif // RHI_PRESENT_MODE_H
RHI_PRESENT_MODE
How a swapchain hands finished images to the display.
@ MAILBOX
Replaces the queued image at each blank, never tears, no wait.
@ FIFO
Waits for a vertical blank, never tears, adds up to a refresh of latency.
@ IMMEDIATE
Shows the image at once, tears unless a compositor owns the final present.
TIME_POINT RhiNextFrameAt(TIME_POINT aFrameStart, double aRefreshHz, std::optional< TIME_POINT > aVblank)
The earliest time the frame after one started at aFrameStart may start, for a window whose presents d...
RHI_PRESENT_MODE RhiChoosePresentMode(const std::vector< RHI_PRESENT_MODE > &aOffered, bool aComposited, bool aImmediateUnderCompositor=false)
Choose the present mode for a swapchain from the modes the surface offers.
constexpr int RHI_PRESENTS_IN_FLIGHT
Presents allowed to wait for the display at once while frames are paced.