mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] Apply some recent color filter fixes to BlendFilterContents::CreateForegroundAdvancedBlend (flutter/engine#55470)
Some recent changes affecting color filters (https://github.com/flutter/engine/pull/55411, https://github.com/flutter/engine/pull/55448) need to be done for both Porter-Duff and advanced blend modes
This commit is contained in:
parent
9e2746c137
commit
faa865b425
@ -22,6 +22,7 @@
|
||||
#include "impeller/display_list/dl_dispatcher.h"
|
||||
#include "impeller/playground/playground.h"
|
||||
#include "impeller/playground/playground_test.h"
|
||||
#include "impeller/renderer/testing/mocks.h"
|
||||
#include "include/core/SkMatrix.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -303,6 +304,97 @@ TEST_P(AiksTest, ColorFilterAdvancedBlend) {
|
||||
ASSERT_TRUE(OpenPlaygroundHere(callback));
|
||||
}
|
||||
|
||||
// Variant of the https://github.com/flutter/flutter/issues/155691 test that
|
||||
// uses an advanced blend in the color filter and disables framebuffer fetch
|
||||
// to force usage of BlendFilterContents::CreateForegroundAdvancedBlend.
|
||||
TEST_P(AiksTest, ColorFilterAdvancedBlendNoFbFetch) {
|
||||
if (GetParam() != PlaygroundBackend::kMetal) {
|
||||
GTEST_SKIP()
|
||||
<< "This backend doesn't yet support setting device capabilities.";
|
||||
}
|
||||
if (!WillRenderSomething()) {
|
||||
GTEST_SKIP() << "This test requires playgrounds.";
|
||||
}
|
||||
|
||||
std::shared_ptr<const Capabilities> old_capabilities =
|
||||
GetContext()->GetCapabilities();
|
||||
auto mock_capabilities = std::make_shared<MockCapabilities>();
|
||||
EXPECT_CALL(*mock_capabilities, SupportsFramebufferFetch())
|
||||
.Times(::testing::AtLeast(1))
|
||||
.WillRepeatedly(::testing::Return(false));
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities,
|
||||
GetDefaultDepthStencilFormat);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities,
|
||||
SupportsImplicitResolvingMSAA);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities,
|
||||
SupportsTextureToTextureBlits);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities, SupportsTriangleFan);
|
||||
FLT_FORWARD(mock_capabilities, old_capabilities,
|
||||
SupportsDecalSamplerAddressMode);
|
||||
ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
|
||||
|
||||
bool has_color_filter = true;
|
||||
auto callback = [&]() -> sk_sp<DisplayList> {
|
||||
if (AiksTest::ImGuiBegin("Controls", nullptr,
|
||||
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||
ImGui::Checkbox("has color filter", &has_color_filter);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
DisplayListBuilder builder;
|
||||
builder.Scale(GetContentScale().x, GetContentScale().y);
|
||||
|
||||
auto src_image =
|
||||
DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png"));
|
||||
auto dst_image =
|
||||
DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png"));
|
||||
|
||||
std::vector<DlBlendMode> blend_modes = {
|
||||
DlBlendMode::kScreen, DlBlendMode::kOverlay,
|
||||
DlBlendMode::kDarken, DlBlendMode::kLighten,
|
||||
DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
|
||||
DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
|
||||
DlBlendMode::kDifference, DlBlendMode::kExclusion,
|
||||
DlBlendMode::kMultiply, DlBlendMode::kHue,
|
||||
DlBlendMode::kSaturation, DlBlendMode::kColor,
|
||||
DlBlendMode::kLuminosity,
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < blend_modes.size(); ++i) {
|
||||
builder.Save();
|
||||
builder.Translate((i % 5) * 200, (i / 5) * 200);
|
||||
builder.Scale(0.4, 0.4);
|
||||
{
|
||||
DlPaint dstPaint;
|
||||
builder.DrawImage(dst_image, {0, 0}, DlImageSampling::kMipmapLinear,
|
||||
&dstPaint);
|
||||
}
|
||||
{
|
||||
DlPaint srcPaint;
|
||||
srcPaint.setBlendMode(blend_modes[i]);
|
||||
if (has_color_filter) {
|
||||
std::shared_ptr<const DlColorFilter> color_filter =
|
||||
DlBlendColorFilter::Make(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
|
||||
DlBlendMode::kMultiply);
|
||||
srcPaint.setColorFilter(color_filter);
|
||||
}
|
||||
builder.DrawImage(src_image, {0, 0}, DlImageSampling::kMipmapLinear,
|
||||
&srcPaint);
|
||||
}
|
||||
builder.Restore();
|
||||
}
|
||||
return builder.Build();
|
||||
};
|
||||
ASSERT_TRUE(OpenPlaygroundHere(callback));
|
||||
}
|
||||
|
||||
// Bug: https://github.com/flutter/flutter/issues/142549
|
||||
TEST_P(AiksTest, BlendModePlusAlphaWideGamut) {
|
||||
EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
|
||||
|
||||
@ -1041,10 +1041,6 @@ TEST_P(AiksTest, BlurredRectangleWithShader) {
|
||||
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
|
||||
}
|
||||
|
||||
#define FLT_FORWARD(mock, real, method) \
|
||||
EXPECT_CALL(*mock, method()) \
|
||||
.WillRepeatedly(::testing::Return(real->method()));
|
||||
|
||||
TEST_P(AiksTest, GaussianBlurWithoutDecalSupport) {
|
||||
if (GetParam() != PlaygroundBackend::kMetal) {
|
||||
GTEST_SKIP()
|
||||
|
||||
@ -303,7 +303,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
|
||||
BlendModeToString(blend_mode)));
|
||||
#endif // IMPELLER_DEBUG
|
||||
pass.SetVertexBuffer(std::move(vtx_buffer));
|
||||
auto options = OptionsFromPass(pass);
|
||||
auto options = OptionsFromPassAndEntity(pass, entity);
|
||||
options.primitive_type = PrimitiveType::kTriangleStrip;
|
||||
|
||||
switch (blend_mode) {
|
||||
@ -370,8 +370,9 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
|
||||
FS::BindTextureSamplerDst(pass, dst_snapshot->texture, dst_sampler);
|
||||
frame_info.dst_y_coord_scale = dst_snapshot->texture->GetYCoordScale();
|
||||
|
||||
frame_info.mvp = Entity::GetShaderTransform(entity.GetShaderClipDepth(),
|
||||
pass, dst_snapshot->transform);
|
||||
frame_info.mvp = Entity::GetShaderTransform(
|
||||
entity.GetShaderClipDepth(), pass,
|
||||
entity.GetTransform() * dst_snapshot->transform);
|
||||
|
||||
blend_info.dst_input_alpha =
|
||||
absorb_opacity == ColorFilterContents::AbsorbOpacity::kYes
|
||||
@ -402,6 +403,7 @@ std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
|
||||
|
||||
Entity sub_entity;
|
||||
sub_entity.SetContents(std::move(contents));
|
||||
sub_entity.SetBlendMode(entity.GetBlendMode());
|
||||
|
||||
return sub_entity;
|
||||
}
|
||||
|
||||
@ -16,6 +16,10 @@
|
||||
#include "impeller/renderer/render_target.h"
|
||||
#include "impeller/renderer/sampler_library.h"
|
||||
|
||||
#define FLT_FORWARD(mock, real, method) \
|
||||
EXPECT_CALL(*mock, method()) \
|
||||
.WillRepeatedly(::testing::Return(real->method()));
|
||||
|
||||
namespace impeller {
|
||||
namespace testing {
|
||||
|
||||
|
||||
@ -523,6 +523,7 @@ impeller_Play_AiksTest_CollapsedDrawPaintInSubpassBackdropFilter_Vulkan.png
|
||||
impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_Metal.png
|
||||
impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_OpenGLES.png
|
||||
impeller_Play_AiksTest_CollapsedDrawPaintInSubpass_Vulkan.png
|
||||
impeller_Play_AiksTest_ColorFilterAdvancedBlendNoFbFetch_Metal.png
|
||||
impeller_Play_AiksTest_ColorFilterAdvancedBlend_Metal.png
|
||||
impeller_Play_AiksTest_ColorFilterAdvancedBlend_OpenGLES.png
|
||||
impeller_Play_AiksTest_ColorFilterAdvancedBlend_Vulkan.png
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user