Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 0dd4bbb

Browse files
authored
[CP][Impeller] Avoid culling when the current matrix has perspective. (#44106)
Cherry pick of #44089 Before this patch, the test would fail to render anything because the culling would decide it fell outside the cull rect when the transform has perspective sometimes. We should fix our Rect::TransformBounds implementation, but I can't quite seem to get it happy enough here so I'm just bailing out on culling if there is perspective instead, which is safe. This also makes the patch a bit easier/safer to cherry pick since it's a simple de-optimization when perspective is involved for the sake of fidelity, instead of a larger change that may have other side effects.
1 parent ae02c8e commit 0dd4bbb

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

impeller/display_list/dl_dispatcher.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,9 @@ void DlDispatcher::drawDisplayList(
10741074
canvas_.SaveLayer(save_paint);
10751075
}
10761076

1077-
if (display_list->has_rtree()) {
1077+
// TODO(131445): Remove this restriction if we can correctly cull with
1078+
// perspective transforms.
1079+
if (display_list->has_rtree() && !initial_matrix_.HasPerspective()) {
10781080
// The canvas remembers the screen-space culling bounds clipped by
10791081
// the surface and the history of clip calls. DisplayList can cull
10801082
// the ops based on a rectangle expressed in its "destination bounds"

impeller/display_list/dl_unittests.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "impeller/display_list/dl_dispatcher.h"
2222
#include "impeller/display_list/dl_image_impeller.h"
2323
#include "impeller/display_list/dl_playground.h"
24+
#include "impeller/entity/contents/solid_color_contents.h"
2425
#include "impeller/entity/contents/solid_rrect_blur_contents.h"
2526
#include "impeller/geometry/constants.h"
2627
#include "impeller/geometry/point.h"
@@ -842,6 +843,42 @@ TEST_P(DisplayListTest, CanDrawShadow) {
842843
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
843844
}
844845

846+
TEST_P(DisplayListTest,
847+
DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists) {
848+
// Regression test for https://github.com/flutter/flutter/issues/130613
849+
flutter::DisplayListBuilder sub_builder(true);
850+
sub_builder.DrawRect(SkRect::MakeXYWH(0, 0, 50, 50),
851+
flutter::DlPaint(flutter::DlColor::kRed()));
852+
auto display_list = sub_builder.Build();
853+
854+
DlDispatcher dispatcher(Rect::MakeLTRB(0, 0, 2400, 1800));
855+
dispatcher.scale(2.0, 2.0);
856+
dispatcher.translate(-93.0, 0.0);
857+
// clang-format off
858+
dispatcher.transformFullPerspective(
859+
0.8, -0.2, -0.1, -0.0,
860+
0.0, 1.0, 0.0, 0.0,
861+
1.4, 1.3, 1.0, 0.0,
862+
63.2, 65.3, 48.6, 1.1
863+
);
864+
// clang-format on
865+
dispatcher.translate(35.0, 75.0);
866+
dispatcher.drawDisplayList(display_list, 1.0f);
867+
auto picture = dispatcher.EndRecordingAsPicture();
868+
869+
bool found = false;
870+
picture.pass->IterateAllEntities([&found](Entity& entity) {
871+
if (std::static_pointer_cast<SolidColorContents>(entity.GetContents())
872+
->GetColor() == Color::Red()) {
873+
found = true;
874+
return false;
875+
}
876+
877+
return true;
878+
});
879+
EXPECT_TRUE(found);
880+
}
881+
845882
TEST_P(DisplayListTest, TransparentShadowProducesCorrectColor) {
846883
flutter::DisplayListBuilder builder;
847884
{

impeller/geometry/matrix.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,10 @@ struct Matrix {
313313
m[9] == 0 && m[10] == 1 && m[11] == 0 && m[14] == 0 && m[15] == 1);
314314
}
315315

316+
constexpr bool HasPerspective() const {
317+
return m[3] != 0 || m[7] != 0 || m[11] != 0 || m[15] != 1;
318+
}
319+
316320
constexpr bool IsAligned(Scalar tolerance = 0) const {
317321
int v[] = {!ScalarNearlyZero(m[0], tolerance), //
318322
!ScalarNearlyZero(m[1], tolerance), //

0 commit comments

Comments
 (0)