Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,11 @@ CreateEmbedderRenderTarget(const FlutterCompositor* compositor,
auto c_create_callback = compositor->create_backing_store_callback;
auto c_collect_callback = compositor->collect_backing_store_callback;

bool avoid_cache = false;
{
TRACE_EVENT0("flutter", "FlutterCompositorCreateBackingStore");
if (!c_create_callback(&config, &backing_store, compositor->user_data)) {
if (!c_create_callback(&config, &backing_store, compositor->user_data,
&avoid_cache)) {
FML_LOG(ERROR) << "Could not create the embedder backing store.";
return nullptr;
}
Expand Down Expand Up @@ -526,7 +528,8 @@ CreateEmbedderRenderTarget(const FlutterCompositor* compositor,
}

return std::make_unique<flutter::EmbedderRenderTarget>(
backing_store, std::move(render_surface), collect_callback.Release());
backing_store, std::move(render_surface), collect_callback.Release(),
avoid_cache);
}

static std::pair<std::unique_ptr<flutter::EmbedderExternalViewEmbedder>,
Expand Down
4 changes: 2 additions & 2 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#ifndef FLUTTER_EMBEDDER_H_
#define FLUTTER_EMBEDDER_H_

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Expand Down Expand Up @@ -905,7 +904,8 @@ typedef struct {
typedef bool (*FlutterBackingStoreCreateCallback)(
const FlutterBackingStoreConfig* config,
FlutterBackingStore* backing_store_out,
void* user_data);
void* user_data,
bool* avoid_cache);

typedef bool (*FlutterBackingStoreCollectCallback)(
const FlutterBackingStore* renderer,
Expand Down
6 changes: 4 additions & 2 deletions shell/platform/embedder/embedder_external_view_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,10 @@ void EmbedderExternalViewEmbedder::SubmitFrame(
// Hold all rendered layers in the render target cache for one frame to
// see if they may be reused next frame.
for (auto& render_target : matched_render_targets) {
render_target_cache_.CacheRenderTarget(render_target.first,
std::move(render_target.second));
if (!render_target.second->GetAvoidCache()) {
render_target_cache_.CacheRenderTarget(render_target.first,
std::move(render_target.second));
}
}

frame->Submit();
Expand Down
10 changes: 8 additions & 2 deletions shell/platform/embedder/embedder_render_target.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ namespace flutter {

EmbedderRenderTarget::EmbedderRenderTarget(FlutterBackingStore backing_store,
sk_sp<SkSurface> render_surface,
fml::closure on_release)
fml::closure on_release,
bool avoid_cache)
: backing_store_(backing_store),
render_surface_(std::move(render_surface)),
on_release_(on_release) {
on_release_(on_release),
avoid_cache_(avoid_cache) {
// TODO(38468): The optimization to elide backing store updates between frames
// has not been implemented yet.
backing_store_.did_update = true;
Expand All @@ -34,4 +36,8 @@ sk_sp<SkSurface> EmbedderRenderTarget::GetRenderSurface() const {
return render_surface_;
}

bool EmbedderRenderTarget::GetAvoidCache() {
return avoid_cache_;
}

} // namespace flutter
11 changes: 10 additions & 1 deletion shell/platform/embedder/embedder_render_target.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class EmbedderRenderTarget {
///
EmbedderRenderTarget(FlutterBackingStore backing_store,
sk_sp<SkSurface> render_surface,
fml::closure on_release);
fml::closure on_release,
bool avoid_cache);

//----------------------------------------------------------------------------
/// @brief Destroys this instance of the render target and invokes the
Expand Down Expand Up @@ -65,10 +66,18 @@ class EmbedderRenderTarget {
///
const FlutterBackingStore* GetBackingStore() const;

//----------------------------------------------------------------------------
/// @brief The render target may want to avoid being cached.
///
/// @return A bool representing if the embedder render target should
/// avoid the cache.
bool GetAvoidCache();

private:
FlutterBackingStore backing_store_;
sk_sp<SkSurface> render_surface_;
fml::closure on_release_;
bool avoid_cache_;

FML_DISALLOW_COPY_AND_ASSIGN(EmbedderRenderTarget);
};
Expand Down
6 changes: 3 additions & 3 deletions shell/platform/embedder/tests/embedder_config_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -257,10 +257,10 @@ void EmbedderConfigBuilder::SetCompositor() {
compositor_.create_backing_store_callback =
[](const FlutterBackingStoreConfig* config, //
FlutterBackingStore* backing_store_out, //
void* user_data //
) {
void* user_data, //
bool* avoid_cache) {
return reinterpret_cast<EmbedderTestCompositor*>(user_data)
->CreateBackingStore(config, backing_store_out);
->CreateBackingStore(config, backing_store_out, avoid_cache);
};
compositor_.collect_backing_store_callback =
[](const FlutterBackingStore* backing_store, //
Expand Down
11 changes: 10 additions & 1 deletion shell/platform/embedder/tests/embedder_test_compositor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@ static void InvokeAllCallbacks(const std::vector<fml::closure>& callbacks) {

bool EmbedderTestCompositor::CreateBackingStore(
const FlutterBackingStoreConfig* config,
FlutterBackingStore* backing_store_out) {
FlutterBackingStore* backing_store_out,
bool* avoid_cache) {
bool success = backingstore_producer_->Create(config, backing_store_out);
if (success) {
backing_stores_created_++;
InvokeAllCallbacks(on_create_render_target_callbacks_);
}
if (avoid_cache_callback_) {
avoid_cache_callback_(avoid_cache);
}
return success;
}

Expand Down Expand Up @@ -104,6 +108,11 @@ void EmbedderTestCompositor::SetPlatformViewRendererCallback(
platform_view_renderer_callback_ = callback;
}

void EmbedderTestCompositor::SetUpdateAvoidCacheCallback(
const UpdateAvoidCacheCallback& avoid_cache_callback) {
avoid_cache_callback_ = avoid_cache_callback;
}

size_t EmbedderTestCompositor::GetPendingBackingStoresCount() const {
FML_CHECK(backing_stores_created_ >= backing_stores_collected_);
return backing_stores_created_ - backing_stores_collected_;
Expand Down
15 changes: 14 additions & 1 deletion shell/platform/embedder/tests/embedder_test_compositor.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class EmbedderTestCompositor {
using PresentCallback =
std::function<void(const FlutterLayer** layers, size_t layers_count)>;

using UpdateAvoidCacheCallback = std::function<void(bool* avoid_cache)>;

EmbedderTestCompositor(SkISize surface_size, sk_sp<GrDirectContext> context);

virtual ~EmbedderTestCompositor();
Expand All @@ -32,7 +34,8 @@ class EmbedderTestCompositor {
std::unique_ptr<EmbedderTestBackingStoreProducer> backingstore_producer);

bool CreateBackingStore(const FlutterBackingStoreConfig* config,
FlutterBackingStore* backing_store_out);
FlutterBackingStore* backing_store_out,
bool* avoid_cache);

bool CollectBackingStore(const FlutterBackingStore* backing_store);

Expand All @@ -53,6 +56,15 @@ class EmbedderTestCompositor {
void SetPresentCallback(const PresentCallback& present_callback,
bool one_shot);

//----------------------------------------------------------------------------
/// @brief Allows tests to install a callback to update the
/// avoid_cache_callback_ bool.
///
/// @param[in] avoid_cache_callback The callback to update the
/// avoid_cache_callback_.
void SetUpdateAvoidCacheCallback(
const UpdateAvoidCacheCallback& avoid_cache_callback);

using NextSceneCallback = std::function<void(sk_sp<SkImage> image)>;
void SetNextSceneCallback(const NextSceneCallback& next_scene_callback);

Expand Down Expand Up @@ -85,6 +97,7 @@ class EmbedderTestCompositor {
bool present_callback_is_one_shot_ = false;
PresentCallback present_callback_;
NextSceneCallback next_scene_callback_;
UpdateAvoidCacheCallback avoid_cache_callback_;
sk_sp<SkImage> last_composition_;
size_t backing_stores_created_ = 0;
size_t backing_stores_collected_ = 0;
Expand Down
47 changes: 47 additions & 0 deletions shell/platform/embedder/tests/embedder_unittests_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2950,6 +2950,53 @@ TEST_F(EmbedderTest, CompositorRenderTargetsAreRecycled) {
ASSERT_EQ(context.GetCompositor().GetBackingStoresCollectedCount(), 10u);
}

//------------------------------------------------------------------------------
/// The RenderTargetCache being disabled should result in the render targets
/// always being discarded.
///
TEST_F(EmbedderTest, RenderTargetCacheDisabled) {
auto& context = GetEmbedderContext(ContextType::kOpenGLContext);

EmbedderConfigBuilder builder(context);
builder.SetOpenGLRendererConfig(SkISize::Make(300, 200));
builder.SetCompositor();
builder.SetDartEntrypoint("render_targets_are_recycled");
builder.SetRenderTargetType(
EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLTexture);

fml::CountDownLatch latch(2);

context.AddNativeCallback("SignalNativeTest",
CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
latch.CountDown();
}));

context.GetCompositor().SetNextPresentCallback(
[&](const FlutterLayer** layers, size_t layers_count) {
ASSERT_EQ(layers_count, 20u);
latch.CountDown();
});

context.GetCompositor().SetUpdateAvoidCacheCallback(
[](bool* avoid_cache) { *avoid_cache = true; });

auto engine = builder.LaunchEngine();
ASSERT_TRUE(engine.is_valid());

FlutterWindowMetricsEvent event = {};
event.struct_size = sizeof(event);
event.width = 300;
event.height = 200;
event.pixel_ratio = 1.0;
ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event),
kSuccess);

latch.Wait();
// Instead of being recycled, the 10 render targets should be created for each
// of the 7 frames.
ASSERT_EQ(context.GetCompositor().GetBackingStoresCreatedCount(), 70u);
}

TEST_F(EmbedderTest, CompositorRenderTargetsAreInStableOrder) {
auto& context = GetEmbedderContext(ContextType::kOpenGLContext);

Expand Down