summaryrefslogtreecommitdiff
path: root/chromium/components/viz/client/hit_test_data_provider_draw_quad.cc
blob: 7131e17cef6d8db2371241667412c0ebf412f8b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 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 "components/viz/client/hit_test_data_provider_draw_quad.h"

#include "components/viz/common/quads/surface_draw_quad.h"

namespace viz {

HitTestDataProviderDrawQuad::HitTestDataProviderDrawQuad(
    bool should_ask_for_child_region)
    : should_ask_for_child_region_(should_ask_for_child_region) {}

HitTestDataProviderDrawQuad::~HitTestDataProviderDrawQuad() = default;

mojom::HitTestRegionListPtr HitTestDataProviderDrawQuad::GetHitTestData(
    const CompositorFrame& compositor_frame) const {
  // Derive hit test regions from information in the CompositorFrame.
  auto hit_test_region_list = mojom::HitTestRegionList::New();
  hit_test_region_list->flags =
      mojom::kHitTestMouse | mojom::kHitTestTouch | mojom::kHitTestMine;
  hit_test_region_list->bounds.set_size(compositor_frame.size_in_pixels());

  for (const auto& render_pass : compositor_frame.render_pass_list) {
    // Skip the render_pass if the transform is not invertible (i.e. it will not
    // be able to receive events).
    gfx::Transform transform_from_root_target;
    if (!render_pass->transform_to_root_target.GetInverse(
            &transform_from_root_target)) {
      continue;
    }

    for (const DrawQuad* quad : render_pass->quad_list) {
      if (quad->material == DrawQuad::SURFACE_CONTENT) {
        const SurfaceDrawQuad* surface_quad =
            SurfaceDrawQuad::MaterialCast(quad);

        // Skip the quad if the FrameSinkId between fallback and primary is not
        // the same, because we don't know which FrameSinkId would be used to
        // draw this quad.
        if (surface_quad->fallback_surface_id.has_value() &&
            surface_quad->fallback_surface_id->frame_sink_id() !=
                surface_quad->primary_surface_id.frame_sink_id()) {
          continue;
        }

        // Skip the quad if the transform is not invertible (i.e. it will not
        // be able to receive events).
        gfx::Transform target_to_quad_transform;
        if (!quad->shared_quad_state->quad_to_target_transform.GetInverse(
                &target_to_quad_transform)) {
          continue;
        }

        auto hit_test_region = mojom::HitTestRegion::New();
        hit_test_region->frame_sink_id =
            surface_quad->primary_surface_id.frame_sink_id();
        hit_test_region->flags = mojom::kHitTestMouse | mojom::kHitTestTouch |
                                 mojom::kHitTestChildSurface;
        if (should_ask_for_child_region_)
          hit_test_region->flags |= mojom::kHitTestAsk;
        hit_test_region->rect = surface_quad->rect;
        hit_test_region->transform =
            target_to_quad_transform * transform_from_root_target;
        hit_test_region_list->regions.push_back(std::move(hit_test_region));
      }
    }
  }

  return hit_test_region_list;
}

}  // namespace viz