[Impeller] adjust coverage origin when rounding out SaveLayer bounds. (#161838)
Fixes https://github.com/flutter/flutter/issues/161374 When we round out the texture size for a saveLayer, also round out the coverage so that the drawing origin is correct. Otherwise we may actually cut off the top left edge of rendering. --------- Co-authored-by: gaaclarke <30870216+gaaclarke@users.noreply.github.com>
This commit is contained in:
parent
64c808b7c8
commit
948e31d19f
@ -1017,12 +1017,19 @@ void Canvas::SaveLayer(const Paint& paint,
|
|||||||
// sampling mode.
|
// sampling mode.
|
||||||
ISize subpass_size;
|
ISize subpass_size;
|
||||||
bool did_round_out = false;
|
bool did_round_out = false;
|
||||||
|
Point coverage_origin_adjustment = Point{0, 0};
|
||||||
if (paint.image_filter) {
|
if (paint.image_filter) {
|
||||||
subpass_size = ISize(subpass_coverage.GetSize());
|
subpass_size = ISize(subpass_coverage.GetSize());
|
||||||
} else {
|
} else {
|
||||||
did_round_out = true;
|
did_round_out = true;
|
||||||
subpass_size =
|
subpass_size =
|
||||||
static_cast<ISize>(IRect::RoundOut(subpass_coverage).GetSize());
|
static_cast<ISize>(IRect::RoundOut(subpass_coverage).GetSize());
|
||||||
|
// If rounding out, adjust the coverage to account for the subpixel shift.
|
||||||
|
coverage_origin_adjustment =
|
||||||
|
Point(subpass_coverage.GetLeftTop().x -
|
||||||
|
std::floor(subpass_coverage.GetLeftTop().x),
|
||||||
|
subpass_coverage.GetLeftTop().y -
|
||||||
|
std::floor(subpass_coverage.GetLeftTop().y));
|
||||||
}
|
}
|
||||||
if (subpass_size.IsEmpty()) {
|
if (subpass_size.IsEmpty()) {
|
||||||
return SkipUntilMatchingRestore(total_content_depth);
|
return SkipUntilMatchingRestore(total_content_depth);
|
||||||
@ -1156,7 +1163,8 @@ void Canvas::SaveLayer(const Paint& paint,
|
|||||||
subpass_size, //
|
subpass_size, //
|
||||||
Color::BlackTransparent() //
|
Color::BlackTransparent() //
|
||||||
)));
|
)));
|
||||||
save_layer_state_.push_back(SaveLayerState{paint_copy, subpass_coverage});
|
save_layer_state_.push_back(SaveLayerState{
|
||||||
|
paint_copy, subpass_coverage.Shift(-coverage_origin_adjustment)});
|
||||||
|
|
||||||
CanvasStackEntry entry;
|
CanvasStackEntry entry;
|
||||||
entry.transform = transform_stack_.back().transform;
|
entry.transform = transform_stack_.back().transform;
|
||||||
|
@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
#include "impeller/display_list/dl_golden_unittests.h"
|
#include "impeller/display_list/dl_golden_unittests.h"
|
||||||
|
|
||||||
|
#include "display_list/dl_color.h"
|
||||||
|
#include "display_list/dl_paint.h"
|
||||||
|
#include "display_list/geometry/dl_geometry_types.h"
|
||||||
#include "flutter/display_list/dl_builder.h"
|
#include "flutter/display_list/dl_builder.h"
|
||||||
#include "flutter/impeller/geometry/path_builder.h"
|
#include "flutter/impeller/geometry/path_builder.h"
|
||||||
#include "flutter/testing/testing.h"
|
#include "flutter/testing/testing.h"
|
||||||
@ -307,5 +310,30 @@ TEST_P(DlGoldenTest, DashedLinesTest) {
|
|||||||
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
|
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(DlGoldenTest, SaveLayerAtFractionalValue) {
|
||||||
|
// Draws a stroked rounded rect at a fractional pixel value. The coverage must
|
||||||
|
// be adjusted so that we still have room to draw it, even though it lies on
|
||||||
|
// the fractional bounds of the saveLayer.
|
||||||
|
DisplayListBuilder builder;
|
||||||
|
builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
|
||||||
|
auto save_paint = DlPaint().setAlpha(100);
|
||||||
|
builder.SaveLayer(nullptr, &save_paint);
|
||||||
|
|
||||||
|
builder.DrawRoundRect(DlRoundRect::MakeRectRadius(
|
||||||
|
DlRect::MakeLTRB(10.5, 10.5, 200.5, 200.5), 10),
|
||||||
|
DlPaint()
|
||||||
|
.setDrawStyle(DlDrawStyle::kStroke)
|
||||||
|
.setStrokeWidth(1.5)
|
||||||
|
.setColor(DlColor::kBlack()));
|
||||||
|
builder.DrawCircle(DlPoint::MakeXY(100, 100), 50.5,
|
||||||
|
DlPaint().setColor(DlColor::kAqua()));
|
||||||
|
builder.DrawCircle(DlPoint::MakeXY(110, 110), 50.5,
|
||||||
|
DlPaint().setColor(DlColor::kCyan()));
|
||||||
|
|
||||||
|
builder.Restore();
|
||||||
|
|
||||||
|
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
} // namespace flutter
|
} // namespace flutter
|
||||||
|
@ -981,6 +981,9 @@ impeller_Play_DlGoldenTest_GaussianVsRRectBlurScaled_Vulkan.png
|
|||||||
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_Metal.png
|
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_Metal.png
|
||||||
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_OpenGLES.png
|
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_OpenGLES.png
|
||||||
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_Vulkan.png
|
impeller_Play_DlGoldenTest_GaussianVsRRectBlur_Vulkan.png
|
||||||
|
impeller_Play_DlGoldenTest_SaveLayerAtFractionalValue_Metal.png
|
||||||
|
impeller_Play_DlGoldenTest_SaveLayerAtFractionalValue_OpenGLES.png
|
||||||
|
impeller_Play_DlGoldenTest_SaveLayerAtFractionalValue_Vulkan.png
|
||||||
impeller_Play_DlGoldenTest_StrokedRRectFastBlur_Metal.png
|
impeller_Play_DlGoldenTest_StrokedRRectFastBlur_Metal.png
|
||||||
impeller_Play_DlGoldenTest_StrokedRRectFastBlur_OpenGLES.png
|
impeller_Play_DlGoldenTest_StrokedRRectFastBlur_OpenGLES.png
|
||||||
impeller_Play_DlGoldenTest_StrokedRRectFastBlur_Vulkan.png
|
impeller_Play_DlGoldenTest_StrokedRRectFastBlur_Vulkan.png
|
||||||
|
Loading…
x
Reference in New Issue
Block a user