Bug 1171441 use simple AudioEventTimeline value when it has a suitable single event r=padenot

Differential Revision: https://phabricator.services.mozilla.com/D188944
This commit is contained in:
Karl Tomlinson 2023-09-23 08:14:47 +00:00
parent 21b7701f0e
commit e49259ab16
2 changed files with 40 additions and 20 deletions

View File

@ -128,6 +128,10 @@ void AudioEventTimeline::CleanupEventsOlderThan(TimeType aTime) {
return aEvent->Time<TimeType>();
};
if (mSimpleValue.isSome()) {
return; // already only a single event
}
// Find first event to keep. Keep one event prior to aTime.
auto begin = mEvents.cbegin();
auto end = mEvents.cend();
@ -138,27 +142,35 @@ void AudioEventTimeline::CleanupEventsOlderThan(TimeType aTime) {
"thread.");
}
auto firstToKeep = event - 1;
if (firstToKeep->mType != AudioTimelineEvent::SetTarget) {
// The value is constant if there is a single remaining non-SetTarget event
// that has already passed.
if (end - firstToKeep == 1 && aTime >= firstToKeep->EndTime<TimeType>()) {
mSimpleValue.emplace(firstToKeep->EndValue());
}
} else {
// The firstToKeep event is a SetTarget. Set its initial value if
// not already set. First find the most recent event where the value at
// the end time of the event is known, either from the event or for
// SetTarget events because it has already been calculated. This may not
// have been calculated if GetValuesAtTime() was not called for the start
// time of the SetTarget event.
for (event = firstToKeep;
event > begin && event->mType == AudioTimelineEvent::SetTarget &&
TimeOf(event) > mSetTargetStartTime.Get<TimeType>();
--event) {
}
// Compute SetTarget start times.
for (; event < firstToKeep; ++event) {
MOZ_ASSERT((event + 1)->mType == AudioTimelineEvent::SetTarget);
ComputeSetTargetStartValue(&*event, TimeOf(event + 1));
}
}
if (firstToKeep == begin) {
return;
}
// If the firstToKeep event is a SetTarget, then set its initial value if
// not already set. First find the most recent event where the value at the
// end time of the event is known, either from the event or for SetTarget
// events because it has already been calculated. This may not have been
// calculated if GetValuesAtTime() was not called for the start time of the
// SetTarget event.
for (event = firstToKeep;
event > begin && event->mType == AudioTimelineEvent::SetTarget &&
TimeOf(event) > mSetTargetStartTime.Get<TimeType>();
--event) {
}
// Compute SetTarget start times.
for (; event < firstToKeep; ++event) {
MOZ_ASSERT((event + 1)->mType == AudioTimelineEvent::SetTarget);
ComputeSetTargetStartValue(&*event, TimeOf(event + 1));
}
JS::AutoSuppressGCAnalysis suppress; // for null mTrack
mEvents.RemoveElementsRange(begin, firstToKeep);
}

View File

@ -170,7 +170,9 @@ inline int64_t AudioTimelineEvent::TimeUnion::Get<int64_t>() const {
class AudioEventTimeline {
public:
explicit AudioEventTimeline(float aDefaultValue)
: mDefaultValue(aDefaultValue), mSetTargetStartValue(aDefaultValue) {}
: mDefaultValue(aDefaultValue),
mSetTargetStartValue(aDefaultValue),
mSimpleValue(Some(aDefaultValue)) {}
bool ValidateEvent(const AudioTimelineEvent& aEvent, ErrorResult& aRv) const {
MOZ_ASSERT(NS_IsMainThread());
@ -259,6 +261,7 @@ class AudioEventTimeline {
template <typename TimeType>
void InsertEvent(const AudioTimelineEvent& aEvent) {
mSimpleValue.reset();
for (unsigned i = 0; i < mEvents.Length(); ++i) {
if (aEvent.Time<TimeType>() == mEvents[i].Time<TimeType>()) {
// If two events happen at the same time, have them in chronological
@ -281,12 +284,12 @@ class AudioEventTimeline {
mEvents.AppendElement(aEvent);
}
bool HasSimpleValue() const { return mEvents.IsEmpty(); }
bool HasSimpleValue() const { return mSimpleValue.isSome(); }
float GetValue() const {
// This method should only be called if HasSimpleValue() returns true
MOZ_ASSERT(HasSimpleValue());
return mDefaultValue;
return mSimpleValue.value();
}
void SetValue(float aValue) {
@ -296,6 +299,7 @@ class AudioEventTimeline {
// Silently don't change anything if there are any events
if (mEvents.IsEmpty()) {
mSetTargetStartValue = mDefaultValue = aValue;
mSimpleValue = Some(aValue);
}
}
@ -362,6 +366,9 @@ class AudioEventTimeline {
break;
}
}
if (mEvents.IsEmpty()) {
mSimpleValue = Some(mDefaultValue);
}
}
void CancelAllEvents() { mEvents.Clear(); }
@ -428,6 +435,7 @@ class AudioEventTimeline {
// event for SetTarget curves.
float mSetTargetStartValue;
AudioTimelineEvent::TimeUnion mSetTargetStartTime;
Maybe<float> mSimpleValue;
};
} // namespace dom