[Impeller] Ensure known geometry has simple bounds computation. (flutter/engine#46623)
Computing the bounds of an RRect can be really slow if you don't actually know that it is an RRect, and shows up in the traces for flutter gallery on wembly. This change should be semantically equivalent and is only an optimization to avoid recomputing the same value we already know.
This commit is contained in:
@@ -252,6 +252,7 @@ void Canvas::DrawRRect(Rect rect, Scalar corner_radius, const Paint& paint) {
|
||||
auto path = PathBuilder{}
|
||||
.SetConvexity(Convexity::kConvex)
|
||||
.AddRoundedRect(rect, corner_radius)
|
||||
.SetBounds(rect)
|
||||
.TakePath();
|
||||
if (paint.style == Paint::Style::kFill) {
|
||||
Entity entity;
|
||||
@@ -273,10 +274,13 @@ void Canvas::DrawCircle(Point center, Scalar radius, const Paint& paint) {
|
||||
paint)) {
|
||||
return;
|
||||
}
|
||||
auto circle_path = PathBuilder{}
|
||||
.AddCircle(center, radius)
|
||||
.SetConvexity(Convexity::kConvex)
|
||||
.TakePath();
|
||||
auto circle_path =
|
||||
PathBuilder{}
|
||||
.AddCircle(center, radius)
|
||||
.SetConvexity(Convexity::kConvex)
|
||||
.SetBounds(Rect::MakeLTRB(center.x - radius, center.y - radius,
|
||||
center.x + radius, center.y + radius))
|
||||
.TakePath();
|
||||
DrawPath(circle_path, paint);
|
||||
}
|
||||
|
||||
@@ -317,6 +321,7 @@ void Canvas::ClipRRect(const Rect& rect,
|
||||
auto path = PathBuilder{}
|
||||
.SetConvexity(Convexity::kConvex)
|
||||
.AddRoundedRect(rect, corner_radius)
|
||||
.SetBounds(rect)
|
||||
.TakePath();
|
||||
|
||||
std::optional<Rect> inner_rect = (corner_radius * 2 < rect.size.width &&
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "impeller/display_list/dl_dispatcher.h"
|
||||
#include "impeller/display_list/dl_image_impeller.h"
|
||||
#include "impeller/display_list/dl_playground.h"
|
||||
#include "impeller/entity/contents/clip_contents.h"
|
||||
#include "impeller/entity/contents/solid_color_contents.h"
|
||||
#include "impeller/entity/contents/solid_rrect_blur_contents.h"
|
||||
#include "impeller/geometry/constants.h"
|
||||
@@ -1681,6 +1682,65 @@ TEST_P(DisplayListTest, DrawVerticesBlendModes) {
|
||||
ASSERT_TRUE(OpenPlaygroundHere(callback));
|
||||
}
|
||||
|
||||
template <typename Contents>
|
||||
static std::optional<Rect> GetCoverageOfFirstEntity(const Picture& picture) {
|
||||
std::optional<Rect> coverage;
|
||||
picture.pass->IterateAllEntities([&coverage](Entity& entity) {
|
||||
if (std::static_pointer_cast<Contents>(entity.GetContents())) {
|
||||
auto contents = std::static_pointer_cast<Contents>(entity.GetContents());
|
||||
Entity entity;
|
||||
coverage = contents->GetCoverage(entity);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return coverage;
|
||||
}
|
||||
|
||||
TEST(DisplayListTest, RRectBoundsComputation) {
|
||||
SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 100, 100), 4, 4);
|
||||
SkPath path = SkPath().addRRect(rrect);
|
||||
|
||||
flutter::DlPaint paint;
|
||||
flutter::DisplayListBuilder builder;
|
||||
|
||||
builder.DrawPath(path, paint);
|
||||
auto display_list = builder.Build();
|
||||
|
||||
DlDispatcher dispatcher;
|
||||
display_list->Dispatch(dispatcher);
|
||||
auto picture = dispatcher.EndRecordingAsPicture();
|
||||
|
||||
std::optional<Rect> coverage =
|
||||
GetCoverageOfFirstEntity<SolidColorContents>(picture);
|
||||
|
||||
// Validate that the RRect coverage is _exactly_ the same as the input rect.
|
||||
ASSERT_TRUE(coverage.has_value());
|
||||
ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
|
||||
Rect::MakeLTRB(0, 0, 100, 100));
|
||||
}
|
||||
|
||||
TEST(DisplayListTest, CircleBoundsComputation) {
|
||||
SkPath path = SkPath().addCircle(0, 0, 5);
|
||||
|
||||
flutter::DlPaint paint;
|
||||
flutter::DisplayListBuilder builder;
|
||||
|
||||
builder.DrawPath(path, paint);
|
||||
auto display_list = builder.Build();
|
||||
|
||||
DlDispatcher dispatcher;
|
||||
display_list->Dispatch(dispatcher);
|
||||
auto picture = dispatcher.EndRecordingAsPicture();
|
||||
|
||||
std::optional<Rect> coverage =
|
||||
GetCoverageOfFirstEntity<SolidColorContents>(picture);
|
||||
|
||||
ASSERT_TRUE(coverage.has_value());
|
||||
ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
|
||||
Rect::MakeLTRB(-5, -5, 5, 5));
|
||||
}
|
||||
|
||||
#ifdef IMPELLER_ENABLE_3D
|
||||
TEST_P(DisplayListTest, SceneColorSource) {
|
||||
// Load up the scene.
|
||||
|
||||
Reference in New Issue
Block a user