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

Commit 396be86

Browse files
authored
[Impeller] Remove cached pipelines when RuntimeStage is hot reloaded (#37307)
1 parent aeae6af commit 396be86

File tree

12 files changed

+108
-0
lines changed

12 files changed

+108
-0
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,8 @@ FILE: ../../../flutter/fml/command_line_unittest.cc
850850
FILE: ../../../flutter/fml/compiler_specific.h
851851
FILE: ../../../flutter/fml/concurrent_message_loop.cc
852852
FILE: ../../../flutter/fml/concurrent_message_loop.h
853+
FILE: ../../../flutter/fml/container.h
854+
FILE: ../../../flutter/fml/container_unittests.cc
853855
FILE: ../../../flutter/fml/dart/dart_converter.cc
854856
FILE: ../../../flutter/fml/dart/dart_converter.h
855857
FILE: ../../../flutter/fml/delayed_task.cc

fml/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ source_set("fml") {
1818
"compiler_specific.h",
1919
"concurrent_message_loop.cc",
2020
"concurrent_message_loop.h",
21+
"container.h",
2122
"delayed_task.cc",
2223
"delayed_task.h",
2324
"eintr_wrapper.h",
@@ -310,6 +311,7 @@ if (enable_unittests) {
310311
"backtrace_unittests.cc",
311312
"base32_unittest.cc",
312313
"command_line_unittest.cc",
314+
"container_unittests.cc",
313315
"endianness_unittests.cc",
314316
"file_unittest.cc",
315317
"hash_combine_unittests.cc",

fml/container.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
#ifndef FLUTTER_FML_CONTAINER_H_
6+
#define FLUTTER_FML_CONTAINER_H_
7+
8+
#include <functional>
9+
#include <map>
10+
11+
namespace fml {
12+
13+
template <
14+
class Collection =
15+
std::unordered_map<class Key, class Value, class Hash, class Equal>>
16+
void erase_if(Collection& container,
17+
std::function<bool(typename Collection::iterator)> predicate) {
18+
auto it = container.begin();
19+
while (it != container.end()) {
20+
if (predicate(it)) {
21+
it = container.erase(it);
22+
continue;
23+
}
24+
it++;
25+
}
26+
}
27+
28+
} // namespace fml
29+
30+
#endif // FLUTTER_FML_CONTAINER_H_

fml/container_unittests.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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 <unordered_map>
6+
7+
#include "flutter/fml/container.h"
8+
9+
#include "gtest/gtest.h"
10+
11+
namespace fml {
12+
namespace {
13+
14+
TEST(ContainerTest, MapEraseIf) {
15+
std::unordered_map<int, int> map = {{0, 1}, {2, 3}, {4, 5}};
16+
17+
fml::erase_if(map, [](std::unordered_map<int, int>::iterator it) {
18+
return it->first == 0 || it->second == 5;
19+
});
20+
21+
EXPECT_EQ(map.size(), 1u);
22+
EXPECT_TRUE(map.find(2) != map.end());
23+
}
24+
25+
} // namespace
26+
} // namespace fml

impeller/entity/contents/runtime_effect_contents.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
5353
runtime_stage_->GetEntrypoint(), ShaderStage::kFragment);
5454

5555
if (function && runtime_stage_->IsDirty()) {
56+
context->GetPipelineLibrary()->RemovePipelinesWithEntryPoint(function);
5657
library->UnregisterFunction(runtime_stage_->GetEntrypoint(),
5758
ShaderStage::kFragment);
5859

impeller/renderer/backend/gles/pipeline_library_gles.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <sstream>
88
#include <string>
99

10+
#include "flutter/fml/container.h"
1011
#include "flutter/fml/trace_event.h"
1112
#include "impeller/base/promise.h"
1213
#include "impeller/renderer/backend/gles/pipeline_gles.h"
@@ -257,6 +258,15 @@ PipelineFuture<ComputePipelineDescriptor> PipelineLibraryGLES::GetPipeline(
257258
return future;
258259
}
259260

261+
// |PipelineLibrary|
262+
void PipelineLibraryGLES::RemovePipelinesWithEntryPoint(
263+
std::shared_ptr<const ShaderFunction> function) {
264+
fml::erase_if(pipelines_, [&](auto item) {
265+
return item->first.GetEntrypointForStage(function->GetStage())
266+
->IsEqual(*function);
267+
});
268+
}
269+
260270
// |PipelineLibrary|
261271
PipelineLibraryGLES::~PipelineLibraryGLES() = default;
262272

impeller/renderer/backend/gles/pipeline_library_gles.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class PipelineLibraryGLES final : public PipelineLibrary {
3636
PipelineFuture<ComputePipelineDescriptor> GetPipeline(
3737
ComputePipelineDescriptor descriptor) override;
3838

39+
// |PipelineLibrary|
40+
void RemovePipelinesWithEntryPoint(
41+
std::shared_ptr<const ShaderFunction> function) override;
42+
3943
FML_DISALLOW_COPY_AND_ASSIGN(PipelineLibraryGLES);
4044
};
4145

impeller/renderer/backend/metal/pipeline_library_mtl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ class PipelineLibraryMTL final : public PipelineLibrary {
4040
PipelineFuture<ComputePipelineDescriptor> GetPipeline(
4141
ComputePipelineDescriptor descriptor) override;
4242

43+
// |PipelineLibrary|
44+
void RemovePipelinesWithEntryPoint(
45+
std::shared_ptr<const ShaderFunction> function) override;
46+
4347
FML_DISALLOW_COPY_AND_ASSIGN(PipelineLibraryMTL);
4448
};
4549

impeller/renderer/backend/metal/pipeline_library_mtl.mm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "impeller/renderer/backend/metal/pipeline_library_mtl.h"
66
#include <Metal/Metal.h>
77

8+
#include "flutter/fml/container.h"
89
#include "impeller/base/promise.h"
910
#include "impeller/renderer/backend/metal/compute_pipeline_mtl.h"
1011
#include "impeller/renderer/backend/metal/formats_mtl.h"
@@ -187,4 +188,13 @@ new ComputePipelineMTL(weak_this,
187188
return future;
188189
}
189190

191+
// |PipelineLibrary|
192+
void PipelineLibraryMTL::RemovePipelinesWithEntryPoint(
193+
std::shared_ptr<const ShaderFunction> function) {
194+
fml::erase_if(pipelines_, [&](auto item) {
195+
return item->first.GetEntrypointForStage(function->GetStage())
196+
->IsEqual(*function);
197+
});
198+
}
199+
190200
} // namespace impeller

impeller/renderer/backend/vulkan/pipeline_library_vk.cc

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

77
#include <optional>
88

9+
#include "flutter/fml/container.h"
910
#include "flutter/fml/trace_event.h"
1011
#include "impeller/base/promise.h"
1112
#include "impeller/base/validation.h"
@@ -131,6 +132,17 @@ static vk::AttachmentDescription CreatePlaceholderAttachmentDescription(
131132
return desc;
132133
}
133134

135+
// |PipelineLibrary|
136+
void PipelineLibraryVK::RemovePipelinesWithEntryPoint(
137+
std::shared_ptr<const ShaderFunction> function) {
138+
Lock lock(pipelines_mutex_);
139+
140+
fml::erase_if(pipelines_, [&](auto item) {
141+
return item->first.GetEntrypointForStage(function->GetStage())
142+
->IsEqual(*function);
143+
});
144+
}
145+
134146
//----------------------------------------------------------------------------
135147
/// Render Pass
136148
/// We are NOT going to use the same render pass with the framebuffer (later)

impeller/renderer/backend/vulkan/pipeline_library_vk.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ class PipelineLibraryVK final
5858
PipelineFuture<ComputePipelineDescriptor> GetPipeline(
5959
ComputePipelineDescriptor descriptor) override;
6060

61+
// |PipelineLibrary|
62+
void RemovePipelinesWithEntryPoint(
63+
std::shared_ptr<const ShaderFunction> function) override;
64+
6165
std::unique_ptr<PipelineCreateInfoVK> CreatePipeline(
6266
const PipelineDescriptor& desc);
6367

impeller/renderer/pipeline_library.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ class PipelineLibrary : public std::enable_shared_from_this<PipelineLibrary> {
3333
virtual PipelineFuture<ComputePipelineDescriptor> GetPipeline(
3434
ComputePipelineDescriptor descriptor) = 0;
3535

36+
virtual void RemovePipelinesWithEntryPoint(
37+
std::shared_ptr<const ShaderFunction> function) = 0;
38+
3639
protected:
3740
PipelineLibrary();
3841

0 commit comments

Comments
 (0)