Skip to content

Commit

Permalink
[embedder] Compositor can specify that no backing stores be cached (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
iskakaushik authored Dec 2, 2020
1 parent d85cb10 commit 14cb066
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 6 deletions.
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

0 comments on commit 14cb066

Please sign in to comment.