0

Allocate SharedMemoryMapping for DroppedFrames UKM.

This CL is part of the investigation into replacing
DroppedFrameCounter UKMs with FrameSequenceMetrics.
Details about DFC metrics and why they are redundant
can be found in go/chrome-cc-metrics-refactor.

New Metric Doc: go/chrome-graphics-fsm-as-ukm

Why is this CL so complicated? Approach explained
here: go/chrome-cc-pdf4-as-ukm-why

Bug: 338977417, 395868899
Change-Id: I2a4f222088881f8e58b61b6d55144f91466f808a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6187722
Reviewed-by: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: Ian Clelland <iclelland@chromium.org>
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Commit-Queue: Stacy Gaikovaia <gaiko@google.com>
Reviewed-by: Ken Buchanan <kenrb@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1422117}
This commit is contained in:
Stacy Gaikovaia
2025-02-19 11:48:01 -08:00
committed by Chromium LUCI CQ
parent 9f07f94af1
commit b3deb703f9
49 changed files with 323 additions and 115 deletions

@ -221,6 +221,8 @@ cc_component("cc") {
"metrics/submit_info.h",
"metrics/total_frame_counter.cc",
"metrics/total_frame_counter.h",
"metrics/ukm_dropped_frames_data.cc",
"metrics/ukm_dropped_frames_data.h",
"metrics/ukm_manager.cc",
"metrics/ukm_manager.h",
"metrics/ukm_smoothness_data.cc",

@ -15,6 +15,7 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "cc/metrics/dropped_frame_counter.h"
#include "cc/metrics/frame_info.h"
#include "cc/metrics/frame_sequence_tracker.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
@ -277,7 +278,7 @@ void FrameSequenceMetrics::AdoptTrace(FrameSequenceMetrics* adopt_from) {
adopt_from->trace_data_.trace_id = 0u;
}
void FrameSequenceMetrics::ReportMetrics() {
int FrameSequenceMetrics::ReportMetrics() {
// Terminates |trace_data_| for all types of FrameSequenceTracker.
trace_data_.Terminate(v3_, v4_, GetEffectiveThread());
@ -301,7 +302,7 @@ void FrameSequenceMetrics::ReportMetrics() {
v4_.frames_checkerboarded = 0u;
v4_.frames_checkerboarded_need_raster = 0u;
v4_.frames_checkerboarded_need_record = 0u;
return;
return -1;
}
const auto thread_type = GetEffectiveThread();
@ -457,6 +458,7 @@ void FrameSequenceMetrics::ReportMetrics() {
base::LinearHistogram::FactoryGet(
GetJankV3HistogramName(type_, thread_name), 1, 100, 101,
base::HistogramBase::kUmaTargetedHistogramFlag));
v3_.frames_expected = 0u;
v3_.frames_dropped = 0u;
v3_.frames_missing_content = 0u;
@ -465,7 +467,11 @@ void FrameSequenceMetrics::ReportMetrics() {
v4_.frames_checkerboarded = 0u;
v4_.frames_checkerboarded_need_raster = 0u;
v4_.frames_checkerboarded_need_record = 0u;
// Return PDF4 to write to UKMs.
return percent_dropped_v4;
}
return -1;
}
FrameSequenceMetrics::TraceData::TraceData(FrameSequenceMetrics* m)

@ -13,6 +13,7 @@
#include "base/check.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ptr_exclusion.h"
#include "base/time/time.h"
#include "base/trace_event/traced_value.h"
#include "cc/cc_export.h"
@ -121,7 +122,8 @@ class CC_EXPORT FrameSequenceMetrics {
bool HasEnoughDataForReporting() const;
bool HasDataLeftForReporting() const;
// Report related metrics: throughput, checkboarding...
void ReportMetrics();
// Returns PercentDroppedFrames4.AllSequences metric.
int ReportMetrics();
void AddSortedFrame(const viz::BeginFrameArgs& args,
const FrameInfo& frame_info);

@ -9,8 +9,13 @@
#include "base/containers/contains.h"
#include "base/memory/ptr_util.h"
#include "base/memory/shared_memory_mapping.h"
#include "base/memory/writable_shared_memory_region.h"
#include "cc/metrics/compositor_frame_reporting_controller.h"
#include "cc/metrics/frame_sequence_metrics.h"
#include "cc/metrics/frame_sequence_tracker.h"
#include "cc/metrics/ukm_dropped_frames_data.h"
#include "cc/metrics/ukm_smoothness_data.h"
namespace cc {
@ -262,8 +267,10 @@ void FrameSequenceTrackerCollection::DestroyTrackers() {
accumulated_metrics_.erase(key);
}
if (metrics->HasEnoughDataForReporting())
if (metrics->HasEnoughDataForReporting()) {
metrics->ReportMetrics();
// TODO(crbug.com/395868899): Write PDF4 metric here
}
if (metrics->HasDataLeftForReporting())
accumulated_metrics_[key] = std::move(metrics);
}
@ -354,4 +361,9 @@ void FrameSequenceTrackerCollection::AddSortedFrame(
DestroyTrackers();
}
void FrameSequenceTrackerCollection::SetUkmDroppedFramesDestination(
UkmDroppedFramesDataShared* dropped_frames_data) {
ukm_dropped_frames_data_ = dropped_frames_data;
}
} // namespace cc

@ -12,8 +12,11 @@
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/shared_memory_mapping.h"
#include "cc/cc_export.h"
#include "cc/metrics/dropped_frame_counter.h"
#include "cc/metrics/frame_sequence_metrics.h"
#include "cc/metrics/ukm_dropped_frames_data.h"
namespace viz {
struct BeginFrameArgs;
@ -22,7 +25,6 @@ struct BeginFrameArgs;
namespace cc {
class FrameSequenceTracker;
class CompositorFrameReportingController;
class UkmManager;
// Map of kCustom tracker results keyed by a sequence id.
using CustomTrackerResults =
@ -88,8 +90,6 @@ class CC_EXPORT FrameSequenceTrackerCollection {
FrameSequenceTracker* GetRemovalTrackerForTesting(
FrameSequenceTrackerType type);
void SetUkmManager(UkmManager* manager);
using NotifyCustomerTrackerResutlsCallback =
base::RepeatingCallback<void(const CustomTrackerResults&)>;
void set_custom_tracker_results_added_callback(
@ -100,6 +100,10 @@ class CC_EXPORT FrameSequenceTrackerCollection {
void AddSortedFrame(const viz::BeginFrameArgs& args,
const FrameInfo& frame_info);
// Registers the shared memory location for PDF4 UKMs.
void SetUkmDroppedFramesDestination(
UkmDroppedFramesDataShared* dropped_frames_data);
private:
friend class FrameSequenceTrackerTest;
@ -150,6 +154,9 @@ class CC_EXPORT FrameSequenceTrackerCollection {
size_t main_thread_driving_smoothness_ = 0;
size_t compositor_thread_driving_smoothness_ = 0;
size_t raster_thread_driving_smoothness_ = 0;
// Pointer to shared memory map for PDF4 UKMs
raw_ptr<UkmDroppedFramesDataShared> ukm_dropped_frames_data_ = nullptr;
};
} // namespace cc

@ -0,0 +1,11 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cc/metrics/ukm_dropped_frames_data.h"
namespace cc {
UkmDroppedFramesData::UkmDroppedFramesData() = default;
} // namespace cc

@ -0,0 +1,26 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_METRICS_UKM_DROPPED_FRAMES_DATA_H_
#define CC_METRICS_UKM_DROPPED_FRAMES_DATA_H_
#include "base/time/time.h"
#include "cc/cc_export.h"
#include "cc/metrics/shared_metrics_buffer.h"
namespace cc {
// PercentDroppedFrames4 UKM metric
// exported from frame_sequence_metrics.cc
struct CC_EXPORT UkmDroppedFramesData {
UkmDroppedFramesData();
double percent_dropped_frames = 0.0;
};
using UkmDroppedFramesDataShared = SharedMetricsBuffer<UkmDroppedFramesData>;
} // namespace cc
#endif // CC_METRICS_UKM_DROPPED_FRAMES_DATA_H_

@ -62,6 +62,8 @@ class FakeProxy : public Proxy {
void SetSourceURL(ukm::SourceId source_id, const GURL& url) override {}
void SetUkmSmoothnessDestination(
base::WritableSharedMemoryMapping ukm_smoothness_data) override {}
void SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_dropped_frames_data) override {}
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) override {}
void CompositeImmediatelyForTest(base::TimeTicks frame_begin_time,

@ -48,6 +48,7 @@
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
#include "cc/layers/painted_scrollbar_layer.h"
#include "cc/metrics/ukm_dropped_frames_data.h"
#include "cc/metrics/ukm_manager.h"
#include "cc/metrics/ukm_smoothness_data.h"
#include "cc/paint/paint_worklet_layer_painter.h"
@ -1986,6 +1987,20 @@ LayerTreeHost::CreateSharedMemoryForSmoothnessUkm() {
return std::move(ukm_smoothness_mapping.region);
}
base::ReadOnlySharedMemoryRegion
LayerTreeHost::CreateSharedMemoryForDroppedFramesUkm() {
DCHECK(IsMainThread());
const auto size = sizeof(UkmDroppedFramesDataShared);
auto ukm_dropped_frames_mapping =
base::ReadOnlySharedMemoryRegion::Create(size);
if (!ukm_dropped_frames_mapping.IsValid()) {
return {};
}
proxy_->SetUkmDroppedFramesDestination(
std::move(ukm_dropped_frames_mapping.mapping));
return std::move(ukm_dropped_frames_mapping.region);
}
void LayerTreeHost::SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) {
DCHECK(IsMainThread());

@ -914,6 +914,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void SetSourceURL(ukm::SourceId source_id, const GURL& url);
base::ReadOnlySharedMemoryRegion CreateSharedMemoryForSmoothnessUkm();
base::ReadOnlySharedMemoryRegion CreateSharedMemoryForDroppedFramesUkm();
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer);

@ -75,6 +75,7 @@
#include "cc/metrics/frame_sequence_metrics.h"
#include "cc/metrics/lcd_text_metrics_reporter.h"
#include "cc/metrics/submit_info.h"
#include "cc/metrics/ukm_dropped_frames_data.h"
#include "cc/metrics/ukm_smoothness_data.h"
#include "cc/paint/display_item_list.h"
#include "cc/paint/paint_worklet_job.h"
@ -5774,6 +5775,13 @@ void LayerTreeHostImpl::SetUkmSmoothnessDestination(
ukm_smoothness_mapping_ = std::move(ukm_smoothness_data);
}
void LayerTreeHostImpl::SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_dropped_frames_data) {
frame_trackers_.SetUkmDroppedFramesDestination(
ukm_dropped_frames_data.GetMemoryAs<UkmDroppedFramesDataShared>());
ukm_dropped_frames_mapping_ = std::move(ukm_dropped_frames_data);
}
void LayerTreeHostImpl::NotifyDidPresentCompositorFrameOnImplThread(
uint32_t frame_token,
std::vector<PresentationTimeCallbackBuffer::SuccessfulCallback> callbacks,

@ -799,6 +799,8 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
void SetUkmSmoothnessDestination(
base::WritableSharedMemoryMapping ukm_smoothness_data);
void SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_dropped_frames_data);
// Notifies FrameTrackers, impl side callbacks that the compsitor frame
// was presented.
@ -1096,6 +1098,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
std::unique_ptr<PageScaleAnimation> page_scale_animation_;
base::WritableSharedMemoryMapping ukm_smoothness_mapping_;
base::WritableSharedMemoryMapping ukm_dropped_frames_mapping_;
TotalFrameCounter total_frame_counter_;
// `dropped_frame_counter_` holds a pointer `to ukm_smoothness_mapping_` so

@ -9695,6 +9695,8 @@ class LayerTreeHostUkmSmoothnessMetric : public LayerTreeTest {
void SetupTree() override {
LayerTreeTest::SetupTree();
shmem_region_ = layer_tree_host()->CreateSharedMemoryForSmoothnessUkm();
shmem_region_dropped_frames_ =
layer_tree_host()->CreateSharedMemoryForDroppedFramesUkm();
}
void BeginTest() override {
@ -9710,6 +9712,9 @@ class LayerTreeHostUkmSmoothnessMetric : public LayerTreeTest {
// It is not always possible to guarantee an exact number of dropped frames.
// So validate that there are non-zero dropped frames.
EXPECT_GT(smoothness->data.avg_smoothness, 0);
ASSERT_TRUE(shmem_region_dropped_frames_.IsValid());
// TODO(crbug.com/395868899): Test that values are exported here.
}
void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
@ -9744,6 +9749,7 @@ class LayerTreeHostUkmSmoothnessMetric : public LayerTreeTest {
bool fcp_sent_ = false;
viz::BeginFrameArgs last_args_;
base::ReadOnlySharedMemoryRegion shmem_region_;
base::ReadOnlySharedMemoryRegion shmem_region_dropped_frames_;
};
MULTI_THREAD_TEST_F(LayerTreeHostUkmSmoothnessMetric);

@ -8,12 +8,14 @@
#include <memory>
#include <string>
#include "base/memory/shared_memory_mapping.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/types/optional_ref.h"
#include "cc/cc_export.h"
#include "cc/input/browser_controls_offset_tag_modifications.h"
#include "cc/input/browser_controls_state.h"
#include "cc/paint/draw_image.h"
#include "cc/trees/paint_holding_commit_trigger.h"
#include "cc/trees/paint_holding_reason.h"
#include "cc/trees/task_runner_provider.h"
@ -115,6 +117,9 @@ class CC_EXPORT Proxy {
virtual void SetUkmSmoothnessDestination(
base::WritableSharedMemoryMapping ukm_smoothness_data) = 0;
virtual void SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_dropped_frames_data) = 0;
virtual void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) = 0;

@ -1013,6 +1013,13 @@ void ProxyImpl::SetUkmSmoothnessDestination(
host_impl_->SetUkmSmoothnessDestination(std::move(ukm_smoothness_data));
}
void ProxyImpl::SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_dropped_frames_data) {
DCHECK(IsImplThread());
host_impl_->SetUkmDroppedFramesDestination(
std::move(ukm_dropped_frames_data));
}
void ProxyImpl::ClearHistory() {
DCHECK(IsImplThread());
scheduler_->ClearHistory();

@ -104,6 +104,8 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
void SetSourceURL(ukm::SourceId source_id, const GURL& url);
void SetUkmSmoothnessDestination(
base::WritableSharedMemoryMapping ukm_smoothness_data);
void SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_dropped_frames_data);
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer);
void DetachInputDelegateAndRenderFrameObserver(

@ -916,6 +916,15 @@ void ProxyMain::SetUkmSmoothnessDestination(
std::move(ukm_smoothness_data)));
}
void ProxyMain::SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_dropped_frames_data) {
DCHECK(IsMainThread());
ImplThreadTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&ProxyImpl::SetUkmDroppedFramesDestination,
base::Unretained(proxy_impl_.get()),
std::move(ukm_dropped_frames_data)));
}
void ProxyMain::SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) {
ImplThreadTaskRunner()->PostTask(

@ -129,6 +129,8 @@ class CC_EXPORT ProxyMain : public Proxy {
void SetSourceURL(ukm::SourceId source_id, const GURL& url) override;
void SetUkmSmoothnessDestination(
base::WritableSharedMemoryMapping ukm_smoothness_data) override;
void SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_dropped_frames_data) override;
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) override;
void CompositeImmediatelyForTest(base::TimeTicks frame_begin_time,

@ -944,6 +944,11 @@ void SingleThreadProxy::SetUkmSmoothnessDestination(
DCHECK(task_runner_provider_->IsMainThread());
}
void SingleThreadProxy::SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_smoothness_data) {
DCHECK(task_runner_provider_->IsMainThread());
}
void SingleThreadProxy::ClearHistory() {
DCHECK(task_runner_provider_->IsImplThread());
if (scheduler_on_impl_thread_)

@ -83,6 +83,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void SetSourceURL(ukm::SourceId source_id, const GURL& url) override;
void SetUkmSmoothnessDestination(
base::WritableSharedMemoryMapping ukm_smoothness_data) override;
void SetUkmDroppedFramesDestination(
base::WritableSharedMemoryMapping ukm_smoothness_data) override;
void SetRenderFrameObserver(
std::unique_ptr<RenderFrameMetadataObserver> observer) override;
void CompositeImmediatelyForTest(base::TimeTicks frame_begin_time,

@ -24,6 +24,7 @@
#include "base/trace_event/trace_id_helper.h"
#include "base/trace_event/typed_macros.h"
#include "cc/base/features.h"
#include "cc/metrics/ukm_dropped_frames_data.h"
#include "cc/metrics/ukm_smoothness_data.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
@ -426,6 +427,7 @@ UkmPageLoadMetricsObserver::FlushMetricsOnAppEnterBackground(
if (GetDelegate().StartedInForeground())
RecordTimingMetrics(timing);
ReportLayoutStability();
RecordDroppedFramesMetrics();
RecordSmoothnessMetrics();
RecordResponsivenessMetrics();
// Assume that page ends on this method, as the app could be evicted right
@ -505,6 +507,7 @@ void UkmPageLoadMetricsObserver::OnComplete(
if (GetDelegate().StartedInForeground())
RecordTimingMetrics(timing);
ReportLayoutStability();
RecordDroppedFramesMetrics();
RecordSmoothnessMetrics();
RecordResponsivenessMetrics();
RecordPageEndMetrics(&timing, current_time,
@ -1523,6 +1526,21 @@ void UkmPageLoadMetricsObserver::RecordPageLoadTimestampMetrics(
builder.SetHourOfDay(exploded.hour);
}
void UkmPageLoadMetricsObserver::RecordDroppedFramesMetrics() {
auto* dropped_frames =
ukm_dropped_frames_data_.GetMemoryAs<cc::UkmDroppedFramesDataShared>();
if (!dropped_frames) {
return;
}
cc::UkmDroppedFramesData dropped_frames_data;
bool success = dropped_frames->Read(dropped_frames_data);
if (!success) {
return;
}
// TODO(crbug.com/395868899): Read PDF4 metric here.
}
void UkmPageLoadMetricsObserver::RecordSmoothnessMetrics() {
auto* smoothness =
ukm_smoothness_data_.GetMemoryAs<cc::UkmSmoothnessDataShared>();
@ -1774,9 +1792,11 @@ void UkmPageLoadMetricsObserver::OnTimingUpdate(
}
}
void UkmPageLoadMetricsObserver::SetUpSharedMemoryForSmoothness(
const base::ReadOnlySharedMemoryRegion& shared_memory) {
ukm_smoothness_data_ = shared_memory.Map();
void UkmPageLoadMetricsObserver::SetUpSharedMemoryForUkms(
const base::ReadOnlySharedMemoryRegion& smoothness_memory,
const base::ReadOnlySharedMemoryRegion& dropped_frames_memory) {
ukm_smoothness_data_ = smoothness_memory.Map();
ukm_dropped_frames_data_ = dropped_frames_memory.Map();
}
void UkmPageLoadMetricsObserver::OnCpuTimingUpdate(

@ -111,8 +111,9 @@ class UkmPageLoadMetricsObserver
content::RenderFrameHost* subframe_rfh,
const page_load_metrics::mojom::PageLoadTiming& timing) override;
void SetUpSharedMemoryForSmoothness(
const base::ReadOnlySharedMemoryRegion& shared_memory) override;
void SetUpSharedMemoryForUkms(
const base::ReadOnlySharedMemoryRegion& smoothness_memory,
const base::ReadOnlySharedMemoryRegion& dropped_frames_memory) override;
void OnCpuTimingUpdate(
content::RenderFrameHost* subframe_rfh,
@ -187,6 +188,7 @@ class UkmPageLoadMetricsObserver
ukm::builders::PageLoad& builder,
const page_load_metrics::PageEndReason page_end_reason);
void RecordDroppedFramesMetrics();
void RecordSmoothnessMetrics();
void RecordResponsivenessMetrics();
@ -362,6 +364,7 @@ class UkmPageLoadMetricsObserver
std::optional<net::HttpConnectionInfo> connection_info_;
base::ReadOnlySharedMemoryMapping ukm_smoothness_data_;
base::ReadOnlySharedMemoryMapping ukm_dropped_frames_data_;
// Only true if the page became hidden after the first time it was shown in
// the foreground, no matter how it started.

@ -11,6 +11,7 @@
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/metrics/histogram_macros.h"
#include "base/observer_list.h"
#include "base/time/time.h"
@ -200,7 +201,7 @@ void MetricsWebContentsObserver::WebContentsDestroyed() {
// access the current WebContents.
primary_page_ = nullptr;
active_pages_.clear();
ukm_smoothness_data_.clear();
ukm_data_.clear();
provisional_loads_.clear();
aborted_provisional_loads_.clear();
}
@ -272,7 +273,7 @@ void MetricsWebContentsObserver::RenderFrameDeleted(
}
active_pages_.erase(rfh);
inactive_pages_.erase(rfh);
ukm_smoothness_data_.erase(rfh);
ukm_data_.erase(rfh);
}
void MetricsWebContentsObserver::MediaStartedPlaying(
@ -825,11 +826,13 @@ void MetricsWebContentsObserver::HandleCommittedNavigationForTrackedLoad(
const bool is_main_frame =
render_frame_host && render_frame_host->GetParent() == nullptr;
if (is_main_frame) {
auto it = ukm_smoothness_data_.find(render_frame_host);
if (it != ukm_smoothness_data_.end()) {
raw_tracker->metrics_update_dispatcher()->SetUpSharedMemoryForSmoothness(
render_frame_host, std::move(it->second));
ukm_smoothness_data_.erase(it);
auto ukm_it = ukm_data_.find(render_frame_host);
if (ukm_it != ukm_data_.end()) {
auto& [smoothness_memory, dropped_frames_memory] = ukm_it->second;
raw_tracker->metrics_update_dispatcher()->SetUpSharedMemoryForUkms(
render_frame_host, std::move(smoothness_memory),
std::move(dropped_frames_memory));
ukm_data_.erase(ukm_it);
}
}
@ -1254,24 +1257,25 @@ void MetricsWebContentsObserver::AddCustomUserTiming(
OnCustomUserTimingUpdated(render_frame_host, std::move(custom_timing));
}
void MetricsWebContentsObserver::SetUpSharedMemoryForSmoothness(
base::ReadOnlySharedMemoryRegion shared_memory) {
void MetricsWebContentsObserver::SetUpSharedMemoryForUkms(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) {
content::RenderFrameHost* render_frame_host =
page_load_metrics_receivers_.GetCurrentTargetFrame();
const bool is_outermost_main_frame =
render_frame_host->GetParentOrOuterDocument() == nullptr;
if (!is_outermost_main_frame) {
// TODO(crbug.com/40144214): Merge smoothness metrics from OOPIFs and
// FencedFrames with the main-frame. Also need to check if FencedFrames
// send this request correctly.
return;
}
if (PageLoadTracker* tracker = GetPageLoadTracker(render_frame_host)) {
tracker->metrics_update_dispatcher()->SetUpSharedMemoryForSmoothness(
render_frame_host, std::move(shared_memory));
tracker->metrics_update_dispatcher()->SetUpSharedMemoryForUkms(
render_frame_host, std::move(smoothness_memory),
std::move(dropped_frames_memory));
} else {
ukm_smoothness_data_.emplace(render_frame_host, std::move(shared_memory));
ukm_data_.emplace(render_frame_host,
std::make_pair(std::move(smoothness_memory),
std::move(dropped_frames_memory)));
}
}

@ -256,8 +256,9 @@ class MetricsWebContentsObserver
void AddCustomUserTiming(
mojom::CustomUserTimingMarkPtr custom_timing) override;
void SetUpSharedMemoryForSmoothness(
base::ReadOnlySharedMemoryRegion shared_memory) override;
void SetUpSharedMemoryForUkms(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) override;
// Common part for UpdateThroughput and OnTimingUpdated.
bool DoesTimingUpdateHaveError(PageLoadTracker* tracker);
@ -392,9 +393,12 @@ class MetricsWebContentsObserver
inactive_pages_;
// This is currently set only for the main frame of each page associated with
// the WebContents.
base::flat_map<content::RenderFrameHost*, base::ReadOnlySharedMemoryRegion>
ukm_smoothness_data_;
// the WebContents. It maps to the shared memory for the smoothness and the
// dropped frame count UKMs.
base::flat_map<content::RenderFrameHost*,
std::pair<base::ReadOnlySharedMemoryRegion,
base::ReadOnlySharedMemoryRegion>>
ukm_data_;
std::vector<mojom::CustomUserTimingMarkPtr> page_load_custom_timings_;

@ -174,8 +174,9 @@ class AssertPageLoadMetricsObserver final
void OnFeaturesUsageObserved(
content::RenderFrameHost* rfh,
const std::vector<blink::UseCounterFeature>& features) override {}
void SetUpSharedMemoryForSmoothness(
const base::ReadOnlySharedMemoryRegion& shared_memory) override {}
void SetUpSharedMemoryForUkms(
const base::ReadOnlySharedMemoryRegion& smoothness_memory,
const base::ReadOnlySharedMemoryRegion& dropped_frames_memory) override {}
void OnResourceDataUseObserved(
content::RenderFrameHost* rfh,
const std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr>&

@ -307,12 +307,10 @@ void PageLoadMetricsForwardObserver::OnFeaturesUsageObserved(
parent_observer_->OnFeaturesUsageObserved(rfh, features);
}
// SetUpSharedMemoryForSmoothness is called only for the outermost page.
void PageLoadMetricsForwardObserver::SetUpSharedMemoryForSmoothness(
const base::ReadOnlySharedMemoryRegion& shared_memory) {
// See also MetricsWebContentsObserver::SetUpSharedMemoryForSmoothness and
// the relevant TODO. Currently, information from OOPIFs and FencedFrames are
// not handled.
// SetUpSharedMemoryForUkms is called only for the outermost page.
void PageLoadMetricsForwardObserver::SetUpSharedMemoryForUkms(
const base::ReadOnlySharedMemoryRegion& smoothness_memory,
const base::ReadOnlySharedMemoryRegion& dropped_frames_memory) {
// TODO(crbug.com/40895492): Investigate whether this should truly be
// unreachable. Note that all NOTREACHED()s were made non-fatal in this file,
// they are not all necessarily hit.

@ -5,6 +5,7 @@
#ifndef COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_FORWARD_OBSERVER_H_
#define COMPONENTS_PAGE_LOAD_METRICS_BROWSER_PAGE_LOAD_METRICS_FORWARD_OBSERVER_H_
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/weak_ptr.h"
#include "components/page_load_metrics/browser/page_load_metrics_observer_delegate.h"
#include "components/page_load_metrics/browser/page_load_metrics_observer_interface.h"
@ -120,8 +121,9 @@ class PageLoadMetricsForwardObserver final
void OnFeaturesUsageObserved(
content::RenderFrameHost* rfh,
const std::vector<blink::UseCounterFeature>& features) override;
void SetUpSharedMemoryForSmoothness(
const base::ReadOnlySharedMemoryRegion& shared_memory) override;
void SetUpSharedMemoryForUkms(
const base::ReadOnlySharedMemoryRegion& smoothness_memory,
const base::ReadOnlySharedMemoryRegion& dropped_frames_memory) override;
void OnResourceDataUseObserved(
content::RenderFrameHost* rfh,
const std::vector<mojom::ResourceDataUpdatePtr>& resources) override;

@ -200,8 +200,9 @@ class PageLoadMetricsObserver : public PageLoadMetricsObserverInterface {
void OnFeaturesUsageObserved(
content::RenderFrameHost* rfh,
const std::vector<blink::UseCounterFeature>& features) override {}
void SetUpSharedMemoryForSmoothness(
const base::ReadOnlySharedMemoryRegion& shared_memory) override {}
void SetUpSharedMemoryForUkms(
const base::ReadOnlySharedMemoryRegion& smoothness_memory,
const base::ReadOnlySharedMemoryRegion& dropped_frames_memory) override {}
void OnResourceDataUseObserved(
content::RenderFrameHost* rfh,
const std::vector<mojom::ResourceDataUpdatePtr>& resources) override {}

@ -450,11 +450,13 @@ class PageLoadMetricsObserverInterface {
content::RenderFrameHost* rfh,
const std::vector<blink::UseCounterFeature>& features) = 0;
// The smoothness metrics is shared over shared-memory. The observer should
// create a mapping (by calling |shared_memory.Map()|) so that they are able
// to read from the shared memory.
virtual void SetUpSharedMemoryForSmoothness(
const base::ReadOnlySharedMemoryRegion& shared_memory) = 0;
// The smoothness and dropped frame count metrics are shared over
// shared-memory. The observer should create a mapping (by calling
// |shared_memory.Map()|) so that they are able to read from the shared
// memory.
virtual void SetUpSharedMemoryForUkms(
const base::ReadOnlySharedMemoryRegion& smoothness_memory,
const base::ReadOnlySharedMemoryRegion& dropped_frames_memory) = 0;
// Invoked when there is data use for loading a resource on the page
// for a given RenderFrameHost. This only contains resources that have had

@ -508,15 +508,14 @@ void PageLoadMetricsUpdateDispatcher::UpdateFeatures(
client_->UpdateFeaturesUsage(render_frame_host, new_features);
}
void PageLoadMetricsUpdateDispatcher::SetUpSharedMemoryForSmoothness(
void PageLoadMetricsUpdateDispatcher::SetUpSharedMemoryForUkms(
content::RenderFrameHost* render_frame_host,
base::ReadOnlySharedMemoryRegion shared_memory) {
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) {
const bool is_main_frame = client_->IsPageMainFrame(render_frame_host);
if (is_main_frame) {
client_->SetUpSharedMemoryForSmoothness(std::move(shared_memory));
} else {
// TODO(crbug.com/40144214): Merge smoothness metrics from OOPIFs with the
// main-frame.
client_->SetUpSharedMemoryForUkms(std::move(smoothness_memory),
std::move(dropped_frames_memory));
}
}

@ -157,8 +157,9 @@ class PageLoadMetricsUpdateDispatcher {
const gfx::Rect& main_frame_viewport_rect) = 0;
virtual void OnMainFrameImageAdRectsChanged(
const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) = 0;
virtual void SetUpSharedMemoryForSmoothness(
base::ReadOnlySharedMemoryRegion shared_memory) = 0;
virtual void SetUpSharedMemoryForUkms(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) = 0;
};
// The |client| instance must outlive this object.
@ -187,9 +188,10 @@ class PageLoadMetricsUpdateDispatcher {
mojom::SoftNavigationMetricsPtr soft_navigation_metrics,
internal::PageLoadTrackerPageType page_type);
void SetUpSharedMemoryForSmoothness(
void SetUpSharedMemoryForUkms(
content::RenderFrameHost* render_frame_host,
base::ReadOnlySharedMemoryRegion shared_memory);
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory);
// This method is only intended to be called for PageLoadFeatures being
// recorded directly from the browser process. Features coming from the

@ -12,6 +12,7 @@
#include "base/check_op.h"
#include "base/feature_list.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
@ -1123,11 +1124,13 @@ void PageLoadTracker::UpdateFeaturesUsage(
}
}
void PageLoadTracker::SetUpSharedMemoryForSmoothness(
base::ReadOnlySharedMemoryRegion shared_memory) {
DCHECK(shared_memory.IsValid());
void PageLoadTracker::SetUpSharedMemoryForUkms(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) {
DCHECK(smoothness_memory.IsValid() && dropped_frames_memory.IsValid());
for (auto& observer : observers_) {
observer->SetUpSharedMemoryForSmoothness(shared_memory);
observer->SetUpSharedMemoryForUkms(smoothness_memory,
dropped_frames_memory);
}
}

@ -235,8 +235,9 @@ class PageLoadTracker : public PageLoadMetricsUpdateDispatcher::Client,
const gfx::Rect& main_frame_viewport_rect) override;
void OnMainFrameImageAdRectsChanged(
const base::flat_map<int, gfx::Rect>& main_frame_image_ad_rects) override;
void SetUpSharedMemoryForSmoothness(
base::ReadOnlySharedMemoryRegion shared_memory) override;
void SetUpSharedMemoryForUkms(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) override;
// PageLoadMetricsObserverDelegate implementation:
content::WebContents* GetWebContents() const override;

@ -584,10 +584,12 @@ interface PageLoadMetrics {
SoftNavigationMetrics soft_navigation_metrics);
// Set up a shared memory used to transfer smoothness data from the renderer
// to the browser. The structure is defined in
// //cc/metrics/ukm_smoothness_data.h
SetUpSharedMemoryForSmoothness(
mojo_base.mojom.ReadOnlySharedMemoryRegion shared_memory);
// to the browser. The structures are defined in
// //cc/metrics/ukm_smoothness_data.h and
// //cc/metrics/ukm_dropped_frames_data.h
SetUpSharedMemoryForUkms(
mojo_base.mojom.ReadOnlySharedMemoryRegion smoothness_memory,
mojo_base.mojom.ReadOnlySharedMemoryRegion dropped_frames_memory);
// Called when performance entries are added via `performance.mark()` from the
// outermost main frame in renderer, except for the case when standard

@ -33,8 +33,9 @@ void FakePageTimingSender::SendTiming(
subresource_load_metrics, soft_navigation_metrics);
}
void FakePageTimingSender::SetUpSmoothnessReporting(
base::ReadOnlySharedMemoryRegion shared_memory) {}
void FakePageTimingSender::SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) {}
void FakePageTimingSender::SendCustomUserTiming(
mojom::CustomUserTimingMarkPtr timing) {}

@ -166,8 +166,9 @@ class FakePageTimingSender : public PageTimingSender {
subresource_load_metrics,
const mojom::SoftNavigationMetricsPtr& soft_navigation_metrics) override;
void SetUpSmoothnessReporting(
base::ReadOnlySharedMemoryRegion shared_memory) override;
void SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) override;
void SendCustomUserTiming(mojom::CustomUserTimingMarkPtr timing) override;

@ -74,11 +74,13 @@ class MojoPageTimingSender : public PageTimingSender {
subresource_load_metrics, soft_navigation_metrics->Clone());
}
void SetUpSmoothnessReporting(
base::ReadOnlySharedMemoryRegion shared_memory) override {
void SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion shared_memory_smoothness,
base::ReadOnlySharedMemoryRegion shared_memory_dropped_frames) override {
DCHECK(page_load_metrics_);
page_load_metrics_->SetUpSharedMemoryForSmoothness(
std::move(shared_memory));
page_load_metrics_->SetUpSharedMemoryForUkms(
std::move(shared_memory_smoothness),
std::move(shared_memory_dropped_frames));
}
void SendCustomUserTiming(mojom::CustomUserTimingMarkPtr timing) override {
@ -419,13 +421,16 @@ void MetricsRenderFrameObserver::OnFrameDetached() {
WillDetach(blink::DetachReason::kNavigation);
}
bool MetricsRenderFrameObserver::SetUpSmoothnessReporting(
base::ReadOnlySharedMemoryRegion& shared_memory) {
bool MetricsRenderFrameObserver::SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion& shared_memory_smoothness,
base::ReadOnlySharedMemoryRegion& shared_memory_dropped_frames) {
if (page_timing_metrics_sender_) {
page_timing_metrics_sender_->SetUpSmoothnessReporting(
std::move(shared_memory));
page_timing_metrics_sender_->SetUpUkmReporting(
std::move(shared_memory_smoothness),
std::move(shared_memory_dropped_frames));
} else {
ukm_smoothness_data_ = std::move(shared_memory);
ukm_smoothness_data_ = std::move(shared_memory_smoothness);
ukm_dropped_frames_data_ = std::move(shared_memory_dropped_frames);
}
return true;
}
@ -479,9 +484,9 @@ void MetricsRenderFrameObserver::SendMetrics() {
}
void MetricsRenderFrameObserver::OnMetricsSenderCreated() {
if (ukm_smoothness_data_.IsValid()) {
page_timing_metrics_sender_->SetUpSmoothnessReporting(
std::move(ukm_smoothness_data_));
if (ukm_smoothness_data_.IsValid() && ukm_dropped_frames_data_.IsValid()) {
page_timing_metrics_sender_->SetUpUkmReporting(
std::move(ukm_smoothness_data_), std::move(ukm_dropped_frames_data_));
}
// Send the latest the frame intersection update, as otherwise we may miss

@ -136,8 +136,9 @@ class MetricsRenderFrameObserver : public content::RenderFrameObserver,
// blink::WebLocalFrameObserver implementation
void OnFrameDetached() override;
bool SetUpSmoothnessReporting(
base::ReadOnlySharedMemoryRegion& shared_memory) override;
bool SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion& shared_memory_smoothness,
base::ReadOnlySharedMemoryRegion& shared_memory_dropped_frames) override;
protected:
// The relative and monotonic page load timings.
@ -182,6 +183,7 @@ class MetricsRenderFrameObserver : public content::RenderFrameObserver,
// Handle to the shared memory for transporting smoothness related ukm data.
base::ReadOnlySharedMemoryRegion ukm_smoothness_data_;
base::ReadOnlySharedMemoryRegion ukm_dropped_frames_data_;
// The main frame intersection rectangle signal received before
// `page_timing_metrics_sender_` is created. The signal will be send out right

@ -250,9 +250,11 @@ void PageTimingMetricsSender::UpdateResourceMetadata(
it->second->SetIsMainFrameResource(is_main_frame_resource);
}
void PageTimingMetricsSender::SetUpSmoothnessReporting(
base::ReadOnlySharedMemoryRegion shared_memory) {
sender_->SetUpSmoothnessReporting(std::move(shared_memory));
void PageTimingMetricsSender::SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion shared_memory_smoothness,
base::ReadOnlySharedMemoryRegion shared_memory_dropped_frames) {
sender_->SetUpUkmReporting(std::move(shared_memory_smoothness),
std::move(shared_memory_dropped_frames));
}
void PageTimingMetricsSender::Update(

@ -107,7 +107,11 @@ class PageTimingMetricsSender {
void UpdateCpuTiming(base::TimeDelta task_time);
void UpdateResourceMetadata(int resource_id, bool is_main_frame_resource);
void SetUpSmoothnessReporting(base::ReadOnlySharedMemoryRegion shared_memory);
void SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion shared_memory_smoothness,
base::ReadOnlySharedMemoryRegion shared_memory_dropped_frames);
void InitiateUserInteractionTiming();
mojom::SoftNavigationMetricsPtr GetSoftNavigationMetrics() {
return soft_navigation_metrics_->Clone();

@ -25,8 +25,9 @@ class PageTimingSender {
const std::optional<blink::SubresourceLoadMetrics>&
subresource_load_metrics,
const mojom::SoftNavigationMetricsPtr& soft_navigation_metrics) = 0;
virtual void SetUpSmoothnessReporting(
base::ReadOnlySharedMemoryRegion shared_memory) = 0;
virtual void SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion shared_memory_smoothness,
base::ReadOnlySharedMemoryRegion shared_memory_dropped_frames) = 0;
virtual void SendCustomUserTiming(mojom::CustomUserTimingMarkPtr timing) = 0;
};

@ -58,8 +58,9 @@ void RenderFrameObserver::RenderFrameGone() {
render_frame_ = nullptr;
}
bool RenderFrameObserver::SetUpSmoothnessReporting(
base::ReadOnlySharedMemoryRegion& shared_memory) {
bool RenderFrameObserver::SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion& shared_memory_smoothness,
base::ReadOnlySharedMemoryRegion& shared_memory_dropped_frames) {
return false;
}

@ -370,11 +370,12 @@ class CONTENT_EXPORT RenderFrameObserver
const std::string& interface_name,
mojo::ScopedInterfaceEndpointHandle* handle);
// The smoothness metrics is shared over shared-memory. The interested
// observer should invalidate |shared_memory| (by std::move()'ing it), and
// return true. All other observers should return false (default).
virtual bool SetUpSmoothnessReporting(
base::ReadOnlySharedMemoryRegion& shared_memory);
// The smoothness and dropped frames metrics is shared over shared-memory. The
// interested observer should invalidate |shared_memory| (by std::move()'ing
// it), and return true. All other observers should return false (default).
virtual bool SetUpUkmReporting(
base::ReadOnlySharedMemoryRegion& shared_memory_smoothness,
base::ReadOnlySharedMemoryRegion& shared_memory_dropped_frames);
#if BUILDFLAG(CONTENT_ENABLE_LEGACY_IPC)
// IPC::Listener implementation.

@ -2142,17 +2142,19 @@ void RenderFrameImpl::OnAssociatedInterfaceRequest(
}
}
void RenderFrameImpl::SetUpSharedMemoryForSmoothness(
base::ReadOnlySharedMemoryRegion shared_memory) {
void RenderFrameImpl::SetUpSharedMemoryForUkms(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) {
TRACE_EVENT_WITH_FLOW0("navigation",
"RenderFrameImpl::SetUpSharedMemoryForSmoothness",
"RenderFrameImpl::SetUpSharedMemoryForUkms",
TRACE_ID_LOCAL(this),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
DCHECK(shared_memory.IsValid());
DCHECK(smoothness_memory.IsValid() && dropped_frames_memory.IsValid());
for (auto& observer : observers_) {
DCHECK(shared_memory.IsValid());
if (observer.SetUpSmoothnessReporting(shared_memory))
DCHECK(smoothness_memory.IsValid() && dropped_frames_memory.IsValid());
if (observer.SetUpUkmReporting(smoothness_memory, dropped_frames_memory)) {
break;
}
}
}

@ -716,8 +716,10 @@ class CONTENT_EXPORT RenderFrameImpl
void OnFrameVisibilityChanged(
blink::mojom::FrameVisibility render_status) override;
void SetUpSharedMemoryForSmoothness(
base::ReadOnlySharedMemoryRegion shared_memory) override;
void SetUpSharedMemoryForUkms(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) override;
blink::WebURL LastCommittedUrlForUKM() override;
void ScriptedPrint() override;

@ -834,9 +834,10 @@ class BLINK_EXPORT WebLocalFrameClient {
virtual void OnFrameVisibilityChanged(mojom::FrameVisibility render_status) {}
// Called after a navigation which set the shared memory region for
// tracking smoothness via UKM.
virtual void SetUpSharedMemoryForSmoothness(
base::ReadOnlySharedMemoryRegion shared_memory) {}
// tracking smoothness and dropped frames UKMs.
virtual void SetUpSharedMemoryForUkms(
base::ReadOnlySharedMemoryRegion smoothness_memory,
base::ReadOnlySharedMemoryRegion dropped_frames_memory) {}
// Returns the last commited URL used for UKM. This is slightly different
// than the document's URL because it will contain a data URL if a base URL

@ -563,10 +563,13 @@ void LocalFrameClientImpl::DispatchDidCommitLoad(
web_frame_->GetDocument().GetUkmSourceId(),
KURL(web_frame_->Client()->LastCommittedUrlForUKM()));
auto shmem = frame_widget->CreateSharedMemoryForSmoothnessUkm();
if (shmem.IsValid()) {
web_frame_->Client()->SetUpSharedMemoryForSmoothness(
std::move(shmem));
auto smoothness_shmem =
frame_widget->CreateSharedMemoryForSmoothnessUkm();
auto dropped_frames_shmem =
frame_widget->CreateSharedMemoryForDroppedFramesUkm();
if (smoothness_shmem.IsValid() && dropped_frames_shmem.IsValid()) {
web_frame_->Client()->SetUpSharedMemoryForUkms(
std::move(smoothness_shmem), std::move(dropped_frames_shmem));
}
}
}

@ -5227,6 +5227,11 @@ WebFrameWidgetImpl::CreateSharedMemoryForSmoothnessUkm() {
return LayerTreeHost()->CreateSharedMemoryForSmoothnessUkm();
}
base::ReadOnlySharedMemoryRegion
WebFrameWidgetImpl::CreateSharedMemoryForDroppedFramesUkm() {
return LayerTreeHost()->CreateSharedMemoryForDroppedFramesUkm();
}
bool WebFrameWidgetImpl::CanComposeInline() {
if (auto* plugin = GetFocusedPluginContainer())
return plugin->CanComposeInline();

@ -718,6 +718,8 @@ class CORE_EXPORT WebFrameWidgetImpl
// Ask compositor to create the shared memory for smoothness ukm region.
base::ReadOnlySharedMemoryRegion CreateSharedMemoryForSmoothnessUkm();
// Ask compositor to create the shared memory for dropped frames ukm region.
base::ReadOnlySharedMemoryRegion CreateSharedMemoryForDroppedFramesUkm();
#if BUILDFLAG(IS_ANDROID)
// Calculate and cache the most up to date line bounding boxes in the document
// coordinate space.