1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/performance_manager/policies/frame_throttling_policy.h"
#include <algorithm>
#include "base/containers/contains.h"
#include "components/performance_manager/graph/frame_node_impl.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
namespace performance_manager::policies {
FrameThrottlingPolicy::FrameThrottlingPolicy() {
throttle_interval_ = viz::BeginFrameArgs::DefaultInterval() * 2;
}
FrameThrottlingPolicy::~FrameThrottlingPolicy() = default;
void FrameThrottlingPolicy::OnFrameNodeAdded(const FrameNode* frame_node) {
// A frame is always important upon being added. The current implementation of
// this class is based on the fact.
DCHECK(frame_node->IsImportant());
}
void FrameThrottlingPolicy::OnBeforeFrameNodeRemoved(
const FrameNode* frame_node) {
DCHECK(frame_node->GetRenderFrameHostProxy().is_valid());
const content::GlobalRenderFrameHostId id =
frame_node->GetRenderFrameHostProxy().global_frame_routing_id();
if (!frame_node->IsImportant()) {
DisableFrameSinkThrottle(id);
}
}
void FrameThrottlingPolicy::OnIsImportantChanged(const FrameNode* frame_node) {
DCHECK(frame_node->GetRenderFrameHostProxy().is_valid());
const content::GlobalRenderFrameHostId id =
frame_node->GetRenderFrameHostProxy().global_frame_routing_id();
if (!frame_node->IsImportant()) {
EnableFrameSinkThrottle(id);
} else {
DisableFrameSinkThrottle(id);
}
}
void FrameThrottlingPolicy::OnPassedToGraph(Graph* graph) {
graph->AddFrameNodeObserver(this);
}
void FrameThrottlingPolicy::OnTakenFromGraph(Graph* graph) {
graph->RemoveFrameNodeObserver(this);
}
bool FrameThrottlingPolicy::IsFrameSinkThrottled(
const content::GlobalRenderFrameHostId& id) const {
return base::Contains(throttled_frames_, id);
}
void FrameThrottlingPolicy::EnableFrameSinkThrottle(
const content::GlobalRenderFrameHostId& id) {
// Only called when a frame goes from important to unimportant, so the frame
// should not be in the throttled set before insertion.
bool inserted = throttled_frames_.insert(id).second;
DCHECK(inserted);
content::UpdateThrottlingFrameSinks(throttled_frames_, throttle_interval_);
}
void FrameThrottlingPolicy::DisableFrameSinkThrottle(
const content::GlobalRenderFrameHostId& id) {
// Only called when a frame goes from unimportant to important or an
// unimportant frame is to be removed, the frame should be in the set before
// erasing.
size_t removed = throttled_frames_.erase(id);
DCHECK_EQ(removed, 1u);
content::UpdateThrottlingFrameSinks(throttled_frames_, throttle_interval_);
}
} // namespace performance_manager::policies
|