[Impeller] Provide an opaque interface for color sources in Aiks (#41315)
Part of https://github.com/flutter/flutter/issues/125017.
Pulls ColorSource construction out of the dispatcher and into Aiks.
Cleans up a few design warts we've accumulated over time:
- Removes special exceptions for solid colors in `Paint`.
- Makes `SolidColorContents` a `ColorSourceContents`.
- Removes paint ref capture for kImage.
diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index 128550b..d86db3f 100644
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -1013,6 +1013,8 @@
ORIGIN: ../../../flutter/impeller/aiks/aiks_playground.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/aiks/canvas.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/aiks/canvas.h + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/impeller/aiks/color_source.cc + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/impeller/aiks/color_source.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/aiks/image.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/aiks/image.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/aiks/paint.cc + ../../../flutter/LICENSE
@@ -3606,6 +3608,8 @@
FILE: ../../../flutter/impeller/aiks/aiks_playground.h
FILE: ../../../flutter/impeller/aiks/canvas.cc
FILE: ../../../flutter/impeller/aiks/canvas.h
+FILE: ../../../flutter/impeller/aiks/color_source.cc
+FILE: ../../../flutter/impeller/aiks/color_source.h
FILE: ../../../flutter/impeller/aiks/image.cc
FILE: ../../../flutter/impeller/aiks/image.h
FILE: ../../../flutter/impeller/aiks/paint.cc
diff --git a/impeller/aiks/BUILD.gn b/impeller/aiks/BUILD.gn
index b5b0d05..16df517 100644
--- a/impeller/aiks/BUILD.gn
+++ b/impeller/aiks/BUILD.gn
@@ -10,6 +10,8 @@
"aiks_context.h",
"canvas.cc",
"canvas.h",
+ "color_source.cc",
+ "color_source.h",
"image.cc",
"image.h",
"paint.cc",
diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc
index a2738b7..1531285 100644
--- a/impeller/aiks/aiks_unittests.cc
+++ b/impeller/aiks/aiks_unittests.cc
@@ -157,12 +157,8 @@
canvas.Scale(aiks_test->GetContentScale());
canvas.Translate({100.0f, 100.0f, 0});
Paint paint;
- paint.color_source = [texture, tile_mode]() {
- auto contents = std::make_shared<TiledTextureContents>();
- contents->SetTexture(texture);
- contents->SetTileModes(tile_mode, tile_mode);
- return contents;
- };
+ paint.color_source =
+ ColorSource::MakeImage(texture, tile_mode, tile_mode, {}, {});
paint.color = Color(1, 1, 1, 1);
canvas.DrawRect({0, 0, 600, 600}, paint);
ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
@@ -347,18 +343,14 @@
canvas.Scale(aiks_test->GetContentScale());
Paint paint;
canvas.Translate({100.0f, 0, 0});
- paint.color_source = [tile_mode]() {
- std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
- Color{0.1294, 0.5882, 0.9529, 0.0}};
- std::vector<Scalar> stops = {0.0, 1.0};
- auto contents = std::make_shared<LinearGradientContents>();
- contents->SetEndPoints({0, 0}, {200, 200});
- contents->SetColors(std::move(colors));
- contents->SetStops(std::move(stops));
- contents->SetTileMode(tile_mode);
- return contents;
- };
+ std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
+ Color{0.1294, 0.5882, 0.9529, 0.0}};
+ std::vector<Scalar> stops = {0.0, 1.0};
+
+ paint.color_source = ColorSource::MakeLinearGradient(
+ {0, 0}, {200, 200}, std::move(colors), std::move(stops), tile_mode, {});
+
paint.color = Color(1.0, 1.0, 1.0, 1.0);
canvas.DrawRect({0, 0, 600, 600}, paint);
ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
@@ -384,19 +376,15 @@
Canvas canvas;
Paint paint;
canvas.Translate({100.0, 100.0, 0});
- paint.color_source = [tile_mode]() {
- std::vector<Color> colors = {
- Color{0.9568, 0.2627, 0.2118, 1.0}, Color{0.9568, 0.2627, 0.2118, 1.0},
- Color{0.1294, 0.5882, 0.9529, 1.0}, Color{0.1294, 0.5882, 0.9529, 1.0}};
- std::vector<Scalar> stops = {0.0, 0.5, 0.5, 1.0};
- auto contents = std::make_shared<LinearGradientContents>();
- contents->SetEndPoints({0, 0}, {500, 500});
- contents->SetColors(std::move(colors));
- contents->SetStops(std::move(stops));
- contents->SetTileMode(tile_mode);
- return contents;
- };
+ std::vector<Color> colors = {
+ Color{0.9568, 0.2627, 0.2118, 1.0}, Color{0.9568, 0.2627, 0.2118, 1.0},
+ Color{0.1294, 0.5882, 0.9529, 1.0}, Color{0.1294, 0.5882, 0.9529, 1.0}};
+ std::vector<Scalar> stops = {0.0, 0.5, 0.5, 1.0};
+
+ paint.color_source = ColorSource::MakeLinearGradient(
+ {0, 0}, {500, 500}, std::move(colors), std::move(stops), tile_mode, {});
+
paint.color = Color(1.0, 1.0, 1.0, 1.0);
canvas.DrawRect({0, 0, 500, 500}, paint);
ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
@@ -415,32 +403,28 @@
canvas.Scale(aiks_test->GetContentScale());
Paint paint;
canvas.Translate({100, 100, 0});
- paint.color_source = [tile_mode]() {
- std::vector<Color> colors = {
- Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
- Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
- Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
- Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
- Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
- Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
- Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
- std::vector<Scalar> stops = {
- 0.0,
- (1.0 / 6.0) * 1,
- (1.0 / 6.0) * 2,
- (1.0 / 6.0) * 3,
- (1.0 / 6.0) * 4,
- (1.0 / 6.0) * 5,
- 1.0,
- };
- auto contents = std::make_shared<LinearGradientContents>();
- contents->SetEndPoints({0, 0}, {200, 200});
- contents->SetColors(std::move(colors));
- contents->SetStops(std::move(stops));
- contents->SetTileMode(tile_mode);
- return contents;
+ std::vector<Color> colors = {
+ Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
+ Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
+ Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
+ Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
+ Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
+ Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
+ Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
+ std::vector<Scalar> stops = {
+ 0.0,
+ (1.0 / 6.0) * 1,
+ (1.0 / 6.0) * 2,
+ (1.0 / 6.0) * 3,
+ (1.0 / 6.0) * 4,
+ (1.0 / 6.0) * 5,
+ 1.0,
};
+
+ paint.color_source = ColorSource::MakeLinearGradient(
+ {0, 0}, {200, 200}, std::move(colors), std::move(stops), tile_mode, {});
+
paint.color = Color(1.0, 1.0, 1.0, 1.0);
canvas.DrawRect({0, 0, 600, 600}, paint);
canvas.Restore();
@@ -477,15 +461,10 @@
current_stop += 1 / 2000.0;
}
stops[2000 - 1] = 1.0;
- paint.color_source = [tile_mode, stops = std::move(stops),
- colors = std::move(colors)]() {
- auto contents = std::make_shared<LinearGradientContents>();
- contents->SetEndPoints({0, 0}, {200, 200});
- contents->SetColors(colors);
- contents->SetStops(stops);
- contents->SetTileMode(tile_mode);
- return contents;
- };
+
+ paint.color_source = ColorSource::MakeLinearGradient(
+ {0, 0}, {200, 200}, std::move(colors), std::move(stops), tile_mode, {});
+
canvas.DrawRect({0, 0, 600, 600}, paint);
ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
@@ -525,28 +504,22 @@
Paint paint;
canvas.Translate({100.0, 100.0, 0});
auto tile_mode = tile_modes[selected_tile_mode];
- paint.color_source = [tile_mode]() {
- std::vector<Color> colors = {
- Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
- Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
- Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
- Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
- Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
- Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
- Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
- std::vector<Scalar> stops = {
- 0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0,
- 16.0 / 62.0, 32.0 / 62.0, 1.0,
- };
- auto contents = std::make_shared<LinearGradientContents>();
- contents->SetEndPoints({0, 0}, {200, 200});
- contents->SetColors(std::move(colors));
- contents->SetStops(std::move(stops));
- contents->SetTileMode(tile_mode);
- contents->SetEffectTransform(matrix);
- return contents;
+ std::vector<Color> colors = {
+ Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
+ Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
+ Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
+ Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
+ Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
+ Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
+ Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
+ std::vector<Scalar> stops = {
+ 0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
};
+
+ paint.color_source = ColorSource::MakeLinearGradient(
+ {0, 0}, {200, 200}, std::move(colors), std::move(stops), tile_mode, {});
+
canvas.DrawRect({0, 0, 600, 600}, paint);
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};
@@ -582,19 +555,14 @@
Paint paint;
canvas.Translate({100.0, 100.0, 0});
auto tile_mode = tile_modes[selected_tile_mode];
- paint.color_source = [tile_mode]() {
- std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
- Color{0.1294, 0.5882, 0.9529, 1.0}};
- std::vector<Scalar> stops = {0.0, 1.0};
- auto contents = std::make_shared<RadialGradientContents>();
- contents->SetCenterAndRadius({100, 100}, 100);
- contents->SetColors(std::move(colors));
- contents->SetStops(std::move(stops));
- contents->SetTileMode(tile_mode);
- contents->SetEffectTransform(matrix);
- return contents;
- };
+ std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
+ Color{0.1294, 0.5882, 0.9529, 1.0}};
+ std::vector<Scalar> stops = {0.0, 1.0};
+
+ paint.color_source = ColorSource::MakeRadialGradient(
+ {100, 100}, 100, std::move(colors), std::move(stops), tile_mode, {});
+
canvas.DrawRect({0, 0, 600, 600}, paint);
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};
@@ -630,33 +598,28 @@
Paint paint;
canvas.Translate({100.0, 100.0, 0});
auto tile_mode = tile_modes[selected_tile_mode];
- paint.color_source = [tile_mode]() {
- std::vector<Color> colors = {
- Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
- Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
- Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
- Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
- Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
- Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
- Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
- std::vector<Scalar> stops = {
- 0.0,
- (1.0 / 6.0) * 1,
- (1.0 / 6.0) * 2,
- (1.0 / 6.0) * 3,
- (1.0 / 6.0) * 4,
- (1.0 / 6.0) * 5,
- 1.0,
- };
- auto contents = std::make_shared<RadialGradientContents>();
- contents->SetCenterAndRadius({100, 100}, 100);
- contents->SetColors(std::move(colors));
- contents->SetStops(std::move(stops));
- contents->SetTileMode(tile_mode);
- contents->SetEffectTransform(matrix);
- return contents;
+ std::vector<Color> colors = {
+ Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
+ Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
+ Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
+ Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
+ Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
+ Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
+ Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
+ std::vector<Scalar> stops = {
+ 0.0,
+ (1.0 / 6.0) * 1,
+ (1.0 / 6.0) * 2,
+ (1.0 / 6.0) * 3,
+ (1.0 / 6.0) * 4,
+ (1.0 / 6.0) * 5,
+ 1.0,
};
+
+ paint.color_source = ColorSource::MakeRadialGradient(
+ {100, 100}, 100, std::move(colors), std::move(stops), tile_mode, {});
+
canvas.DrawRect({0, 0, 600, 600}, paint);
return renderer.Render(canvas.EndRecordingAsPicture(), render_target);
};
@@ -669,17 +632,15 @@
canvas.Scale(aiks_test->GetContentScale());
Paint paint;
canvas.Translate({100, 100, 0});
- paint.color_source = [tile_mode]() {
- auto contents = std::make_shared<SweepGradientContents>();
- contents->SetCenterAndAngles({100, 100}, Degrees(45), Degrees(135));
- std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
- Color{0.1294, 0.5882, 0.9529, 1.0}};
- std::vector<Scalar> stops = {0.0, 1.0};
- contents->SetColors(std::move(colors));
- contents->SetStops(std::move(stops));
- contents->SetTileMode(tile_mode);
- return contents;
- };
+
+ std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
+ Color{0.1294, 0.5882, 0.9529, 1.0}};
+ std::vector<Scalar> stops = {0.0, 1.0};
+
+ paint.color_source = ColorSource::MakeSweepGradient(
+ {100, 100}, Degrees(45), Degrees(135), std::move(colors),
+ std::move(stops), tile_mode, {});
+
canvas.DrawRect({0, 0, 600, 600}, paint);
ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
@@ -704,32 +665,29 @@
Canvas canvas;
Paint paint;
canvas.Translate({100.0, 100.0, 0});
- paint.color_source = [tile_mode]() {
- auto contents = std::make_shared<SweepGradientContents>();
- contents->SetCenterAndAngles({100, 100}, Degrees(45), Degrees(135));
- std::vector<Color> colors = {
- Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
- Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
- Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
- Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
- Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
- Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
- Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
- std::vector<Scalar> stops = {
- 0.0,
- (1.0 / 6.0) * 1,
- (1.0 / 6.0) * 2,
- (1.0 / 6.0) * 3,
- (1.0 / 6.0) * 4,
- (1.0 / 6.0) * 5,
- 1.0,
- };
- contents->SetStops(std::move(stops));
- contents->SetColors(std::move(colors));
- contents->SetTileMode(tile_mode);
- return contents;
+ std::vector<Color> colors = {
+ Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
+ Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
+ Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
+ Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
+ Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
+ Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
+ Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
+ std::vector<Scalar> stops = {
+ 0.0,
+ (1.0 / 6.0) * 1,
+ (1.0 / 6.0) * 2,
+ (1.0 / 6.0) * 3,
+ (1.0 / 6.0) * 4,
+ (1.0 / 6.0) * 5,
+ 1.0,
};
+
+ paint.color_source = ColorSource::MakeSweepGradient(
+ {100, 100}, Degrees(45), Degrees(135), std::move(colors),
+ std::move(stops), tile_mode, {});
+
canvas.DrawRect({0, 0, 600, 600}, paint);
ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
@@ -751,20 +709,18 @@
TEST_P(AiksTest, CanRenderDifferentShapesWithSameColorSource) {
Canvas canvas;
Paint paint;
- paint.color_source = []() {
- auto contents = std::make_shared<LinearGradientContents>();
- contents->SetEndPoints({0, 0}, {100, 100});
- std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
- Color{0.1294, 0.5882, 0.9529, 1.0}};
- std::vector<Scalar> stops = {
- 0.0,
- 1.0,
- };
- contents->SetColors(std::move(colors));
- contents->SetStops(std::move(stops));
- contents->SetTileMode(Entity::TileMode::kRepeat);
- return contents;
+
+ std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
+ Color{0.1294, 0.5882, 0.9529, 1.0}};
+ std::vector<Scalar> stops = {
+ 0.0,
+ 1.0,
};
+
+ paint.color_source = ColorSource::MakeLinearGradient(
+ {0, 0}, {100, 100}, std::move(colors), std::move(stops),
+ Entity::TileMode::kRepeat, {});
+
canvas.Save();
canvas.Translate({100, 100, 0});
canvas.DrawRect({0, 0, 200, 200}, paint);
@@ -1545,24 +1501,13 @@
paint.color = Color(1.0, 1.0, 1.0, alpha);
paint.stroke_width = 10;
auto tile_mode = tile_modes[selected_tile_mode];
- paint.color_source = [tile_mode]() {
- std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
- Color{0.1294, 0.5882, 0.9529, 1.0}};
- std::vector<Scalar> stops = {0.0, 1.0};
- Matrix matrix = {
- 1, 0, 0, 0, //
- 0, 1, 0, 0, //
- 0, 0, 1, 0, //
- 0, 0, 0, 1 //
- };
- auto contents = std::make_shared<LinearGradientContents>();
- contents->SetEndPoints({0, 0}, {50, 50});
- contents->SetColors(std::move(colors));
- contents->SetStops(std::move(stops));
- contents->SetTileMode(tile_mode);
- contents->SetEffectTransform(matrix);
- return contents;
- };
+
+ std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
+ Color{0.1294, 0.5882, 0.9529, 1.0}};
+ std::vector<Scalar> stops = {0.0, 1.0};
+
+ paint.color_source = ColorSource::MakeLinearGradient(
+ {0, 0}, {50, 50}, std::move(colors), std::move(stops), tile_mode, {});
Path path = PathBuilder{}
.MoveTo({20, 20})
@@ -1778,18 +1723,14 @@
ImGui::SliderFloat("FOV", &fov, 1, 180);
ImGui::End();
- paint.color_source_type = Paint::ColorSourceType::kScene;
- paint.color_source = [&]() {
- Scalar angle = GetSecondsElapsed();
- auto camera_position = Vector3(distance * std::sin(angle), y_pos,
- -distance * std::cos(angle));
- auto contents = std::make_shared<SceneContents>();
- contents->SetNode(gltf_scene);
- contents->SetCameraTransform(
- Matrix::MakePerspective(Degrees(fov), GetWindowSize(), 0.1, 1000) *
- Matrix::MakeLookAt(camera_position, {0, 0, 0}, {0, 1, 0}));
- return contents;
- };
+ Scalar angle = GetSecondsElapsed();
+ auto camera_position =
+ Vector3(distance * std::sin(angle), y_pos, -distance * std::cos(angle));
+
+ paint.color_source = ColorSource::MakeScene(
+ gltf_scene,
+ Matrix::MakePerspective(Degrees(fov), GetWindowSize(), 0.1, 1000) *
+ Matrix::MakeLookAt(camera_position, {0, 0, 0}, {0, 1, 0}));
Canvas canvas;
canvas.DrawPaint(Paint{.color = Color::MakeRGBA8(0xf9, 0xf9, 0xf9, 0xff)});
diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc
index 5ae2303..6c69fe0 100644
--- a/impeller/aiks/canvas.cc
+++ b/impeller/aiks/canvas.cc
@@ -22,23 +22,6 @@
namespace impeller {
-static bool UseColorSourceContents(
- const std::shared_ptr<VerticesGeometry>& vertices,
- const Paint::ColorSourceType& type) {
- // If there are no vertex color or texture coordinates. Or if there
- // are vertex coordinates then only if the contents are an image or
- // a solid color.
- if (vertices->HasVertexColors()) {
- return false;
- }
- if (vertices->HasTextureCoordinates() &&
- (type == Paint::ColorSourceType::kImage ||
- type == Paint::ColorSourceType::kColor)) {
- return true;
- }
- return !vertices->HasTextureCoordinates();
-}
-
Canvas::Canvas() {
Initialize();
}
@@ -191,8 +174,7 @@
bool Canvas::AttemptDrawBlurredRRect(const Rect& rect,
Scalar corner_radius,
const Paint& paint) {
- if (paint.color_source == nullptr ||
- paint.color_source_type != Paint::ColorSourceType::kColor ||
+ if (paint.color_source.GetType() != ColorSource::Type::kColor ||
paint.style != Paint::Style::kFill) {
return false;
}
@@ -436,8 +418,7 @@
text_contents->SetTextFrame(text_frame);
text_contents->SetGlyphAtlas(lazy_glyph_atlas_);
- if (paint.color_source.has_value()) {
- auto& source = paint.color_source.value();
+ if (paint.color_source.GetType() != ColorSource::Type::kColor) {
auto color_text_contents = std::make_shared<ColorSourceTextContents>();
entity.SetTransformation(GetCurrentTransformation());
@@ -447,7 +428,8 @@
text_contents->SetOffset(-cvg.origin);
color_text_contents->SetTextContents(std::move(text_contents));
- color_text_contents->SetColorSourceContents(source());
+ color_text_contents->SetColorSourceContents(
+ paint.color_source.GetContents(paint));
entity.SetContents(
paint.WithFilters(std::move(color_text_contents), false));
@@ -466,13 +448,30 @@
GetCurrentPass().AddEntity(entity);
}
+static bool UseColorSourceContents(
+ const std::shared_ptr<VerticesGeometry>& vertices,
+ const Paint& paint) {
+ // If there are no vertex color or texture coordinates. Or if there
+ // are vertex coordinates then only if the contents are an image or
+ // a solid color.
+ if (vertices->HasVertexColors()) {
+ return false;
+ }
+ if (vertices->HasTextureCoordinates() &&
+ (paint.color_source.GetType() == ColorSource::Type::kImage ||
+ paint.color_source.GetType() == ColorSource::Type::kColor)) {
+ return true;
+ }
+ return !vertices->HasTextureCoordinates();
+}
+
void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
BlendMode blend_mode,
const Paint& paint) {
// Override the blend mode with kDestination in order to match the behavior
// of Skia's SK_LEGACY_IGNORE_DRAW_VERTICES_BLEND_WITH_NO_SHADER flag, which
// is enabled when the Flutter engine builds Skia.
- if (paint.color_source_type == Paint::ColorSourceType::kColor) {
+ if (paint.color_source.GetType() == ColorSource::Type::kColor) {
blend_mode = BlendMode::kDestination;
}
@@ -483,7 +482,7 @@
// If there are no vertex color or texture coordinates. Or if there
// are vertex coordinates then only if the contents are an image.
- if (UseColorSourceContents(vertices, paint.color_source_type)) {
+ if (UseColorSourceContents(vertices, paint)) {
auto contents = paint.CreateContentsForGeometry(vertices);
entity.SetContents(paint.WithFilters(std::move(contents)));
GetCurrentPass().AddEntity(entity);
@@ -496,7 +495,7 @@
std::shared_ptr<Contents> src_contents =
src_paint.CreateContentsForGeometry(vertices);
if (vertices->HasTextureCoordinates() &&
- paint.color_source_type != Paint::ColorSourceType::kImage) {
+ paint.color_source.GetType() != ColorSource::Type::kImage) {
// If the color source has an intrinsic size, then we use that to
// create the src contents as a simplification. Otherwise we use
// the extent of the texture coordinates to determine how large
diff --git a/impeller/aiks/color_source.cc b/impeller/aiks/color_source.cc
new file mode 100644
index 0000000..f5644b2
--- /dev/null
+++ b/impeller/aiks/color_source.cc
@@ -0,0 +1,225 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "impeller/aiks/color_source.h"
+
+#include <memory>
+#include <vector>
+
+#include "impeller/aiks/paint.h"
+#include "impeller/core/sampler_descriptor.h"
+#include "impeller/entity/contents/conical_gradient_contents.h"
+#include "impeller/entity/contents/linear_gradient_contents.h"
+#include "impeller/entity/contents/radial_gradient_contents.h"
+#include "impeller/entity/contents/runtime_effect_contents.h"
+#include "impeller/entity/contents/scene_contents.h"
+#include "impeller/entity/contents/solid_color_contents.h"
+#include "impeller/entity/contents/sweep_gradient_contents.h"
+#include "impeller/entity/contents/tiled_texture_contents.h"
+#include "impeller/geometry/matrix.h"
+#include "impeller/geometry/scalar.h"
+#include "impeller/runtime_stage/runtime_stage.h"
+#include "impeller/scene/node.h"
+
+namespace impeller {
+
+ColorSource::ColorSource() noexcept
+ : proc_([](const Paint& paint) -> std::shared_ptr<ColorSourceContents> {
+ auto contents = std::make_shared<SolidColorContents>();
+ contents->SetColor(paint.color);
+ return contents;
+ }){};
+
+ColorSource::~ColorSource() = default;
+
+ColorSource ColorSource::MakeColor() {
+ return {};
+}
+
+ColorSource ColorSource::MakeLinearGradient(Point start_point,
+ Point end_point,
+ std::vector<Color> colors,
+ std::vector<Scalar> stops,
+ Entity::TileMode tile_mode,
+ Matrix effect_transform) {
+ ColorSource result;
+ result.type_ = Type::kLinearGradient;
+ result.proc_ = [start_point, end_point, colors = std::move(colors),
+ stops = std::move(stops), tile_mode,
+ effect_transform](const Paint& paint) {
+ auto contents = std::make_shared<LinearGradientContents>();
+ contents->SetOpacity(paint.color.alpha);
+ contents->SetColors(colors);
+ contents->SetStops(stops);
+ contents->SetEndPoints(start_point, end_point);
+ contents->SetTileMode(tile_mode);
+ contents->SetEffectTransform(effect_transform);
+
+ std::vector<Point> bounds{start_point, end_point};
+ auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end());
+ if (intrinsic_size.has_value()) {
+ contents->SetColorSourceSize(intrinsic_size->size);
+ }
+ return contents;
+ };
+ return result;
+}
+
+ColorSource ColorSource::MakeConicalGradient(Point center,
+ Scalar radius,
+ std::vector<Color> colors,
+ std::vector<Scalar> stops,
+ Point focus_center,
+ Scalar focus_radius,
+ Entity::TileMode tile_mode,
+ Matrix effect_transform) {
+ ColorSource result;
+ result.type_ = Type::kConicalGradient;
+ result.proc_ = [center, radius, colors = std::move(colors),
+ stops = std::move(stops), focus_center, focus_radius,
+ tile_mode, effect_transform](const Paint& paint) {
+ std::shared_ptr<ConicalGradientContents> contents =
+ std::make_shared<ConicalGradientContents>();
+ contents->SetOpacity(paint.color.alpha);
+ contents->SetColors(colors);
+ contents->SetStops(stops);
+ contents->SetCenterAndRadius(center, radius);
+ contents->SetTileMode(tile_mode);
+ contents->SetEffectTransform(effect_transform);
+ contents->SetFocus(focus_center, focus_radius);
+
+ auto radius_pt = Point(radius, radius);
+ std::vector<Point> bounds{center + radius_pt, center - radius_pt};
+ auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end());
+ if (intrinsic_size.has_value()) {
+ contents->SetColorSourceSize(intrinsic_size->size);
+ }
+ return contents;
+ };
+ return result;
+}
+
+ColorSource ColorSource::MakeRadialGradient(Point center,
+ Scalar radius,
+ std::vector<Color> colors,
+ std::vector<Scalar> stops,
+ Entity::TileMode tile_mode,
+ Matrix effect_transform) {
+ ColorSource result;
+ result.type_ = Type::kRadialGradient;
+ result.proc_ = [center, radius, colors = std::move(colors),
+ stops = std::move(stops), tile_mode,
+ effect_transform](const Paint& paint) {
+ auto contents = std::make_shared<RadialGradientContents>();
+ contents->SetOpacity(paint.color.alpha);
+ contents->SetColors(colors);
+ contents->SetStops(stops);
+ contents->SetCenterAndRadius(center, radius);
+ contents->SetTileMode(tile_mode);
+ contents->SetEffectTransform(effect_transform);
+
+ auto radius_pt = Point(radius, radius);
+ std::vector<Point> bounds{center + radius_pt, center - radius_pt};
+ auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end());
+ if (intrinsic_size.has_value()) {
+ contents->SetColorSourceSize(intrinsic_size->size);
+ }
+ return contents;
+ };
+ return result;
+}
+
+ColorSource ColorSource::MakeSweepGradient(Point center,
+ Degrees start_angle,
+ Degrees end_angle,
+ std::vector<Color> colors,
+ std::vector<Scalar> stops,
+ Entity::TileMode tile_mode,
+ Matrix effect_transform) {
+ ColorSource result;
+ result.type_ = Type::kSweepGradient;
+ result.proc_ = [center, start_angle, end_angle, colors = std::move(colors),
+ stops = std::move(stops), tile_mode,
+ effect_transform](const Paint& paint) {
+ auto contents = std::make_shared<SweepGradientContents>();
+ contents->SetOpacity(paint.color.alpha);
+ contents->SetCenterAndAngles(center, start_angle, end_angle);
+ contents->SetColors(colors);
+ contents->SetStops(stops);
+ contents->SetTileMode(tile_mode);
+ contents->SetEffectTransform(effect_transform);
+
+ return contents;
+ };
+ return result;
+}
+
+ColorSource ColorSource::MakeImage(std::shared_ptr<Texture> texture,
+ Entity::TileMode x_tile_mode,
+ Entity::TileMode y_tile_mode,
+ SamplerDescriptor sampler_descriptor,
+ Matrix effect_transform) {
+ ColorSource result;
+ result.type_ = Type::kImage;
+ result.proc_ = [texture = std::move(texture), x_tile_mode, y_tile_mode,
+ sampler_descriptor = std::move(sampler_descriptor),
+ effect_transform](const Paint& paint) {
+ auto contents = std::make_shared<TiledTextureContents>();
+ contents->SetOpacity(paint.color.alpha);
+ contents->SetTexture(texture);
+ contents->SetTileModes(x_tile_mode, y_tile_mode);
+ contents->SetSamplerDescriptor(sampler_descriptor);
+ contents->SetEffectTransform(effect_transform);
+ contents->SetColorFilter(paint.color_filter);
+ contents->SetColorSourceSize(Size::Ceil(texture->GetSize()));
+ return contents;
+ };
+ return result;
+}
+
+ColorSource ColorSource::MakeRuntimeEffect(
+ std::shared_ptr<RuntimeStage> runtime_stage,
+ std::shared_ptr<std::vector<uint8_t>> uniform_data,
+ std::vector<RuntimeEffectContents::TextureInput> texture_inputs) {
+ ColorSource result;
+ result.type_ = Type::kRuntimeEffect;
+ result.proc_ = [runtime_stage = std::move(runtime_stage),
+ uniform_data = std::move(uniform_data),
+ texture_inputs =
+ std::move(texture_inputs)](const Paint& paint) {
+ auto contents = std::make_shared<RuntimeEffectContents>();
+ contents->SetOpacity(paint.color.alpha);
+ contents->SetRuntimeStage(runtime_stage);
+ contents->SetUniformData(uniform_data);
+ contents->SetTextureInputs(texture_inputs);
+ return contents;
+ };
+ return result;
+}
+
+ColorSource ColorSource::MakeScene(std::shared_ptr<scene::Node> scene_node,
+ Matrix camera_transform) {
+ ColorSource result;
+ result.type_ = Type::kScene;
+ result.proc_ = [scene_node = std::move(scene_node),
+ camera_transform](const Paint& paint) {
+ auto contents = std::make_shared<SceneContents>();
+ contents->SetOpacity(paint.color.alpha);
+ contents->SetNode(scene_node);
+ contents->SetCameraTransform(camera_transform);
+ return contents;
+ };
+ return result;
+}
+
+ColorSource::Type ColorSource::GetType() const {
+ return type_;
+}
+
+std::shared_ptr<ColorSourceContents> ColorSource::GetContents(
+ const Paint& paint) const {
+ return proc_(paint);
+}
+
+} // namespace impeller
diff --git a/impeller/aiks/color_source.h b/impeller/aiks/color_source.h
new file mode 100644
index 0000000..84c6a6e
--- /dev/null
+++ b/impeller/aiks/color_source.h
@@ -0,0 +1,100 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+#include "flutter/fml/macros.h"
+#include "impeller/entity/contents/runtime_effect_contents.h"
+#include "impeller/entity/entity.h"
+#include "impeller/geometry/color.h"
+#include "impeller/geometry/matrix.h"
+#include "impeller/geometry/point.h"
+#include "impeller/runtime_stage/runtime_stage.h"
+#include "impeller/scene/node.h"
+
+namespace impeller {
+
+struct Paint;
+
+class ColorSource {
+ public:
+ enum class Type {
+ kColor,
+ kImage,
+ kLinearGradient,
+ kRadialGradient,
+ kConicalGradient,
+ kSweepGradient,
+ kRuntimeEffect,
+ kScene,
+ };
+
+ using ColorSourceProc =
+ std::function<std::shared_ptr<ColorSourceContents>(const Paint& paint)>;
+
+ ColorSource() noexcept;
+
+ ~ColorSource();
+
+ static ColorSource MakeColor();
+
+ static ColorSource MakeLinearGradient(Point start_point,
+ Point end_point,
+ std::vector<Color> colors,
+ std::vector<Scalar> stops,
+ Entity::TileMode tile_mode,
+ Matrix effect_transform);
+
+ static ColorSource MakeConicalGradient(Point center,
+ Scalar radius,
+ std::vector<Color> colors,
+ std::vector<Scalar> stops,
+ Point focus_center,
+ Scalar focus_radius,
+ Entity::TileMode tile_mode,
+ Matrix effect_transform);
+
+ static ColorSource MakeRadialGradient(Point center,
+ Scalar radius,
+ std::vector<Color> colors,
+ std::vector<Scalar> stops,
+ Entity::TileMode tile_mode,
+ Matrix effect_transform);
+
+ static ColorSource MakeSweepGradient(Point center,
+ Degrees start_angle,
+ Degrees end_angle,
+ std::vector<Color> colors,
+ std::vector<Scalar> stops,
+ Entity::TileMode tile_mode,
+ Matrix effect_transform);
+
+ static ColorSource MakeImage(std::shared_ptr<Texture> texture,
+ Entity::TileMode x_tile_mode,
+ Entity::TileMode y_tile_mode,
+ SamplerDescriptor sampler_descriptor,
+ Matrix effect_transform);
+
+ static ColorSource MakeRuntimeEffect(
+ std::shared_ptr<RuntimeStage> runtime_stage,
+ std::shared_ptr<std::vector<uint8_t>> uniform_data,
+ std::vector<RuntimeEffectContents::TextureInput> texture_inputs);
+
+ static ColorSource MakeScene(std::shared_ptr<scene::Node> scene_node,
+ Matrix camera_transform);
+
+ Type GetType() const;
+
+ std::shared_ptr<ColorSourceContents> GetContents(const Paint& paint) const;
+
+ private:
+ Type type_ = Type::kColor;
+ ColorSourceProc proc_;
+};
+
+} // namespace impeller
diff --git a/impeller/aiks/paint.cc b/impeller/aiks/paint.cc
index 330b7b1..47af197 100644
--- a/impeller/aiks/paint.cc
+++ b/impeller/aiks/paint.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "impeller/aiks/paint.h"
+#include "impeller/entity/contents/color_source_contents.h"
#include "impeller/entity/contents/solid_color_contents.h"
#include "impeller/entity/geometry.h"
@@ -27,38 +28,23 @@
std::shared_ptr<Contents> Paint::CreateContentsForGeometry(
std::unique_ptr<Geometry> geometry) const {
- if (color_source.has_value()) {
- auto& source = color_source.value();
- auto contents = source();
- contents->SetGeometry(std::move(geometry));
- contents->SetOpacity(color.alpha);
- return contents;
- }
- auto solid_color = std::make_shared<SolidColorContents>();
- solid_color->SetGeometry(std::move(geometry));
- solid_color->SetColor(color);
- return solid_color;
+ auto contents = color_source.GetContents(*this);
+ contents->SetGeometry(std::move(geometry));
+ return contents;
}
std::shared_ptr<Contents> Paint::CreateContentsForGeometry(
const std::shared_ptr<Geometry>& geometry) const {
- if (color_source.has_value()) {
- auto& source = color_source.value();
- auto contents = source();
- contents->SetGeometry(geometry);
- contents->SetOpacity(color.alpha);
- return contents;
- }
- auto solid_color = std::make_shared<SolidColorContents>();
- solid_color->SetGeometry(geometry);
- solid_color->SetColor(color);
- return solid_color;
+ auto contents = color_source.GetContents(*this);
+ contents->SetGeometry(geometry);
+ return contents;
}
std::shared_ptr<Contents> Paint::WithFilters(
std::shared_ptr<Contents> input,
std::optional<bool> is_solid_color) const {
- bool is_solid_color_val = is_solid_color.value_or(!color_source);
+ bool is_solid_color_val = is_solid_color.value_or(color_source.GetType() ==
+ ColorSource::Type::kColor);
input = WithColorFilter(input, /*absorb_opacity=*/true);
input = WithInvertFilter(input);
input = WithMaskBlur(input, is_solid_color_val, Matrix());
@@ -101,7 +87,7 @@
bool absorb_opacity) const {
// Image input types will directly set their color filter,
// if any. See `TiledTextureContents.SetColorFilter`.
- if (color_source_type == ColorSourceType::kImage) {
+ if (color_source.GetType() == ColorSource::Type::kImage) {
return input;
}
if (color_filter.has_value()) {
diff --git a/impeller/aiks/paint.h b/impeller/aiks/paint.h
index 5279a7d..709e66e 100644
--- a/impeller/aiks/paint.h
+++ b/impeller/aiks/paint.h
@@ -7,6 +7,7 @@
#include <memory>
#include "flutter/fml/macros.h"
+#include "impeller/aiks/color_source.h"
#include "impeller/entity/contents/contents.h"
#include "impeller/entity/contents/filters/color_filter_contents.h"
#include "impeller/entity/contents/filters/filter_contents.h"
@@ -37,17 +38,6 @@
kStroke,
};
- enum class ColorSourceType {
- kColor,
- kImage,
- kLinearGradient,
- kRadialGradient,
- kConicalGradient,
- kSweepGradient,
- kRuntimeEffect,
- kScene,
- };
-
struct MaskBlurDescriptor {
FilterContents::BlurStyle style;
Sigma sigma;
@@ -59,8 +49,7 @@
};
Color color = Color::Black();
- std::optional<ColorSourceProc> color_source;
- ColorSourceType color_source_type = ColorSourceType::kColor;
+ ColorSource color_source;
Scalar stroke_width = 0.0;
Cap stroke_cap = Cap::kButt;
diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc
index 9603f25..61fe206 100644
--- a/impeller/display_list/display_list_dispatcher.cc
+++ b/impeller/display_list/display_list_dispatcher.cc
@@ -286,26 +286,26 @@
}
}
-static std::optional<Paint::ColorSourceType> ToColorSourceType(
+static std::optional<ColorSource::Type> ToColorSourceType(
flutter::DlColorSourceType type) {
switch (type) {
case flutter::DlColorSourceType::kColor:
- return Paint::ColorSourceType::kColor;
+ return ColorSource::Type::kColor;
case flutter::DlColorSourceType::kImage:
- return Paint::ColorSourceType::kImage;
+ return ColorSource::Type::kImage;
case flutter::DlColorSourceType::kLinearGradient:
- return Paint::ColorSourceType::kLinearGradient;
+ return ColorSource::Type::kLinearGradient;
case flutter::DlColorSourceType::kRadialGradient:
- return Paint::ColorSourceType::kRadialGradient;
+ return ColorSource::Type::kRadialGradient;
case flutter::DlColorSourceType::kConicalGradient:
- return Paint::ColorSourceType::kConicalGradient;
+ return ColorSource::Type::kConicalGradient;
case flutter::DlColorSourceType::kSweepGradient:
- return Paint::ColorSourceType::kSweepGradient;
+ return ColorSource::Type::kSweepGradient;
case flutter::DlColorSourceType::kRuntimeEffect:
- return Paint::ColorSourceType::kRuntimeEffect;
+ return ColorSource::Type::kRuntimeEffect;
#ifdef IMPELLER_ENABLE_3D
case flutter::DlColorSourceType::kScene:
- return Paint::ColorSourceType::kScene;
+ return ColorSource::Type::kScene;
#endif // IMPELLER_ENABLE_3D
}
}
@@ -314,32 +314,28 @@
void DisplayListDispatcher::setColorSource(
const flutter::DlColorSource* source) {
if (!source) {
- paint_.color_source = std::nullopt;
- paint_.color_source_type = Paint::ColorSourceType::kColor;
+ paint_.color_source = ColorSource::MakeColor();
return;
}
- std::optional<Paint::ColorSourceType> type =
- ToColorSourceType(source->type());
+ std::optional<ColorSource::Type> type = ToColorSourceType(source->type());
if (!type.has_value()) {
FML_LOG(ERROR) << "Requested ColorSourceType::kUnknown";
- paint_.color_source = std::nullopt;
- paint_.color_source_type = Paint::ColorSourceType::kColor;
+ paint_.color_source = ColorSource::MakeColor();
return;
}
- paint_.color_source_type = type.value();
-
switch (type.value()) {
- case Paint::ColorSourceType::kColor: {
+ case ColorSource::Type::kColor: {
const flutter::DlColorColorSource* color = source->asColor();
- paint_.color_source = std::nullopt;
+
+ paint_.color_source = ColorSource::MakeColor();
setColor(color->color());
FML_DCHECK(color);
return;
}
- case Paint::ColorSourceType::kLinearGradient: {
+ case ColorSource::Type::kLinearGradient: {
const flutter::DlLinearGradientColorSource* linear =
source->asLinearGradient();
FML_DCHECK(linear);
@@ -351,26 +347,13 @@
auto tile_mode = ToTileMode(linear->tile_mode());
auto matrix = ToMatrix(linear->matrix());
- paint_.color_source = [start_point, end_point, colors = std::move(colors),
- stops = std::move(stops), tile_mode, matrix]() {
- auto contents = std::make_shared<LinearGradientContents>();
- contents->SetColors(colors);
- contents->SetStops(stops);
- contents->SetEndPoints(start_point, end_point);
- contents->SetTileMode(tile_mode);
- contents->SetEffectTransform(matrix);
- std::vector<Point> bounds{start_point, end_point};
- auto intrinsic_size =
- Rect::MakePointBounds(bounds.begin(), bounds.end());
- if (intrinsic_size.has_value()) {
- contents->SetColorSourceSize(intrinsic_size->size);
- }
- return contents;
- };
+ paint_.color_source = ColorSource::MakeLinearGradient(
+ start_point, end_point, std::move(colors), std::move(stops),
+ tile_mode, matrix);
return;
}
- case Paint::ColorSourceType::kConicalGradient: {
+ case ColorSource::Type::kConicalGradient: {
const flutter::DlConicalGradientColorSource* conical_gradient =
source->asConicalGradient();
FML_DCHECK(conical_gradient);
@@ -385,30 +368,13 @@
auto tile_mode = ToTileMode(conical_gradient->tile_mode());
auto matrix = ToMatrix(conical_gradient->matrix());
- paint_.color_source = [center, radius, colors = std::move(colors),
- stops = std::move(stops), tile_mode, matrix,
- focus_center, focus_radius]() {
- std::shared_ptr<ConicalGradientContents> contents =
- std::make_shared<ConicalGradientContents>();
- contents->SetColors(colors);
- contents->SetStops(stops);
- contents->SetCenterAndRadius(center, radius);
- contents->SetTileMode(tile_mode);
- contents->SetEffectTransform(matrix);
- contents->SetFocus(focus_center, focus_radius);
- auto radius_pt = Point(radius, radius);
- std::vector<Point> bounds{center + radius_pt, center - radius_pt};
- auto intrinsic_size =
- Rect::MakePointBounds(bounds.begin(), bounds.end());
- if (intrinsic_size.has_value()) {
- contents->SetColorSourceSize(intrinsic_size->size);
- }
- return contents;
- };
+ paint_.color_source = ColorSource::MakeConicalGradient(
+ center, radius, std::move(colors), std::move(stops), focus_center,
+ focus_radius, tile_mode, matrix);
return;
}
- case Paint::ColorSourceType::kRadialGradient: {
+ case ColorSource::Type::kRadialGradient: {
const flutter::DlRadialGradientColorSource* radialGradient =
source->asRadialGradient();
FML_DCHECK(radialGradient);
@@ -420,27 +386,12 @@
auto tile_mode = ToTileMode(radialGradient->tile_mode());
auto matrix = ToMatrix(radialGradient->matrix());
- paint_.color_source = [center, radius, colors = std::move(colors),
- stops = std::move(stops), tile_mode, matrix]() {
- auto contents = std::make_shared<RadialGradientContents>();
- contents->SetColors(colors);
- contents->SetStops(stops);
- contents->SetCenterAndRadius(center, radius);
- contents->SetTileMode(tile_mode);
- contents->SetEffectTransform(matrix);
-
- auto radius_pt = Point(radius, radius);
- std::vector<Point> bounds{center + radius_pt, center - radius_pt};
- auto intrinsic_size =
- Rect::MakePointBounds(bounds.begin(), bounds.end());
- if (intrinsic_size.has_value()) {
- contents->SetColorSourceSize(intrinsic_size->size);
- }
- return contents;
- };
+ paint_.color_source =
+ ColorSource::MakeRadialGradient(center, radius, std::move(colors),
+ std::move(stops), tile_mode, matrix);
return;
}
- case Paint::ColorSourceType::kSweepGradient: {
+ case ColorSource::Type::kSweepGradient: {
const flutter::DlSweepGradientColorSource* sweepGradient =
source->asSweepGradient();
FML_DCHECK(sweepGradient);
@@ -454,21 +405,12 @@
auto tile_mode = ToTileMode(sweepGradient->tile_mode());
auto matrix = ToMatrix(sweepGradient->matrix());
- paint_.color_source = [center, start_angle, end_angle,
- colors = std::move(colors),
- stops = std::move(stops), tile_mode, matrix]() {
- auto contents = std::make_shared<SweepGradientContents>();
- contents->SetCenterAndAngles(center, start_angle, end_angle);
- contents->SetColors(colors);
- contents->SetStops(stops);
- contents->SetTileMode(tile_mode);
- contents->SetEffectTransform(matrix);
-
- return contents;
- };
+ paint_.color_source = ColorSource::MakeSweepGradient(
+ center, start_angle, end_angle, std::move(colors), std::move(stops),
+ tile_mode, matrix);
return;
}
- case Paint::ColorSourceType::kImage: {
+ case ColorSource::Type::kImage: {
const flutter::DlImageColorSource* image_color_source = source->asImage();
FML_DCHECK(image_color_source &&
image_color_source->image()->impeller_texture());
@@ -477,20 +419,11 @@
auto y_tile_mode = ToTileMode(image_color_source->vertical_tile_mode());
auto desc = ToSamplerDescriptor(image_color_source->sampling());
auto matrix = ToMatrix(image_color_source->matrix());
- paint_.color_source = [texture, x_tile_mode, y_tile_mode, desc, matrix,
- &paint = paint_]() {
- auto contents = std::make_shared<TiledTextureContents>();
- contents->SetTexture(texture);
- contents->SetTileModes(x_tile_mode, y_tile_mode);
- contents->SetSamplerDescriptor(desc);
- contents->SetEffectTransform(matrix);
- contents->SetColorFilter(paint.color_filter);
- contents->SetColorSourceSize(Size::Ceil(texture->GetSize()));
- return contents;
- };
+ paint_.color_source = ColorSource::MakeImage(texture, x_tile_mode,
+ y_tile_mode, desc, matrix);
return;
}
- case Paint::ColorSourceType::kRuntimeEffect: {
+ case ColorSource::Type::kRuntimeEffect: {
const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source =
source->asRuntimeEffect();
auto runtime_stage =
@@ -516,28 +449,19 @@
});
}
- paint_.color_source = [runtime_stage, uniform_data, texture_inputs]() {
- auto contents = std::make_shared<RuntimeEffectContents>();
- contents->SetRuntimeStage(runtime_stage);
- contents->SetUniformData(uniform_data);
- contents->SetTextureInputs(texture_inputs);
- return contents;
- };
+ paint_.color_source = ColorSource::MakeRuntimeEffect(
+ runtime_stage, uniform_data, texture_inputs);
return;
}
- case Paint::ColorSourceType::kScene: {
+ case ColorSource::Type::kScene: {
#ifdef IMPELLER_ENABLE_3D
const flutter::DlSceneColorSource* scene_color_source = source->asScene();
std::shared_ptr<scene::Node> scene_node =
scene_color_source->scene_node();
Matrix camera_transform = scene_color_source->camera_matrix();
- paint_.color_source = [scene_node, camera_transform]() {
- auto contents = std::make_shared<SceneContents>();
- contents->SetNode(scene_node);
- contents->SetCameraTransform(camera_transform);
- return contents;
- };
+ paint_.color_source =
+ ColorSource::MakeScene(scene_node, camera_transform);
#else // IMPELLER_ENABLE_3D
FML_LOG(ERROR) << "ColorSourceType::kScene can only be used if Impeller "
"Scene is enabled.";
diff --git a/impeller/entity/contents/runtime_effect_contents.h b/impeller/entity/contents/runtime_effect_contents.h
index 0a85d5a..61cb426 100644
--- a/impeller/entity/contents/runtime_effect_contents.h
+++ b/impeller/entity/contents/runtime_effect_contents.h
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#pragma once
+
#include <functional>
#include <memory>
#include <vector>
diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc
index 28c5145..9c14169 100644
--- a/impeller/entity/contents/solid_color_contents.cc
+++ b/impeller/entity/contents/solid_color_contents.cc
@@ -21,21 +21,7 @@
}
Color SolidColorContents::GetColor() const {
- return color_.WithAlpha(color_.alpha * inherited_opacity_);
-}
-
-void SolidColorContents::SetGeometry(std::shared_ptr<Geometry> geometry) {
- geometry_ = std::move(geometry);
-}
-
-// | Contents|
-bool SolidColorContents::CanInheritOpacity(const Entity& entity) const {
- return true;
-}
-
-// | Contents|
-void SolidColorContents::SetInheritedOpacity(Scalar opacity) {
- inherited_opacity_ = opacity;
+ return color_.WithAlpha(color_.alpha * GetOpacity());
}
std::optional<Rect> SolidColorContents::GetCoverage(
@@ -43,10 +29,12 @@
if (GetColor().IsTransparent()) {
return std::nullopt;
}
- if (geometry_ == nullptr) {
+
+ auto geometry = GetGeometry();
+ if (geometry == nullptr) {
return std::nullopt;
}
- return geometry_->GetCoverage(entity.GetTransformation());
+ return geometry->GetCoverage(entity.GetTransformation());
};
bool SolidColorContents::ShouldRender(
@@ -68,7 +56,8 @@
cmd.label = "Solid Fill";
cmd.stencil_reference = entity.GetStencilDepth();
- auto geometry_result = geometry_->GetPositionBuffer(renderer, entity, pass);
+ auto geometry_result =
+ GetGeometry()->GetPositionBuffer(renderer, entity, pass);
auto options = OptionsFromPassAndEntity(pass, entity);
if (geometry_result.prevent_overdraw) {
diff --git a/impeller/entity/contents/solid_color_contents.h b/impeller/entity/contents/solid_color_contents.h
index 91d5720..5348b90 100644
--- a/impeller/entity/contents/solid_color_contents.h
+++ b/impeller/entity/contents/solid_color_contents.h
@@ -9,6 +9,7 @@
#include <vector>
#include "flutter/fml/macros.h"
+#include "impeller/entity/contents/color_source_contents.h"
#include "impeller/entity/contents/contents.h"
#include "impeller/entity/geometry.h"
#include "impeller/geometry/color.h"
@@ -20,7 +21,7 @@
class HostBuffer;
struct VertexBuffer;
-class SolidColorContents final : public Contents {
+class SolidColorContents final : public ColorSourceContents {
public:
SolidColorContents();
@@ -29,18 +30,10 @@
static std::unique_ptr<SolidColorContents> Make(const Path& path,
Color color);
- void SetGeometry(std::shared_ptr<Geometry> geometry);
-
void SetColor(Color color);
Color GetColor() const;
- // | Contents|
- bool CanInheritOpacity(const Entity& entity) const override;
-
- // | Contents|
- void SetInheritedOpacity(Scalar opacity) override;
-
// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;
@@ -54,10 +47,7 @@
RenderPass& pass) const override;
private:
- std::shared_ptr<Geometry> geometry_;
-
Color color_;
- Scalar inherited_opacity_ = 1.0;
FML_DISALLOW_COPY_AND_ASSIGN(SolidColorContents);
};
diff --git a/impeller/golden_tests/golden_tests.cc b/impeller/golden_tests/golden_tests.cc
index c7ea062..24a229e 100644
--- a/impeller/golden_tests/golden_tests.cc
+++ b/impeller/golden_tests/golden_tests.cc
@@ -65,16 +65,11 @@
TEST_F(GoldenTests, ConicalGradient) {
Canvas canvas;
Paint paint;
- paint.color_source_type = Paint::ColorSourceType::kConicalGradient;
- paint.color_source = []() {
- auto result = std::make_shared<ConicalGradientContents>();
- result->SetCenterAndRadius(Point(125, 125), 125);
- result->SetColors({Color(1.0, 0.0, 0.0, 1.0), Color(0.0, 0.0, 1.0, 1.0)});
- result->SetStops({0, 1});
- result->SetFocus(Point(180, 180), 0);
- result->SetTileMode(Entity::TileMode::kClamp);
- return result;
- };
+
+ paint.color_source = ColorSource::MakeConicalGradient(
+ {125, 125}, 125, {Color(1.0, 0.0, 0.0, 1.0), Color(0.0, 0.0, 1.0, 1.0)},
+ {0, 1}, {180, 180}, 0, Entity::TileMode::kClamp, {});
+
paint.stroke_width = 0.0;
paint.style = Paint::Style::kFill;
canvas.DrawRect(Rect(10, 10, 250, 250), paint);