Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
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
2 changes: 2 additions & 0 deletions flow/embedded_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ bool DisplayListEmbedderViewSlice::recording_ended() {
return builder_ == nullptr;
}

void ExternalViewEmbedder::CollectView(int64_t view_id) {}

void ExternalViewEmbedder::SubmitFlutterView(
int64_t flutter_view_id,
GrDirectContext* context,
Expand Down
9 changes: 9 additions & 0 deletions flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,15 @@ class ExternalViewEmbedder {

virtual ~ExternalViewEmbedder() = default;

// Deallocate the resources for displaying a view.
//
// This method must be called when a view is removed from the engine.
//
// When the ExternalViewEmbedder is requested to draw an unrecognized view, it
// implicitly allocates necessary resources. These resources must be
// explicitly deallocated.
virtual void CollectView(int64_t view_id);

// Usually, the root canvas is not owned by the view embedder. However, if
// the view embedder wants to provide a canvas to the rasterizer, it may
// return one here. This canvas takes priority over the canvas materialized
Expand Down
3 changes: 3 additions & 0 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ void Rasterizer::NotifyLowMemoryWarning() const {
}

void Rasterizer::CollectView(int64_t view_id) {
if (external_view_embedder_) {
external_view_embedder_->CollectView(view_id);
}
view_records_.erase(view_id);
}

Expand Down
9 changes: 5 additions & 4 deletions shell/common/rasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,11 +261,12 @@ class Rasterizer final : public SnapshotDelegate,
//----------------------------------------------------------------------------
/// @brief Deallocate the resources for displaying a view.
///
/// This method must be called when a view is removed.
/// This method must be called on the raster task runner when a
/// view is removed from the engine.
///
/// The rasterizer don't need views to be registered. Last-frame
/// states for views are recorded when layer trees are rasterized
/// to the view and used during `Rasterizer::DrawLastLayerTrees`.
/// When the rasterizer is requested to draw an unrecognized view,
/// it implicitly allocates necessary resources. These resources
/// must be explicitly deallocated.
///
/// @param[in] view_id The ID of the view.
///
Expand Down
11 changes: 11 additions & 0 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1780,6 +1780,9 @@ typedef struct {
size_t struct_size;
/// The size of the render target the engine expects to render into.
FlutterSize size;
/// The identifier for the view that the engine will use this backing store to
/// render into.
FlutterViewId view_id;
} FlutterBackingStoreConfig;

typedef enum {
Expand Down Expand Up @@ -1893,9 +1896,13 @@ typedef struct {
/// `FlutterBackingStore::struct_size` when specifying a new backing store to
/// the engine. This only matters if the embedder expects to be used with
/// engines older than the version whose headers it used during compilation.
///
/// The callback should return true if the operation was successful.
FlutterBackingStoreCreateCallback create_backing_store_callback;
/// A callback invoked by the engine to release the backing store. The
/// embedder may collect any resources associated with the backing store.
///
/// The callback should return true if the operation was successful.
FlutterBackingStoreCollectCallback collect_backing_store_callback;
/// Callback invoked by the engine to composite the contents of each layer
/// onto the implicit view.
Expand All @@ -1907,6 +1914,8 @@ typedef struct {
/// Only one of `present_layers_callback` and `present_view_callback` may be
/// provided. Providing both is an error and engine initialization will
/// terminate.
///
/// The callback should return true if the operation was successful.
FlutterLayersPresentCallback present_layers_callback;
/// Avoid caching backing stores provided by this compositor.
bool avoid_backing_store_cache;
Expand All @@ -1916,6 +1925,8 @@ typedef struct {
/// Only one of `present_layers_callback` and `present_view_callback` may be
/// provided. Providing both is an error and engine initialization will
/// terminate.
///
/// The callback should return true if the operation was successful.
FlutterPresentViewCallback present_view_callback;
} FlutterCompositor;

Expand Down
42 changes: 26 additions & 16 deletions shell/platform/embedder/embedder_external_view_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ EmbedderExternalViewEmbedder::EmbedderExternalViewEmbedder(

EmbedderExternalViewEmbedder::~EmbedderExternalViewEmbedder() = default;

void EmbedderExternalViewEmbedder::CollectView(int64_t view_id) {
render_target_caches_.erase(view_id);
}

void EmbedderExternalViewEmbedder::SetSurfaceTransformationCallback(
SurfaceTransformationCallback surface_transformation_callback) {
surface_transformation_callback_ = std::move(surface_transformation_callback);
Expand Down Expand Up @@ -114,13 +118,15 @@ DlCanvas* EmbedderExternalViewEmbedder::CompositeEmbeddedView(int64_t view_id) {
}

static FlutterBackingStoreConfig MakeBackingStoreConfig(
int64_t view_id,
const SkISize& backing_store_size) {
FlutterBackingStoreConfig config = {};

config.struct_size = sizeof(config);

config.size.width = backing_store_size.width();
config.size.height = backing_store_size.height();
config.view_id = view_id;

return config;
}
Expand Down Expand Up @@ -284,6 +290,10 @@ class Layer {
/// Implements https://flutter.dev/go/optimized-platform-view-layers
class LayerBuilder {
public:
using RenderTargetProvider =
std::function<std::unique_ptr<EmbedderRenderTarget>(
const SkISize& frame_size)>;

explicit LayerBuilder(SkISize frame_size) : frame_size_(frame_size) {
layers_.push_back(Layer());
}
Expand All @@ -304,13 +314,10 @@ class LayerBuilder {
}

/// Prepares the render targets for all layers that have Flutter contents.
void PrepareBackingStore(
const std::function<std::unique_ptr<EmbedderRenderTarget>(
FlutterBackingStoreConfig)>& target_provider) {
auto config = MakeBackingStoreConfig(frame_size_);
void PrepareBackingStore(const RenderTargetProvider& target_provider) {
for (auto& layer : layers_) {
if (layer.has_flutter_contents()) {
layer.SetRenderTarget(target_provider(config));
layer.SetRenderTarget(target_provider(frame_size_));
}
}
}
Expand Down Expand Up @@ -416,6 +423,10 @@ void EmbedderExternalViewEmbedder::SubmitFlutterView(
GrDirectContext* context,
const std::shared_ptr<impeller::AiksContext>& aiks_context,
std::unique_ptr<SurfaceFrame> frame) {
// The unordered_map render_target_cache creates a new entry if the view ID is
// unrecognized.
EmbedderRenderTargetCache& render_target_cache =
Copy link
Member

@loic-sharma loic-sharma Apr 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a comment on EmbedderRenderTargetCache's class declaration that it is view-specific?

render_target_caches_[flutter_view_id];
SkRect _rect = SkRect::MakeIWH(pending_frame_size_.width(),
pending_frame_size_.height());
pending_surface_transformation_.mapRect(&_rect);
Expand All @@ -427,17 +438,16 @@ void EmbedderExternalViewEmbedder::SubmitFlutterView(
builder.AddExternalView(view.get());
}

builder.PrepareBackingStore([&](FlutterBackingStoreConfig config) {
std::unique_ptr<EmbedderRenderTarget> target;
builder.PrepareBackingStore([&](const SkISize& frame_size) {
if (!avoid_backing_store_cache_) {
target = render_target_cache_.GetRenderTarget(
EmbedderExternalView::RenderTargetDescriptor(
SkISize{static_cast<int32_t>(config.size.width),
static_cast<int32_t>(config.size.height)}));
}
if (target != nullptr) {
return target;
std::unique_ptr<EmbedderRenderTarget> target =
render_target_cache.GetRenderTarget(
EmbedderExternalView::RenderTargetDescriptor(frame_size));
if (target != nullptr) {
return target;
}
}
auto config = MakeBackingStoreConfig(flutter_view_id, frame_size);
return create_render_target_callback_(context, aiks_context, config);
});

Expand All @@ -454,7 +464,7 @@ void EmbedderExternalViewEmbedder::SubmitFlutterView(
//
// @warning: Embedder may trample on our OpenGL context here.
auto deferred_cleanup_render_targets =
render_target_cache_.ClearAllRenderTargetsInCache();
render_target_cache.ClearAllRenderTargetsInCache();

// The OpenGL context could have been trampled by the embedder at this point
// as it attempted to collect old render targets and create new ones. Tell
Expand Down Expand Up @@ -502,7 +512,7 @@ void EmbedderExternalViewEmbedder::SubmitFlutterView(
auto render_targets = builder.ClearAndCollectRenderTargets();
for (auto& render_target : render_targets) {
if (!avoid_backing_store_cache_) {
render_target_cache_.CacheRenderTarget(std::move(render_target));
render_target_cache.CacheRenderTarget(std::move(render_target));
}
}

Expand Down
6 changes: 5 additions & 1 deletion shell/platform/embedder/embedder_external_view_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder {
///
~EmbedderExternalViewEmbedder() override;

// |ExternalViewEmbedder|
void CollectView(int64_t view_id) override;

//----------------------------------------------------------------------------
/// @brief Sets the surface transformation callback used by the external
/// view embedder to ask the platform for the per frame root
Expand Down Expand Up @@ -118,7 +121,8 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder {
SkMatrix pending_surface_transformation_;
EmbedderExternalView::PendingViews pending_views_;
std::vector<EmbedderExternalView::ViewIdentifier> composition_order_;
EmbedderRenderTargetCache render_target_cache_;
// The render target caches for views. Each key is a view ID.
std::unordered_map<int64_t, EmbedderRenderTargetCache> render_target_caches_;

void Reset();

Expand Down
4 changes: 4 additions & 0 deletions shell/platform/embedder/embedder_render_target_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ namespace flutter {
/// @brief A cache used to reference render targets that are owned by the
/// embedder but needed by th engine to render a frame.
///
/// A map of class is managed by EmbedderExternalViewEmbedder. Each
/// instance of this class manages the cached render targets for a
/// view.
///
class EmbedderRenderTargetCache {
public:
EmbedderRenderTargetCache();
Expand Down
Loading