[Impeller] dont cache failed render target allocations. (#45895)
Otherwise we'll null de-ref when trying to create a texture with the same descriptor later on.
diff --git a/impeller/entity/render_target_cache.cc b/impeller/entity/render_target_cache.cc
index a265517..89e1628 100644
--- a/impeller/entity/render_target_cache.cc
+++ b/impeller/entity/render_target_cache.cc
@@ -39,12 +39,16 @@
for (auto& td : texture_data_) {
const auto other_desc = td.texture->GetTextureDescriptor();
+ FML_DCHECK(td.texture != nullptr);
if (!td.used_this_frame && desc == other_desc) {
td.used_this_frame = true;
return td.texture;
}
}
auto result = RenderTargetAllocator::CreateTexture(desc);
+ if (result == nullptr) {
+ return result;
+ }
texture_data_.push_back(
TextureData{.used_this_frame = true, .texture = result});
return result;
diff --git a/impeller/entity/render_target_cache_unittests.cc b/impeller/entity/render_target_cache_unittests.cc
index d8086b3..fc402f8 100644
--- a/impeller/entity/render_target_cache_unittests.cc
+++ b/impeller/entity/render_target_cache_unittests.cc
@@ -25,13 +25,21 @@
std::shared_ptr<DeviceBuffer> OnCreateBuffer(
const DeviceBufferDescriptor& desc) override {
+ if (should_fail) {
+ return nullptr;
+ }
return std::make_shared<MockDeviceBuffer>(desc);
};
virtual std::shared_ptr<Texture> OnCreateTexture(
const TextureDescriptor& desc) override {
+ if (should_fail) {
+ return nullptr;
+ }
return std::make_shared<MockTexture>(desc);
};
+
+ bool should_fail = false;
};
TEST(RenderTargetCacheTest, CachesUsedTexturesAcrossFrames) {
@@ -62,5 +70,20 @@
ASSERT_EQ(render_target_cache.CachedTextureCount(), 1u);
}
+TEST(RenderTargetCacheTest, DoesNotPersistFailedAllocations) {
+ auto allocator = std::make_shared<TestAllocator>();
+ auto render_target_cache = RenderTargetCache(allocator);
+ auto desc = TextureDescriptor{
+ .format = PixelFormat::kR8G8B8A8UNormInt,
+ .size = ISize(100, 100),
+ .usage = static_cast<TextureUsageMask>(TextureUsage::kRenderTarget)};
+
+ render_target_cache.Start();
+ allocator->should_fail = true;
+
+ ASSERT_EQ(render_target_cache.CreateTexture(desc), nullptr);
+ ASSERT_EQ(render_target_cache.CachedTextureCount(), 0u);
+}
+
} // namespace testing
} // namespace impeller