37#define BLEND_MODE_TUPLE(blend_mode) {#blend_mode, BlendMode::k##blend_mode},
45 std::vector<const char*> blend_mode_names;
46 std::vector<BlendMode> blend_mode_values;
48 const std::vector<std::tuple<const char*, BlendMode>> blends = {
50 assert(blends.size() ==
52 for (
const auto& [
name,
mode] : blends) {
53 blend_mode_names.push_back(
name);
54 blend_mode_values.push_back(
mode);
58 return {blend_mode_names, blend_mode_values};
70 builder.
SaveLayer(layer_rect, &save_paint);
79 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
104 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
110 builder.
Scale(0.2, 0.2);
122 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
139 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
151 std::vector<DlColor> colors = {
DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
153 std::vector<Scalar> stops = {0.0, 1.0};
169 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
194 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
199 bool has_color_filter =
true;
200 auto callback = [&]() -> sk_sp<DisplayList> {
202 ImGuiWindowFlags_AlwaysAutoResize)) {
203 ImGui::Checkbox(
"has color filter", &has_color_filter);
208 builder.
Scale(GetContentScale().
x, GetContentScale().
y);
215 std::vector<DlBlendMode> blend_modes = {
216 DlBlendMode::kSrc, DlBlendMode::kSrcATop, DlBlendMode::kSrcOver,
217 DlBlendMode::kSrcIn, DlBlendMode::kSrcOut, DlBlendMode::kDst,
218 DlBlendMode::kDstATop, DlBlendMode::kDstOver, DlBlendMode::kDstIn,
219 DlBlendMode::kDstOut, DlBlendMode::kClear, DlBlendMode::kXor};
221 for (uint32_t
i = 0;
i < blend_modes.size(); ++
i) {
224 builder.
Scale(0.4, 0.4);
228 DlImageSampling::kMipmapLinear, &dstPaint);
233 if (has_color_filter) {
234 std::shared_ptr<const DlColorFilter> color_filter =
236 DlBlendMode::kSrcIn);
240 DlImageSampling::kMipmapLinear, &srcPaint);
244 return builder.
Build();
246 ASSERT_TRUE(OpenPlaygroundHere(
callback));
251 bool has_color_filter =
true;
252 auto callback = [&]() -> sk_sp<DisplayList> {
254 ImGuiWindowFlags_AlwaysAutoResize)) {
255 ImGui::Checkbox(
"has color filter", &has_color_filter);
260 builder.
Scale(GetContentScale().
x, GetContentScale().
y);
267 std::vector<DlBlendMode> blend_modes = {
268 DlBlendMode::kScreen, DlBlendMode::kOverlay,
269 DlBlendMode::kDarken, DlBlendMode::kLighten,
270 DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
271 DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
272 DlBlendMode::kDifference, DlBlendMode::kExclusion,
273 DlBlendMode::kMultiply, DlBlendMode::kHue,
274 DlBlendMode::kSaturation, DlBlendMode::kColor,
275 DlBlendMode::kLuminosity,
278 for (uint32_t
i = 0;
i < blend_modes.size(); ++
i) {
281 builder.
Scale(0.4, 0.4);
285 DlImageSampling::kMipmapLinear, &dstPaint);
290 if (has_color_filter) {
291 std::shared_ptr<const DlColorFilter> color_filter =
293 DlBlendMode::kSrcIn);
297 DlImageSampling::kMipmapLinear, &srcPaint);
301 return builder.
Build();
303 ASSERT_TRUE(OpenPlaygroundHere(
callback));
312 <<
"This backend doesn't yet support setting device capabilities.";
314 if (!WillRenderSomething()) {
315 GTEST_SKIP() <<
"This test requires playgrounds.";
318 std::shared_ptr<const Capabilities> old_capabilities =
319 GetContext()->GetCapabilities();
320 auto mock_capabilities = std::make_shared<MockCapabilities>();
321 EXPECT_CALL(*mock_capabilities, SupportsFramebufferFetch())
322 .Times(::testing::AtLeast(1))
323 .WillRepeatedly(::testing::Return(
false));
324 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
325 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
327 GetDefaultDepthStencilFormat);
328 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
330 SupportsImplicitResolvingMSAA);
331 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
332 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
333 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
335 SupportsTextureToTextureBlits);
336 FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
337 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsTriangleFan);
339 SupportsDecalSamplerAddressMode);
340 FLT_FORWARD(mock_capabilities, old_capabilities, SupportsPrimitiveRestart);
341 FLT_FORWARD(mock_capabilities, old_capabilities, GetMinimumUniformAlignment);
342 ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
344 bool has_color_filter =
true;
345 auto callback = [&]() -> sk_sp<DisplayList> {
347 ImGuiWindowFlags_AlwaysAutoResize)) {
348 ImGui::Checkbox(
"has color filter", &has_color_filter);
353 builder.
Scale(GetContentScale().
x, GetContentScale().
y);
360 std::vector<DlBlendMode> blend_modes = {
361 DlBlendMode::kScreen, DlBlendMode::kOverlay,
362 DlBlendMode::kDarken, DlBlendMode::kLighten,
363 DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
364 DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
365 DlBlendMode::kDifference, DlBlendMode::kExclusion,
366 DlBlendMode::kMultiply, DlBlendMode::kHue,
367 DlBlendMode::kSaturation, DlBlendMode::kColor,
368 DlBlendMode::kLuminosity,
371 for (uint32_t
i = 0;
i < blend_modes.size(); ++
i) {
374 builder.
Scale(0.4, 0.4);
378 DlImageSampling::kMipmapLinear, &dstPaint);
383 if (has_color_filter) {
384 std::shared_ptr<const DlColorFilter> color_filter =
386 DlBlendMode::kMultiply);
390 DlImageSampling::kMipmapLinear, &srcPaint);
394 return builder.
Build();
396 ASSERT_TRUE(OpenPlaygroundHere(
callback));
401 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
403 auto texture = CreateTextureForFixture(
"airplane.jpg",
408 builder.
Scale(GetContentScale().
x, GetContentScale().
y);
425 rect.GetRight(), rect.GetBottom()),
426 DlImageSampling::kMipmapLinear, &paint);
428 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
433 EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
435 auto texture = CreateTextureForFixture(
"airplane.jpg",
439 builder.
Scale(GetContentScale().
x, GetContentScale().
y);
448 builder.
SaveLayer(std::nullopt, &save_paint);
460 rect.GetRight(), rect.GetBottom()),
461 DlImageSampling::kMipmapLinear, &paint);
464 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
473 builder.
SaveLayer(std::nullopt, &save_paint);
482 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
497 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
502 const sk_sp<DlImageImpeller>& src_image,
503 const sk_sp<DlImageImpeller>& dst_image,
506 ImGuiWindowFlags_AlwaysAutoResize)) {
507 ImGui::SliderFloat(
"Source alpha", &src_alpha, 0, 1);
520 builder.DrawPaint(paint);
531 for (
const auto& color : source_colors) {
538 builder.SaveLayer(std::nullopt);
543 destination_color.
blue, destination_color.
alpha));
544 builder.DrawPaint(draw_paint);
550 builder.SaveLayer(std::nullopt, &save_paint);
554 DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
562 builder.Translate(100, 0);
564 builder.RestoreToCount(0);
571 builder.Translate(0, 100);
574 builder.SaveLayer(std::nullopt);
575 for (
const auto& color : source_colors) {
578 auto dest = destination_color.
Blend(color, blend_mode);
582 builder.Translate(100, 0);
594 builder.Translate(0, 250);
605 for (
int y = 0;
y < 400 / 8;
y++) {
606 for (
int x = 0;
x < 800 / 16;
x++) {
616 builder.SaveLayer(std::nullopt, &paint);
618 builder.DrawImage(dst_image,
DlPoint(0, 0), DlImageSampling::kMipmapLinear,
623 builder.DrawImage(src_image,
DlPoint(0, 0), DlImageSampling::kMipmapLinear,
633 builder.SaveLayer(std::nullopt, &save_paint);
635 builder.DrawImage(dst_image,
DlPoint(400, 0),
636 DlImageSampling::kMipmapLinear,
nullptr);
641 builder.SaveLayer(std::nullopt, &save_paint);
643 builder.DrawImage(src_image,
DlPoint(400, 0),
644 DlImageSampling::kMipmapLinear,
nullptr);
651 return builder.Build();
654#define BLEND_MODE_TEST(blend_mode) \
655 TEST_P(AiksTest, BlendMode##blend_mode) { \
657 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png")); \
659 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png")); \
660 auto callback = [&]() -> sk_sp<DisplayList> { \
661 return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
662 src_image, dst_image, 1.0); \
664 OpenPlaygroundHere(callback); \
668#define BLEND_MODE_SRC_ALPHA_TEST(blend_mode) \
669 TEST_P(AiksTest, BlendModeSrcAlpha##blend_mode) { \
671 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png")); \
673 DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png")); \
674 auto callback = [&]() -> sk_sp<DisplayList> { \
675 return BlendModeTest(GetContentScale(), BlendMode::k##blend_mode, \
676 src_image, dst_image, 0.5); \
678 OpenPlaygroundHere(callback); \
685 auto callback = [&]() -> sk_sp<DisplayList> {
687 static Color foreground = Color::Color::OrangeRed().
WithAlpha(0.5);
688 static int current_blend_index = 3;
691 ImGuiWindowFlags_AlwaysAutoResize)) {
692 ImGui::ColorEdit4(
"Background",
reinterpret_cast<float*
>(&background));
693 ImGui::ColorEdit4(
"Foreground",
reinterpret_cast<float*
>(&foreground));
694 ImGui::ListBox(
"Blend mode", ¤t_blend_index,
695 modes.blend_mode_names.data(),
696 modes.blend_mode_names.size());
701 builder.
Scale(0.2, 0.2);
709 return builder.
Build();
711 ASSERT_TRUE(OpenPlaygroundHere(
callback));
715 auto texture = CreateTextureForFixture(
"airplane.jpg",
723 DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
724 DlBlendMode::kSrcIn));
727 DlImageSampling::kMipmapLinear, &image_paint);
729 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
733 auto texture = CreateTextureForFixture(
"airplane.jpg",
741 DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
742 DlBlendMode::kColorDodge));
745 DlImageSampling::kMipmapLinear, &image_paint);
747 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
751 auto texture = CreateTextureForFixture(
"airplane.jpg",
760 DlColor::RGBA(169.0f / 255.0f, 169.0f / 255.0f, 169.0f / 255.0f, 1.0f));
762 builder.
Scale(0.4, 0.4);
768 DlImageSampling::kMipmapLinear, &image_paint);
770 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
781 auto color_wheel_sampler = [](
Radians r) {
785 auto color_cycle = [](
Scalar x) {
786 Scalar cycle = std::fmod(
x, 6.0f);
787 return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
789 return Color(color_cycle(6 *
x + 1),
790 color_cycle(6 *
x - 1),
791 color_cycle(6 *
x - 3),
800 const int max_dist = 900;
801 for (
int i = 0;
i <= 900;
i++) {
804 Scalar normalized_distance =
static_cast<Scalar>(
i) / max_dist;
806 auto color = color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
808 DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
810 -distance * std::cos(r.
radians));
812 builder.DrawCircle(position, 9 + normalized_distance * 3, paint);
816 auto callback = [&]() -> sk_sp<DisplayList> {
818 static bool cache_the_wheel =
true;
819 static int current_blend_index = 3;
820 static float dst_alpha = 1;
821 static float src_alpha = 1;
827 ImGuiWindowFlags_AlwaysAutoResize)) {
828 ImGui::Checkbox(
"Cache the wheel", &cache_the_wheel);
829 ImGui::ListBox(
"Blending mode", ¤t_blend_index,
832 ImGui::SliderFloat(
"Source alpha", &src_alpha, 0, 1);
833 ImGui::ColorEdit4(
"Color A",
reinterpret_cast<float*
>(&color0));
834 ImGui::ColorEdit4(
"Color B",
reinterpret_cast<float*
>(&color1));
835 ImGui::ColorEdit4(
"Color C",
reinterpret_cast<float*
>(&color2));
836 ImGui::SliderFloat(
"Destination alpha", &dst_alpha, 0, 1);
851 builder.
SaveLayer(std::nullopt,
nullptr);
852 builder.
Scale(GetContentScale().
x, GetContentScale().
y);
855 draw_color_wheel(builder);
860 builder.
Scale(GetContentScale().
x, GetContentScale().
y);
869 builder.
SaveLayer(std::nullopt, &save_paint);
884 return builder.
Build();
887 ASSERT_TRUE(OpenPlaygroundHere(
callback));
900 builder.
SaveLayer(std::nullopt, &save_paint);
904 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
915 DlBlendMode::kSaturation));
916 builder.
SaveLayer(std::nullopt, &save_paint);
924 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
938 .setBlendMode(DlBlendMode::kDifference));
944 ASSERT_TRUE(OpenPlaygroundHere(builder.
Build()));
#define BLEND_MODE_TUPLE(blend_mode)
#define BLEND_MODE_SRC_ALPHA_TEST(blend_mode)
#define BLEND_MODE_TEST(blend_mode)
void ClipRect(const DlRect &rect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast) override
void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr) override
void DrawCircle(const DlPoint ¢er, DlScalar radius, const DlPaint &paint) override
void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt) override
void Rotate(DlScalar degrees) override
void Scale(DlScalar sx, DlScalar sy) override
void Translate(DlScalar tx, DlScalar ty) override
void DrawPaint(const DlPaint &paint) override
sk_sp< DisplayList > Build()
void DrawRect(const DlRect &rect, const DlPaint &paint) override
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
static std::shared_ptr< const DlColorFilter > MakeBlend(DlColor color, DlBlendMode mode)
static std::shared_ptr< DlColorSource > MakeLinear(const DlPoint start_point, const DlPoint end_point, uint32_t stop_count, const DlColor *colors, const float *stops, DlTileMode tile_mode, const DlMatrix *matrix=nullptr)
DlPaint & setColor(DlColor color)
DlPaint & setBlendMode(DlBlendMode mode)
DlPaint & setMaskFilter(std::nullptr_t filter)
DlPaint & setOpacity(DlScalar opacity)
DlPaint & setColorFilter(std::nullptr_t filter)
DlPaint & setColorSource(std::nullptr_t source)
static bool ImGuiBegin(const char *name, bool *p_open, ImGuiWindowFlags flags)
static sk_sp< DlImageImpeller > Make(std::shared_ptr< Texture > texture, OwningContext owning_context=OwningContext::kIO)
static constexpr BlendMode kLastAdvancedBlendMode
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
FlutterDesktopBinaryReply callback
#define FLT_FORWARD(mock, real, method)
DEF_SWITCHES_START aot vmservice shared library name
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
static sk_sp< DisplayList > BlendModeTest(Vector2 content_scale, BlendMode blend_mode, const sk_sp< DlImageImpeller > &src_image, const sk_sp< DlImageImpeller > &dst_image, Scalar src_alpha)
TEST_P(AiksTest, DrawAtlasNoColor)
static BlendModeSelection GetBlendModeSelection()
static constexpr DlColor kWhite()
static constexpr DlColor kBlue()
static constexpr DlColor RGBA(DlScalar r, DlScalar g, DlScalar b, DlScalar a)
Construct a 32 bit color from floating point R, G, B, and A color channels.
static constexpr DlColor kBlack()
static constexpr DlColor kMaroon()
static constexpr DlColor kTransparent()
static constexpr DlColor kRed()
static constexpr DlColor kGreen()
DlColor withAlpha(uint8_t alpha) const
uint32_t ToARGB() const
Convert to ARGB 32 bit color.
static constexpr Color LimeGreen()
static constexpr Color Black()
static constexpr Color CornflowerBlue()
static constexpr Color MediumTurquoise()
static constexpr Color White()
constexpr Color WithAlpha(Scalar new_alpha) const
static constexpr Color OrangeRed()
Color Blend(Color source, BlendMode blend_mode) const
Blends an unpremultiplied destination color into a given unpremultiplied source color to form a new u...
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeScale(const Vector3 &s)
static constexpr TRect MakeWH(Type width, Type height)
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
std::vector< BlendMode > blend_mode_values
std::vector< const char * > blend_mode_names