Commit 535e31ec authored by Alexander Shah's avatar Alexander Shah Committed by Commit Bot

viz: HitTest debug logging.

Ctrl+Shift+H to trigger. Requires --enable-viz-hit-test-debug flag and logging level of 1 on hit_test_debug_key_event_observer.

Adds observer to render_widget_host_impl to act on OnInputEventAck.

Example: https://pastebin.com/pcxrZv6A

R=riajiang@chromium.org

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel
Change-Id: I1c9a0867debe5b4aa670a51f85fe24909073374c
Reviewed-on: https://chromium-review.googlesource.com/1226099
Commit-Queue: Alexander Shah <zandershah@google.com>
Reviewed-by: default avatarNavid Zolghadr <nzolghadr@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarRia Jiang <riajiang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595563}
parent b27efd1e
......@@ -14,6 +14,8 @@
namespace viz {
// New flags must be added to GetFlagNames in hit_test_query.cc in order to be
// displayed in hit-test debug logging.
enum HitTestRegionFlags : uint32_t {
// Region maps to this surface (me).
kHitTestMine = 0x01,
......
......@@ -4,6 +4,7 @@
#include "components/viz/host/hit_test/hit_test_query.h"
#include "base/containers/stack.h"
#include "base/metrics/histogram_macros.h"
#include "base/timer/elapsed_timer.h"
#include "components/viz/common/hit_test/hit_test_region_list.h"
......@@ -29,6 +30,35 @@ bool CheckChildCount(int32_t child_count, size_t child_count_max) {
(static_cast<size_t>(child_count) < child_count_max);
}
const std::string GetFlagNames(uint32_t flag) {
std::string names = "";
uint32_t mask = 1;
#define CASE_TYPE(t) \
case kHitTest##t: \
names += names.empty() ? #t : ", " #t; \
break;
while (flag) {
switch (flag & mask) {
CASE_TYPE(Mine);
CASE_TYPE(Ignore);
CASE_TYPE(ChildSurface);
CASE_TYPE(Ask);
CASE_TYPE(Mouse);
CASE_TYPE(Touch);
CASE_TYPE(NotActive);
case 0:
break;
}
flag &= ~mask;
mask <<= 1;
}
#undef CASE_TYPE
return names;
}
} // namespace
HitTestQuery::HitTestQuery(base::RepeatingClosure bad_message_gpu_callback)
......@@ -259,4 +289,47 @@ void HitTestQuery::ReceivedBadMessageFromGpuProcess() const {
bad_message_gpu_callback_.Run();
}
std::string HitTestQuery::PrintHitTestData() const {
std::ostringstream oss;
base::stack<uint32_t> parents;
std::string tabs = "";
for (uint32_t i = 0; i < hit_test_data_.size(); ++i) {
const AggregatedHitTestRegion& htr = hit_test_data_[i];
oss << tabs << "Index: " << i << '\n';
oss << tabs << "Children: " << htr.child_count << '\n';
oss << tabs << "Flags: " << GetFlagNames(htr.flags) << '\n';
oss << tabs << "Frame Sink Id: " << htr.frame_sink_id.ToString() << '\n';
oss << tabs << "Rect: " << htr.rect.ToString() << '\n';
oss << tabs << "Transform:" << '\n';
// gfx::Transform::ToString spans multiple lines, so we use an additional
// stringstream.
{
std::string s;
std::stringstream transform_ss;
transform_ss << htr.transform().ToString() << '\n';
while (getline(transform_ss, s)) {
oss << tabs << s << '\n';
}
}
tabs += "\t\t";
parents.push(i);
while (!parents.empty() &&
parents.top() + hit_test_data_[parents.top()].child_count <= i) {
tabs.pop_back();
tabs.pop_back();
parents.pop();
}
}
return oss.str();
}
} // namespace viz
......@@ -101,6 +101,9 @@ class VIZ_HOST_EXPORT HitTestQuery {
// data for |frame_sink_id|.
bool ContainsActiveFrameSinkId(const FrameSinkId& frame_sink_id) const;
// Returns hit-test data, using indentation to visualize the tree structure.
std::string PrintHitTestData() const;
private:
friend class content::HitTestRegionObserver;
// Helper function to find |target| for |location_in_parent| in the
......
......@@ -1305,6 +1305,8 @@ jumbo_source_set("browser") {
"renderer_host/frame_sink_provider_impl.h",
"renderer_host/frame_token_message_queue.cc",
"renderer_host/frame_token_message_queue.h",
"renderer_host/hit_test_debug_key_event_observer.cc",
"renderer_host/hit_test_debug_key_event_observer.h",
"renderer_host/input/fling_controller.cc",
"renderer_host/input/fling_controller.h",
"renderer_host/input/fling_scheduler.cc",
......
// Copyright 2018 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 "content/browser/renderer_host/hit_test_debug_key_event_observer.h"
#include "components/viz/common/hit_test/hit_test_region_list.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "ui/events/keycodes/keyboard_codes.h"
typedef blink::WebInputEvent::Type Type;
typedef blink::WebInputEvent::Modifiers Modifiers;
namespace {
viz::HitTestQuery* GetHitTestQuery(
viz::HostFrameSinkManager* host_frame_sink_manager,
const viz::FrameSinkId& frame_sink_id) {
if (!frame_sink_id.is_valid())
return nullptr;
const auto& display_hit_test_query_map =
host_frame_sink_manager->display_hit_test_query();
const auto iter = display_hit_test_query_map.find(frame_sink_id);
if (iter == display_hit_test_query_map.end())
return nullptr;
return iter->second.get();
}
} // namespace
namespace content {
HitTestDebugKeyEventObserver::HitTestDebugKeyEventObserver(
RenderWidgetHostImpl* host)
: host_(host), hit_test_query_(nullptr) {
host_->AddInputEventObserver(this);
}
HitTestDebugKeyEventObserver::~HitTestDebugKeyEventObserver() {
host_->RemoveInputEventObserver(this);
}
void HitTestDebugKeyEventObserver::OnInputEventAck(
InputEventAckSource source,
InputEventAckState state,
const blink::WebInputEvent& event) {
if (INPUT_EVENT_ACK_STATE_CONSUMED == state ||
(event.GetType() != Type::kRawKeyDown &&
event.GetType() != Type::kKeyDown)) {
return;
}
const blink::WebKeyboardEvent& key_event =
static_cast<const blink::WebKeyboardEvent&>(event);
if (key_event.windows_key_code != ui::VKEY_H ||
key_event.GetModifiers() !=
(Modifiers::kControlKey | Modifiers::kShiftKey)) {
return;
}
if (!hit_test_query_) {
hit_test_query_ = GetHitTestQuery(GetHostFrameSinkManager(),
host_->GetView()->GetRootFrameSinkId());
}
if (hit_test_query_) {
std::string printed_hit_test_data = hit_test_query_->PrintHitTestData();
VLOG(1) << (printed_hit_test_data.empty() ? "No hit-test data."
: printed_hit_test_data);
}
}
} // namespace content
// Copyright 2018 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 CONTENT_BROWSER_RENDERER_HOST_HIT_TEST_DEBUG_KEY_EVENT_OBSERVER_H_
#define CONTENT_BROWSER_RENDERER_HOST_HIT_TEST_DEBUG_KEY_EVENT_OBSERVER_H_
#include "content/public/browser/render_widget_host.h"
namespace viz {
class HitTestQuery;
} // namespace viz
namespace content {
class RenderWidgetHostImpl;
// Implements the RenderWidgetHost::InputEventObserver interface, and acts on
// keyboard input events to print hit-test data.
class HitTestDebugKeyEventObserver
: public RenderWidgetHost::InputEventObserver {
public:
explicit HitTestDebugKeyEventObserver(RenderWidgetHostImpl* host);
~HitTestDebugKeyEventObserver() override;
// RenderWidgetHost::InputEventObserver:
void OnInputEventAck(InputEventAckSource source,
InputEventAckState state,
const blink::WebInputEvent&) override;
private:
RenderWidgetHostImpl* host_;
viz::HitTestQuery* hit_test_query_;
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_HIT_TEST_DEBUG_KEY_EVENT_OBSERVER_H_
......@@ -4,8 +4,11 @@
#include "content/browser/renderer_host/render_widget_host_view_event_handler.h"
#include "base/command_line.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#include "components/viz/common/features.h"
#include "content/browser/renderer_host/hit_test_debug_key_event_observer.h"
#include "content/browser/renderer_host/input/touch_selection_controller_client_aura.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/render_view_host_delegate.h"
......@@ -101,6 +104,15 @@ bool NeedsInputGrab(content::RenderWidgetHostViewBase* view) {
return view->GetWidgetType() == content::WidgetType::kPopup;
}
// Enables hit-test debug logging.
const char kEnableVizHitTestDebug[] = "enable-viz-hit-test-debug";
inline bool IsVizHitTestingDebugEnabled() {
return features::IsVizHitTestingEnabled() &&
base::CommandLine::ForCurrentProcess()->HasSwitch(
kEnableVizHitTestDebug);
}
} // namespace
namespace content {
......@@ -128,7 +140,10 @@ RenderWidgetHostViewEventHandler::RenderWidgetHostViewEventHandler(
popup_child_event_handler_(nullptr),
delegate_(delegate),
window_(nullptr),
mouse_wheel_phase_handler_(host_view) {}
mouse_wheel_phase_handler_(host_view),
debug_observer_(IsVizHitTestingDebugEnabled()
? std::make_unique<HitTestDebugKeyEventObserver>(host)
: nullptr) {}
RenderWidgetHostViewEventHandler::~RenderWidgetHostViewEventHandler() {}
......
......@@ -42,6 +42,7 @@ class OverscrollController;
class RenderWidgetHostImpl;
class RenderWidgetHostViewBase;
class TouchSelectionControllerClientAura;
class HitTestDebugKeyEventObserver;
// Provides an implementation of ui::EventHandler for use with
// RenderWidgetHostViewBase. A delegate is required in order to provide platform
......@@ -290,6 +291,8 @@ class CONTENT_EXPORT RenderWidgetHostViewEventHandler
aura::Window* window_;
MouseWheelPhaseHandler mouse_wheel_phase_handler_;
std::unique_ptr<HitTestDebugKeyEventObserver> debug_observer_;
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewEventHandler);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment