blob: 4584abc78b6228fb6052fe95f5a60d0a7c2a97f7 [file] [log] [blame]
// Copyright (C) 2018 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {assertTrue} from '../base/logging';
import {duration, Span, time} from '../base/time';
import {
HighPrecisionTime,
HighPrecisionTimeSpan,
} from '../common/high_precision_time';
export class TimeScale {
private _start: HighPrecisionTime;
private _durationNanos: number;
readonly pxSpan: PxSpan;
private _nanosPerPx = 0;
static fromHPTimeSpan(span: Span<HighPrecisionTime>, pxSpan: PxSpan) {
return new TimeScale(span.start, span.duration.nanos, pxSpan);
}
constructor(start: HighPrecisionTime, durationNanos: number, pxSpan: PxSpan) {
this.pxSpan = pxSpan;
this._start = start;
this._durationNanos = durationNanos;
if (durationNanos <= 0 || pxSpan.delta <= 0) {
this._nanosPerPx = 1;
} else {
this._nanosPerPx = durationNanos / pxSpan.delta;
}
}
get timeSpan(): Span<HighPrecisionTime> {
const end = this._start.addNanos(this._durationNanos);
return new HighPrecisionTimeSpan(this._start, end);
}
timeToPx(ts: time): number {
// WARNING: Number(bigint) can be surprisingly slow. Avoid in hotpath.
const timeOffsetNanos = Number(ts - this._start.base) - this._start.offset;
return this.pxSpan.start + timeOffsetNanos / this._nanosPerPx;
}
hpTimeToPx(time: HighPrecisionTime): number {
const timeOffsetNanos = time.sub(this._start).nanos;
return this.pxSpan.start + timeOffsetNanos / this._nanosPerPx;
}
// Convert pixels to a high precision time object, which can be futher
// converted to other time formats.
pxToHpTime(px: number): HighPrecisionTime {
const offsetNanos = (px - this.pxSpan.start) * this._nanosPerPx;
return this._start.addNanos(offsetNanos);
}
durationToPx(dur: duration): number {
// WARNING: Number(bigint) can be surprisingly slow. Avoid in hotpath.
return Number(dur) / this._nanosPerPx;
}
pxDeltaToDuration(pxDelta: number): HighPrecisionTime {
const time = pxDelta * this._nanosPerPx;
return HighPrecisionTime.fromNanos(time);
}
}
export class PxSpan {
static readonly ZERO = new PxSpan(0, 0);
constructor(private _start: number, private _end: number) {
assertTrue(_start <= _end, 'PxSpan start > end');
}
get start(): number {
return this._start;
}
get end(): number {
return this._end;
}
get delta(): number {
return this._end - this._start;
}
}