13#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
20 bool avoid_backing_store_cache,
23 : avoid_backing_store_cache_(avoid_backing_store_cache),
24 create_render_target_callback_(create_render_target_callback),
25 present_callback_(present_callback) {
33 render_target_caches_.erase(
view_id);
38 surface_transformation_callback_ = std::move(surface_transformation_callback);
41DlMatrix EmbedderExternalViewEmbedder::GetSurfaceTransformation()
const {
42 if (!surface_transformation_callback_) {
46 return surface_transformation_callback_();
49void EmbedderExternalViewEmbedder::Reset() {
50 pending_views_.clear();
51 composition_order_.clear();
55void EmbedderExternalViewEmbedder::CancelFrame() {
60void EmbedderExternalViewEmbedder::BeginFrame(
61 GrDirectContext* context,
65void EmbedderExternalViewEmbedder::PrepareFlutterView(
67 double device_pixel_ratio) {
70 pending_frame_size_ = frame_size;
71 pending_device_pixel_ratio_ = device_pixel_ratio;
72 pending_surface_transformation_ = GetSurfaceTransformation();
75 pending_frame_size_, pending_surface_transformation_);
80void EmbedderExternalViewEmbedder::PrerollCompositeEmbeddedView(
82 std::unique_ptr<EmbeddedViewParams>
params) {
83 auto vid = EmbedderExternalView::ViewIdentifier(
view_id);
86 pending_views_[vid] = std::make_unique<EmbedderExternalView>(
88 pending_surface_transformation_,
92 composition_order_.push_back(vid);
96DlCanvas* EmbedderExternalViewEmbedder::GetRootCanvas() {
98 if (found == pending_views_.end()) {
100 <<
"No root canvas could be found. This is extremely unlikely and "
101 "indicates that the external view embedder did not receive the "
102 "notification to begin the frame.";
105 return found->second->GetCanvas();
109DlCanvas* EmbedderExternalViewEmbedder::CompositeEmbeddedView(int64_t
view_id) {
110 auto vid = EmbedderExternalView::ViewIdentifier(
view_id);
111 auto found = pending_views_.find(vid);
112 if (found == pending_views_.end()) {
113 FML_DCHECK(
false) <<
"Attempted to composite a view that was not "
117 return found->second->GetCanvas();
122 const DlISize& backing_store_size) {
143 explicit PlatformView(
const EmbedderExternalView*
view) {
148 DlRect clip =
view->GetEmbeddedViewParams()->finalBoundingRect();
150 for (
auto i =
params->mutatorsStack().Begin();
151 i !=
params->mutatorsStack().End(); ++
i) {
153 switch (m->GetType()) {
155 auto rect = m->GetRect().TransformAndClipBounds(matrix);
156 clip = clip.IntersectionOrEmpty(rect);
160 auto rect = m->GetRRect().GetBounds().TransformAndClipBounds(matrix);
161 clip = clip.IntersectionOrEmpty(rect);
165 auto rect = m->GetRSE().GetBounds().TransformAndClipBounds(matrix);
166 clip = clip.IntersectionOrEmpty(rect);
170 auto rect = m->GetPath().GetBounds().TransformAndClipBounds(matrix);
171 clip = clip.IntersectionOrEmpty(rect);
175 matrix = matrix * m->GetMatrix();
201 bool IntersectsPlatformView(
const SkRect& rect) {
212 bool IntersectsPlatformView(
const DlRegion& region) {
224 bool IntersectsFlutterContents(
const SkRect& rect) {
225 return flutter_contents_region_.intersects(
ToDlIRect(rect.roundOut()));
230 bool IntersectsFlutterContents(
const DlRegion& region) {
231 return flutter_contents_region_.intersects(region);
240 void AddFlutterContents(EmbedderExternalView* contents,
241 const DlRegion& contents_region) {
242 flutter_contents_.push_back(contents);
243 flutter_contents_region_ =
247 bool has_flutter_contents()
const {
return !flutter_contents_.empty(); }
249 void SetRenderTarget(std::unique_ptr<EmbedderRenderTarget>
target) {
252 render_target_ = std::move(
target);
257 void RenderFlutterContents() {
259 if (render_target_) {
260 bool clear_surface =
true;
261 for (
auto c : flutter_contents_) {
262 c->Render(*render_target_, clear_surface);
263 clear_surface =
false;
270 const std::vector<PlatformView>& platform_views()
const {
271 return platform_views_;
274 EmbedderRenderTarget* render_target() {
return render_target_.get(); }
276 std::vector<DlIRect> coverage() {
277 return flutter_contents_region_.getRects();
281 std::vector<PlatformView> platform_views_;
282 std::vector<EmbedderExternalView*> flutter_contents_;
283 DlRegion flutter_contents_region_;
284 std::unique_ptr<EmbedderRenderTarget> render_target_;
285 friend class LayerBuilder;
298 using RenderTargetProvider =
299 std::function<std::unique_ptr<EmbedderRenderTarget>(
302 explicit LayerBuilder(
DlISize frame_size) : frame_size_(frame_size) {
303 layers_.push_back(Layer());
311 void AddExternalView(EmbedderExternalView*
view) {
312 if (
view->HasPlatformView()) {
316 if (
view->HasEngineRenderedContents()) {
317 AddFlutterContents(
view);
322 void PrepareBackingStore(
const RenderTargetProvider& target_provider) {
323 for (
auto& layer : layers_) {
324 if (layer.has_flutter_contents()) {
325 layer.SetRenderTarget(target_provider(frame_size_));
333 for (
auto& layer : layers_) {
334 if (layer.has_flutter_contents()) {
335 layer.RenderFlutterContents();
341 void PushLayers(EmbedderLayers&
layers) {
342 for (
auto& layer : layers_) {
343 for (
auto&
view : layer.platform_views()) {
344 auto platform_view_id =
view.view_identifier.platform_view_id;
345 if (platform_view_id.has_value()) {
346 layers.PushPlatformViewLayer(platform_view_id.value(), *
view.params);
349 if (layer.render_target() !=
nullptr) {
350 layers.PushBackingStoreLayer(layer.render_target()->GetBackingStore(),
357 std::vector<std::unique_ptr<EmbedderRenderTarget>>
358 ClearAndCollectRenderTargets() {
359 std::vector<std::unique_ptr<EmbedderRenderTarget>> result;
360 for (
auto& layer : layers_) {
361 if (layer.render_target() !=
nullptr) {
362 result.push_back(std::move(layer.render_target_));
370 void AddPlatformView(PlatformView
view) {
371 GetLayerForPlatformView(
view).AddPlatformView(
view);
374 void AddFlutterContents(EmbedderExternalView* contents) {
375 FML_DCHECK(contents->HasEngineRenderedContents());
377 DlRegion region = contents->GetDlRegion();
378 GetLayerForFlutterContentsRegion(region).AddFlutterContents(contents,
388 Layer& GetLayerForPlatformView(PlatformView
view) {
389 for (
auto iter = layers_.rbegin(); iter != layers_.rend(); ++iter) {
392 if (iter->IntersectsFlutterContents(
view.clipped_frame)) {
393 if (iter == layers_.rbegin()) {
394 layers_.emplace_back();
395 return layers_.back();
401 if (iter->IntersectsPlatformView(
view.clipped_frame)) {
405 return layers_.front();
410 Layer& GetLayerForFlutterContentsRegion(
const DlRegion& region) {
411 for (
auto iter = layers_.rbegin(); iter != layers_.rend(); ++iter) {
412 if (iter->IntersectsPlatformView(region) ||
413 iter->IntersectsFlutterContents(region)) {
417 return layers_.front();
420 std::vector<Layer> layers_;
426void EmbedderExternalViewEmbedder::SubmitFlutterView(
427 int64_t flutter_view_id,
428 GrDirectContext* context,
429 const std::shared_ptr<impeller::AiksContext>& aiks_context,
430 std::unique_ptr<SurfaceFrame> frame) {
433 EmbedderRenderTargetCache& render_target_cache =
434 render_target_caches_[flutter_view_id];
440 for (
auto view_id : composition_order_) {
442 builder.AddExternalView(
view.get());
445 builder.PrepareBackingStore([&](
const DlISize& frame_size) {
446 if (!avoid_backing_store_cache_) {
447 std::unique_ptr<EmbedderRenderTarget>
target =
448 render_target_cache.GetRenderTarget(
449 EmbedderExternalView::RenderTargetDescriptor(frame_size));
455 return create_render_target_callback_(context, aiks_context, config);
470 auto deferred_cleanup_render_targets =
471 render_target_cache.ClearAllRenderTargetsInCache();
478 context->resetContext(kAll_GrBackendState);
491 context->flushAndSubmit();
496 auto presentation_time_optional = frame->submit_info().presentation_time;
497 uint64_t presentation_time =
498 presentation_time_optional.has_value()
499 ? presentation_time_optional->ToEpochDelta().ToNanoseconds()
505 EmbedderLayers presented_layers(
506 pending_frame_size_, pending_device_pixel_ratio_,
507 pending_surface_transformation_, presentation_time);
509 builder.PushLayers(presented_layers);
511 presented_layers.InvokePresentCallback(flutter_view_id, present_callback_);
518 deferred_cleanup_render_targets.clear();
520 auto render_targets = builder.ClearAndCollectRenderTargets();
521 for (
auto& render_target : render_targets) {
522 if (!avoid_backing_store_cache_) {
523 render_target_cache.CacheRenderTarget(std::move(render_target));
static DlRegion MakeUnion(const DlRegion &a, const DlRegion &b)
void CollectView(int64_t view_id) override
EmbedderExternalViewEmbedder(bool avoid_backing_store_cache, const CreateRenderTargetCallback &create_render_target_callback, const PresentCallback &present_callback)
Creates an external view embedder used by the generic embedder API.
~EmbedderExternalViewEmbedder() override
Collects the external view embedder.
std::function< bool(FlutterViewId view_id, const std::vector< const FlutterLayer * > &layers)> PresentCallback
std::function< std::unique_ptr< EmbedderRenderTarget >(GrDirectContext *context, const std::shared_ptr< impeller::AiksContext > &aiks_context, const FlutterBackingStoreConfig &config)> CreateRenderTargetCallback
void SetSurfaceTransformationCallback(SurfaceTransformationCallback surface_transformation_callback)
Sets the surface transformation callback used by the external view embedder to ask the platform for t...
std::function< DlMatrix(void)> SurfaceTransformationCallback
EmbedderExternalView::ViewIdentifier view_identifier
const EmbeddedViewParams * params
const FlutterLayer ** layers
G_BEGIN_DECLS FlutterViewId view_id
#define FML_DLOG(severity)
#define FML_DCHECK(condition)
impeller::Matrix DlMatrix
impeller::ISize32 DlISize
static FlutterBackingStoreConfig MakeBackingStoreConfig(int64_t view_id, const DlISize &backing_store_size)
@ kBackdropClipRSuperellipse
const DlIRect & ToDlIRect(const SkIRect &rect)
static const auto kRootViewIdentifier
const SkRect & ToSkRect(const DlRect &rect)
flutter::DlCanvas DlCanvas
size_t struct_size
The size of this struct. Must be sizeof(FlutterBackingStoreConfig).
FlutterSize size
The size of the render target the engine expects to render into.
A 4x4 matrix using column-major storage.
RoundOut(const TRect< U > &r)
constexpr TRect TransformAndClipBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle, clipped against the near clippin...
static constexpr TRect MakeSize(const TSize< U > &size)