Commit d7a75fec authored by Dominic Mazzoni's avatar Dominic Mazzoni Committed by Commit Bot

Speed up computation of inline text box bounding boxes.

In the layout tree, a LayoutText corresponds to a static text node in
HTML, which can span more than one line. Each line of text is represented
by an InlineTextBox.

In the accessibility tree, we have an AXLayoutObject for the LayoutText,
and an AXInlineTextBox for the InlineTextBox.

The coordinates of the AXInlineTextBox need to be expressed relative to
its parent object, just like everything in the accessibility tree. It turns
out that we need the local bounding box of the parent object (the LayoutText)
to compute this.

However, this leads to an inefficiency, because when you have a very large
LayoutText (as an example, a TEXTAREA element with thousands of lines of
text), each AXInlineTextBox keeps querying its parent LayoutText for its
bounds, but the LayoutText iterates over all of its InlineTextBox children
to compute its bounds! This leads to n^2 complexity where n is the number
of lines in the LayoutText.

The solution is just to cache the bounds of the LayoutText, so it only
needs to be computed once.

Bug: 875344
Change-Id: I97578ec0eadc597f962b142fb074e6929e834802
Reviewed-on: https://chromium-review.googlesource.com/1180647Reviewed-by: default avatarAaron Leventhal <aleventhal@chromium.org>
Commit-Queue: Dominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584528}
parent 0282c24f
...@@ -75,9 +75,8 @@ void AXInlineTextBox::GetRelativeBounds(AXObject** out_container, ...@@ -75,9 +75,8 @@ void AXInlineTextBox::GetRelativeBounds(AXObject** out_container,
// Subtract the local bounding box of the parent because they're // Subtract the local bounding box of the parent because they're
// both in the same coordinate system. // both in the same coordinate system.
LayoutObject* parent_layout_object = ParentObject()->GetLayoutObject();
FloatRect parent_bounding_box = FloatRect parent_bounding_box =
parent_layout_object->LocalBoundingBoxRectForAccessibility(); ParentObject()->LocalBoundingBoxRectForAccessibility();
out_bounds_in_container.MoveBy(-parent_bounding_box.Location()); out_bounds_in_container.MoveBy(-parent_bounding_box.Location());
} }
......
...@@ -899,6 +899,11 @@ void AXObject::UpdateCachedAttributeValuesIfNeeded() const { ...@@ -899,6 +899,11 @@ void AXObject::UpdateCachedAttributeValuesIfNeeded() const {
if (parent) if (parent)
parent->ChildrenChanged(); parent->ChildrenChanged();
} }
if (GetLayoutObject() && GetLayoutObject()->IsText()) {
cached_local_bounding_box_rect_for_accessibility_ =
GetLayoutObject()->LocalBoundingBoxRectForAccessibility();
}
} }
bool AXObject::AccessibilityIsIgnoredByDefault( bool AXObject::AccessibilityIsIgnoredByDefault(
...@@ -2796,6 +2801,14 @@ void AXObject::GetRelativeBounds(AXObject** out_container, ...@@ -2796,6 +2801,14 @@ void AXObject::GetRelativeBounds(AXObject** out_container,
} }
} }
FloatRect AXObject::LocalBoundingBoxRectForAccessibility() {
if (!GetLayoutObject())
return FloatRect();
DCHECK(GetLayoutObject()->IsText());
UpdateCachedAttributeValuesIfNeeded();
return cached_local_bounding_box_rect_for_accessibility_;
}
LayoutRect AXObject::GetBoundsInFrameCoordinates() const { LayoutRect AXObject::GetBoundsInFrameCoordinates() const {
AXObject* container = nullptr; AXObject* container = nullptr;
FloatRect bounds; FloatRect bounds;
......
...@@ -772,6 +772,8 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> { ...@@ -772,6 +772,8 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
SkMatrix44& out_container_transform, SkMatrix44& out_container_transform,
bool* clips_children = nullptr) const; bool* clips_children = nullptr) const;
FloatRect LocalBoundingBoxRectForAccessibility();
// Get the bounds in frame-relative coordinates as a LayoutRect. // Get the bounds in frame-relative coordinates as a LayoutRect.
LayoutRect GetBoundsInFrameCoordinates() const; LayoutRect GetBoundsInFrameCoordinates() const;
...@@ -1059,6 +1061,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> { ...@@ -1059,6 +1061,7 @@ class MODULES_EXPORT AXObject : public GarbageCollectedFinalized<AXObject> {
mutable Member<AXObject> cached_live_region_root_; mutable Member<AXObject> cached_live_region_root_;
mutable int cached_aria_column_index_; mutable int cached_aria_column_index_;
mutable int cached_aria_row_index_; mutable int cached_aria_row_index_;
mutable FloatRect cached_local_bounding_box_rect_for_accessibility_;
Member<AXObjectCacheImpl> ax_object_cache_; Member<AXObjectCacheImpl> ax_object_cache_;
......
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