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

Commit b1aea8a

Browse files
author
Jonah Williams
authored
Prevent Gradients from creating textures of size 0 when stops overlap (#36218)
1 parent d911a75 commit b1aea8a

2 files changed

Lines changed: 17 additions & 5 deletions

File tree

impeller/geometry/geometry_unittests.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,17 @@ TEST(GeometryTest, Gradient) {
14511451
ASSERT_EQ(texture_size, 2u);
14521452
}
14531453

1454+
{
1455+
// Gradient with duplicate stops does not create an empty texture.
1456+
std::vector<Color> colors = {Color::Red(), Color::Yellow(), Color::Black(),
1457+
Color::Blue()};
1458+
std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
1459+
uint32_t texture_size;
1460+
1461+
auto gradient = CreateGradientBuffer(colors, stops, &texture_size);
1462+
ASSERT_EQ(texture_size, 5u);
1463+
}
1464+
14541465
{
14551466
// Simple N color gradient produces color buffer containing exactly those
14561467
// values.
@@ -1488,9 +1499,9 @@ TEST(GeometryTest, Gradient) {
14881499
// Gradient size is capped at 1024.
14891500
std::vector<Color> colors = {};
14901501
std::vector<Scalar> stops = {};
1491-
for (auto i = 0u; i < 2000; i++) {
1502+
for (auto i = 0u; i < 1025; i++) {
14921503
colors.push_back(Color::Blue());
1493-
stops.push_back(i / 2000.0);
1504+
stops.push_back(i / 1025.0);
14941505
}
14951506
stops[1999] = 1.0;
14961507

impeller/geometry/gradient.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,16 @@ std::vector<uint8_t> CreateGradientBuffer(const std::vector<Color>& colors,
2222
uint32_t texture_size;
2323
// TODO(jonahwilliams): we should add a display list flag to check if the
2424
// stops were provided or not, then we can skip this step.
25-
// TODO(jonahwilliams): Skia has a check for stop sizes below a certain
26-
// threshold, we should make sure that we behave reasonably with them.
2725
if (stops.size() == 2) {
2826
texture_size = 2;
2927
} else {
3028
auto minimum_delta = 1.0;
3129
for (size_t i = 1; i < stops.size(); i++) {
3230
auto value = stops[i] - stops[i - 1];
31+
// Smaller than kEhCloseEnough
32+
if (value < 0.0001) {
33+
continue;
34+
}
3335
if (value < minimum_delta) {
3436
minimum_delta = value;
3537
}
@@ -41,7 +43,6 @@ std::vector<uint8_t> CreateGradientBuffer(const std::vector<Color>& colors,
4143
texture_size =
4244
std::min((uint32_t)std::round(1.0 / minimum_delta) + 1, 1024u);
4345
}
44-
4546
*out_texture_size = texture_size;
4647
std::vector<uint8_t> color_stop_channels;
4748
color_stop_channels.reserve(texture_size * 4);

0 commit comments

Comments
 (0)