From 88462530746749163bcf1dc89be20a19f2394e71 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Thu, 6 Feb 2025 09:28:20 +0100 Subject: [PATCH] Stop using time@0.1 --- webrender/Cargo.toml | 1 - webrender/src/lib.rs | 1 - webrender/src/prim_store/mod.rs | 4 +- webrender/src/profiler.rs | 3 +- webrender/src/render_api.rs | 2 +- webrender/src/render_backend.rs | 2 +- webrender/src/renderer/mod.rs | 2 +- webrender/src/renderer/shade.rs | 3 +- webrender/src/renderer/upload.rs | 2 +- webrender/src/scene_builder_thread.rs | 2 +- webrender_api/Cargo.toml | 11 ++- webrender_api/src/display_list.rs | 2 +- webrender_api/src/lib.rs | 3 +- webrender_api/src/precise_time_ns.rs | 119 ++++++++++++++++++++++++++ 14 files changed, 141 insertions(+), 16 deletions(-) create mode 100644 webrender_api/src/precise_time_ns.rs diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml index eda61c72b1..26d8782679 100644 --- a/webrender/Cargo.toml +++ b/webrender/Cargo.toml @@ -43,7 +43,6 @@ rayon = "1" ron = { optional = true, version = "0.8" } serde = { optional = true, version = "1.0", features = ["serde_derive"] } smallvec = "1" -time = "0.1" api = { version = "0.66.0", path = "../webrender_api", package = "webrender_api" } webrender_build = { version = "0.0.2", path = "../webrender_build" } malloc_size_of = { version = "0.0.3", path = "../wr_malloc_size_of", package = "wr_malloc_size_of" } diff --git a/webrender/src/lib.rs b/webrender/src/lib.rs index 394814c653..7aca9c641a 100644 --- a/webrender/src/lib.rs +++ b/webrender/src/lib.rs @@ -156,7 +156,6 @@ extern crate rayon; extern crate ron; #[macro_use] extern crate smallvec; -extern crate time; #[cfg(all(feature = "capture", feature = "png"))] extern crate png; #[cfg(test)] diff --git a/webrender/src/prim_store/mod.rs b/webrender/src/prim_store/mod.rs index 6c03011051..dad9bce221 100644 --- a/webrender/src/prim_store/mod.rs +++ b/webrender/src/prim_store/mod.rs @@ -1332,7 +1332,7 @@ impl PrimitiveScratchBuffer { const LINE_HEIGHT: f32 = 20.0; const X0: f32 = 32.0; const Y0: f32 = 32.0; - let now = time::precise_time_ns(); + let now = api::precise_time_ns(); let msgs_to_remove = self.messages.len().max(MSGS_TO_RETAIN) - MSGS_TO_RETAIN; let mut msgs_removed = 0; @@ -1438,7 +1438,7 @@ impl PrimitiveScratchBuffer { ) { self.messages.push(DebugMessage { msg, - timestamp: time::precise_time_ns(), + timestamp: api::precise_time_ns(), }) } } diff --git a/webrender/src/profiler.rs b/webrender/src/profiler.rs index d6d9931927..4117de625b 100644 --- a/webrender/src/profiler.rs +++ b/webrender/src/profiler.rs @@ -19,7 +19,7 @@ //! - A '|' token to start a new column. //! - A '_' token to start a new row. -use api::{ColorF, ColorU}; +use api::{ColorF, ColorU, precise_time_ns}; use glyph_rasterizer::profiler::GlyphRasterizeProfiler; use crate::renderer::DebugRenderer; use crate::device::query::GpuTimer; @@ -32,7 +32,6 @@ use std::fmt::{Write, Debug}; use std::f32; use std::ops::Range; use std::time::Duration; -use time::precise_time_ns; macro_rules! set_text { ($dst:expr, $($arg:tt)*) => { diff --git a/webrender/src/render_api.rs b/webrender/src/render_api.rs index 8113864e05..8af660fc68 100644 --- a/webrender/src/render_api.rs +++ b/webrender/src/render_api.rs @@ -4,6 +4,7 @@ #![deny(missing_docs)] +use api::precise_time_ns; use std::cell::Cell; use std::fmt; use std::marker::PhantomData; @@ -11,7 +12,6 @@ use std::path::PathBuf; use std::sync::Arc; use std::u32; use api::{HitTestFlags, MinimapData, SnapshotImageKey}; -use time::precise_time_ns; use crate::api::channel::{Sender, single_msg_channel, unbounded_channel}; use crate::api::{BuiltDisplayList, IdNamespace, ExternalScrollId, Parameter, BoolParameter}; use crate::api::{FontKey, FontInstanceKey, NativeFontHandle}; diff --git a/webrender/src/render_backend.rs b/webrender/src/render_backend.rs index f76585f6a9..c4b08a2558 100644 --- a/webrender/src/render_backend.rs +++ b/webrender/src/render_backend.rs @@ -13,6 +13,7 @@ use api::{DocumentId, ExternalScrollId, HitTestResult}; use api::{IdNamespace, PipelineId, RenderNotifier, SampledScrollOffset}; use api::{NotificationRequest, Checkpoint, QualitySettings}; use api::{FramePublishId, PrimitiveKeyKind, RenderReasons}; +use api::precise_time_ns; use api::units::*; use api::channel::{single_msg_channel, Sender, Receiver}; use crate::bump_allocator::ChunkPool; @@ -71,7 +72,6 @@ use std::{mem, u32}; use std::path::PathBuf; #[cfg(feature = "replay")] use crate::frame_builder::Frame; -use time::precise_time_ns; use core::time::Duration; use crate::util::{Recycler, VecHelper, drain_filter}; diff --git a/webrender/src/renderer/mod.rs b/webrender/src/renderer/mod.rs index 6a3a016eb3..5b202f9c96 100644 --- a/webrender/src/renderer/mod.rs +++ b/webrender/src/renderer/mod.rs @@ -43,6 +43,7 @@ use api::{PipelineId, ImageRendering, Checkpoint, NotificationRequest, ImageBuff #[cfg(feature = "replay")] use api::ExternalImage; use api::FramePublishId; +use api::precise_time_ns; use api::units::*; use api::channel::{Sender, Receiver}; pub use api::DebugFlags; @@ -114,7 +115,6 @@ use std::{ }; #[cfg(any(feature = "capture", feature = "replay"))] use std::collections::hash_map::Entry; -use time::precise_time_ns; mod debug; mod gpu_buffer; diff --git a/webrender/src/renderer/shade.rs b/webrender/src/renderer/shade.rs index 5463e8eb67..ecf9de4e2f 100644 --- a/webrender/src/renderer/shade.rs +++ b/webrender/src/renderer/shade.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use api::{ImageBufferKind, units::DeviceSize}; +use api::{precise_time_ns, ImageBufferKind, units::DeviceSize}; use crate::batch::{BatchKey, BatchKind, BrushBatchKind, BatchFeatures}; use crate::composite::{CompositeFeatures, CompositeSurfaceFormat}; use crate::device::{Device, Program, ShaderError}; @@ -17,7 +17,6 @@ use crate::renderer::{ use crate::profiler::{self, TransactionProfile, ns_to_ms}; use gleam::gl::GlType; -use time::precise_time_ns; use std::cell::RefCell; use std::rc::Rc; diff --git a/webrender/src/renderer/upload.rs b/webrender/src/renderer/upload.rs index c987038651..f9c5b2ebe0 100644 --- a/webrender/src/renderer/upload.rs +++ b/webrender/src/renderer/upload.rs @@ -16,12 +16,12 @@ //! here relies on submitting draw calls via the renderer. +use api::precise_time_ns; use std::mem; use std::collections::VecDeque; use std::sync::Arc; use std::time::Duration; use euclid::{Transform3D, point2}; -use time::precise_time_ns; use malloc_size_of::MallocSizeOfOps; use api::units::*; use api::{ExternalImageSource, ImageBufferKind, ImageFormat}; diff --git a/webrender/src/scene_builder_thread.rs b/webrender/src/scene_builder_thread.rs index a7bd3cfc8a..09f685d628 100644 --- a/webrender/src/scene_builder_thread.rs +++ b/webrender/src/scene_builder_thread.rs @@ -7,6 +7,7 @@ use api::{DocumentId, PipelineId, ExternalEvent, BlobImageRequest}; use api::{NotificationRequest, Checkpoint, IdNamespace, QualitySettings}; use api::{PrimitiveKeyKind, GlyphDimensionRequest, GlyphIndexRequest}; use api::channel::{unbounded_channel, single_msg_channel, Receiver, Sender}; +use api::precise_time_ns; use api::units::*; use crate::render_api::{ApiMsg, FrameMsg, SceneMsg, ResourceUpdate, TransactionMsg, MemoryReport}; use crate::box_shadow::BoxShadow; @@ -35,7 +36,6 @@ use crate::spatial_tree::{SceneSpatialTree, SpatialTreeUpdates}; use crate::telemetry::Telemetry; use crate::SceneBuilderHooks; use std::iter; -use time::precise_time_ns; use crate::util::drain_filter; use std::thread; use std::time::Duration; diff --git a/webrender_api/Cargo.toml b/webrender_api/Cargo.toml index 30557d1cd4..e87952d4bb 100644 --- a/webrender_api/Cargo.toml +++ b/webrender_api/Cargo.toml @@ -22,7 +22,16 @@ malloc_size_of_derive = "0.1" serde = { version = "1.0", features = ["rc"] } serde_derive = "1.0" serde_bytes = "0.11" -time = "0.1" malloc_size_of = { version = "0.0.3", path = "../wr_malloc_size_of", package = "wr_malloc_size_of" } peek-poke = { version = "0.3", path = "../peek-poke", features = ["extras"] } crossbeam-channel = "0.5" + +[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] +mach2 = { version = "0.4" } + +[target.'cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))'.dependencies] +libc = { version = "0.2" } + +[target.'cfg(target_os = "windows")'.dependencies] +windows-sys = { version = "0.59", features = ["Win32_System_Performance"] } + diff --git a/webrender_api/src/display_list.rs b/webrender_api/src/display_list.rs index e8884fc71e..31ba3f14d0 100644 --- a/webrender_api/src/display_list.rs +++ b/webrender_api/src/display_list.rs @@ -15,7 +15,6 @@ use std::marker::PhantomData; use std::ops::Range; use std::mem; use std::collections::HashMap; -use time::precise_time_ns; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; // local imports use crate::display_item as di; @@ -25,6 +24,7 @@ use crate::gradient_builder::GradientBuilder; use crate::color::ColorF; use crate::font::{FontInstanceKey, GlyphInstance, GlyphOptions}; use crate::image::{ColorDepth, ImageKey}; +use crate::precise_time_ns; use crate::units::*; diff --git a/webrender_api/src/lib.rs b/webrender_api/src/lib.rs index 2eab5925bf..0003018a6e 100644 --- a/webrender_api/src/lib.rs +++ b/webrender_api/src/lib.rs @@ -36,7 +36,6 @@ extern crate malloc_size_of_derive; extern crate serde; #[macro_use] extern crate serde_derive; -extern crate time; extern crate malloc_size_of; extern crate peek_poke; @@ -49,6 +48,7 @@ mod display_list; mod font; mod gradient_builder; mod image; +mod precise_time_ns; mod tile_pool; pub mod units; @@ -59,6 +59,7 @@ pub use crate::display_list::*; pub use crate::font::*; pub use crate::gradient_builder::*; pub use crate::image::*; +pub use crate::precise_time_ns::precise_time_ns; pub use crate::tile_pool::*; use crate::units::*; diff --git a/webrender_api/src/precise_time_ns.rs b/webrender_api/src/precise_time_ns.rs new file mode 100644 index 0000000000..347495188b --- /dev/null +++ b/webrender_api/src/precise_time_ns.rs @@ -0,0 +1,119 @@ +// Copyright 2024 The Servo Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn precise_time_ns() -> u64 { + platform::now() +} + +#[cfg(all(unix, not(any(target_os = "macos", target_os = "ios"))))] +mod platform { + use libc::timespec; + + #[allow(unsafe_code)] + pub(super) fn now() -> u64 { + // SAFETY: libc::timespec is zero initializable. + let time = unsafe { + let mut time: timespec = std::mem::zeroed(); + libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut time); + time + }; + (time.tv_sec as u64) * 1000000000 + (time.tv_nsec as u64) + } +} + +#[cfg(any(target_os = "macos", target_os = "ios"))] +mod platform { + use std::sync::LazyLock; + + use mach2::mach_time::{mach_absolute_time, mach_timebase_info}; + + #[allow(unsafe_code)] + fn timebase_info() -> &'static mach_timebase_info { + static TIMEBASE_INFO: LazyLock = LazyLock::new(|| { + let mut timebase_info = mach_timebase_info { numer: 0, denom: 0 }; + unsafe { mach_timebase_info(&mut timebase_info) }; + timebase_info + }); + &TIMEBASE_INFO + } + + #[allow(unsafe_code)] + pub(super) fn now() -> u64 { + let timebase_info = timebase_info(); + let absolute_time = unsafe { mach_absolute_time() }; + absolute_time * timebase_info.numer as u64 / timebase_info.denom as u64 + } +} + +#[cfg(target_os = "windows")] +mod platform { + use std::sync::atomic::{AtomicU64, Ordering}; + + use windows_sys::Win32::System::Performance::{ + QueryPerformanceCounter, QueryPerformanceFrequency, + }; + + /// The frequency of the value returned by `QueryPerformanceCounter` in counts per + /// second. This is taken from the Rust source code at: + /// + #[allow(unsafe_code)] + fn frequency() -> i64 { + // Either the cached result of `QueryPerformanceFrequency` or `0` for + // uninitialized. Storing this as a single `AtomicU64` allows us to use + // `Relaxed` operations, as we are only interested in the effects on a + // single memory location. + static FREQUENCY: AtomicU64 = AtomicU64::new(0); + + let cached = FREQUENCY.load(Ordering::Relaxed); + // If a previous thread has filled in this global state, use that. + if cached != 0 { + return cached as i64; + } + // ... otherwise learn for ourselves ... + let mut frequency = 0; + let result = unsafe { QueryPerformanceFrequency(&mut frequency) }; + + if result == 0 { + return 0; + } + + FREQUENCY.store(frequency as u64, Ordering::Relaxed); + frequency + } + + #[allow(unsafe_code)] + /// Get the current instant value in nanoseconds. + /// Originally from: + pub(super) fn now() -> u64 { + let mut counter_value = 0; + unsafe { QueryPerformanceCounter(&mut counter_value) }; + + /// Computes (value*numer)/denom without overflow, as long as both + /// (numer*denom) and the overall result fit into i64 (which is the case + /// for our time conversions). + /// Originally from: + fn mul_div_u64(value: u64, numer: u64, denom: u64) -> u64 { + let q = value / denom; + let r = value % denom; + // Decompose value as (value/denom*denom + value%denom), + // substitute into (value*numer)/denom and simplify. + // r < denom, so (denom*numer) is the upper bound of (r*numer) + q * numer + r * numer / denom + } + + static NANOSECONDS_PER_SECOND: u64 = 1_000_000_000; + mul_div_u64( + counter_value as u64, + NANOSECONDS_PER_SECOND, + frequency() as u64, + ) + } +} +