Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  time.rs   Sprache: unbekannt

 
#![allow(dead_code)] // IPresentationManager is unused currently

use windows::Win32::System::Performance::{QueryPerformanceCounter, QueryPerformanceFrequency};

pub enum PresentationTimer {
    /// DXGI uses [`QueryPerformanceCounter()`]
    Dxgi {
        /// How many ticks of QPC per second
        frequency: u64,
    },
    /// [`IPresentationManager`] uses [`QueryInterruptTimePrecise()`]
    ///
    /// [`IPresentationManager`]: https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Graphics/CompositionSwapchain/struct.IPresentationManager.html
    /// [`QueryInterruptTimePrecise()`]: https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/System/WindowsProgramming/fn.QueryInterruptTimePrecise.html
    #[allow(non_snake_case)]
    IPresentationManager {
        fnQueryInterruptTimePrecise: unsafe extern "system" fn(*mut u64),
    },
}

impl std::fmt::Debug for PresentationTimer {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match *self {
            Self::Dxgi { frequency } => f
                .debug_struct("DXGI")
                .field("frequency", &frequency)
                .finish(),
            Self::IPresentationManager {
                fnQueryInterruptTimePrecise,
            } => f
                .debug_struct("IPresentationManager")
                .field(
                    "QueryInterruptTimePrecise",
                    &(fnQueryInterruptTimePrecise as usize),
                )
                .finish(),
        }
    }
}

impl PresentationTimer {
    /// Create a presentation timer using QueryPerformanceFrequency (what DXGI uses for presentation times)
    pub fn new_dxgi() -> Self {
        let mut frequency = 0;
        unsafe { QueryPerformanceFrequency(&mut frequency) }.unwrap();

        Self::Dxgi {
            frequency: frequency
                .try_into()
                .expect("Frequency should not be negative"),
        }
    }

    /// Create a presentation timer using QueryInterruptTimePrecise (what IPresentationManager uses for presentation times)
    ///
    /// Panics if QueryInterruptTimePrecise isn't found (below Win10)
    pub fn new_ipresentation_manager() -> Self {
        // We need to load this explicitly, as QueryInterruptTimePrecise is only available on Windows 10+
        //
        // Docs say it's in kernel32.dll, but it's actually in kernelbase.dll.
        // api-ms-win-core-realtime-l1-1-1.dll
        let kernelbase =
            libloading::os::windows::Library::open_already_loaded("kernelbase.dll").unwrap();
        // No concerns about lifetimes here as kernelbase is always there.
        let ptr = unsafe { kernelbase.get(b"QueryInterruptTimePrecise\0").unwrap() };
        Self::IPresentationManager {
            fnQueryInterruptTimePrecise: *ptr,
        }
    }

    /// Gets the current time in nanoseconds.
    pub fn get_timestamp_ns(&self) -> u128 {
        // Always do u128 math _after_ hitting the timing function.
        match *self {
            PresentationTimer::Dxgi { frequency } => {
                let mut counter = 0;
                unsafe { QueryPerformanceCounter(&mut counter) }.unwrap();

                // counter * (1_000_000_000 / freq) but re-ordered to make more precise
                (counter as u128 * 1_000_000_000) / frequency as u128
            }
            PresentationTimer::IPresentationManager {
                fnQueryInterruptTimePrecise,
            } => {
                let mut counter = 0;
                unsafe { fnQueryInterruptTimePrecise(&mut counter) };

                // QueryInterruptTimePrecise uses units of 100ns for its tick.
                counter as u128 * 100
            }
        }
    }
}

[ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge