revised video renderer's invalidate cache to use ranges rather than discrete

frames

Previously, when the video renderer received a dirty cache signal, it would
proceed to extract all frames from the range and queue them. However, this could
be extremely slow for long ranges since it had to iterate through the entire
range and calculate the individual frames it contained. Now, we use the same
range combining system as audio and automatically calculate the next frame
within the range only when necessary. Essentially the same work, but split up
over time and done only when needed leading to no discernible UI pause when
invalidating cache.
This commit is contained in:
itsmattkc
2020-01-03 15:50:43 +11:00
parent db146b376a
commit 7f796bd99f
10 changed files with 118 additions and 128 deletions
+24 -5
View File
@@ -58,9 +58,13 @@ TimeRange TimeRange::CombineWith(const TimeRange &a) const
return Combine(a, *this);
}
bool TimeRange::Contains(const TimeRange &a) const
bool TimeRange::Contains(const TimeRange &compare, bool inout_inclusive) const
{
return (a.in() >= in() && a.out() <= out());
if (inout_inclusive) {
return (compare.in() >= in() && compare.out() <= out());
} else {
return (compare.in() > in() && compare.out() < out());
}
}
bool TimeRange::Overlap(const TimeRange &a, const TimeRange &b)
@@ -114,7 +118,7 @@ void TimeRangeList::RemoveTimeRange(const TimeRange &range)
// This element is entirely encompassed in this range, remove it
removeAt(i);
i--;
} else if (compare.Contains(range)) {
} else if (compare.Contains(range, false)) {
// The remove range is within this element, only choice is to split the element into two
TimeRange first(compare.in(), range.in());
TimeRange last(range.out(), compare.out());
@@ -123,10 +127,25 @@ void TimeRangeList::RemoveTimeRange(const TimeRange &range)
append(last);
} else if (compare.in() < range.in() && compare.out() > range.in()) {
// This element's out point overlaps the range's in, we'll trim it
(*this)[i].set_out(range.in());
TimeRange trimmed = compare;
trimmed.set_out(range.in());
replace(i, trimmed);
} else if (compare.in() < range.out() && compare.out() > range.out()) {
// This element's in point overlaps the range's out, we'll trim it
(*this)[i].set_in(range.out());
TimeRange trimmed = compare;
trimmed.set_in(range.out());
replace(i, trimmed);
}
}
}
bool TimeRangeList::ContainsTimeRange(const TimeRange &range) const
{
for (int i=0;i<size();i++) {
if (at(i).Contains(range)) {
return true;
}
}
return false;
}