Skip to content

Commit

Permalink
ash: Add a PresentationTimeRecorder interface
Browse files Browse the repository at this point in the history
- Add a PresentationTimeRecorder interface;
- Add a factory to create a wrapper for ui::PresentationTimeRecorder;
- Revise WindowStateDelegate::OnDragStart to optionally return
  a recorder to track resize latency. This allows exo code that
  implements WindowStateDelegate to return a recorder to track exo
  timing.

Bug: 1249765
Change-Id: I41ae6247e677dd4c7435f50835973789d3dff11d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3550133
Reviewed-by: Mitsuru Oshima <oshima@chromium.org>
Commit-Queue: Xiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#986536}
  • Loading branch information
Xiyuan Xia authored and Chromium LUCI CQ committed Mar 29, 2022
1 parent d3b4b75 commit e3b8049
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 15 deletions.
2 changes: 2 additions & 0 deletions ash/public/cpp/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ component("cpp") {
"personalization_app/user_display_info.h",
"power_utils.cc",
"power_utils.h",
"presentation_time_recorder.cc",
"presentation_time_recorder.h",
"privacy_screen_dlp_helper.cc",
"privacy_screen_dlp_helper.h",
"projector/annotator_tool.cc",
Expand Down
58 changes: 58 additions & 0 deletions ash/public/cpp/presentation_time_recorder.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2022 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 "ash/public/cpp/presentation_time_recorder.h"

#include <memory>

#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/presentation_time_recorder.h"

namespace ash {

namespace {

// Wrapper class of ui::PresentationTimeRecorder that reports latency based
// on ui::Compositor.
class CompositorPresentationTimeRecorder : public PresentationTimeRecorder {
public:
CompositorPresentationTimeRecorder(aura::Window* window,
const char* latency_histogram_name,
const char* max_latency_histogram_name)
: compositor_recorder_(ui::CreatePresentationTimeHistogramRecorder(
window->layer()->GetCompositor(),
latency_histogram_name,
max_latency_histogram_name)) {}

CompositorPresentationTimeRecorder(
const CompositorPresentationTimeRecorder&) = delete;
CompositorPresentationTimeRecorder& operator=(
const CompositorPresentationTimeRecorder&) = delete;

~CompositorPresentationTimeRecorder() override = default;

// PresentationTimeRecorder:
bool RequestNext() override { return compositor_recorder_->RequestNext(); }

private:
std::unique_ptr<ui::PresentationTimeRecorder> compositor_recorder_;
};

} // namespace

// static
std::unique_ptr<PresentationTimeRecorder>
PresentationTimeRecorder::CreateCompositorRecorder(
aura::Window* window,
const char* latency_histogram_name,
absl::optional<const char*> max_latency_histogram_name) {
return std::make_unique<CompositorPresentationTimeRecorder>(
window, latency_histogram_name,
max_latency_histogram_name.has_value()
? max_latency_histogram_name.value()
: "");
}

} // namespace ash
37 changes: 37 additions & 0 deletions ash/public/cpp/presentation_time_recorder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2022 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.

#ifndef ASH_PUBLIC_CPP_PRESENTATION_TIME_RECORDER_H_
#define ASH_PUBLIC_CPP_PRESENTATION_TIME_RECORDER_H_

#include <memory>

#include "ash/public/cpp/ash_public_export.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace aura {
class Window;
}

namespace ash {

// A general interface for presentation time recording.
class ASH_PUBLIC_EXPORT PresentationTimeRecorder {
public:
// Creates a recorder tracking ui::Compositor.
static std::unique_ptr<PresentationTimeRecorder> CreateCompositorRecorder(
aura::Window* window,
const char* latency_histogram_name,
absl::optional<const char*> max_latency_histogram_name = absl::nullopt);

virtual ~PresentationTimeRecorder() = default;

// Request to record timing for the next frame. Returns true if the request
// is accepted. Otherwise, returns false.
virtual bool RequestNext() = 0;
};

} // namespace ash

#endif // ASH_PUBLIC_CPP_PRESENTATION_TIME_RECORDER_H_
6 changes: 5 additions & 1 deletion ash/wm/overview/overview_session_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6670,7 +6670,11 @@ class TestWindowStateDelegate : public WindowStateDelegate {
~TestWindowStateDelegate() override = default;

// WindowStateDelegate:
void OnDragStarted(int component) override { drag_in_progress_ = true; }
std::unique_ptr<PresentationTimeRecorder> OnDragStarted(
int component) override {
drag_in_progress_ = true;
return nullptr;
}
void OnDragFinished(bool cancel, const gfx::PointF& location) override {
drag_in_progress_ = false;
}
Expand Down
6 changes: 5 additions & 1 deletion ash/wm/splitview/split_view_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,11 @@ class TestWindowStateDelegate : public WindowStateDelegate {
~TestWindowStateDelegate() override = default;

// WindowStateDelegate:
void OnDragStarted(int component) override { drag_in_progress_ = true; }
std::unique_ptr<PresentationTimeRecorder> OnDragStarted(
int component) override {
drag_in_progress_ = true;
return nullptr;
}
void OnDragFinished(bool cancel, const gfx::PointF& location) override {
drag_in_progress_ = false;
}
Expand Down
5 changes: 2 additions & 3 deletions ash/wm/window_resizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,8 @@ const int WindowResizer::kBoundsChangeDirection_Vertical = 2;

WindowResizer::WindowResizer(WindowState* window_state)
: window_state_(window_state) {
recorder_ = CreatePresentationTimeHistogramRecorder(
GetTarget()->layer()->GetCompositor(),
"Ash.InteractiveWindowResize.TimeToPresent",
recorder_ = PresentationTimeRecorder::CreateCompositorRecorder(
GetTarget(), "Ash.InteractiveWindowResize.TimeToPresent",
"Ash.InteractiveWindowResize.TimeToPresent.MaxLatency");
DCHECK(window_state_->drag_details());
}
Expand Down
4 changes: 2 additions & 2 deletions ash/wm/window_resizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include "ash/wm/drag_details.h"
#include "ash/wm/window_state.h"
#include "base/memory/weak_ptr.h"
#include "ui/compositor/presentation_time_recorder.h"
#include "ui/wm/public/window_move_client.h"

namespace aura {
Expand All @@ -27,6 +26,7 @@ class GestureEvent;
}

namespace ash {
class PresentationTimeRecorder;

// WindowResizer is used by ToplevelWindowEventFilter to handle dragging, moving
// or resizing a window. All coordinates passed to this are in the parent
Expand Down Expand Up @@ -118,7 +118,7 @@ class ASH_EXPORT WindowResizer {
void CalculateBoundsWithAspectRatio(float aspect_ratio,
gfx::Rect* new_bounds);

std::unique_ptr<ui::PresentationTimeRecorder> recorder_;
std::unique_ptr<PresentationTimeRecorder> recorder_;

base::WeakPtrFactory<WindowResizer> weak_ptr_factory_{this};
};
Expand Down
7 changes: 5 additions & 2 deletions ash/wm/window_state.cc
Original file line number Diff line number Diff line change
Expand Up @@ -621,10 +621,13 @@ void WindowState::set_bounds_changed_by_user(bool bounds_changed_by_user) {
}
}

void WindowState::OnDragStarted(int window_component) {
std::unique_ptr<PresentationTimeRecorder> WindowState::OnDragStarted(
int window_component) {
DCHECK(drag_details_);
if (delegate_)
delegate_->OnDragStarted(window_component);
return delegate_->OnDragStarted(window_component);

return nullptr;
}

void WindowState::OnCompleteDrag(const gfx::PointF& location) {
Expand Down
6 changes: 4 additions & 2 deletions ash/wm/window_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "ash/ash_export.h"
#include "ash/display/persistent_window_info.h"
#include "ash/public/cpp/presentation_time_recorder.h"
#include "ash/wm/drag_details.h"
#include "ash/wm/wm_metrics.h"
#include "base/gtest_prod_util.h"
Expand Down Expand Up @@ -350,8 +351,9 @@ class ASH_EXPORT WindowState : public aura::WindowObserver {
// Sets the currently stored restore bounds and clears the restore bounds.
void SetAndClearRestoreBounds();

// Notifies that the drag operation has been started.
void OnDragStarted(int window_component);
// Notifies that the drag operation has been started. Optionally returns
// a presentation time recorder for the drag.
std::unique_ptr<PresentationTimeRecorder> OnDragStarted(int window_component);

// Notifies that the drag operation has been either completed or reverted.
// |location| is the last position of the pointer device used to drag.
Expand Down
5 changes: 5 additions & 0 deletions ash/wm/window_state_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ bool WindowStateDelegate::ToggleFullscreen(WindowState* window_state) {

void WindowStateDelegate::ToggleLockedFullscreen(WindowState* window_state) {}

std::unique_ptr<PresentationTimeRecorder> WindowStateDelegate::OnDragStarted(
int component) {
return nullptr;
}

} // namespace ash
9 changes: 7 additions & 2 deletions ash/wm/window_state_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
#ifndef ASH_WM_WINDOW_STATE_DELEGATE_H_
#define ASH_WM_WINDOW_STATE_DELEGATE_H_

#include <memory>

#include "ash/ash_export.h"
#include "ash/public/cpp/presentation_time_recorder.h"

namespace gfx {
class PointF;
Expand Down Expand Up @@ -40,8 +43,10 @@ class ASH_EXPORT WindowStateDelegate {
// Invoked when the user started drag operation. |component| must be
// a member of ui::HitTestCompat enum and specifies which part of
// the window the pointer device was on when the user started drag
// operation.
virtual void OnDragStarted(int component) {}
// operation. Returns a presentation time recorder that could be used to
// track resize latency.
virtual std::unique_ptr<PresentationTimeRecorder> OnDragStarted(
int component);

// Invoked when the user finished drag operation. |cancel| is true
// if the drag operation was canceled.
Expand Down
6 changes: 5 additions & 1 deletion ash/wm/workspace/multi_window_resize_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,11 @@ class TestWindowStateDelegate : public WindowStateDelegate {
~TestWindowStateDelegate() override = default;

// WindowStateDelegate:
void OnDragStarted(int component) override { component_ = component; }
std::unique_ptr<PresentationTimeRecorder> OnDragStarted(
int component) override {
component_ = component;
return nullptr;
}
void OnDragFinished(bool cancel, const gfx::PointF& location) override {
location_ = location;
}
Expand Down
2 changes: 2 additions & 0 deletions ash/wm/workspace/workspace_window_resizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#include "ash/wm/window_resizer.h"
#include "ash/wm/workspace/magnetism_matcher.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "ui/aura/window_tracker.h"
#include "ui/compositor/presentation_time_recorder.h"
#include "ui/display/display.h"
#include "ui/gfx/geometry/point_f.h"

Expand Down
4 changes: 3 additions & 1 deletion components/exo/client_controlled_shell_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,10 @@ class ClientControlledWindowStateDelegate : public ash::WindowStateDelegate {
return;
}

void OnDragStarted(int component) override {
std::unique_ptr<ash::PresentationTimeRecorder> OnDragStarted(
int component) override {
shell_surface_->OnDragStarted(component);
return nullptr;
}

void OnDragFinished(bool canceled, const gfx::PointF& location) override {
Expand Down

0 comments on commit e3b8049

Please sign in to comment.