Skip to content

Commit 1d4e591

Browse files
authored
Merge branch 'flutter-3.44-candidate.0' into cp-stable-6efbbadd2ee7921be6135990dd6bfee856fb4d1e
2 parents 0ef0776 + 83675ed commit 1d4e591

17 files changed

Lines changed: 316 additions & 104 deletions

engine/src/flutter/impeller/display_list/aiks_dl_text_unittests.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,5 +1055,31 @@ TEST_P(AiksTest, TextWithNonUniformScale) {
10551055
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
10561056
}
10571057

1058+
TEST_P(AiksTest, TextWithShadowAndPosition) {
1059+
DisplayListBuilder builder;
1060+
builder.Scale(GetContentScale().x, GetContentScale().y);
1061+
builder.Clear(DlColor::kWhite());
1062+
1063+
auto frame = MakeDefaultTextFrame("Hello", 25.0f);
1064+
auto text = DlTextImpeller::Make(frame);
1065+
DlPaint paint = DlPaint().setColor(DlColor::kMagenta());
1066+
DlPaint shadow_paint_ctm = DlPaint().setMaskFilter(
1067+
DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 5.0f, true));
1068+
DlPaint shadow_paint_no_ctm = DlPaint().setMaskFilter(
1069+
DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 5.0f, false));
1070+
1071+
builder.Translate(100, 100);
1072+
builder.Scale(4, 4);
1073+
for (int x = 10; x <= 100; x += 30) {
1074+
builder.DrawText(text, x, 20, shadow_paint_ctm);
1075+
builder.DrawText(text, x, 20, paint);
1076+
1077+
builder.DrawText(text, x, 50, shadow_paint_no_ctm);
1078+
builder.DrawText(text, x, 50, paint);
1079+
}
1080+
1081+
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1082+
}
1083+
10581084
} // namespace testing
10591085
} // namespace impeller

engine/src/flutter/impeller/display_list/canvas.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1947,7 +1947,7 @@ void Canvas::DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
19471947
? std::optional(paint.stroke)
19481948
: std::nullopt);
19491949

1950-
entity.SetTransform(GetCurrentTransform());
1950+
entity.SetTransform(GetCurrentTransform().Translate(position));
19511951

19521952
if (AttemptBlurredTextOptimization(text_frame, text_contents, entity,
19531953
paint)) {

engine/src/flutter/impeller/entity/contents/text_contents.cc

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ void TextContents::SetForceTextColor(bool value) {
5858
}
5959

6060
std::optional<Rect> TextContents::GetCoverage(const Entity& entity) const {
61-
const Matrix entity_offset_transform =
62-
entity.GetTransform() * Matrix::MakeTranslation(position_);
63-
return frame_->GetBounds().TransformBounds(entity_offset_transform);
61+
return frame_->GetBounds().TransformBounds(entity.GetTransform());
6462
}
6563

6664
void TextContents::SetTextProperties(
@@ -92,7 +90,7 @@ Scalar AttractToOne(Scalar x) {
9290

9391
void TextContents::ComputeVertexData(
9492
VS::PerVertexData* vtx_contents,
95-
const Matrix& entity_transform,
93+
const Matrix& entity_offset_transform,
9694
const std::shared_ptr<TextFrame>& frame,
9795
Point position,
9896
const Matrix& screen_transform,
@@ -108,9 +106,6 @@ void TextContents::ComputeVertexData(
108106
constexpr std::array<Point, 4> unit_points = {Point{0, 0}, Point{1, 0},
109107
Point{0, 1}, Point{1, 1}};
110108

111-
Matrix entity_offset_transform =
112-
entity_transform * Matrix::MakeTranslation(position);
113-
114109
ISize atlas_size = atlas->GetTexture()->GetSize();
115110
bool is_translation_scale = entity_offset_transform.IsTranslationScaleOnly();
116111
Matrix basis_transform = entity_offset_transform.Basis();

engine/src/flutter/impeller/renderer/backend/vulkan/BUILD.gn

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ import("//flutter/testing/android/native_activity/native_activity.gni")
66
import("//flutter/vulkan/config.gni")
77
import("../../../tools/impeller.gni")
88

9+
source_set("mock_vulkan") {
10+
testonly = true
11+
12+
sources = [
13+
"test/mock_vulkan.cc",
14+
"test/mock_vulkan.h",
15+
]
16+
17+
deps = [
18+
":vulkan",
19+
"//flutter/fml",
20+
]
21+
}
22+
923
impeller_component("vulkan_unittests") {
1024
testonly = true
1125
sources = [
@@ -25,13 +39,12 @@ impeller_component("vulkan_unittests") {
2539
"resource_manager_vk_unittests.cc",
2640
"surface_context_vk_unittests.cc",
2741
"test/gpu_tracer_unittests.cc",
28-
"test/mock_vulkan.cc",
29-
"test/mock_vulkan.h",
3042
"test/mock_vulkan_unittests.cc",
3143
"test/sampler_library_vk_unittests.cc",
3244
"test/swapchain_unittests.cc",
3345
]
3446
deps = [
47+
":mock_vulkan",
3548
":vulkan",
3649
"../../../playground:playground_test",
3750
"//flutter/testing:testing_lib",
@@ -179,9 +192,13 @@ if (is_android) {
179192

180193
testonly = true
181194

182-
sources = [ "android/ahb_texture_source_vk_unittests.cc" ]
195+
sources = [
196+
"android/ahb_swapchain_vk_unittests.cc",
197+
"android/ahb_texture_source_vk_unittests.cc",
198+
]
183199

184200
deps = [
201+
":mock_vulkan",
185202
":unittests_fixtures",
186203
":vulkan",
187204
"//flutter/testing",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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 "gtest/gtest.h"
6+
7+
#include "impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h"
8+
#include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
9+
#include "impeller/toolkit/android/surface_control.h"
10+
11+
namespace impeller::android::testing {
12+
13+
using impeller::testing::GetMockVulkanFunctions;
14+
using impeller::testing::MockVulkanContextBuilder;
15+
16+
const std::vector<std::string> kAndroidDeviceExtensions = {
17+
"VK_KHR_swapchain",
18+
"VK_ANDROID_external_memory_android_hardware_buffer",
19+
"VK_KHR_sampler_ycbcr_conversion",
20+
"VK_KHR_external_memory",
21+
"VK_EXT_queue_family_foreign",
22+
"VK_KHR_dedicated_allocation",
23+
};
24+
25+
class FakeSurfaceControl : public SurfaceControl {
26+
public:
27+
bool IsValid() const override { return true; }
28+
29+
ASurfaceControl* GetHandle() const override { return nullptr; }
30+
31+
bool RemoveFromParent() const override { return true; }
32+
};
33+
34+
TEST(AndroidAHBSwapchainTest, AHBSwapchainDtorCallsWaitIdle) {
35+
const auto context = MockVulkanContextBuilder()
36+
.SetDeviceExtensions(kAndroidDeviceExtensions)
37+
.Build();
38+
39+
auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
40+
context, std::make_shared<FakeSurfaceControl>(), {}, {100, 100}, false));
41+
42+
ahb_swapchain.reset();
43+
44+
auto called_functions = GetMockVulkanFunctions(context->GetDevice());
45+
EXPECT_NE(std::find(called_functions->begin(), called_functions->end(),
46+
"vkDeviceWaitIdle"),
47+
called_functions->end());
48+
}
49+
50+
} // namespace impeller::android::testing

engine/src/flutter/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ AHBSwapchainImplVK::AHBSwapchainImplVK(
102102
is_valid_ = control && control->IsValid();
103103
}
104104

105-
AHBSwapchainImplVK::~AHBSwapchainImplVK() = default;
105+
AHBSwapchainImplVK::~AHBSwapchainImplVK() {
106+
// Ensure that the Vulkan device is idle before destroying objects that the
107+
// device may have been using.
108+
WaitIdle();
109+
}
106110

107111
const ISize& AHBSwapchainImplVK::GetSize() const {
108112
return desc_.size;
@@ -117,6 +121,17 @@ const android::HardwareBufferDescriptor& AHBSwapchainImplVK::GetDescriptor()
117121
return desc_;
118122
}
119123

124+
void AHBSwapchainImplVK::WaitIdle() const {
125+
if (transients_) {
126+
if (auto context = transients_->GetContext().lock()) {
127+
auto result = ContextVK::Cast(*context).GetDevice().waitIdle();
128+
if (result != vk::Result::eSuccess) {
129+
FML_LOG(INFO) << "Device waitIdle failed: " << vk::to_string(result);
130+
}
131+
}
132+
}
133+
}
134+
120135
std::unique_ptr<Surface> AHBSwapchainImplVK::AcquireNextDrawable() {
121136
auto context = transients_->GetContext().lock();
122137
if (!context) {

engine/src/flutter/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_impl_vk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ class AHBSwapchainImplVK final
140140

141141
bool Present(const std::shared_ptr<AHBTextureSourceVK>& texture);
142142

143+
void WaitIdle() const;
144+
143145
vk::UniqueSemaphore CreateRenderReadySemaphore(
144146
const std::shared_ptr<fml::UniqueFD>& fd) const;
145147

engine/src/flutter/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ bool AHBSwapchainVK::IsAvailableOnPlatform() {
1717
android::HardwareBuffer::IsAvailableOnPlatform();
1818
}
1919

20-
AHBSwapchainVK::AHBSwapchainVK(const std::shared_ptr<Context>& context,
21-
ANativeWindow* window,
22-
const CreateTransactionCB& cb,
23-
const ISize& size,
24-
bool enable_msaa)
20+
AHBSwapchainVK::AHBSwapchainVK(
21+
const std::shared_ptr<Context>& context,
22+
const std::shared_ptr<android::SurfaceControl>& surface_control,
23+
const CreateTransactionCB& cb,
24+
const ISize& size,
25+
bool enable_msaa)
2526
: context_(context),
26-
surface_control_(
27-
std::make_shared<android::SurfaceControl>(window, "ImpellerSurface")),
27+
surface_control_(surface_control),
2828
enable_msaa_(enable_msaa),
2929
cb_(cb) {
3030
UpdateSurfaceSize(size);

engine/src/flutter/impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313

1414
namespace impeller {
1515

16+
namespace android::testing {
17+
FML_TEST_CLASS(AndroidAHBSwapchainTest, AHBSwapchainDtorCallsWaitIdle);
18+
} // namespace android::testing
19+
1620
using CreateTransactionCB = std::function<android::SurfaceTransaction()>;
1721

1822
//------------------------------------------------------------------------------
@@ -55,18 +59,21 @@ class AHBSwapchainVK final : public SwapchainVK {
5559

5660
private:
5761
friend class SwapchainVK;
62+
FML_FRIEND_TEST(android::testing::AndroidAHBSwapchainTest,
63+
AHBSwapchainDtorCallsWaitIdle);
5864

5965
std::weak_ptr<Context> context_;
6066
std::shared_ptr<android::SurfaceControl> surface_control_;
6167
const bool enable_msaa_;
6268
CreateTransactionCB cb_;
6369
std::shared_ptr<AHBSwapchainImplVK> impl_;
6470

65-
explicit AHBSwapchainVK(const std::shared_ptr<Context>& context,
66-
ANativeWindow* window,
67-
const CreateTransactionCB& cb,
68-
const ISize& size,
69-
bool enable_msaa);
71+
explicit AHBSwapchainVK(
72+
const std::shared_ptr<Context>& context,
73+
const std::shared_ptr<android::SurfaceControl>& surface_control,
74+
const CreateTransactionCB& cb,
75+
const ISize& size,
76+
bool enable_msaa);
7077
};
7178

7279
} // namespace impeller

engine/src/flutter/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,15 @@ std::shared_ptr<SwapchainVK> SwapchainVK::Create(
5050
AHBSwapchainVK::IsAvailableOnPlatform()) {
5151
CreateTransactionCB callback =
5252
android_get_device_api_level() >= 34 ? cb : CreateTransactionCB({});
53-
auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
54-
context, //
55-
window.GetHandle(), //
56-
callback, //
57-
window.GetSize(), //
58-
enable_msaa //
59-
));
53+
auto surface_control = std::shared_ptr(
54+
android::SurfaceControl::Create(window.GetHandle(), "ImpellerSurface"));
55+
auto ahb_swapchain =
56+
std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(context, //
57+
surface_control, //
58+
callback, //
59+
window.GetSize(), //
60+
enable_msaa //
61+
));
6062

6163
if (ahb_swapchain->IsValid()) {
6264
return ahb_swapchain;

0 commit comments

Comments
 (0)