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

Commit 5d178b2

Browse files
[Impeller] Fix EntityPassTarget::Flip with implict MSAA. (#47701)
This allows backdrop filters to work with GLES and MSAA. The swap implementation was only swapping out the resolve texture. But with implicit msaa resolve, the resolve texture and msaa texture are the same - so both need to be swapped. Fixes flutter/flutter#137301
1 parent 315495e commit 5d178b2

File tree

8 files changed

+142
-20
lines changed

8 files changed

+142
-20
lines changed

ci/licenses_golden/excluded_files

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@
138138
../../../flutter/impeller/entity/contents/filters/inputs/filter_input_unittests.cc
139139
../../../flutter/impeller/entity/contents/test
140140
../../../flutter/impeller/entity/contents/vertices_contents_unittests.cc
141+
../../../flutter/impeller/entity/entity_pass_target_unittests.cc
141142
../../../flutter/impeller/entity/entity_unittests.cc
142143
../../../flutter/impeller/entity/geometry/geometry_unittests.cc
143144
../../../flutter/impeller/entity/render_target_cache_unittests.cc

impeller/BUILD.gn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ impeller_component("impeller_unittests") {
9898
"aiks:aiks_unittests",
9999
"display_list:display_list_unittests",
100100
"entity:entity_unittests",
101-
"entity:render_target_cache_unittests",
102101
"fixtures",
103102
"geometry:geometry_unittests",
104103
"image:image_unittests",

impeller/core/texture.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include <string_view>
88

9-
#include "flutter/fml/macros.h"
109
#include "flutter/fml/mapping.h"
1110
#include "impeller/core/formats.h"
1211
#include "impeller/core/texture_descriptor.h"

impeller/entity/BUILD.gn

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,12 @@ impeller_component("entity_unittests") {
282282
"contents/checkerboard_contents_unittests.cc",
283283
"contents/filters/inputs/filter_input_unittests.cc",
284284
"contents/vertices_contents_unittests.cc",
285+
"entity_pass_target_unittests.cc",
285286
"entity_playground.cc",
286287
"entity_playground.h",
287288
"entity_unittests.cc",
288289
"geometry/geometry_unittests.cc",
290+
"render_target_cache_unittests.cc",
289291
]
290292

291293
deps = [
@@ -296,14 +298,3 @@ impeller_component("entity_unittests") {
296298
"//flutter/impeller/typographer/backends/skia:typographer_skia_backend",
297299
]
298300
}
299-
300-
impeller_component("render_target_cache_unittests") {
301-
testonly = true
302-
303-
sources = [ "render_target_cache_unittests.cc" ]
304-
305-
deps = [
306-
":entity",
307-
"//flutter/testing:testing_lib",
308-
]
309-
}

impeller/entity/entity_pass.cc

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ static EntityPassTarget CreateRenderTarget(ContentContext& renderer,
286286
}
287287

288288
return EntityPassTarget(
289-
target, renderer.GetDeviceCapabilities().SupportsReadFromResolve());
289+
target, renderer.GetDeviceCapabilities().SupportsReadFromResolve(),
290+
renderer.GetDeviceCapabilities().SupportsImplicitResolvingMSAA());
290291
}
291292

292293
uint32_t EntityPass::GetTotalPassReads(ContentContext& renderer) const {
@@ -397,7 +398,10 @@ bool EntityPass::Render(ContentContext& renderer,
397398
entity.SetContents(contents);
398399
entity.SetBlendMode(BlendMode::kSource);
399400

400-
entity.Render(renderer, *render_pass);
401+
if (!entity.Render(renderer, *render_pass)) {
402+
VALIDATION_LOG << "Failed to render EntityPass root blit.";
403+
return false;
404+
}
401405
}
402406

403407
if (!render_pass->EncodeCommands()) {
@@ -455,7 +459,8 @@ bool EntityPass::Render(ContentContext& renderer,
455459

456460
EntityPassTarget pass_target(
457461
root_render_target,
458-
renderer.GetDeviceCapabilities().SupportsReadFromResolve());
462+
renderer.GetDeviceCapabilities().SupportsReadFromResolve(),
463+
renderer.GetDeviceCapabilities().SupportsImplicitResolvingMSAA());
459464

460465
return OnRender( //
461466
renderer, // renderer

impeller/entity/entity_pass_target.cc

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
namespace impeller {
1212

1313
EntityPassTarget::EntityPassTarget(const RenderTarget& render_target,
14-
bool supports_read_from_resolve)
14+
bool supports_read_from_resolve,
15+
bool supports_implicit_msaa)
1516
: target_(render_target),
16-
supports_read_from_resolve_(supports_read_from_resolve) {}
17+
supports_read_from_resolve_(supports_read_from_resolve),
18+
supports_implicit_msaa_(supports_implicit_msaa) {}
1719

1820
std::shared_ptr<Texture> EntityPassTarget::Flip(Allocator& allocator) {
1921
auto color0 = target_.GetColorAttachments().find(0)->second;
@@ -45,7 +47,16 @@ std::shared_ptr<Texture> EntityPassTarget::Flip(Allocator& allocator) {
4547
}
4648
}
4749

48-
std::swap(color0.resolve_texture, secondary_color_texture_);
50+
// If the color0 resolve texture is the same as the texture, then we're
51+
// running on the GLES backend with implicit resolve.
52+
if (supports_implicit_msaa_) {
53+
auto new_secondary = color0.resolve_texture;
54+
color0.resolve_texture = secondary_color_texture_;
55+
color0.texture = secondary_color_texture_;
56+
secondary_color_texture_ = new_secondary;
57+
} else {
58+
std::swap(color0.resolve_texture, secondary_color_texture_);
59+
}
4960

5061
target_.SetColorAttachment(color0, 0);
5162

impeller/entity/entity_pass_target.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ class InlinePassContext;
1414
class EntityPassTarget {
1515
public:
1616
explicit EntityPassTarget(const RenderTarget& render_target,
17-
bool supports_read_from_resolve);
17+
bool supports_read_from_resolve,
18+
bool supports_implicit_msaa);
1819

1920
/// @brief Flips the backdrop and returns a readable texture that can be
2021
/// bound/sampled to restore the previous pass.
@@ -34,6 +35,7 @@ class EntityPassTarget {
3435
std::shared_ptr<Texture> secondary_color_texture_;
3536

3637
bool supports_read_from_resolve_;
38+
bool supports_implicit_msaa_;
3739

3840
friend InlinePassContext;
3941

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include <memory>
6+
7+
#include "flutter/testing/testing.h"
8+
#include "gtest/gtest.h"
9+
#include "impeller/core/formats.h"
10+
#include "impeller/entity/entity_pass_target.h"
11+
#include "impeller/entity/entity_playground.h"
12+
13+
namespace impeller {
14+
namespace testing {
15+
16+
using EntityPassTargetTest = EntityPlayground;
17+
INSTANTIATE_PLAYGROUND_SUITE(EntityPassTargetTest);
18+
19+
TEST_P(EntityPassTargetTest, SwapWithMSAATexture) {
20+
if (GetContentContext()
21+
->GetDeviceCapabilities()
22+
.SupportsImplicitResolvingMSAA()) {
23+
GTEST_SKIP() << "Implicit MSAA is used on this device.";
24+
}
25+
auto content_context = GetContentContext();
26+
auto buffer = content_context->GetContext()->CreateCommandBuffer();
27+
auto render_target = RenderTarget::CreateOffscreenMSAA(
28+
*content_context->GetContext(),
29+
*GetContentContext()->GetRenderTargetCache(), {100, 100});
30+
31+
auto entity_pass_target = EntityPassTarget(render_target, false, false);
32+
33+
auto color0 = entity_pass_target.GetRenderTarget()
34+
.GetColorAttachments()
35+
.find(0u)
36+
->second;
37+
auto msaa_tex = color0.texture;
38+
auto resolve_tex = color0.resolve_texture;
39+
40+
entity_pass_target.Flip(
41+
*content_context->GetContext()->GetResourceAllocator());
42+
43+
color0 = entity_pass_target.GetRenderTarget()
44+
.GetColorAttachments()
45+
.find(0u)
46+
->second;
47+
48+
ASSERT_EQ(msaa_tex, color0.texture);
49+
ASSERT_NE(resolve_tex, color0.resolve_texture);
50+
}
51+
52+
TEST_P(EntityPassTargetTest, SwapWithMSAAImplicitResolve) {
53+
auto content_context = GetContentContext();
54+
auto buffer = content_context->GetContext()->CreateCommandBuffer();
55+
auto context = content_context->GetContext();
56+
auto& allocator = *context->GetResourceAllocator();
57+
58+
// Emulate implicit MSAA resolve by making color resolve and msaa texture the
59+
// same.
60+
RenderTarget render_target;
61+
{
62+
PixelFormat pixel_format =
63+
context->GetCapabilities()->GetDefaultColorFormat();
64+
65+
// Create MSAA color texture.
66+
67+
TextureDescriptor color0_tex_desc;
68+
color0_tex_desc.storage_mode = StorageMode::kDevicePrivate;
69+
color0_tex_desc.type = TextureType::kTexture2DMultisample;
70+
color0_tex_desc.sample_count = SampleCount::kCount4;
71+
color0_tex_desc.format = pixel_format;
72+
color0_tex_desc.size = ISize{100, 100};
73+
color0_tex_desc.usage = static_cast<uint64_t>(TextureUsage::kRenderTarget);
74+
75+
auto color0_msaa_tex = allocator.CreateTexture(color0_tex_desc);
76+
77+
// Color attachment.
78+
79+
ColorAttachment color0;
80+
color0.load_action = LoadAction::kDontCare;
81+
color0.store_action = StoreAction::kStoreAndMultisampleResolve;
82+
color0.texture = color0_msaa_tex;
83+
color0.resolve_texture = color0_msaa_tex;
84+
85+
render_target.SetColorAttachment(color0, 0u);
86+
render_target.SetStencilAttachment(std::nullopt);
87+
}
88+
89+
auto entity_pass_target = EntityPassTarget(render_target, false, true);
90+
91+
auto color0 = entity_pass_target.GetRenderTarget()
92+
.GetColorAttachments()
93+
.find(0u)
94+
->second;
95+
auto msaa_tex = color0.texture;
96+
auto resolve_tex = color0.resolve_texture;
97+
98+
ASSERT_EQ(msaa_tex, resolve_tex);
99+
100+
entity_pass_target.Flip(
101+
*content_context->GetContext()->GetResourceAllocator());
102+
103+
color0 = entity_pass_target.GetRenderTarget()
104+
.GetColorAttachments()
105+
.find(0u)
106+
->second;
107+
108+
ASSERT_NE(msaa_tex, color0.texture);
109+
ASSERT_NE(resolve_tex, color0.resolve_texture);
110+
ASSERT_EQ(color0.texture, color0.resolve_texture);
111+
}
112+
113+
} // namespace testing
114+
} // namespace impeller

0 commit comments

Comments
 (0)