blob: b1c8b16b26572492f0783797914445b9205e7677 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_MEDIA_AUDIO_LIB_CLOCK_CLOCK_SNAPSHOT_H_
#define SRC_MEDIA_AUDIO_LIB_CLOCK_CLOCK_SNAPSHOT_H_
#include <memory>
#include <string>
#include <unordered_map>
#include "src/media/audio/lib/clock/clock.h"
namespace media_audio {
// A snapshot of a clock at a single moment in time. The API is similar to that of a `const Clock`.
// This is a value type that supports copy and assignment.
class ClockSnapshot {
public:
// Create a snapshot of the given clock at the given monotonic time.
ClockSnapshot(const std::shared_ptr<const Clock>& clock, zx::time mono_time)
: backing_clock_(clock),
to_clock_mono_snapshot_(clock->to_clock_mono_snapshot()),
mono_now_(mono_time),
// Use `to_clock_mono_snapshot_` to ensure a consistent snapshot.
ref_now_(zx::time(to_clock_mono_snapshot_.to_clock_mono.ApplyInverse(mono_time.get()))) {}
std::string_view name() const { return backing_clock_->name(); }
zx_koid_t koid() const { return backing_clock_->koid(); }
uint32_t domain() const { return backing_clock_->domain(); }
// Returns when the snapshot was taken according to the snapshotted clock.
zx::time now() const { return ref_now_; }
// Returns when the snapshot was taken according to the system monotonic clock.
zx::time mono_now() const { return mono_now_; }
// Returns the TimelineFunction for the current snapshot.
Clock::ToClockMonoSnapshot to_clock_mono_snapshot() const { return to_clock_mono_snapshot_; }
media::TimelineFunction to_clock_mono() const { return to_clock_mono_snapshot().to_clock_mono; }
// Returns the reference time equivalent to the given system monotonic time.
zx::time ReferenceTimeFromMonotonicTime(zx::time mono_time) const {
return zx::time(to_clock_mono().ApplyInverse(mono_time.get()));
}
// Returns the system monotonic time equivalent to the given reference time.
zx::time MonotonicTimeFromReferenceTime(zx::time ref_time) const {
return zx::time(to_clock_mono().Apply(ref_time.get()));
}
private:
// Hold a shared_ptr to the clock, rather than copying state, to avoid copying the name.
std::shared_ptr<const Clock> backing_clock_;
Clock::ToClockMonoSnapshot to_clock_mono_snapshot_;
zx::time mono_now_;
zx::time ref_now_;
};
// This class provides a way to snapshot multiple clocks at once.
// Not safe for concurrent use.
class ClockSnapshots {
public:
// Returns the most recent snapshot for the clock with the given koid.
// Update must have been called since this clock was added.
ClockSnapshot SnapshotFor(zx_koid_t clock_koid) const;
// Adds a clock to snapshot in future calls to Update.
//
// REQUIRES: A clock with the same koid has not already been added.
void AddClock(std::shared_ptr<Clock> clock);
// Removes a clock from this container.
//
// REQUIRES: A clock with the same koid has been added.
void RemoveClock(std::shared_ptr<Clock> clock);
// Update the snapshot of every clock.
void Update(zx::time mono_now);
private:
struct ClockInfo {
std::shared_ptr<Clock> clock;
std::optional<ClockSnapshot> last_snapshot;
};
std::unordered_map<zx_koid_t, ClockInfo> snapshots_;
};
} // namespace media_audio
#endif // SRC_MEDIA_AUDIO_LIB_CLOCK_CLOCK_SNAPSHOT_H_