Add UMA for PresentationDelayForInteractiveFrames feature
This CL adds two histograms to help understand the percentage of frames that can be swapped immediately and frames that need to wait. GPU.Presentation.FrameHandlesAnimationOrInteraction GPU.Presentation.NonAnimatdOrInteractiveFrameWithPendingFrame When VSyncAlignedPresent and kPresentationDelayForInteractiveFrames are enabled, frames not handling interaction and animation can be swapped immediately. However, they must wait in the queue for VSync when there is a pending frame(s). Bug: 330771325 Change-Id: I9a85b2c398c37c5e428dd8327f5e0a332f335b00 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6334447 Commit-Queue: Maggie Chen <magchen@chromium.org> Reviewed-by: Colin Blundell <blundell@chromium.org> Reviewed-by: Jonathan Ross <jonross@chromium.org> Cr-Commit-Position: refs/heads/main@{#1430521}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
6ab89ac2b4
commit
3bdab00d57
components/viz/service/display
gpu/ipc/service
tools/metrics/histograms
ui/gfx
@ -121,7 +121,8 @@ class VIZ_SERVICE_EXPORT DirectRenderer {
|
||||
gfx::CALayerResult ca_layer_error_code = gfx::kCALayerSuccess;
|
||||
#endif
|
||||
|
||||
bool is_handling_interaction_or_animation = false;
|
||||
bool is_handling_interaction = false;
|
||||
bool is_handling_animation = false;
|
||||
|
||||
std::optional<int64_t> choreographer_vsync_id;
|
||||
int64_t swap_trace_id = -1;
|
||||
|
@ -1115,7 +1115,8 @@ bool Display::DrawAndSwap(const DrawAndSwapParams& params) {
|
||||
std::move(animation_thread_ids), std::move(renderer_main_thread_ids),
|
||||
boost_type);
|
||||
|
||||
bool has_interactive_or_animated_frame = false;
|
||||
bool has_interactive_frame = false;
|
||||
bool has_animated_frame = false;
|
||||
for (const auto& surface_id : aggregator_->previous_contained_surfaces()) {
|
||||
surface = surface_manager_->GetSurfaceForId(surface_id);
|
||||
if (surface) {
|
||||
@ -1125,10 +1126,12 @@ bool Display::DrawAndSwap(const DrawAndSwapParams& params) {
|
||||
presentation_group_timing.AddPresentationHelper(std::move(helper));
|
||||
}
|
||||
|
||||
has_interactive_or_animated_frame |=
|
||||
has_interactive_frame |=
|
||||
surface->HasActiveFrame() &&
|
||||
(surface->GetActiveFrameMetadata().is_handling_interaction ||
|
||||
surface->GetActiveFrameMetadata().is_handling_animation);
|
||||
surface->GetActiveFrameMetadata().is_handling_interaction;
|
||||
has_animated_frame |=
|
||||
surface->HasActiveFrame() &&
|
||||
surface->GetActiveFrameMetadata().is_handling_animation;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1164,8 +1167,8 @@ bool Display::DrawAndSwap(const DrawAndSwapParams& params) {
|
||||
swap_frame_data.ca_layer_error_code =
|
||||
overlay_processor_->GetCALayerErrorCode();
|
||||
#endif
|
||||
swap_frame_data.is_handling_interaction_or_animation =
|
||||
has_interactive_or_animated_frame;
|
||||
swap_frame_data.is_handling_interaction = has_interactive_frame;
|
||||
swap_frame_data.is_handling_animation = has_animated_frame;
|
||||
|
||||
// We must notify scheduler and increase |pending_swaps_| before calling
|
||||
// SwapBuffers() as it can call DidReceiveSwapBuffersAck synchronously.
|
||||
|
@ -1197,8 +1197,10 @@ void SkiaRenderer::SwapBuffers(SwapFrameData swap_frame_data) {
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
output_frame.data.is_handling_interaction_or_animation =
|
||||
swap_frame_data.is_handling_interaction_or_animation;
|
||||
output_frame.data.is_handling_interaction =
|
||||
swap_frame_data.is_handling_interaction;
|
||||
output_frame.data.is_handling_animation =
|
||||
swap_frame_data.is_handling_animation;
|
||||
#endif
|
||||
|
||||
if (buffer_queue_) {
|
||||
|
@ -63,6 +63,48 @@ void RecordVSyncCallbackDelay(base::TimeDelta delay) {
|
||||
/*min=*/base::Microseconds(10),
|
||||
/*max=*/base::Milliseconds(33), /*bucket_count=*/50);
|
||||
}
|
||||
|
||||
// These values are persisted to logs. Entries should not be renumbered and
|
||||
// numeric values should never be reused.
|
||||
//
|
||||
// LINT.IfChange(AnimationOrInteractionType)
|
||||
enum class AnimationOrInteractionType {
|
||||
kNone = 0,
|
||||
kInteractionOnly = 1,
|
||||
kAnimationOnly = 2,
|
||||
kAnimationAndInteraction = 3,
|
||||
kMaxValue = kAnimationAndInteraction,
|
||||
};
|
||||
// LINT.ThenChange(//tools/metrics/histograms/enums.xml:FrameHandlingType)
|
||||
|
||||
void RecordFrameTypes(bool is_handling_interaction,
|
||||
bool is_handling_animation,
|
||||
int num_pending_frames) {
|
||||
AnimationOrInteractionType type;
|
||||
if (is_handling_interaction && is_handling_animation) {
|
||||
type = AnimationOrInteractionType::kAnimationAndInteraction;
|
||||
} else if (is_handling_interaction) {
|
||||
type = AnimationOrInteractionType::kInteractionOnly;
|
||||
} else if (is_handling_animation) {
|
||||
type = AnimationOrInteractionType::kAnimationOnly;
|
||||
} else {
|
||||
type = AnimationOrInteractionType::kNone;
|
||||
}
|
||||
|
||||
UMA_HISTOGRAM_ENUMERATION(
|
||||
"GPU.Presentation.FrameHandlesAnimationOrInteraction", type);
|
||||
|
||||
// Although the current frame is free of interation and animation, the pending
|
||||
// frame blocks the current frame from being swapped immediately when
|
||||
// VSyncAlignedPresent and kPresentationDelayForInteractiveFrames are enabled.
|
||||
// Note: |num_pending_frames| is always 0 when VSyncAlignedPresent is
|
||||
// disabled.
|
||||
if (type == AnimationOrInteractionType::kNone) {
|
||||
UMA_HISTOGRAM_BOOLEAN(
|
||||
"GPU.Presentation.NonAnimatedOrInteractiveFrameWithPendingFrame",
|
||||
!!num_pending_frames);
|
||||
}
|
||||
}
|
||||
#endif // BUILDFLAG(IS_MAC)
|
||||
|
||||
} // namespace
|
||||
@ -129,7 +171,7 @@ void ImageTransportSurfaceOverlayMacEGL::Present(
|
||||
// Commit the first pending frame before adding one more in Present() if there
|
||||
// are more than supported .
|
||||
if (ca_layer_tree_coordinator_->NumPendingSwaps() >= cap_max_pending_swaps_) {
|
||||
TRACE_EVENT0("gpu", "Commit now. Exceeds the max pending swaps.");
|
||||
TRACE_EVENT0("gpu", "Exceeds the max pending swaps. Commit now.");
|
||||
CommitPresentedFrameToCA();
|
||||
}
|
||||
|
||||
@ -185,10 +227,16 @@ void ImageTransportSurfaceOverlayMacEGL::Present(
|
||||
|
||||
if (base::FeatureList::IsEnabled(kPresentationDelayForInteractiveFrames) &&
|
||||
!ca_layer_tree_coordinator_->NumPendingSwaps() &&
|
||||
!data.is_handling_interaction_or_animation) {
|
||||
!data.is_handling_interaction && !data.is_handling_animation) {
|
||||
delay_presenetation_until_next_vsync = false;
|
||||
}
|
||||
|
||||
if (features::IsVSyncAlignedPresentEnabled() &&
|
||||
base::FeatureList::IsEnabled(kPresentationDelayForInteractiveFrames)) {
|
||||
RecordFrameTypes(data.is_handling_interaction, data.is_handling_animation,
|
||||
ca_layer_tree_coordinator_->NumPendingSwaps());
|
||||
}
|
||||
|
||||
if (vsync_callback_mac_) {
|
||||
vsync_callback_mac_keep_alive_counter_ = kMaxKeepAliveCounter;
|
||||
if (delay_presenetation_until_next_vsync) {
|
||||
|
@ -5388,6 +5388,17 @@ to ensure that the crash string is shown properly on the user-facing crash UI.
|
||||
<int value="3" label="Start on NTP"/>
|
||||
</enum>
|
||||
|
||||
<!-- LINT.IfChange(FrameHandlingType) -->
|
||||
|
||||
<enum name="FrameHandlingType">
|
||||
<int value="0" label="None"/>
|
||||
<int value="1" label="InteractionOnly"/>
|
||||
<int value="2" label="AnimationOnly"/>
|
||||
<int value="3" label="InteractionAndAnimation"/>
|
||||
</enum>
|
||||
|
||||
<!-- LINT.ThenChange(//gpu/ipc/service/image_transport_surface_overlay_mac.mm:AnimationOrInteractionType) -->
|
||||
|
||||
<enum name="FsckResult">
|
||||
<summary>
|
||||
These correspond to e2fsck exit codes. Note that 0 differs from e2fsck's man
|
||||
|
@ -1199,6 +1199,33 @@ chromium-metrics-reviews@google.com.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="GPU.Presentation.FrameHandlesAnimationOrInteraction"
|
||||
enum="FrameHandlingType" expires_after="2025-09-07">
|
||||
<owner>magchen@chromium.org</owner>
|
||||
<owner>vmiura@chromium.org</owner>
|
||||
<owner>chrome-gpu-metric-alerts@chromium.org</owner>
|
||||
<summary>
|
||||
Recorded on Mac when a frame is ready to present and GPU Present() is
|
||||
called. It records whether the current frame is handling interaction,
|
||||
animation, both, or none.
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram
|
||||
name="GPU.Presentation.NonAnimatedOrInteractiveFrameWithPendingFrame"
|
||||
enum="Boolean" expires_after="2025-09-07">
|
||||
<owner>magchen@chromium.org</owner>
|
||||
<owner>vmiura@chromium.org</owner>
|
||||
<owner>chrome-gpu-metric-alerts@chromium.org</owner>
|
||||
<summary>
|
||||
Recorded on Mac for frames that are not handling interaction and animation
|
||||
at the time when they are ready to present and GPU Present() is called . If
|
||||
VSyncAlignedPresent and kPresentationDelayForInteractiveFrames are enabled,
|
||||
this type of frames can be swapped immediately. However, they must wait in
|
||||
the queue for VSync when there is a pending frame(s).
|
||||
</summary>
|
||||
</histogram>
|
||||
|
||||
<histogram name="GPU.Presentation.VSyncCallbackDelay" units="microseconds"
|
||||
expires_after="2025-08-10">
|
||||
<owner>magchen@chromium.org</owner>
|
||||
|
@ -40,7 +40,8 @@ struct FrameData {
|
||||
#endif
|
||||
|
||||
#if BUILDFLAG(IS_MAC)
|
||||
bool is_handling_interaction_or_animation = false;
|
||||
bool is_handling_interaction = false;
|
||||
bool is_handling_animation = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user