Commit fbd4f2df authored by yjliu's avatar yjliu Committed by Chromium LUCI CQ

Small optimization in cc::DamageTracker.

Two steps are used to track if a surface intersects damage from under
it.
1) When the surface (assume A) accumulates damage in
AccumulateDamageFromRenderSurface(), if the surface doesn't intersect
any damage, it would be appended to the vector
|surfaces_with_no_damage_under|.
2) When surface A's render target (assume B) computes damage from
left-over rects in ComputeSurfaceDamage(), A (and all other surfaces
rendering to B) will be removed from the vector
|surfaces_with_no_damage_under|.

For example, suppose, nodes below all represent render surfaces.

    A
   / \
  B   C
 /\   /\
G  H  J K

B,C renders to A; G,H renders to B; J,K renders to C.
The draw order is  K, J, C, H, G, B, A.

During damage tracking, G and H, for instance, will be added to the
vector when they each AccumulateDamageFromRenderSurface(), and then when
their parent B ComputeSurfaceDamage(), both G and H will be removed from
the vector. This means the vector's use pattern is similar to a stack: a
surface's children will first be appended to the vector, and then the
surface itself will be inserted into the vector after all its children
are removed.

Based on such an idea, in this CL, ComputeSurfaceDamage() no longer
iterates through all elements in the vector, but rather, stops at the
first element that's not current surface's children.

Bug: N/A
Change-Id: I22a022530f6869a5dd3b07f900da2c3e1ede2079
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2582843
Commit-Queue: weiliangc <weiliangc@chromium.org>
Reviewed-by: default avatarweiliangc <weiliangc@chromium.org>
Auto-Submit: Jun Liu <yjliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#839160}
parent 8cf38164
......@@ -213,18 +213,19 @@ void DamageTracker::ComputeSurfaceDamage(
if (!surfaces_with_no_damage_under.empty()) {
gfx::Rect leftover_damage_rect;
bool valid = damage_from_leftover_rects.GetAsRect(&leftover_damage_rect);
std::vector<std::pair<RenderSurfaceImpl*, gfx::Rect>>::iterator it =
surfaces_with_no_damage_under.begin();
while (it != surfaces_with_no_damage_under.end()) {
RenderSurfaceImpl* surface = it->first;
auto rit = surfaces_with_no_damage_under.rbegin();
while (rit != surfaces_with_no_damage_under.rend()) {
RenderSurfaceImpl* surface = rit->first;
if (surface->render_target() == render_surface) {
surface->set_intersects_damage_under(
!valid || it->second.Intersects(leftover_damage_rect));
it = surfaces_with_no_damage_under.erase(it);
!valid || rit->second.Intersects(leftover_damage_rect));
++rit;
} else {
++it;
break;
}
}
surfaces_with_no_damage_under.erase(rit.base(),
surfaces_with_no_damage_under.end());
}
}
......
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