mirror of
https://github.com/servo/servo.git
synced 2025-06-19 22:59:03 +01:00
Auto merge of #25659 - pshaughn:timingresolution, r=jdm,nox
Expose DOMHighResTimeStamps at lower res As explained in https://www.w3.org/TR/hr-time-2/#clock-resolution and tested in a few WPT tests, we're not supposed to show Javascript the full resolution of OS timestamps. This fixes that on all the DOMHighResTimeStamp interfaces that weren't already limiting themselves to integer milliseconds. The specific choice of how to coarsen the resolution is extremely bikesheddable; I commented the reasoning for my arbitrary choice but I admit it's arbitrary. A couple tests of timing resolution still fail, but because they're seeing undefined and NaN values due to unimplemented attributes (#25658). --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #25656 fix #25296 fix #21276 <!-- Either: --> - [X] There are tests for these changes <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
commit
c0ee7594c2
10 changed files with 46 additions and 51 deletions
|
@ -10,7 +10,6 @@ use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeS
|
|||
use crate::dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceBinding::PerformanceMethods;
|
||||
use crate::dom::bindings::error::Fallible;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::num::Finite;
|
||||
use crate::dom::bindings::refcounted::Trusted;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||
use crate::dom::bindings::root::{DomRoot, DomSlice, MutNullableDom};
|
||||
|
@ -19,6 +18,7 @@ use crate::dom::document::Document;
|
|||
use crate::dom::eventtarget::{CompiledEventListener, EventTarget, ListenerPhase};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::node::Node;
|
||||
use crate::dom::performance::reduce_timing_resolution;
|
||||
use crate::dom::virtualmethods::vtable_for;
|
||||
use crate::dom::window::Window;
|
||||
use crate::task::TaskOnce;
|
||||
|
@ -333,7 +333,7 @@ impl EventMethods for Event {
|
|||
|
||||
// https://dom.spec.whatwg.org/#dom-event-timestamp
|
||||
fn TimeStamp(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(
|
||||
reduce_timing_resolution(
|
||||
(self.precise_time_ns - (*self.global().performance().TimeOrigin()).round() as u64)
|
||||
.to_ms(),
|
||||
)
|
||||
|
|
|
@ -401,12 +401,12 @@ impl PerformanceMethods for Performance {
|
|||
|
||||
// https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/HighResolutionTime/Overview.html#dom-performance-now
|
||||
fn Now(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.now())
|
||||
reduce_timing_resolution(self.now())
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/hr-time-2/#dom-performance-timeorigin
|
||||
fn TimeOrigin(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.navigation_start_precise as f64)
|
||||
reduce_timing_resolution(self.navigation_start_precise as f64)
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/performance-timeline-2/#dom-performance-getentries
|
||||
|
@ -525,3 +525,14 @@ impl PerformanceMethods for Performance {
|
|||
SetOnresourcetimingbufferfull
|
||||
);
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/hr-time-2/#clock-resolution
|
||||
pub fn reduce_timing_resolution(exact: f64) -> DOMHighResTimeStamp {
|
||||
// We need a granularity no finer than 5 microseconds.
|
||||
// 5 microseconds isn't an exactly representable f64 so WPT tests
|
||||
// might occasionally corner-case on rounding.
|
||||
// web-platform-tests/wpt#21526 wants us to use an integer number of
|
||||
// microseconds; the next divisor of milliseconds up from 5 microseconds
|
||||
// is 10, which is 1/100th of a millisecond.
|
||||
Finite::wrap((exact * 100.0).floor() / 100.0)
|
||||
}
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp;
|
||||
use crate::dom::bindings::codegen::Bindings::PerformanceEntryBinding;
|
||||
use crate::dom::bindings::codegen::Bindings::PerformanceEntryBinding::PerformanceEntryMethods;
|
||||
use crate::dom::bindings::num::Finite;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::performance::reduce_timing_resolution;
|
||||
use dom_struct::dom_struct;
|
||||
|
||||
#[dom_struct]
|
||||
|
@ -77,12 +78,12 @@ impl PerformanceEntryMethods for PerformanceEntry {
|
|||
}
|
||||
|
||||
// https://w3c.github.io/performance-timeline/#dom-performanceentry-starttime
|
||||
fn StartTime(&self) -> Finite<f64> {
|
||||
Finite::wrap(self.start_time)
|
||||
fn StartTime(&self) -> DOMHighResTimeStamp {
|
||||
reduce_timing_resolution(self.start_time)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/performance-timeline/#dom-performanceentry-duration
|
||||
fn Duration(&self) -> Finite<f64> {
|
||||
Finite::wrap(self.duration)
|
||||
fn Duration(&self) -> DOMHighResTimeStamp {
|
||||
reduce_timing_resolution(self.duration)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@ use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeS
|
|||
use crate::dom::bindings::codegen::Bindings::PerformanceResourceTimingBinding::{
|
||||
self, PerformanceResourceTimingMethods,
|
||||
};
|
||||
use crate::dom::bindings::num::Finite;
|
||||
use crate::dom::bindings::reflector::reflect_dom_object;
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::performance::reduce_timing_resolution;
|
||||
use crate::dom::performanceentry::PerformanceEntry;
|
||||
use dom_struct::dom_struct;
|
||||
use net_traits::ResourceFetchTiming;
|
||||
|
@ -182,17 +182,17 @@ impl PerformanceResourceTimingMethods for PerformanceResourceTiming {
|
|||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-domainlookupstart
|
||||
fn DomainLookupStart(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.domain_lookup_start)
|
||||
reduce_timing_resolution(self.domain_lookup_start)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-domainlookupend
|
||||
fn DomainLookupEnd(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.domain_lookup_end)
|
||||
reduce_timing_resolution(self.domain_lookup_end)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-secureconnectionstart
|
||||
fn SecureConnectionStart(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.secure_connection_start)
|
||||
reduce_timing_resolution(self.secure_connection_start)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-transfersize
|
||||
|
@ -212,41 +212,41 @@ impl PerformanceResourceTimingMethods for PerformanceResourceTiming {
|
|||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-requeststart
|
||||
fn RequestStart(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.request_start)
|
||||
reduce_timing_resolution(self.request_start)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-redirectstart
|
||||
fn RedirectStart(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.redirect_start)
|
||||
reduce_timing_resolution(self.redirect_start)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-redirectend
|
||||
fn RedirectEnd(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.redirect_end)
|
||||
reduce_timing_resolution(self.redirect_end)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-responsestart
|
||||
fn ResponseStart(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.response_start)
|
||||
reduce_timing_resolution(self.response_start)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-fetchstart
|
||||
fn FetchStart(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.fetch_start)
|
||||
reduce_timing_resolution(self.fetch_start)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-connectstart
|
||||
fn ConnectStart(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.connect_start)
|
||||
reduce_timing_resolution(self.connect_start)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-connectend
|
||||
fn ConnectEnd(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.connect_end)
|
||||
reduce_timing_resolution(self.connect_end)
|
||||
}
|
||||
|
||||
// https://w3c.github.io/resource-timing/#dom-performanceresourcetiming-responseend
|
||||
fn ResponseEnd(&self) -> DOMHighResTimeStamp {
|
||||
Finite::wrap(self.response_end)
|
||||
reduce_timing_resolution(self.response_end)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp;
|
||||
use crate::dom::bindings::codegen::Bindings::VRFrameDataBinding;
|
||||
use crate::dom::bindings::codegen::Bindings::VRFrameDataBinding::VRFrameDataMethods;
|
||||
use crate::dom::bindings::error::Fallible;
|
||||
use crate::dom::bindings::num::Finite;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::performance::reduce_timing_resolution;
|
||||
use crate::dom::vrpose::VRPose;
|
||||
use crate::dom::window::Window;
|
||||
use crate::script_runtime::JSContext;
|
||||
|
@ -119,8 +120,8 @@ impl VRFrameData {
|
|||
|
||||
impl VRFrameDataMethods for VRFrameData {
|
||||
// https://w3c.github.io/webvr/#dom-vrframedata-timestamp
|
||||
fn Timestamp(&self) -> Finite<f64> {
|
||||
Finite::wrap(self.timestamp.get() - self.first_timestamp.get())
|
||||
fn Timestamp(&self) -> DOMHighResTimeStamp {
|
||||
reduce_timing_resolution(self.timestamp.get() - self.first_timestamp.get())
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
|
|
@ -19,7 +19,6 @@ use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRVisibilityState
|
|||
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods;
|
||||
use crate::dom::bindings::error::{Error, ErrorResult};
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::num::Finite;
|
||||
use crate::dom::bindings::refcounted::Trusted;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot, MutDom, MutNullableDom};
|
||||
|
@ -28,6 +27,7 @@ use crate::dom::eventtarget::EventTarget;
|
|||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::node::Node;
|
||||
use crate::dom::node::NodeDamage;
|
||||
use crate::dom::performance::reduce_timing_resolution;
|
||||
use crate::dom::promise::Promise;
|
||||
use crate::dom::xrframe::XRFrame;
|
||||
use crate::dom::xrinputsourcearray::XRInputSourceArray;
|
||||
|
@ -336,7 +336,7 @@ impl XRSession {
|
|||
// Step 4-5
|
||||
let mut callbacks = mem::replace(&mut *self.raf_callback_list.borrow_mut(), vec![]);
|
||||
let start = self.global().as_window().get_navigation_start();
|
||||
let time = (frame.time_ns - start).to_ms();
|
||||
let time = reduce_timing_resolution((frame.time_ns - start).to_ms());
|
||||
|
||||
let frame = XRFrame::new(&self.global(), self, frame);
|
||||
// Step 6,7
|
||||
|
@ -347,7 +347,7 @@ impl XRSession {
|
|||
self.outside_raf.set(false);
|
||||
for (_, callback) in callbacks.drain(..) {
|
||||
if let Some(callback) = callback {
|
||||
let _ = callback.Call__(Finite::wrap(time), &frame, ExceptionHandling::Report);
|
||||
let _ = callback.Call__(time, &frame, ExceptionHandling::Report);
|
||||
}
|
||||
}
|
||||
self.outside_raf.set(true);
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
[Event-timestamp-safe-resolution.html]
|
||||
type: testharness
|
||||
|
||||
[Event timestamp should not have a resolution better than 5 microseconds]
|
||||
expected: FAIL
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
[webtiming-resolution.any.html]
|
||||
[Verifies the resolution of performance.now() is at least 5 microseconds.]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[webtiming-resolution.any.worker.html]
|
||||
[Verifies the resolution of performance.now() is at least 20 microseconds.]
|
||||
expected: FAIL
|
||||
|
||||
[Verifies the resolution of entry.startTime is at least 20 microseconds.]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Verifies the resolution of performance.now() is at least 5 microseconds.]
|
||||
expected: FAIL
|
||||
|
|
@ -19708,7 +19708,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"mozilla/window_performance.html": [
|
||||
"302073e8041763102d678326509d7ef0a1fb5c79",
|
||||
"c1e38a1e00147caf82492dc82f1cb5e85759f8e3",
|
||||
"testharness"
|
||||
],
|
||||
"mozilla/window_performance_topLevelDomComplete.html": [
|
||||
|
|
|
@ -27,12 +27,15 @@ test(function() {
|
|||
var last = window.performance.now();
|
||||
assert_greater_than(last, 0);
|
||||
|
||||
// Check that window.performance.now() is monotonically increasing
|
||||
// Check that window.performance.now() is monotonically nondecreasing
|
||||
// and eventually increases
|
||||
var before_loop = window.performance.now();
|
||||
for (var i = 0; i < 100; i++) {
|
||||
var next = window.performance.now();
|
||||
assert_greater_than(next, last);
|
||||
assert_greater_than_equal(next, last);
|
||||
last = next;
|
||||
}
|
||||
assert_greater_than(last, before_loop, "If this fails, either performance timing is broken, or Servo JS execution has gotten much faster since this test was written.");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue