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

[embedder] Compositor can specify that no backing stores be cached #22780

Merged
merged 1 commit into from
Dec 2, 2020
Merged
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
5 changes: 4 additions & 1 deletion shell/platform/embedder/embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,8 @@ InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor) {
SAFE_ACCESS(compositor, collect_backing_store_callback, nullptr);
auto c_present_callback =
SAFE_ACCESS(compositor, present_layers_callback, nullptr);
bool avoid_backing_store_cache =
SAFE_ACCESS(compositor, avoid_backing_store_cache, false);

// Make sure the required callbacks are present
if (!c_create_callback || !c_collect_callback || !c_present_callback) {
Expand All @@ -568,7 +570,8 @@ InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor) {
};

return {std::make_unique<flutter::EmbedderExternalViewEmbedder>(
create_render_target_callback, present_callback),
avoid_backing_store_cache, create_render_target_callback,
present_callback),
false};
}

Expand Down
2 changes: 2 additions & 0 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,8 @@ typedef struct {
/// Callback invoked by the engine to composite the contents of each layer
/// onto the screen.
FlutterLayersPresentCallback present_layers_callback;
/// Avoid caching backing stores provided by this compositor.
bool avoid_backing_store_cache;
} FlutterCompositor;

typedef struct {
Expand Down
10 changes: 7 additions & 3 deletions shell/platform/embedder/embedder_external_view_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
namespace flutter {

EmbedderExternalViewEmbedder::EmbedderExternalViewEmbedder(
bool avoid_backing_store_cache,
const CreateRenderTargetCallback& create_render_target_callback,
const PresentCallback& present_callback)
: create_render_target_callback_(create_render_target_callback),
: avoid_backing_store_cache_(avoid_backing_store_cache),
create_render_target_callback_(create_render_target_callback),
present_callback_(present_callback) {
FML_DCHECK(create_render_target_callback_);
FML_DCHECK(present_callback_);
Expand Down Expand Up @@ -263,8 +265,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 (!avoid_backing_store_cache_) {
render_target_cache_.CacheRenderTarget(render_target.first,
std::move(render_target.second));
}
}

frame->Submit();
Expand Down
7 changes: 7 additions & 0 deletions shell/platform/embedder/embedder_external_view_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder {
/// @brief Creates an external view embedder used by the generic embedder
/// API.
///
/// @param[in] avoid_backing_store_cache If set, create_render_target callback
/// will beinvoked every frame for every
/// engine composited layer. The result
/// will not cached.
///
/// @param[in] create_render_target_callback
/// The render target callback used to
/// request the render target for a layer.
Expand All @@ -49,6 +54,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder {
/// embedder for presentation.
///
EmbedderExternalViewEmbedder(
bool avoid_backing_store_cache,
const CreateRenderTargetCallback& create_render_target_callback,
const PresentCallback& present_callback);

Expand Down Expand Up @@ -100,6 +106,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder {
SkCanvas* GetRootCanvas() override;

private:
const bool avoid_backing_store_cache_;
const CreateRenderTargetCallback create_render_target_callback_;
const PresentCallback present_callback_;
SurfaceTransformationCallback surface_transformation_callback_;
Expand Down
3 changes: 2 additions & 1 deletion shell/platform/embedder/tests/embedder_config_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ void EmbedderConfigBuilder::SetPlatformMessageCallback(
context_.SetPlatformMessageCallback(callback);
}

void EmbedderConfigBuilder::SetCompositor() {
void EmbedderConfigBuilder::SetCompositor(bool avoid_backing_store_cache) {
context_.SetupCompositor();
auto& compositor = context_.GetCompositor();
compositor_.struct_size = sizeof(compositor_);
Expand Down Expand Up @@ -279,6 +279,7 @@ void EmbedderConfigBuilder::SetCompositor() {

);
};
compositor_.avoid_backing_store_cache = avoid_backing_store_cache;
project_args_.compositor = &compositor_;
}

Expand Down
2 changes: 1 addition & 1 deletion shell/platform/embedder/tests/embedder_config_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class EmbedderConfigBuilder {
void SetPlatformMessageCallback(
const std::function<void(const FlutterPlatformMessage*)>& callback);

void SetCompositor();
void SetCompositor(bool avoid_backing_store_cache = false);

FlutterCompositor& GetCompositor();

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 @@ -3352,5 +3352,52 @@ TEST_F(EmbedderTest, MultipleDisplaysWithSameDisplayIdIsInvalid) {
latch.Wait();
}

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

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

const unsigned num_frames = 8;
const unsigned num_engine_layers = 10;
const unsigned num_backing_stores = num_frames * num_engine_layers;
fml::CountDownLatch latch(1 + num_frames); // 1 for native test signal.

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

context.GetCompositor().SetPresentCallback(
[&](const FlutterLayer** layers, size_t layers_count) {
ASSERT_EQ(layers_count, 20u);
latch.CountDown();
},
/*one_shot=*/false);

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();

ASSERT_EQ(context.GetCompositor().GetBackingStoresCreatedCount(),
num_backing_stores);
// Killing the engine should collect all the frames.
engine.reset();
ASSERT_EQ(context.GetCompositor().GetPendingBackingStoresCount(), 0u);
}

} // namespace testing
} // namespace flutter