1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef COMPONENTS_VIZ_COMMON_HIT_TEST_AGGREGATED_HIT_TEST_REGION_H_
6 #define COMPONENTS_VIZ_COMMON_HIT_TEST_AGGREGATED_HIT_TEST_REGION_H_
7 
8 #include <stdint.h>
9 
10 #include "components/viz/common/hit_test/hit_test_region_list.h"
11 #include "components/viz/common/surfaces/frame_sink_id.h"
12 #include "mojo/public/cpp/bindings/struct_traits.h"
13 #include "ui/gfx/geometry/rect.h"
14 #include "ui/gfx/transform.h"
15 
16 namespace viz {
17 
18 namespace mojom {
19 class AggregatedHitTestRegionDataView;
20 }
21 
22 // A AggregatedHitTestRegion element with child_count of kEndOfList indicates
23 // the last element and end of the list.
24 constexpr int32_t kEndOfList = -1;
25 
26 // An array of AggregatedHitTestRegion elements is used to define the
27 // aggregated hit-test data for the Display.
28 //
29 // It is designed to be in shared memory so that the viz service can
30 // write the hit_test data, and the viz host can read without
31 // process hops.
32 struct AggregatedHitTestRegion {
33   AggregatedHitTestRegion() = default;
34 
35   AggregatedHitTestRegion(
36       const FrameSinkId& frame_sink_id,
37       uint32_t flags,
38       const gfx::Rect& rect,
39       const gfx::Transform& transform,
40       int32_t child_count,
41       uint32_t async_hit_test_reasons = AsyncHitTestReasons::kNotAsyncHitTest)
frame_sink_idAggregatedHitTestRegion42       : frame_sink_id(frame_sink_id),
43         flags(flags),
44         async_hit_test_reasons(async_hit_test_reasons),
45         rect(rect),
46         child_count(child_count),
47         transform_(transform) {
48     DCHECK_EQ(!!(flags & HitTestRegionFlags::kHitTestAsk),
49               !!async_hit_test_reasons);
50   }
51 
52   // The FrameSinkId corresponding to this region.  Events that match
53   // are routed to this surface.
54   FrameSinkId frame_sink_id;
55 
56   // HitTestRegionFlags to indicate the type of region.
57   uint32_t flags = 0;
58 
59   // AsyncHitTestReasons to indicate why we are doing slow path hit testing.
60   uint32_t async_hit_test_reasons = AsyncHitTestReasons::kNotAsyncHitTest;
61 
62   // The rectangle that defines the region in parent region's coordinate space.
63   gfx::Rect rect;
64 
65   // The number of children including their children below this entry.
66   // If this element is not matched then child_count elements can be skipped
67   // to move to the next entry.
68   int32_t child_count = 0;
69 
70   // gfx::Transform is backed by SkMatrix44. SkMatrix44 has a mutable attribute
71   // which can be changed even during a const function call (e.g.
72   // SkMatrix44::getType()). This means that when HitTestQuery reads the
73   // transform in the read-only shared memory segment created (and populated) by
74   // HitTestAggregator, if it attempts to perform any operation on the
75   // transform (e.g. use Transform::IsIdentity()), skia will attempt to write to
76   // the read-only shared memory segment, causing exception in HitTestQuery.
77   // For this reason, it is necessary for the HitTestQuery to make a copy of the
78   // transform before using it. To enforce this, the |transform_| attribute is
79   // made private here, and exposed through an accessor which always makes a
80   // copy.
transformAggregatedHitTestRegion81   gfx::Transform transform() const { return transform_; }
set_transformAggregatedHitTestRegion82   void set_transform(const gfx::Transform& transform) {
83     transform_ = transform;
84   }
85 
86   bool operator==(const AggregatedHitTestRegion& rhs) const {
87     return (frame_sink_id == rhs.frame_sink_id && flags == rhs.flags &&
88             async_hit_test_reasons == rhs.async_hit_test_reasons &&
89             rect == rhs.rect && child_count == rhs.child_count &&
90             transform_ == rhs.transform());
91   }
92 
93   bool operator!=(const AggregatedHitTestRegion& other) const {
94     return !(*this == other);
95   }
96 
97  private:
98   friend struct mojo::StructTraits<mojom::AggregatedHitTestRegionDataView,
99                                    AggregatedHitTestRegion>;
100 
101   // The transform applied to the rect in parent region's coordinate space.
102   gfx::Transform transform_;
103 };
104 
105 }  // namespace viz
106 
107 #endif  // COMPONENTS_VIZ_COMMON_HIT_TEST_AGGREGATED_HIT_TEST_REGION_H_
108