Commit 179ebccd authored by Stefan Zager's avatar Stefan Zager Committed by Commit Bot

[IntersectionObserver] Compute RootGeometry once per observer

For an observer with multiple observations, this avoids doing redundant
work to compute the local bounds of the root and its transform to
absolute coordinates.

BUG=956071

Change-Id: I587997da1f5f120a1fd276f703aa1e5a1131696b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1774246
Commit-Queue: Stefan Zager <szager@chromium.org>
Reviewed-by: default avatarvmpstr <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#692206}
parent d5704c68
......@@ -217,6 +217,21 @@ IntersectionGeometry::IntersectionGeometry(const Element* root_element,
ComputeGeometry(root_geometry, root, target, thresholds);
}
IntersectionGeometry::IntersectionGeometry(const RootGeometry& root_geometry,
const Element& explicit_root,
const Element& target_element,
const Vector<float>& thresholds,
unsigned flags)
: flags_(flags & kConstructorFlagsMask),
intersection_ratio_(0),
threshold_index_(0) {
LayoutObject* target = GetTargetLayoutObject(target_element);
LayoutObject* root = explicit_root.GetLayoutObject();
if (!IsContainingBlockChainDescendant(target, root))
return;
ComputeGeometry(root_geometry, root, target, thresholds);
}
IntersectionGeometry::~IntersectionGeometry() = default;
void IntersectionGeometry::ComputeGeometry(const RootGeometry& root_geometry,
......
......@@ -58,6 +58,12 @@ class CORE_EXPORT IntersectionGeometry {
const Vector<float>& thresholds,
unsigned flags);
IntersectionGeometry(const RootGeometry& root_geometry,
const Element& explicit_root,
const Element& target,
const Vector<float>& thresholds,
unsigned flags);
IntersectionGeometry(const IntersectionGeometry&) = default;
~IntersectionGeometry();
......
......@@ -30,6 +30,18 @@ IntersectionObservation::IntersectionObservation(IntersectionObserver& observer,
// different sentinel value.
last_threshold_index_(kMaxThresholdIndex - 1) {}
void IntersectionObservation::ComputeIntersection(
const IntersectionGeometry::RootGeometry& root_geometry,
unsigned compute_flags) {
if (!ShouldCompute(compute_flags))
return;
DCHECK(observer_->root());
unsigned geometry_flags = GetIntersectionGeometryFlags(compute_flags);
IntersectionGeometry geometry(root_geometry, *observer_->root(), *Target(),
observer_->thresholds(), geometry_flags);
ProcessIntersectionGeometry(geometry);
}
void IntersectionObservation::ComputeIntersection(unsigned compute_flags) {
if (!ShouldCompute(compute_flags))
return;
......
......@@ -21,7 +21,7 @@ class IntersectionObserver;
class IntersectionObservation final
: public GarbageCollected<IntersectionObservation> {
public:
// Flags that drive the behavior of the ComputeIntersection() method. For an
// Flags that drive the behavior of the ComputeIntersections() method. For an
// explanation of implicit vs. explicit root, see intersection_observer.h.
enum ComputeFlags {
// If this bit is set, and observer_->RootIsImplicit() is true, then the
......@@ -46,6 +46,9 @@ class IntersectionObservation final
Element* Target() const { return target_; }
unsigned LastThresholdIndex() const { return last_threshold_index_; }
void ComputeIntersection(unsigned flags);
void ComputeIntersection(
const IntersectionGeometry::RootGeometry& root_geometry,
unsigned flags);
void TakeRecords(HeapVector<Member<IntersectionObserverEntry>>&);
void Disconnect();
......
......@@ -387,11 +387,13 @@ bool IntersectionObserver::ComputeIntersections(unsigned flags) {
DCHECK(!RootIsImplicit());
if (!RootIsValid() || !GetExecutionContext() || observations_.IsEmpty())
return false;
IntersectionGeometry::RootGeometry root_geometry(root()->GetLayoutObject(),
root_margin_);
HeapVector<Member<IntersectionObservation>> observations_to_process;
// TODO(szager): Is this copy necessary?
CopyToVector(observations_, observations_to_process);
for (auto& observation : observations_to_process) {
observation->ComputeIntersection(flags);
observation->ComputeIntersection(root_geometry, flags);
}
return trackVisibility();
}
......
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