blob: 880bce817cb35f414c9c690acca38a2c5f323b38 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/gpu/android/promotion_hint_aggregator_impl.h"
#include <memory>
#include "base/bind.h"
#include "base/time/default_tick_clock.h"
namespace media {
// Minimum amount of time between promotable frames before we start over. The
// idea is to prevent promoting on paused / background rendering. Note that
// this time is only enforced when transitioning from unpromotable to promotable
// frames. We don't unpromote later because of this.
constexpr base::TimeDelta MaximumInterFrameTime =
base::TimeDelta::FromMilliseconds(100);
// Minimum number of consecutive promotable frames before we actually start
// promoting frames.
constexpr int MinimumPromotableFrames = 10;
// Minimum time since the last unpromotable frame that we require before we will
// promote new ones.
constexpr base::TimeDelta MinimumUnpromotableFrameTime =
base::TimeDelta::FromMilliseconds(2000);
PromotionHintAggregatorImpl::PromotionHintAggregatorImpl(
const base::TickClock* tick_clock)
: weak_ptr_factory_(this) {
if (!tick_clock)
tick_clock = base::DefaultTickClock::GetInstance();
tick_clock_ = tick_clock;
}
PromotionHintAggregatorImpl::~PromotionHintAggregatorImpl() {}
void PromotionHintAggregatorImpl::NotifyPromotionHint(const Hint& hint) {
base::TimeTicks now = tick_clock_->NowTicks();
if (!hint.is_promotable) {
most_recent_unpromotable_ = now;
consecutive_promotable_frames_ = 0;
} else if (!IsSafeToPromote() &&
now - most_recent_update_ > MaximumInterFrameTime) {
// Promotable, but we aren't getting frames fast enough to count. We
// don't want to transition to promotable unless frames are actually
// playing. We check IsSafeToPromote() so that we don't transition back
// to unpromotable just because it's paused; that would cause the frame
// to become unrenderable. We just want to delay the transition into
// promotable until it works.
consecutive_promotable_frames_ = 1;
} else {
// Promotable frame, and we're getting frames fast enough.
consecutive_promotable_frames_++;
}
most_recent_update_ = now;
}
bool PromotionHintAggregatorImpl::IsSafeToPromote() {
base::TimeTicks now = tick_clock_->NowTicks();
base::TimeDelta since_last_unpromotable = now - most_recent_unpromotable_;
return consecutive_promotable_frames_ >= MinimumPromotableFrames &&
since_last_unpromotable >= MinimumUnpromotableFrameTime;
}
} // namespace media