 Chromium Code Reviews
 Chromium Code Reviews Issue 2908783002:
  WIP Hittest Component.
    
  
    Issue 2908783002:
  WIP Hittest Component. 
  | Index: components/viz/hit_test/hit_test_aggregator.cc | 
| diff --git a/components/viz/hit_test/hit_test_aggregator.cc b/components/viz/hit_test/hit_test_aggregator.cc | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..4fbca4c331951d632a8eb6d7a0d8fa984ea90de7 | 
| --- /dev/null | 
| +++ b/components/viz/hit_test/hit_test_aggregator.cc | 
| @@ -0,0 +1,116 @@ | 
| +// Copyright 2017 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/hit_test/hit_test_aggregator.h" | 
| +#include "base/logging.h" | 
| +#include "display_hit_test_data.h" | 
| + | 
| +namespace viz { | 
| + | 
| +namespace { | 
| +constexpr int kInitialSize = 1024; | 
| 
rjkroege
2017/06/07 21:19:05
need a TODO() to figure out what a good initial si
 
gklassen
2017/06/08 20:33:21
Done.
 | 
| +} | 
| + | 
| +using namespace hit_test::mojom; | 
| 
rjkroege
2017/06/07 21:19:05
I'm not keen on this.
 
gklassen
2017/06/08 20:33:20
Ok.  Removed.  Done.
 | 
| + | 
| +HitTestAggregator::HitTestAggregator() { | 
| + AllocateDisplayHitTestData(); | 
| +} | 
| +HitTestAggregator::~HitTestAggregator() {} | 
| + | 
| +void HitTestAggregator::SubmitHitTestData(HitTestDataPtr hit_test_data) { | 
| + pending_[hit_test_data->surface_id_] = std::move(hit_test_data); | 
| +} | 
| + | 
| +void HitTestAggregator::OnSurfaceDiscarded(const cc::SurfaceId& surface_id) { | 
| + pending_.erase(surface_id); | 
| + active_.erase(surface_id); | 
| +} | 
| +void HitTestAggregator::OnSurfaceWillDraw(const cc::SurfaceId& surface_id) { | 
| + active_[surface_id] = std::move(pending_[surface_id]); | 
| 
rjkroege
2017/06/07 21:19:05
so...  when you get another OnSurfaceWillDraw re-u
 
gklassen
2017/06/08 20:33:20
Thanks.  Code added to explicitly check and handle
 | 
| +} | 
| + | 
| +void HitTestAggregator::AllocateDisplayHitTestData() { | 
| + AllocateDisplayHitTestData(kInitialSize); | 
| +} | 
| + | 
| +void HitTestAggregator::AllocateDisplayHitTestData(int size) { | 
| + int cb = sizeof(DisplayHitTestData) + size * sizeof(DisplayHitTestRegion); | 
| + display_hit_test_data_ = (DisplayHitTestData*)::operator new(cb); | 
| + | 
| + display_hit_test_data_->size_ = size; | 
| 
rjkroege
2017/06/07 21:19:04
DisplayHitTestData could have a constructor?
 
gklassen
2017/06/08 20:33:21
It's now a struct ( based on earlier discussion an
 | 
| + display_hit_test_data_->front_offset_ = 0; | 
| + display_hit_test_data_->regions_[0].child_count_ = kEndOfList; | 
| + display_hit_test_data_->regions_[size << 2].child_count_ = kEndOfList; | 
| 
rjkroege
2017/06/07 21:19:05
Why do you init it?
 
gklassen
2017/06/08 20:33:21
It's using child_count == kEndOfList to indicate t
 
rjkroege
2017/06/09 15:47:07
struct declaration could init (is C++11-ism appare
 | 
| +} | 
| + | 
| +void HitTestAggregator::Aggregate(cc::SurfaceId display_surface_id) { | 
| + int index = GetBackIndex(); | 
| + int last_index = Append(display_surface_id, index); | 
| + display_hit_test_data_->regions_[last_index].child_count_ = kEndOfList; | 
| +} | 
| + | 
| +int HitTestAggregator::Append(cc::SurfaceId surface_id, int index) { | 
| 
rjkroege
2017/06/07 21:19:05
completely private methods could be in an anonymou
 
gklassen
2017/06/08 20:33:21
Thanks.  This method currently accesses some membe
 
rjkroege
2017/06/09 15:47:07
Acknowledged.
 | 
| + auto search = active_.find(surface_id); | 
| + if (search == active_.end()) { | 
| + // referenced surface not found! | 
| 
rjkroege
2017/06/07 21:19:05
this indicates a bug in SurfaceAggregator yes? The
 
gklassen
2017/06/08 20:33:21
Based on earlier conversations I believe it's poss
 | 
| + return index; | 
| + } | 
| + HitTestData* hit_test_data = search->second.get(); | 
| + | 
| + if (hit_test_data->regions_.size() == 0) { | 
| 
rjkroege
2017/06/07 21:19:04
we must have at least 1 region for valid data yes?
 
gklassen
2017/06/08 20:33:21
A surface with no children may have no sub-regions
 
rjkroege
2017/06/09 15:47:07
A HTD can have HTRs without any of them having the
 
gklassen
2017/06/12 16:30:41
Right.
 | 
| + // if there are no sub-regions then we don't need a bounds check entry | 
| + return index; | 
| + } | 
| + | 
| + DisplayHitTestRegion* element = &display_hit_test_data_->regions_[index]; | 
| + | 
| + int parent_index = index++; | 
| + | 
| + element->frame_sink_id_ = hit_test_data->surface_id_.frame_sink_id(); | 
| + element->flags_ = HitTestRegionFlags::HIT_TEST_BOUNDS; | 
| 
rjkroege
2017/06/07 21:19:04
You have a separate region for the bounds? Why?
 
gklassen
2017/06/08 20:33:21
After review and discussion this morning I think y
 | 
| + element->rect_ = hit_test_data->bounds_; | 
| + | 
| + for (auto& region : hit_test_data->regions_) { | 
| + index = Append(region, index); | 
| + } | 
| + | 
| + element->child_count_ = index - parent_index - 1; | 
| 
rjkroege
2017/06/07 21:19:05
Assumptions here should be wrapped in DCHECK
 
gklassen
2017/06/08 20:33:21
Agreed.  Do you have suggestions for assumptions t
 
rjkroege
2017/06/09 15:47:07
this one. I'll note all the others that occur to m
 
gklassen
2017/06/12 16:30:40
Done.
 | 
| + return index; | 
| +} | 
| + | 
| +int HitTestAggregator::Append(const HitTestRegionPtr& region, int index) { | 
| + DisplayHitTestRegion* element = &display_hit_test_data_->regions_[index]; | 
| + | 
| + element->frame_sink_id_ = region->surface_id_.frame_sink_id(); | 
| + element->flags_ = region->flags_; | 
| + element->rect_ = region->rect_; | 
| + element->transform_ = region->transform_; | 
| + | 
| + int parent_index = index++; | 
| + | 
| + if (region->flags_ == HitTestRegionFlags::HIT_TEST_CHILD_SURFACE) { | 
| + index = Append(region->surface_id_, index); | 
| + } | 
| + | 
| + element->child_count_ = index - parent_index - 1; | 
| + return index; | 
| +} | 
| + | 
| +void HitTestAggregator::Swap() { | 
| + display_hit_test_data_->front_offset_ = GetBackIndex(); | 
| +} | 
| + | 
| +int HitTestAggregator::GetBackIndex() { | 
| + return display_hit_test_data_->front_offset_ == 0 | 
| 
rjkroege
2017/06/07 21:19:05
if is easier to read?
 
gklassen
2017/06/08 20:33:20
I wrote it both ways.  I think I agree with you.
 | 
| + ? display_hit_test_data_->size_ / 2 | 
| + : 0; | 
| +} | 
| + | 
| +DisplayHitTestRegion* HitTestAggregator::GetCurrentRegions() { | 
| + return display_hit_test_data_->regions_ + | 
| + display_hit_test_data_->front_offset_; | 
| +} | 
| + | 
| +} // namespace viz |