Reverts "[Impeller] adds a plus advanced blend for f16 pixel formats (#51589)" (flutter/engine#51741)

Reverts: flutter/engine#51589
Initiated by: jonahwilliams
Reason for reverting: draw vertices devicelab test is crashing due to SIGABRT in blend contents

![image](https://github.com/flutter/engine/assets/8975114/8bfaec63-29e9-43c2-8954-181d0ad1c413)

Original PR Author: gaaclarke

Reviewed By: {jonahwilliams}

This change reverts the following previous change:
fixes https://github.com/flutter/flutter/issues/142549

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
auto-submit[bot] 2024-03-28 05:41:48 +00:00 committed by GitHub
parent 4a3619cc21
commit ebe91c2a5c
30 changed files with 178 additions and 363 deletions

View File

@ -115,7 +115,7 @@ sk_sp<DlImage> DlMetalSurfaceProvider::MakeImpellerImage(
void DlMetalSurfaceProvider::InitScreenShotter() const {
if (!snapshotter_) {
snapshotter_.reset(new MetalScreenshotter(/*enable_wide_gamut=*/false));
snapshotter_.reset(new MetalScreenshotter());
auto typographer = impeller::TypographerContextSkia::Make();
aiks_context_.reset(new impeller::AiksContext(
snapshotter_->GetPlayground().GetContext(), typographer));

View File

@ -1102,76 +1102,6 @@ TEST_P(AiksTest, PaintBlendModeIsRespected) {
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
// This makes sure the WideGamut named tests use 16bit float pixel format.
TEST_P(AiksTest, F16WideGamut) {
if (GetParam() != PlaygroundBackend::kMetal) {
GTEST_SKIP_("This backend doesn't yet support wide gamut.");
}
EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
PixelFormat::kR16G16B16A16Float);
EXPECT_FALSE(IsAlphaClampedToOne(
GetContext()->GetCapabilities()->GetDefaultColorFormat()));
}
TEST_P(AiksTest, NotF16) {
EXPECT_TRUE(IsAlphaClampedToOne(
GetContext()->GetCapabilities()->GetDefaultColorFormat()));
}
// Bug: https://github.com/flutter/flutter/issues/142549
TEST_P(AiksTest, BlendModePlusAlphaWideGamut) {
if (GetParam() != PlaygroundBackend::kMetal) {
GTEST_SKIP_("This backend doesn't yet support wide gamut.");
}
EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
PixelFormat::kR16G16B16A16Float);
auto texture = CreateTextureForFixture("airplane.jpg",
/*enable_mipmapping=*/true);
Canvas canvas;
canvas.Scale(GetContentScale());
canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)});
canvas.SaveLayer({});
Paint paint;
paint.blend_mode = BlendMode::kPlus;
paint.color = Color::Red();
canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
paint.color = Color::White();
canvas.DrawImageRect(
std::make_shared<Image>(texture), Rect::MakeSize(texture->GetSize()),
Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint);
canvas.Restore();
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
// Bug: https://github.com/flutter/flutter/issues/142549
TEST_P(AiksTest, BlendModePlusAlphaColorFilterWideGamut) {
if (GetParam() != PlaygroundBackend::kMetal) {
GTEST_SKIP_("This backend doesn't yet support wide gamut.");
}
EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
PixelFormat::kR16G16B16A16Float);
auto texture = CreateTextureForFixture("airplane.jpg",
/*enable_mipmapping=*/true);
Canvas canvas;
canvas.Scale(GetContentScale());
canvas.DrawPaint({.color = Color(0.1, 0.2, 0.1, 1.0)});
canvas.SaveLayer({
.color_filter =
ColorFilter::MakeBlend(BlendMode::kPlus, Color(Vector4{1, 0, 0, 1})),
});
Paint paint;
paint.color = Color::Red();
canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
paint.color = Color::White();
canvas.DrawImageRect(
std::make_shared<Image>(texture), Rect::MakeSize(texture->GetSize()),
Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint);
canvas.Restore();
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
}
TEST_P(AiksTest, ColorWheel) {
// Compare with https://fiddle.skia.org/c/@BlendModes

View File

@ -46,12 +46,4 @@ f16vec4 IPHalfPremultiply(f16vec4 color) {
return f16vec4(color.rgb * color.a, color.a);
}
/// Performs the plus blend on `src` and `dst` which are premultiplied colors.
//`max` determines the values the results are clamped to.
f16vec4 IPHalfPlusBlend(f16vec4 src, f16vec4 dst) {
float16_t min = 0.0hf;
float16_t max = 1.0hf;
return clamp(dst + src, min, max);
}
#endif

View File

@ -138,14 +138,6 @@ constexpr bool IsStencilWritable(PixelFormat format) {
}
}
/// Returns `true` if the pixel format has an implicit `clamp(x, 0, 1)` in the
/// pixel format. This is important for example when performing the `Plus` blend
/// where we don't want alpha values over 1.0.
constexpr bool IsAlphaClampedToOne(PixelFormat pixel_format) {
return !(pixel_format == PixelFormat::kR32G32B32A32Float ||
pixel_format == PixelFormat::kR16G16B16A16Float);
}
constexpr const char* PixelFormatToString(PixelFormat format) {
switch (format) {
case PixelFormat::kUnknown:

View File

@ -124,8 +124,6 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
break;
case BlendMode::kPlus:
// The kPlusAdvanced should be used instead.
FML_DCHECK(IsAlphaClampedToOne(color_attachment_pixel_format));
color0.dst_alpha_blend_factor = BlendFactor::kOne;
color0.dst_color_blend_factor = BlendFactor::kOne;
color0.src_alpha_blend_factor = BlendFactor::kOne;
@ -326,10 +324,6 @@ ContentContext::ContentContext(
framebuffer_blend_lighten_pipelines_.CreateDefault(
*context_, options_trianglestrip,
{static_cast<Scalar>(BlendSelectValues::kLighten), supports_decal});
framebuffer_blend_plus_advanced_pipelines_.CreateDefault(
*context_, options_trianglestrip,
{static_cast<Scalar>(BlendSelectValues::kPlusAdvanced),
supports_decal});
framebuffer_blend_luminosity_pipelines_.CreateDefault(
*context_, options_trianglestrip,
{static_cast<Scalar>(BlendSelectValues::kLuminosity), supports_decal});
@ -377,9 +371,6 @@ ContentContext::ContentContext(
blend_lighten_pipelines_.CreateDefault(
*context_, options_trianglestrip,
{static_cast<Scalar>(BlendSelectValues::kLighten), supports_decal});
blend_plus_advanced_pipelines_.CreateDefault(
*context_, options_trianglestrip,
{static_cast<Scalar>(BlendSelectValues::kPlusAdvanced), supports_decal});
blend_luminosity_pipelines_.CreateDefault(
*context_, options_trianglestrip,
{static_cast<Scalar>(BlendSelectValues::kLuminosity), supports_decal});

View File

@ -197,8 +197,6 @@ using BlendHuePipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendLightenPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendPlusAdvancedPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendLuminosityPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendMultiplyPipeline =
@ -239,9 +237,6 @@ using FramebufferBlendHuePipeline =
using FramebufferBlendLightenPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendPlusAdvancedPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendLuminosityPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
@ -645,11 +640,6 @@ class ContentContext {
return GetPipeline(blend_lighten_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendPlusAdvancedPipeline(
ContentContextOptions opts) const {
return GetPipeline(blend_plus_advanced_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendLuminosityPipeline(
ContentContextOptions opts) const {
return GetPipeline(blend_luminosity_pipelines_, opts);
@ -735,12 +725,6 @@ class ContentContext {
return GetPipeline(framebuffer_blend_lighten_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendPlusAdvancedPipeline(ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_plus_advanced_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
@ -1005,7 +989,6 @@ class ContentContext {
mutable Variants<BlendHardLightPipeline> blend_hardlight_pipelines_;
mutable Variants<BlendHuePipeline> blend_hue_pipelines_;
mutable Variants<BlendLightenPipeline> blend_lighten_pipelines_;
mutable Variants<BlendPlusAdvancedPipeline> blend_plus_advanced_pipelines_;
mutable Variants<BlendLuminosityPipeline> blend_luminosity_pipelines_;
mutable Variants<BlendMultiplyPipeline> blend_multiply_pipelines_;
mutable Variants<BlendOverlayPipeline> blend_overlay_pipelines_;
@ -1031,8 +1014,6 @@ class ContentContext {
framebuffer_blend_hue_pipelines_;
mutable Variants<FramebufferBlendLightenPipeline>
framebuffer_blend_lighten_pipelines_;
mutable Variants<FramebufferBlendPlusAdvancedPipeline>
framebuffer_blend_plus_advanced_pipelines_;
mutable Variants<FramebufferBlendLuminosityPipeline>
framebuffer_blend_luminosity_pipelines_;
mutable Variants<FramebufferBlendMultiplyPipeline>

View File

@ -338,9 +338,6 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
case BlendMode::kColor:
pass.SetPipeline(renderer.GetBlendColorPipeline(options));
break;
case BlendMode::kPlusAdvanced:
pass.SetPipeline(renderer.GetBlendPlusAdvancedPipeline(options));
break;
case BlendMode::kLuminosity:
pass.SetPipeline(renderer.GetBlendLuminosityPipeline(options));
break;
@ -586,7 +583,6 @@ void BlendFilterContents::SetBlendMode(BlendMode blend_mode) {
BLEND_CASE(Hue)
BLEND_CASE(Saturation)
BLEND_CASE(Color)
BLEND_CASE(PlusAdvanced)
BLEND_CASE(Luminosity)
default:
FML_UNREACHABLE();
@ -615,26 +611,19 @@ std::optional<Entity> BlendFilterContents::RenderFilter(
std::nullopt, GetAbsorbOpacity(), GetAlpha());
}
BlendMode blend_mode = blend_mode_;
if (blend_mode == BlendMode::kPlus &&
!IsAlphaClampedToOne(
renderer.GetContext()->GetCapabilities()->GetDefaultColorFormat())) {
blend_mode = BlendMode::kPlusAdvanced;
}
if (blend_mode <= Entity::kLastPipelineBlendMode) {
return PipelineBlend(inputs, renderer, entity, coverage, blend_mode,
if (blend_mode_ <= Entity::kLastPipelineBlendMode) {
return PipelineBlend(inputs, renderer, entity, coverage, blend_mode_,
foreground_color_, GetAbsorbOpacity(), GetAlpha());
}
if (blend_mode <= Entity::kLastAdvancedBlendMode) {
if (blend_mode_ <= Entity::kLastAdvancedBlendMode) {
if (inputs.size() == 1 && foreground_color_.has_value() &&
GetAbsorbOpacity() == ColorFilterContents::AbsorbOpacity::kYes) {
return CreateForegroundAdvancedBlend(
inputs[0], renderer, entity, coverage, foreground_color_.value(),
blend_mode, GetAlpha(), GetAbsorbOpacity());
blend_mode_, GetAlpha(), GetAbsorbOpacity());
}
return advanced_blend_proc_(inputs, renderer, entity, coverage, blend_mode,
return advanced_blend_proc_(inputs, renderer, entity, coverage, blend_mode_,
foreground_color_, GetAbsorbOpacity(),
GetAlpha());
}

View File

@ -118,10 +118,6 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer,
case BlendMode::kColor:
pass.SetPipeline(renderer.GetFramebufferBlendColorPipeline(options));
break;
case BlendMode::kPlusAdvanced:
pass.SetPipeline(
renderer.GetFramebufferBlendPlusAdvancedPipeline(options));
break;
case BlendMode::kLuminosity:
pass.SetPipeline(renderer.GetFramebufferBlendLuminosityPipeline(options));
break;

View File

@ -27,7 +27,6 @@ enum class BlendSelectValues {
kHue,
kSaturation,
kColor,
kPlusAdvanced,
kLuminosity,
};

View File

@ -970,13 +970,6 @@ bool EntityPass::OnRender(
/// Setup advanced blends.
///
if (result.entity.GetBlendMode() == BlendMode::kPlus &&
!IsAlphaClampedToOne(pass_context.GetPassTarget()
.GetRenderTarget()
.GetRenderTargetPixelFormat())) {
result.entity.SetBlendMode(BlendMode::kPlusAdvanced);
}
if (result.entity.GetBlendMode() > Entity::kLastPipelineBlendMode) {
if (renderer.GetDeviceCapabilities().SupportsFramebufferFetch()) {
auto src_contents = result.entity.GetContents();

View File

@ -36,33 +36,22 @@ f16vec4 Sample(f16sampler2D texture_sampler, vec2 texture_coords) {
}
void main() {
f16vec4 premultiplied_dst =
Sample(texture_sampler_dst, // sampler
v_dst_texture_coords // texture coordinates
);
int nblend_type = int(blend_type);
if (nblend_type == /*BlendSelectValues::kPlusAdvanced*/ 14) {
f16vec4 premultiplied_src =
Sample(texture_sampler_src, // sampler
v_src_texture_coords // texture coordinates
);
frag_color = IPHalfPlusBlend(premultiplied_src, premultiplied_dst);
} else {
f16vec4 dst = IPHalfUnpremultiply(premultiplied_dst);
dst *= blend_info.dst_input_alpha;
f16vec4 src = blend_info.color_factor > 0.0hf
? blend_info.color
: IPHalfUnpremultiply(Sample(
texture_sampler_src, // sampler
v_src_texture_coords // texture coordinates
));
if (blend_info.color_factor == 0.0hf) {
src.a *= blend_info.src_input_alpha;
}
f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, nblend_type);
frag_color = IPApplyBlendedColor(dst, src, blend_result);
f16vec4 dst =
IPHalfUnpremultiply(Sample(texture_sampler_dst, // sampler
v_dst_texture_coords // texture coordinates
));
dst *= blend_info.dst_input_alpha;
f16vec4 src = blend_info.color_factor > 0.0hf
? blend_info.color
: IPHalfUnpremultiply(Sample(
texture_sampler_src, // sampler
v_src_texture_coords // texture coordinates
));
if (blend_info.color_factor == 0.0hf) {
src.a *= blend_info.src_input_alpha;
}
f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type));
frag_color = IPApplyBlendedColor(dst, src, blend_result);
}

View File

@ -20,7 +20,6 @@
// kHue,
// kSaturation,
// kColor,
// kPlusAdvanced,
// kLuminosity,
// Note, this isn't a switch as GLSL ES 1.0 does not support them.
f16vec3 AdvancedBlend(f16vec3 dst, f16vec3 src, int blend_type) {
@ -66,9 +65,7 @@ f16vec3 AdvancedBlend(f16vec3 dst, f16vec3 src, int blend_type) {
if (blend_type == 13) {
return IPBlendColor(dst, src);
}
// 14 is `PlusAdvanced`, it's handled in advanced_blend.frag and
// framebuffer_blend.frag.
if (blend_type == 15) {
if (blend_type == 14) {
return IPBlendLuminosity(dst, src);
}
return f16vec3(0.0hf);

View File

@ -43,21 +43,14 @@ vec4 Sample(sampler2D texture_sampler, vec2 texture_coords) {
}
void main() {
f16vec4 premultiplied_dst = f16vec4(ReadDestination());
f16vec4 premultiplied_src =
f16vec4 dst = IPHalfUnpremultiply(f16vec4(ReadDestination()));
f16vec4 src = IPHalfUnpremultiply(
f16vec4(Sample(texture_sampler_src, // sampler
v_src_texture_coords // texture coordinates
));
int nblend_type = int(blend_type);
)));
src.a *= frag_info.src_input_alpha;
if (nblend_type == /*BlendSelectValues::kPlusAdvanced*/ 14) {
frag_color = IPHalfPlusBlend(premultiplied_src, premultiplied_dst);
} else {
f16vec4 dst = IPHalfUnpremultiply(premultiplied_dst);
f16vec4 src = IPHalfUnpremultiply(premultiplied_src);
src.a *= frag_info.src_input_alpha;
f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, int(blend_type));
f16vec3 blend_result = AdvancedBlend(dst.rgb, src.rgb, nblend_type);
frag_color = IPApplyBlendedColor(dst, src, blend_result);
}
frag_color = IPApplyBlendedColor(dst, src, blend_result);
}

View File

@ -276,8 +276,6 @@ Color Color::Blend(Color src, BlendMode blend_mode) const {
return (src.Premultiply() * (1 - dst.alpha) +
dst.Premultiply() * (1 - src.alpha))
.Unpremultiply();
case BlendMode::kPlusAdvanced:
[[fallthrough]];
case BlendMode::kPlus:
// r = min(s + d, 1)
return (Min(src.Premultiply() + dst.Premultiply(), 1)).Unpremultiply();

View File

@ -45,7 +45,6 @@
V(Hue) \
V(Saturation) \
V(Color) \
V(PlusAdvanced) \
V(Luminosity)
namespace impeller {
@ -92,7 +91,6 @@ enum class BlendMode : uint8_t {
kHue,
kSaturation,
kColor,
kPlusAdvanced,
kLuminosity,
kLast = kLuminosity,

View File

@ -6,7 +6,6 @@
#include "impeller/geometry/geometry_asserts.h"
#include <limits>
#include <map>
#include <sstream>
#include <type_traits>
@ -1451,112 +1450,107 @@ struct ColorBlendTestData {
Color::LimeGreen().WithAlpha(0.75),
Color::Black().WithAlpha(0.75)};
static const std::map<BlendMode, Color>
kExpectedResults[sizeof(kSourceColors)];
};
// THIS RESULT TABLE IS GENERATED!
//
// Uncomment the `GenerateColorBlendResults` test below to print a new table
// after making changes to `Color::Blend`.
const std::map<BlendMode, Color> ColorBlendTestData::kExpectedResults[sizeof(
ColorBlendTestData::kSourceColors)] = {
{
{BlendMode::kClear, {0, 0, 0, 0}},
{BlendMode::kSource, {1, 1, 1, 0.75}},
{BlendMode::kDestination, {0.392157, 0.584314, 0.929412, 0.75}},
{BlendMode::kSourceOver, {0.878431, 0.916863, 0.985882, 0.9375}},
{BlendMode::kDestinationOver, {0.513726, 0.667451, 0.943529, 0.9375}},
{BlendMode::kSourceIn, {1, 1, 1, 0.5625}},
{BlendMode::kDestinationIn, {0.392157, 0.584314, 0.929412, 0.5625}},
{BlendMode::kSourceOut, {1, 1, 1, 0.1875}},
{BlendMode::kDestinationOut, {0.392157, 0.584314, 0.929412, 0.1875}},
{BlendMode::kSourceATop, {0.848039, 0.896078, 0.982353, 0.75}},
{BlendMode::kDestinationATop, {0.544118, 0.688235, 0.947059, 0.75}},
{BlendMode::kXor, {0.696078, 0.792157, 0.964706, 0.375}},
{BlendMode::kPlus, {1, 1, 1, 1}},
{BlendMode::kModulate, {0.392157, 0.584314, 0.929412, 0.5625}},
{BlendMode::kScreen, {0.878431, 0.916863, 0.985882, 0.9375}},
{BlendMode::kOverlay, {0.74902, 0.916863, 0.985882, 0.9375}},
{BlendMode::kDarken, {0.513726, 0.667451, 0.943529, 0.9375}},
{BlendMode::kLighten, {0.878431, 0.916863, 0.985882, 0.9375}},
{BlendMode::kColorDodge, {0.878431, 0.916863, 0.985882, 0.9375}},
{BlendMode::kColorBurn, {0.513725, 0.667451, 0.943529, 0.9375}},
{BlendMode::kHardLight, {0.878431, 0.916863, 0.985882, 0.9375}},
{BlendMode::kSoftLight, {0.654166, 0.775505, 0.964318, 0.9375}},
{BlendMode::kDifference, {0.643137, 0.566275, 0.428235, 0.9375}},
{BlendMode::kExclusion, {0.643137, 0.566275, 0.428235, 0.9375}},
{BlendMode::kMultiply, {0.513726, 0.667451, 0.943529, 0.9375}},
{BlendMode::kHue, {0.617208, 0.655639, 0.724659, 0.9375}},
{BlendMode::kSaturation, {0.617208, 0.655639, 0.724659, 0.9375}},
{BlendMode::kColor, {0.617208, 0.655639, 0.724659, 0.9375}},
{BlendMode::kPlusAdvanced, {1, 1, 1, 1}},
{BlendMode::kLuminosity, {0.878431, 0.916863, 0.985882, 0.9375}},
},
{
{BlendMode::kClear, {0, 0, 0, 0}},
{BlendMode::kSource, {0.196078, 0.803922, 0.196078, 0.75}},
{BlendMode::kDestination, {0.392157, 0.584314, 0.929412, 0.75}},
{BlendMode::kSourceOver, {0.235294, 0.76, 0.342745, 0.9375}},
{BlendMode::kDestinationOver, {0.352941, 0.628235, 0.782745, 0.9375}},
{BlendMode::kSourceIn, {0.196078, 0.803922, 0.196078, 0.5625}},
{BlendMode::kDestinationIn, {0.392157, 0.584314, 0.929412, 0.5625}},
{BlendMode::kSourceOut, {0.196078, 0.803922, 0.196078, 0.1875}},
{BlendMode::kDestinationOut, {0.392157, 0.584314, 0.929412, 0.1875}},
{BlendMode::kSourceATop, {0.245098, 0.74902, 0.379412, 0.75}},
{BlendMode::kDestinationATop, {0.343137, 0.639216, 0.746078, 0.75}},
{BlendMode::kXor, {0.294118, 0.694118, 0.562745, 0.375}},
{BlendMode::kPlus, {0.441176, 1, 0.844118, 1}},
{BlendMode::kModulate, {0.0768935, 0.469742, 0.182238, 0.5625}},
{BlendMode::kScreen, {0.424452, 0.828743, 0.79105, 0.9375}},
{BlendMode::kOverlay, {0.209919, 0.779839, 0.757001, 0.9375}},
{BlendMode::kDarken, {0.235294, 0.628235, 0.342745, 0.9375}},
{BlendMode::kLighten, {0.352941, 0.76, 0.782745, 0.9375}},
{BlendMode::kColorDodge, {0.41033, 0.877647, 0.825098, 0.9375}},
{BlendMode::kColorBurn, {0.117647, 0.567403, 0.609098, 0.9375}},
{BlendMode::kHardLight, {0.209919, 0.779839, 0.443783, 0.9375}},
{BlendMode::kSoftLight, {0.266006, 0.693915, 0.758818, 0.9375}},
{BlendMode::kDifference, {0.235294, 0.409412, 0.665098, 0.9375}},
{BlendMode::kExclusion, {0.378316, 0.546897, 0.681707, 0.9375}},
{BlendMode::kMultiply, {0.163783, 0.559493, 0.334441, 0.9375}},
{BlendMode::kHue, {0.266235, 0.748588, 0.373686, 0.9375}},
{BlendMode::kSaturation, {0.339345, 0.629787, 0.811502, 0.9375}},
{BlendMode::kColor, {0.241247, 0.765953, 0.348698, 0.9375}},
{BlendMode::kPlusAdvanced, {0.441176, 1, 0.844118, 1}},
{BlendMode::kLuminosity, {0.346988, 0.622282, 0.776792, 0.9375}},
},
{
{BlendMode::kClear, {0, 0, 0, 0}},
{BlendMode::kSource, {0, 0, 0, 0.75}},
{BlendMode::kDestination, {0.392157, 0.584314, 0.929412, 0.75}},
{BlendMode::kSourceOver, {0.0784314, 0.116863, 0.185882, 0.9375}},
{BlendMode::kDestinationOver, {0.313726, 0.467451, 0.743529, 0.9375}},
{BlendMode::kSourceIn, {0, 0, 0, 0.5625}},
{BlendMode::kDestinationIn, {0.392157, 0.584314, 0.929412, 0.5625}},
{BlendMode::kSourceOut, {0, 0, 0, 0.1875}},
{BlendMode::kDestinationOut, {0.392157, 0.584314, 0.929412, 0.1875}},
{BlendMode::kSourceATop, {0.0980392, 0.146078, 0.232353, 0.75}},
{BlendMode::kDestinationATop, {0.294118, 0.438235, 0.697059, 0.75}},
{BlendMode::kXor, {0.196078, 0.292157, 0.464706, 0.375}},
{BlendMode::kPlus, {0.294118, 0.438235, 0.697059, 1}},
{BlendMode::kModulate, {0, 0, 0, 0.5625}},
{BlendMode::kScreen, {0.313726, 0.467451, 0.743529, 0.9375}},
{BlendMode::kOverlay, {0.0784314, 0.218039, 0.701176, 0.9375}},
{BlendMode::kDarken, {0.0784314, 0.116863, 0.185882, 0.9375}},
{BlendMode::kLighten, {0.313726, 0.467451, 0.743529, 0.9375}},
{BlendMode::kColorDodge, {0.313726, 0.467451, 0.743529, 0.9375}},
{BlendMode::kColorBurn, {0.0784314, 0.116863, 0.185882, 0.9375}},
{BlendMode::kHardLight, {0.0784314, 0.116863, 0.185882, 0.9375}},
{BlendMode::kSoftLight, {0.170704, 0.321716, 0.704166, 0.9375}},
{BlendMode::kDifference, {0.313726, 0.467451, 0.743529, 0.9375}},
{BlendMode::kExclusion, {0.313726, 0.467451, 0.743529, 0.9375}},
{BlendMode::kMultiply, {0.0784314, 0.116863, 0.185882, 0.9375}},
{BlendMode::kHue, {0.417208, 0.455639, 0.524659, 0.9375}},
{BlendMode::kSaturation, {0.417208, 0.455639, 0.524659, 0.9375}},
{BlendMode::kColor, {0.417208, 0.455639, 0.524659, 0.9375}},
{BlendMode::kPlusAdvanced, {0.294118, 0.438235, 0.697059, 1}},
{BlendMode::kLuminosity, {0.0784314, 0.116863, 0.185882, 0.9375}},
},
// THIS RESULT TABLE IS GENERATED!
//
// Uncomment the `GenerateColorBlendResults` test below to print a new table
// after making changes to `Color::Blend`.
static constexpr Color kExpectedResults
[sizeof(kSourceColors)]
[static_cast<std::underlying_type_t<BlendMode>>(BlendMode::kLast) + 1] = {
{
{0, 0, 0, 0}, // Clear
{1, 1, 1, 0.75}, // Source
{0.392157, 0.584314, 0.929412, 0.75}, // Destination
{0.878431, 0.916863, 0.985882, 0.9375}, // SourceOver
{0.513726, 0.667451, 0.943529, 0.9375}, // DestinationOver
{1, 1, 1, 0.5625}, // SourceIn
{0.392157, 0.584314, 0.929412, 0.5625}, // DestinationIn
{1, 1, 1, 0.1875}, // SourceOut
{0.392157, 0.584314, 0.929412, 0.1875}, // DestinationOut
{0.848039, 0.896078, 0.982353, 0.75}, // SourceATop
{0.544118, 0.688235, 0.947059, 0.75}, // DestinationATop
{0.696078, 0.792157, 0.964706, 0.375}, // Xor
{1, 1, 1, 1}, // Plus
{0.392157, 0.584314, 0.929412, 0.5625}, // Modulate
{0.878431, 0.916863, 0.985882, 0.9375}, // Screen
{0.74902, 0.916863, 0.985882, 0.9375}, // Overlay
{0.513726, 0.667451, 0.943529, 0.9375}, // Darken
{0.878431, 0.916863, 0.985882, 0.9375}, // Lighten
{0.878431, 0.916863, 0.985882, 0.9375}, // ColorDodge
{0.513725, 0.667451, 0.943529, 0.9375}, // ColorBurn
{0.878431, 0.916863, 0.985882, 0.9375}, // HardLight
{0.654166, 0.775505, 0.964318, 0.9375}, // SoftLight
{0.643137, 0.566275, 0.428235, 0.9375}, // Difference
{0.643137, 0.566275, 0.428235, 0.9375}, // Exclusion
{0.513726, 0.667451, 0.943529, 0.9375}, // Multiply
{0.617208, 0.655639, 0.724659, 0.9375}, // Hue
{0.617208, 0.655639, 0.724659, 0.9375}, // Saturation
{0.617208, 0.655639, 0.724659, 0.9375}, // Color
{0.878431, 0.916863, 0.985882, 0.9375}, // Luminosity
},
{
{0, 0, 0, 0}, // Clear
{0.196078, 0.803922, 0.196078, 0.75}, // Source
{0.392157, 0.584314, 0.929412, 0.75}, // Destination
{0.235294, 0.76, 0.342745, 0.9375}, // SourceOver
{0.352941, 0.628235, 0.782745, 0.9375}, // DestinationOver
{0.196078, 0.803922, 0.196078, 0.5625}, // SourceIn
{0.392157, 0.584314, 0.929412, 0.5625}, // DestinationIn
{0.196078, 0.803922, 0.196078, 0.1875}, // SourceOut
{0.392157, 0.584314, 0.929412, 0.1875}, // DestinationOut
{0.245098, 0.74902, 0.379412, 0.75}, // SourceATop
{0.343137, 0.639216, 0.746078, 0.75}, // DestinationATop
{0.294118, 0.694118, 0.562745, 0.375}, // Xor
{0.441176, 1, 0.844118, 1}, // Plus
{0.0768935, 0.469742, 0.182238, 0.5625}, // Modulate
{0.424452, 0.828743, 0.79105, 0.9375}, // Screen
{0.209919, 0.779839, 0.757001, 0.9375}, // Overlay
{0.235294, 0.628235, 0.342745, 0.9375}, // Darken
{0.352941, 0.76, 0.782745, 0.9375}, // Lighten
{0.41033, 0.877647, 0.825098, 0.9375}, // ColorDodge
{0.117647, 0.567403, 0.609098, 0.9375}, // ColorBurn
{0.209919, 0.779839, 0.443783, 0.9375}, // HardLight
{0.266006, 0.693915, 0.758818, 0.9375}, // SoftLight
{0.235294, 0.409412, 0.665098, 0.9375}, // Difference
{0.378316, 0.546897, 0.681707, 0.9375}, // Exclusion
{0.163783, 0.559493, 0.334441, 0.9375}, // Multiply
{0.266235, 0.748588, 0.373686, 0.9375}, // Hue
{0.339345, 0.629787, 0.811502, 0.9375}, // Saturation
{0.241247, 0.765953, 0.348698, 0.9375}, // Color
{0.346988, 0.622282, 0.776792, 0.9375}, // Luminosity
},
{
{0, 0, 0, 0}, // Clear
{0, 0, 0, 0.75}, // Source
{0.392157, 0.584314, 0.929412, 0.75}, // Destination
{0.0784314, 0.116863, 0.185882, 0.9375}, // SourceOver
{0.313726, 0.467451, 0.743529, 0.9375}, // DestinationOver
{0, 0, 0, 0.5625}, // SourceIn
{0.392157, 0.584314, 0.929412, 0.5625}, // DestinationIn
{0, 0, 0, 0.1875}, // SourceOut
{0.392157, 0.584314, 0.929412, 0.1875}, // DestinationOut
{0.0980392, 0.146078, 0.232353, 0.75}, // SourceATop
{0.294118, 0.438235, 0.697059, 0.75}, // DestinationATop
{0.196078, 0.292157, 0.464706, 0.375}, // Xor
{0.294118, 0.438235, 0.697059, 1}, // Plus
{0, 0, 0, 0.5625}, // Modulate
{0.313726, 0.467451, 0.743529, 0.9375}, // Screen
{0.0784314, 0.218039, 0.701176, 0.9375}, // Overlay
{0.0784314, 0.116863, 0.185882, 0.9375}, // Darken
{0.313726, 0.467451, 0.743529, 0.9375}, // Lighten
{0.313726, 0.467451, 0.743529, 0.9375}, // ColorDodge
{0.0784314, 0.116863, 0.185882, 0.9375}, // ColorBurn
{0.0784314, 0.116863, 0.185882, 0.9375}, // HardLight
{0.170704, 0.321716, 0.704166, 0.9375}, // SoftLight
{0.313726, 0.467451, 0.743529, 0.9375}, // Difference
{0.313726, 0.467451, 0.743529, 0.9375}, // Exclusion
{0.0784314, 0.116863, 0.185882, 0.9375}, // Multiply
{0.417208, 0.455639, 0.524659, 0.9375}, // Hue
{0.417208, 0.455639, 0.524659, 0.9375}, // Saturation
{0.417208, 0.455639, 0.524659, 0.9375}, // Color
{0.0784314, 0.116863, 0.185882, 0.9375}, // Luminosity
},
};
};
/// To print a new ColorBlendTestData::kExpectedResults table, uncomment this
@ -1573,10 +1567,8 @@ TEST(GeometryTest, GenerateColorBlendResults) {
blend_i < static_cast<BlendT>(BlendMode::kLast) + 1; blend_i++) {
auto blend = static_cast<BlendMode>(blend_i);
Color c = ColorBlendTestData::kDestinationColor.Blend(source, blend);
o << "{ BlendMode::k" << BlendModeToString(blend) << ", ";
o << "{" << c.red << "," << c.green << "," << c.blue << "," << c.alpha
<< "}";
o << "}," << std::endl;
<< "}, // " << BlendModeToString(blend) << std::endl;
}
o << "},";
}
@ -1584,19 +1576,20 @@ TEST(GeometryTest, GenerateColorBlendResults) {
}
*/
#define _BLEND_MODE_RESULT_CHECK(blend_mode) \
expected = ColorBlendTestData::kExpectedResults[source_i] \
.find(BlendMode::k##blend_mode) \
->second; \
#define _BLEND_MODE_RESULT_CHECK(blend_mode) \
blend_i = static_cast<BlendT>(BlendMode::k##blend_mode); \
expected = ColorBlendTestData::kExpectedResults[source_i][blend_i]; \
EXPECT_COLOR_NEAR(dst.Blend(src, BlendMode::k##blend_mode), expected);
TEST(GeometryTest, ColorBlendReturnsExpectedResults) {
using BlendT = std::underlying_type_t<BlendMode>;
Color dst = ColorBlendTestData::kDestinationColor;
for (size_t source_i = 0;
source_i < sizeof(ColorBlendTestData::kSourceColors) / sizeof(Color);
source_i++) {
Color src = ColorBlendTestData::kSourceColors[source_i];
size_t blend_i;
Color expected;
IMPELLER_FOR_EACH_BLEND_MODE(_BLEND_MODE_RESULT_CHECK)
}

View File

@ -138,12 +138,9 @@ void GoldenPlaygroundTest::SetUp() {
std::filesystem::path icd_path = target_path / "vk_swiftshader_icd.json";
setenv("VK_ICD_FILENAMES", icd_path.c_str(), 1);
std::string test_name = GetTestName();
bool enable_wide_gamut = test_name.find("WideGamut_") != std::string::npos;
switch (GetParam()) {
case PlaygroundBackend::kMetal:
pimpl_->screenshotter =
std::make_unique<testing::MetalScreenshotter>(enable_wide_gamut);
pimpl_->screenshotter = std::make_unique<testing::MetalScreenshotter>();
break;
case PlaygroundBackend::kVulkan: {
const std::unique_ptr<PlaygroundImpl>& playground =
@ -163,7 +160,16 @@ void GoldenPlaygroundTest::SetUp() {
break;
}
}
if (GetParam() == PlaygroundBackend::kMetal) {
pimpl_->screenshotter = std::make_unique<testing::MetalScreenshotter>();
} else if (GetParam() == PlaygroundBackend::kVulkan) {
const std::unique_ptr<PlaygroundImpl>& playground =
GetSharedVulkanPlayground(/*enable_validations=*/true);
pimpl_->screenshotter =
std::make_unique<testing::VulkanScreenshotter>(playground);
}
std::string test_name = GetTestName();
if (std::find(kSkipTests.begin(), kSkipTests.end(), test_name) !=
kSkipTests.end()) {
GTEST_SKIP_(

View File

@ -50,8 +50,7 @@ bool SaveScreenshot(std::unique_ptr<Screenshot> screenshot) {
class GoldenTests : public ::testing::Test {
public:
GoldenTests()
: screenshotter_(new MetalScreenshotter(/*enable_wide_gamut=*/false)) {}
GoldenTests() : screenshotter_(new MetalScreenshotter()) {}
MetalScreenshotter& Screenshotter() { return *screenshotter_; }

View File

@ -18,7 +18,7 @@ namespace testing {
/// playground backend.
class MetalScreenshotter : public Screenshotter {
public:
explicit MetalScreenshotter(bool enable_wide_gamut);
MetalScreenshotter();
std::unique_ptr<Screenshot> MakeScreenshot(
AiksContext& aiks_context,

View File

@ -13,11 +13,10 @@
namespace impeller {
namespace testing {
MetalScreenshotter::MetalScreenshotter(bool enable_wide_gamut) {
MetalScreenshotter::MetalScreenshotter() {
FML_CHECK(::glfwInit() == GLFW_TRUE);
PlaygroundSwitches switches;
switches.enable_wide_gamut = enable_wide_gamut;
playground_ = PlaygroundImpl::Create(PlaygroundBackend::kMetal, switches);
playground_ =
PlaygroundImpl::Create(PlaygroundBackend::kMetal, PlaygroundSwitches{});
}
std::unique_ptr<Screenshot> MetalScreenshotter::MakeScreenshot(
@ -34,6 +33,10 @@ std::unique_ptr<Screenshot> MetalScreenshotter::MakeScreenshot(
id<MTLTexture> metal_texture =
std::static_pointer_cast<TextureMTL>(texture)->GetMTLTexture();
if (metal_texture.pixelFormat != MTLPixelFormatBGRA8Unorm) {
return {};
}
CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
CIImage* ciImage = [[CIImage alloc]
initWithMTLTexture:metal_texture

View File

@ -73,12 +73,9 @@ PlaygroundImplMTL::PlaygroundImplMTL(PlaygroundSwitches switches)
if (!window) {
return;
}
auto context = ContextMTL::Create(
ShaderLibraryMappingsForPlayground(), is_gpu_disabled_sync_switch_,
"Playground Library",
switches.enable_wide_gamut
? std::optional<PixelFormat>(PixelFormat::kR16G16B16A16Float)
: std::nullopt);
auto context =
ContextMTL::Create(ShaderLibraryMappingsForPlayground(),
is_gpu_disabled_sync_switch_, "Playground Library");
if (!context) {
return;
}

View File

@ -25,7 +25,7 @@ void ComputePlaygroundTest::SetUp() {
return;
}
SetupContext(GetParam(), switches_);
SetupContext(GetParam());
SetupWindow();
start_time_ = fml::TimePoint::Now().ToEpochDelta();

View File

@ -120,11 +120,10 @@ bool Playground::SupportsBackend(PlaygroundBackend backend) {
FML_UNREACHABLE();
}
void Playground::SetupContext(PlaygroundBackend backend,
const PlaygroundSwitches& switches) {
void Playground::SetupContext(PlaygroundBackend backend) {
FML_CHECK(SupportsBackend(backend));
impl_ = PlaygroundImpl::Create(backend, switches);
impl_ = PlaygroundImpl::Create(backend, switches_);
if (!impl_) {
FML_LOG(WARNING) << "PlaygroundImpl::Create failed.";
return;

View File

@ -57,8 +57,7 @@ class Playground {
static bool ShouldOpenNewPlaygrounds();
void SetupContext(PlaygroundBackend backend,
const PlaygroundSwitches& switches);
void SetupContext(PlaygroundBackend backend);
void SetupWindow();

View File

@ -28,13 +28,7 @@ void PlaygroundTest::SetUp() {
ImpellerValidationErrorsSetFatal(true);
// Test names that end with "WideGamut" will render with wide gamut support.
std::string test_name = flutter::testing::GetCurrentTestName();
PlaygroundSwitches switches = switches_;
switches.enable_wide_gamut =
test_name.find("WideGamut/") != std::string::npos;
SetupContext(GetParam(), switches);
SetupContext(GetParam());
SetupWindow();
}

View File

@ -33,8 +33,6 @@ struct PlaygroundSwitches {
///
bool use_angle = false;
bool enable_wide_gamut = false;
PlaygroundSwitches();
explicit PlaygroundSwitches(const fml::CommandLine& args);

View File

@ -43,8 +43,7 @@ class ContextMTL final : public Context,
static std::shared_ptr<ContextMTL> Create(
const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data,
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
const std::string& label,
std::optional<PixelFormat> pixel_format_override = std::nullopt);
const std::string& label);
static std::shared_ptr<ContextMTL> Create(
id<MTLDevice> device,
@ -134,11 +133,11 @@ class ContextMTL final : public Context,
std::shared_ptr<CommandQueue> command_queue_ip_;
bool is_valid_ = false;
ContextMTL(id<MTLDevice> device,
id<MTLCommandQueue> command_queue,
NSArray<id<MTLLibrary>>* shader_libraries,
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
std::optional<PixelFormat> pixel_format_override = std::nullopt);
ContextMTL(
id<MTLDevice> device,
id<MTLCommandQueue> command_queue,
NSArray<id<MTLLibrary>>* shader_libraries,
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch);
std::shared_ptr<CommandBuffer> CreateCommandBufferInQueue(
id<MTLCommandQueue> queue) const;

View File

@ -75,8 +75,7 @@ ContextMTL::ContextMTL(
id<MTLDevice> device,
id<MTLCommandQueue> command_queue,
NSArray<id<MTLLibrary>>* shader_libraries,
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
std::optional<PixelFormat> pixel_format_override)
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch)
: device_(device),
command_queue_(command_queue),
is_gpu_disabled_sync_switch_(std::move(is_gpu_disabled_sync_switch)) {
@ -129,9 +128,7 @@ ContextMTL::ContextMTL(
}
device_capabilities_ =
InferMetalCapabilities(device_, pixel_format_override.has_value()
? pixel_format_override.value()
: PixelFormat::kB8G8R8A8UNormInt);
InferMetalCapabilities(device_, PixelFormat::kB8G8R8A8UNormInt);
command_queue_ip_ = std::make_shared<CommandQueue>();
#ifdef IMPELLER_DEBUG
gpu_tracer_ = std::make_shared<GPUTracerMTL>();
@ -241,18 +238,17 @@ std::shared_ptr<ContextMTL> ContextMTL::Create(
std::shared_ptr<ContextMTL> ContextMTL::Create(
const std::vector<std::shared_ptr<fml::Mapping>>& shader_libraries_data,
std::shared_ptr<const fml::SyncSwitch> is_gpu_disabled_sync_switch,
const std::string& library_label,
std::optional<PixelFormat> pixel_format_override) {
const std::string& library_label) {
auto device = CreateMetalDevice();
auto command_queue = CreateMetalCommandQueue(device);
if (!command_queue) {
return nullptr;
}
auto context = std::shared_ptr<ContextMTL>(new ContextMTL(
device, command_queue,
MTLShaderLibraryFromFileData(device, shader_libraries_data,
library_label),
std::move(is_gpu_disabled_sync_switch), pixel_format_override));
auto context = std::shared_ptr<ContextMTL>(
new ContextMTL(device, command_queue,
MTLShaderLibraryFromFileData(device, shader_libraries_data,
library_label),
std::move(is_gpu_disabled_sync_switch)));
if (!context->IsValid()) {
FML_LOG(ERROR) << "Could not create Metal context.";
return nullptr;

View File

@ -62,7 +62,6 @@ TEST_P(RuntimeStageTest, CanReadUniforms) {
ASSERT_TRUE(stage->IsValid());
switch (GetBackend()) {
case PlaygroundBackend::kMetal:
[[fallthrough]];
case PlaygroundBackend::kOpenGLES: {
ASSERT_EQ(stage->GetUniforms().size(), 17u);
{

View File

@ -57,11 +57,6 @@ impeller_Play_AiksTest_BlendModeMultiply_Vulkan.png
impeller_Play_AiksTest_BlendModeOverlay_Metal.png
impeller_Play_AiksTest_BlendModeOverlay_OpenGLES.png
impeller_Play_AiksTest_BlendModeOverlay_Vulkan.png
impeller_Play_AiksTest_BlendModePlusAdvanced_Metal.png
impeller_Play_AiksTest_BlendModePlusAdvanced_OpenGLES.png
impeller_Play_AiksTest_BlendModePlusAdvanced_Vulkan.png
impeller_Play_AiksTest_BlendModePlusAlphaColorFilterWideGamut_Metal.png
impeller_Play_AiksTest_BlendModePlusAlphaWideGamut_Metal.png
impeller_Play_AiksTest_BlendModePlus_Metal.png
impeller_Play_AiksTest_BlendModePlus_OpenGLES.png
impeller_Play_AiksTest_BlendModePlus_Vulkan.png