Commit 75c8db0a authored by Alexander Shah's avatar Alexander Shah Committed by Commit Bot

viz: Visualize hit-test regions: highlight queried regions async path.

Highlights frames queried during kMouseDown events in the
asynchronous targeting path.

https://screenshot.googleplex.com/4ioX6RouGkD

https://drive.google.com/open?id=1IpyR6nKXG9H4s9_Zkko8QTzOB5RagkEZ

R=riajiang@chromium.org

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel
Change-Id: Ica3b0b77dde61aad465d36c3bdb20715cc206c65
Reviewed-on: https://chromium-review.googlesource.com/c/1286352
Commit-Queue: Alexander Shah <zandershah@google.com>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarRia Jiang <riajiang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#609474}
parent 08dbb44e
......@@ -55,6 +55,12 @@ bool IsSurfaceSynchronizationEnabled() {
base::FeatureList::IsEnabled(kVizDisplayCompositor);
}
bool IsVizHitTestingDebugEnabled() {
return features::IsVizHitTestingEnabled() &&
base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableVizHitTestDebug);
}
bool IsVizHitTestingDrawQuadEnabled() {
return base::FeatureList::IsEnabled(kEnableVizHitTestDrawQuad) ||
base::FeatureList::IsEnabled(kVizDisplayCompositor);
......
......@@ -22,6 +22,7 @@ VIZ_COMMON_EXPORT extern const base::Feature kVizDisplayCompositor;
VIZ_COMMON_EXPORT bool IsDrawOcclusionEnabled();
VIZ_COMMON_EXPORT bool IsSurfaceSynchronizationEnabled();
VIZ_COMMON_EXPORT bool IsVizHitTestingDebugEnabled();
VIZ_COMMON_EXPORT bool IsVizHitTestingDrawQuadEnabled();
VIZ_COMMON_EXPORT bool IsVizHitTestingEnabled();
VIZ_COMMON_EXPORT bool IsVizHitTestingSurfaceLayerEnabled();
......
......@@ -24,6 +24,9 @@ const char kEnableSurfaceSynchronization[] = "enable-surface-synchronization";
// For local inspection use chrome://inspect#other
const char kEnableVizDevTools[] = "enable-viz-devtools";
// Enables hit-test debug logging.
const char kEnableVizHitTestDebug[] = "enable-viz-hit-test-debug";
// Effectively disables pipelining of compositor frame production stages by
// waiting for each stage to finish before completing a frame.
const char kRunAllCompositorStagesBeforeDraw[] =
......
......@@ -17,6 +17,7 @@ namespace switches {
VIZ_COMMON_EXPORT extern const char kDeadlineToSynchronizeSurfaces[];
VIZ_COMMON_EXPORT extern const char kEnableSurfaceSynchronization[];
VIZ_COMMON_EXPORT extern const char kEnableVizDevTools[];
VIZ_COMMON_EXPORT extern const char kEnableVizHitTestDebug[];
VIZ_COMMON_EXPORT extern const char kRunAllCompositorStagesBeforeDraw[];
VIZ_COMMON_EXPORT extern const char kUseVizHitTestSurfaceLayer[];
VIZ_COMMON_EXPORT extern const char kDisableFrameRateLimit[];
......
......@@ -190,6 +190,13 @@ void HostFrameSinkManager::OnFrameTokenChanged(const FrameSinkId& frame_sink_id,
data.client->OnFrameTokenChanged(frame_token);
}
void HostFrameSinkManager::SetHitTestAsyncQueriedDebugRegions(
const FrameSinkId& root_frame_sink_id,
const std::vector<FrameSinkId>& hit_test_async_queried_debug_queue) {
frame_sink_manager_->SetHitTestAsyncQueriedDebugRegions(
root_frame_sink_id, hit_test_async_queried_debug_queue);
}
bool HostFrameSinkManager::RegisterFrameSinkHierarchy(
const FrameSinkId& parent_frame_sink_id,
const FrameSinkId& child_frame_sink_id) {
......
......@@ -188,6 +188,10 @@ class VIZ_HOST_EXPORT HostFrameSinkManager
void OnFrameTokenChanged(const FrameSinkId& frame_sink_id,
uint32_t frame_token) override;
void SetHitTestAsyncQueriedDebugRegions(
const FrameSinkId& root_frame_sink_id,
const std::vector<FrameSinkId>& hit_test_async_queried_debug_queue);
private:
friend class HostFrameSinkManagerTestApi;
friend class HostFrameSinkManagerTestBase;
......
......@@ -282,6 +282,15 @@ void FrameSinkManagerImpl::RequestCopyOfOutput(
std::move(request));
}
void FrameSinkManagerImpl::SetHitTestAsyncQueriedDebugRegions(
const FrameSinkId& root_frame_sink_id,
const std::vector<FrameSinkId>& hit_test_async_queried_debug_queue) {
hit_test_manager_.SetHitTestAsyncQueriedDebugRegions(
root_frame_sink_id, hit_test_async_queried_debug_queue);
DCHECK(base::ContainsKey(root_sink_map_, root_frame_sink_id));
root_sink_map_[root_frame_sink_id]->ForceImmediateDrawAndSwapIfPossible();
}
void FrameSinkManagerImpl::OnFirstSurfaceActivation(
const SurfaceInfo& surface_info) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
......
......@@ -110,6 +110,10 @@ class VIZ_SERVICE_EXPORT FrameSinkManagerImpl
void EvictSurfaces(const std::vector<SurfaceId>& surface_ids) override;
void RequestCopyOfOutput(const SurfaceId& surface_id,
std::unique_ptr<CopyOutputRequest> request) override;
void SetHitTestAsyncQueriedDebugRegions(
const FrameSinkId& root_frame_sink_id,
const std::vector<FrameSinkId>& hit_test_async_queried_debug_queue)
override;
// SurfaceObserver implementation.
void OnFirstSurfaceActivation(const SurfaceInfo& surface_info) override;
......
......@@ -63,6 +63,10 @@ void HitTestAggregator::Aggregate(const SurfaceId& display_surface_id,
}
void HitTestAggregator::InsertHitTestDebugQuads(RenderPassList* render_passes) {
const base::flat_set<FrameSinkId>* hit_test_async_queried_debug_regions =
hit_test_manager_->GetHitTestAsyncQueriedDebugRegions(
root_frame_sink_id_);
QuadList& ql = render_passes->back()->quad_list;
ql.InsertBeforeAndInvalidateAllPointers<DebugBorderDrawQuad>(
ql.begin(), hit_test_data_size_);
......@@ -88,7 +92,11 @@ void HitTestAggregator::InsertHitTestDebugQuads(RenderPassList* render_passes) {
return;
}
const SkColor color = colors[parents.size() % 3];
SkColor color = colors[parents.size() % 3];
if (hit_test_async_queried_debug_regions &&
hit_test_async_queried_debug_regions->count(htr.frame_sink_id)) {
color = SK_ColorRED;
}
parents.push(i);
// Concatenate transformation.
......
......@@ -13,6 +13,18 @@ namespace {
// TODO(gklassen): Review and select appropriate sizes based on
// telemetry / UMA.
constexpr uint32_t kMaxRegionsPerSurface = 1024;
HitTestAsyncQueriedDebugRegion::HitTestAsyncQueriedDebugRegion() = default;
HitTestAsyncQueriedDebugRegion::HitTestAsyncQueriedDebugRegion(
base::flat_set<FrameSinkId> regions)
: regions(std::move(regions)) {}
HitTestAsyncQueriedDebugRegion::~HitTestAsyncQueriedDebugRegion() = default;
HitTestAsyncQueriedDebugRegion::HitTestAsyncQueriedDebugRegion(
HitTestAsyncQueriedDebugRegion&&) = default;
HitTestAsyncQueriedDebugRegion& HitTestAsyncQueriedDebugRegion::operator=(
HitTestAsyncQueriedDebugRegion&&) = default;
} // namespace
HitTestManager::HitTestManager(SurfaceManager* surface_manager)
......@@ -102,6 +114,26 @@ int64_t HitTestManager::GetTraceId(const SurfaceId& id) const {
return surface->GetActiveFrame().metadata.begin_frame_ack.trace_id;
}
const base::flat_set<FrameSinkId>*
HitTestManager::GetHitTestAsyncQueriedDebugRegions(
const FrameSinkId& root_frame_sink_id) const {
auto it = hit_test_async_queried_debug_regions_.find(root_frame_sink_id);
if (it == hit_test_async_queried_debug_regions_.end() ||
it->second.timer.Elapsed().InMilliseconds() > 2000) {
return nullptr;
}
return &it->second.regions;
}
void HitTestManager::SetHitTestAsyncQueriedDebugRegions(
const FrameSinkId& root_frame_sink_id,
const std::vector<FrameSinkId>& hit_test_async_queried_debug_queue) {
hit_test_async_queried_debug_regions_[root_frame_sink_id] =
HitTestAsyncQueriedDebugRegion(base::flat_set<FrameSinkId>(
hit_test_async_queried_debug_queue.begin(),
hit_test_async_queried_debug_queue.end()));
}
bool HitTestManager::ValidateHitTestRegionList(
const SurfaceId& surface_id,
HitTestRegionList* hit_test_region_list) {
......
......@@ -6,6 +6,7 @@
#define COMPONENTS_VIZ_SERVICE_HIT_TEST_HIT_TEST_MANAGER_H_
#include "base/optional.h"
#include "base/timer/elapsed_timer.h"
#include "components/viz/common/hit_test/aggregated_hit_test_region.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/service/surfaces/surface_manager.h"
......@@ -14,6 +15,23 @@
#include "services/viz/public/interfaces/hit_test/hit_test_region_list.mojom.h"
namespace viz {
namespace {
struct HitTestAsyncQueriedDebugRegion {
HitTestAsyncQueriedDebugRegion();
explicit HitTestAsyncQueriedDebugRegion(base::flat_set<FrameSinkId> regions);
~HitTestAsyncQueriedDebugRegion();
HitTestAsyncQueriedDebugRegion(HitTestAsyncQueriedDebugRegion&&);
HitTestAsyncQueriedDebugRegion& operator=(HitTestAsyncQueriedDebugRegion&&);
base::flat_set<FrameSinkId> regions;
base::ElapsedTimer timer;
};
} // namespace
class LatestLocalSurfaceIdLookupDelegate;
// HitTestManager manages the collection of HitTestRegionList objects
......@@ -54,6 +72,12 @@ class VIZ_SERVICE_EXPORT HitTestManager : public SurfaceObserver {
int64_t GetTraceId(const SurfaceId& id) const;
const base::flat_set<FrameSinkId>* GetHitTestAsyncQueriedDebugRegions(
const FrameSinkId& root_frame_sink_id) const;
void SetHitTestAsyncQueriedDebugRegions(
const FrameSinkId& root_frame_sink_id,
const std::vector<FrameSinkId>& hit_test_async_queried_debug_queue);
private:
bool ValidateHitTestRegionList(const SurfaceId& surface_id,
HitTestRegionList* hit_test_region_list);
......@@ -63,6 +87,12 @@ class VIZ_SERVICE_EXPORT HitTestManager : public SurfaceObserver {
std::map<SurfaceId, base::flat_map<uint64_t, HitTestRegionList>>
hit_test_region_lists_;
// We store the async queried regions for each |root_frame_sink_id|. If viz
// hit-test debug is enabled, We will highlight the regions red in
// HitTestAggregator for 2 seconds, or until the next async queried event.
base::flat_map<FrameSinkId, HitTestAsyncQueriedDebugRegion>
hit_test_async_queried_debug_regions_;
DISALLOW_COPY_AND_ASSIGN(HitTestManager);
};
......
......@@ -52,6 +52,10 @@ class TestFrameSinkManagerImpl : public mojom::FrameSinkManager {
void RequestCopyOfOutput(
const SurfaceId& surface_id,
std::unique_ptr<CopyOutputRequest> request) override {}
void SetHitTestAsyncQueriedDebugRegions(
const FrameSinkId& root_frame_sink_id,
const std::vector<FrameSinkId>& hit_test_async_queried_debug_queue)
override {}
mojo::Binding<mojom::FrameSinkManager> binding_;
mojom::FrameSinkManagerClientPtr client_;
......
......@@ -104,15 +104,6 @@ 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 {
......@@ -141,7 +132,7 @@ RenderWidgetHostViewEventHandler::RenderWidgetHostViewEventHandler(
delegate_(delegate),
window_(nullptr),
mouse_wheel_phase_handler_(host_view),
debug_observer_(IsVizHitTestingDebugEnabled()
debug_observer_(features::IsVizHitTestingDebugEnabled()
? std::make_unique<HitTestDebugKeyEventObserver>(host)
: nullptr) {}
......
......@@ -8,6 +8,8 @@
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
#include "components/viz/common/features.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/renderer_host/input/one_shot_timeout_monitor.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
......@@ -127,6 +129,8 @@ RenderWidgetTargeter::TargetingRequest::~TargetingRequest() = default;
RenderWidgetTargeter::RenderWidgetTargeter(Delegate* delegate)
: trace_id_(base::RandUint64()),
is_viz_hit_testing_debug_enabled_(
features::IsVizHitTestingDebugEnabled()),
delegate_(delegate),
weak_ptr_factory_(this) {
DCHECK(delegate_);
......@@ -368,6 +372,11 @@ void RenderWidgetTargeter::FoundFrameSinkId(
} else {
request_in_flight_ = false;
async_hit_test_timeout_.reset(nullptr);
if (is_viz_hit_testing_debug_enabled_ &&
event->GetType() == blink::WebInputEvent::Type::kMouseDown) {
hit_test_async_queried_debug_queue_.push_back(target->GetFrameSinkId());
}
}
auto* view = delegate_->FindViewFromFrameSinkId(frame_sink_id);
if (!view)
......@@ -413,6 +422,13 @@ void RenderWidgetTargeter::FoundTarget(
if (!root_view || !root_view->GetRenderWidgetHost())
return;
if (is_viz_hit_testing_debug_enabled_ &&
!hit_test_async_queried_debug_queue_.empty()) {
GetHostFrameSinkManager()->SetHitTestAsyncQueriedDebugRegions(
root_view->GetRootFrameSinkId(), hit_test_async_queried_debug_queue_);
hit_test_async_queried_debug_queue_.clear();
}
if (features::IsVizHitTestingSurfaceLayerEnabled() &&
expected_frame_sink_id.is_valid()) {
static const char* kResultsMatchHistogramName =
......
......@@ -234,6 +234,11 @@ class RenderWidgetTargeter {
uint64_t trace_id_;
const bool is_viz_hit_testing_debug_enabled_;
// Stores SurfaceIds for regions that were async queried if hit-test debugging
// is enabled. This allows us to send the queried regions in batches.
std::vector<viz::FrameSinkId> hit_test_async_queried_debug_queue_;
Delegate* const delegate_;
base::WeakPtrFactory<RenderWidgetTargeter> weak_ptr_factory_;
......
......@@ -129,6 +129,13 @@ interface FrameSinkManager {
// FrameSinkId. The request will be queued up until such surface exists and is
// reachable from the root surface.
RequestCopyOfOutput(SurfaceId surface_id, CopyOutputRequest request);
// Marks a region as having been recently async queried. This is used by the
// HitTestAggregator to highlight queried regions if hit-test debugging is
// enabled.
SetHitTestAsyncQueriedDebugRegions(
FrameSinkId root_frame_sink_id,
array<FrameSinkId> hit_test_async_queried_debug_queue);
};
// The FrameSinkManagerClient interface is implemented by the Display
......
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