0

cc: set is_fast_rounded_corner to draw properties of a RenderSurface

There are cases when SurfaceAggregator can merge render passes and
avoid unnecessary draws. This is very important for LaCros, which
does delegation of root render passes' quads.

It was figured out that whenever an effect node had rounded corners
and the |is_fast_rounded_corners| set, the shared quad state that
was created further for this render surface didn't have the fast
rounded corners bit set. The reason for that was a missing member
in draw properties for render surface that could be used when
a shared quad state was created. It wasn't a problem for other
layers that were not for render surfaces.

Bug: 1474855
Change-Id: I6e1f50d19aaa09934c6bfc3d405688ae792326dd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4808046
Reviewed-by: Khushal Sagar <khushalsagar@chromium.org>
Commit-Queue: Khushal Sagar <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1191409}
This commit is contained in:
Maksim Sisov
2023-09-01 16:38:52 +00:00
committed by Chromium LUCI CQ
parent c7c0707bd7
commit a5b20ea783
4 changed files with 65 additions and 4 deletions

@ -461,6 +461,7 @@ void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode,
mask_filter_info(), clip_rect, contents_opaque,
draw_properties_.draw_opacity, BlendMode(),
sorting_context_id);
shared_quad_state->is_fast_rounded_corner = is_fast_rounded_corner();
if (layer_tree_impl_->debug_state().show_debug_borders.test(
DebugBorderType::RENDERPASS)) {

@ -74,12 +74,17 @@ class CC_EXPORT RenderSurfaceImpl {
}
float draw_opacity() const { return draw_properties_.draw_opacity; }
void SetMaskFilterInfo(const gfx::MaskFilterInfo& mask_filter_info) {
void SetMaskFilterInfo(const gfx::MaskFilterInfo& mask_filter_info,
bool is_fast_rounded_corner) {
draw_properties_.mask_filter_info = mask_filter_info;
draw_properties_.is_fast_rounded_corner = is_fast_rounded_corner;
}
const gfx::MaskFilterInfo& mask_filter_info() const {
return draw_properties_.mask_filter_info;
}
bool is_fast_rounded_corner() const {
return draw_properties_.is_fast_rounded_corner;
}
SkBlendMode BlendMode() const;
@ -282,6 +287,13 @@ class CC_EXPORT RenderSurfaceImpl {
// the target space of the render surface. The root render surface will
// never have this set.
gfx::MaskFilterInfo mask_filter_info;
// This information is further passed to SharedQuadState when a
// SharedQuadState and a quad for this layer that represents a render
// surface is appended. Then, it's up to the SurfaceAggregator to decide
// whether it can actually merge this render surface and avoid having
// additional render pass.
bool is_fast_rounded_corner : 1 = false;
};
DrawProperties draw_properties_;

@ -856,10 +856,12 @@ void ComputeSurfaceDrawProperties(PropertyTrees* property_trees,
SetSurfaceDrawOpacity(property_trees->effect_tree(), render_surface);
SetSurfaceDrawTransform(property_trees, render_surface);
render_surface->SetMaskFilterInfo(
auto mask_filter_info_pair =
GetMaskFilterInfoPair(property_trees, render_surface->EffectTreeIndex(),
/*for_render_surface=*/true)
.first);
/*for_render_surface=*/true);
render_surface->SetMaskFilterInfo(
/*mask_filter_info=*/mask_filter_info_pair.first,
/*is_fast_rounded_corner=*/mask_filter_info_pair.second);
render_surface->SetScreenSpaceTransform(
property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale(
render_surface->TransformTreeIndex(),

@ -10,6 +10,7 @@
#include "base/test/scoped_feature_list.h"
#include "base/time/time.h"
#include "cc/base/features.h"
#include "cc/layers/append_quads_data.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_raster_source.h"
@ -2611,6 +2612,51 @@ TEST_F(LayerTreeImplTest, ElementIdToAnimationMapsTrackOnlyOnSyncTree) {
EXPECT_EQ(filter_map.size(), 1u);
}
// Verifies that the effect node's |is_fast_rounded_corner| is set to a draw
// properties of a RenderSurface, and then correctly forwarded to the shared
// quad state.
TEST_F(LayerTreeImplTest, CheckRenderSurfaceIsFastRoundedCorner) {
const gfx::MaskFilterInfo kMaskFilterWithRoundedCorners(
gfx::RectF(5, 5), gfx::RoundedCornersF(2.5), gfx::LinearGradient());
LayerImpl* root = root_layer();
root->SetBounds(gfx::Size(100, 100));
root->SetDrawsContent(true);
root->SetHitTestOpaqueness(HitTestOpaqueness::kMixed);
LayerImpl* child1 = AddLayer<LayerImpl>();
child1->SetBounds(gfx::Size(50, 50));
child1->SetDrawsContent(true);
child1->SetHitTestOpaqueness(HitTestOpaqueness::kMixed);
CopyProperties(root, child1);
auto& node = CreateEffectNode(child1);
node.render_surface_reason = RenderSurfaceReason::kRoundedCorner;
node.mask_filter_info = kMaskFilterWithRoundedCorners;
node.is_fast_rounded_corner = true;
host_impl().active_tree()->SetDeviceViewportRect(gfx::Rect(root->bounds()));
UpdateDrawProperties(host_impl().active_tree());
// Sanity check the scenario we just created.
ASSERT_EQ(2u, GetRenderSurfaceList().size());
RenderSurfaceImpl* render_surface = GetRenderSurface(child1);
EXPECT_TRUE(render_surface->is_fast_rounded_corner());
auto render_pass = viz::CompositorRenderPass::Create();
AppendQuadsData append_quads_data;
render_surface->AppendQuads(DRAW_MODE_HARDWARE, render_pass.get(),
&append_quads_data);
ASSERT_EQ(1u, render_pass->shared_quad_state_list.size());
viz::SharedQuadState* shared_quad_state =
render_pass->shared_quad_state_list.front();
EXPECT_EQ(kMaskFilterWithRoundedCorners, shared_quad_state->mask_filter_info);
EXPECT_TRUE(shared_quad_state->is_fast_rounded_corner);
}
class LayerTreeImplOcclusionSettings : public LayerListSettings {
public:
LayerTreeImplOcclusionSettings() {