5#include "flutter/shell/platform/embedder/embedder_external_view_embedder.h"
10#include "flutter/common/constants.h"
11#include "flutter/shell/platform/embedder/embedder_layers.h"
12#include "flutter/shell/platform/embedder/embedder_render_target.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);
41SkMatrix 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(
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 SkISize& backing_store_size) {
143 explicit PlatformView(
const EmbedderExternalView* view) {
146 params = view->GetEmbeddedViewParams();
148 clipped_frame = view->GetEmbeddedViewParams()->finalBoundingRect();
150 for (
auto i =
params->mutatorsStack().Begin();
151 i !=
params->mutatorsStack().End(); ++
i) {
153 switch (
m->GetType()) {
197 bool IntersectsPlatformView(
const SkRect&
rect) {
208 bool IntersectsPlatformView(
const DlRegion&
region) {
219 bool IntersectsFlutterContents(
const SkRect&
rect) {
220 return flutter_contents_region_.intersects(
rect.roundOut());
225 bool IntersectsFlutterContents(
const DlRegion&
region) {
226 return flutter_contents_region_.intersects(
region);
235 void AddFlutterContents(EmbedderExternalView* contents,
236 const DlRegion& contents_region) {
237 flutter_contents_.push_back(contents);
238 flutter_contents_region_ =
242 bool has_flutter_contents()
const {
return !flutter_contents_.empty(); }
244 void SetRenderTarget(std::unique_ptr<EmbedderRenderTarget>
target) {
247 render_target_ = std::move(
target);
252 void RenderFlutterContents() {
254 if (render_target_) {
255 bool clear_surface =
true;
256 for (
auto c : flutter_contents_) {
257 c->Render(*render_target_, clear_surface);
258 clear_surface =
false;
265 const std::vector<PlatformView>& platform_views()
const {
266 return platform_views_;
269 EmbedderRenderTarget* render_target() {
return render_target_.get(); }
272 return flutter_contents_region_.getRects();
276 std::vector<PlatformView> platform_views_;
277 std::vector<EmbedderExternalView*> flutter_contents_;
278 DlRegion flutter_contents_region_;
279 std::unique_ptr<EmbedderRenderTarget> render_target_;
280 friend class LayerBuilder;
293 using RenderTargetProvider =
294 std::function<std::unique_ptr<EmbedderRenderTarget>(
297 explicit LayerBuilder(
SkISize frame_size) : frame_size_(frame_size) {
298 layers_.push_back(Layer());
306 void AddExternalView(EmbedderExternalView* view) {
307 if (view->HasPlatformView()) {
311 if (view->HasEngineRenderedContents()) {
312 AddFlutterContents(view);
317 void PrepareBackingStore(
const RenderTargetProvider& target_provider) {
318 for (
auto& layer : layers_) {
319 if (layer.has_flutter_contents()) {
320 layer.SetRenderTarget(target_provider(frame_size_));
328 for (
auto& layer : layers_) {
329 if (layer.has_flutter_contents()) {
330 layer.RenderFlutterContents();
336 void PushLayers(EmbedderLayers& layers) {
337 for (
auto& layer : layers_) {
338 for (
auto& view : layer.platform_views()) {
339 auto platform_view_id = view.view_identifier.platform_view_id;
340 if (platform_view_id.has_value()) {
341 layers.PushPlatformViewLayer(platform_view_id.value(), *view.params);
344 if (layer.render_target() !=
nullptr) {
345 layers.PushBackingStoreLayer(layer.render_target()->GetBackingStore(),
352 std::vector<std::unique_ptr<EmbedderRenderTarget>>
353 ClearAndCollectRenderTargets() {
354 std::vector<std::unique_ptr<EmbedderRenderTarget>>
result;
355 for (
auto& layer : layers_) {
356 if (layer.render_target() !=
nullptr) {
357 result.push_back(std::move(layer.render_target_));
365 void AddPlatformView(PlatformView view) {
366 GetLayerForPlatformView(view).AddPlatformView(view);
369 void AddFlutterContents(EmbedderExternalView* contents) {
370 FML_DCHECK(contents->HasEngineRenderedContents());
372 DlRegion
region = contents->GetDlRegion();
373 GetLayerForFlutterContentsRegion(
region).AddFlutterContents(contents,
383 Layer& GetLayerForPlatformView(PlatformView view) {
384 for (
auto iter = layers_.rbegin(); iter != layers_.rend(); ++iter) {
387 if (iter->IntersectsFlutterContents(view.clipped_frame)) {
388 if (iter == layers_.rbegin()) {
389 layers_.emplace_back();
390 return layers_.back();
396 if (iter->IntersectsPlatformView(view.clipped_frame)) {
400 return layers_.front();
405 Layer& GetLayerForFlutterContentsRegion(
const DlRegion&
region) {
406 for (
auto iter = layers_.rbegin(); iter != layers_.rend(); ++iter) {
407 if (iter->IntersectsPlatformView(
region) ||
408 iter->IntersectsFlutterContents(
region)) {
412 return layers_.front();
415 std::vector<Layer> layers_;
421void EmbedderExternalViewEmbedder::SubmitFlutterView(
422 int64_t flutter_view_id,
424 const std::shared_ptr<impeller::AiksContext>& aiks_context,
425 std::unique_ptr<SurfaceFrame>
frame) {
428 EmbedderRenderTargetCache& render_target_cache =
429 render_target_caches_[flutter_view_id];
431 pending_frame_size_.
height());
432 pending_surface_transformation_.
mapRect(&_rect);
436 for (
auto view_id : composition_order_) {
437 auto& view = pending_views_[view_id];
438 builder.AddExternalView(view.get());
442 if (!avoid_backing_store_cache_) {
443 std::unique_ptr<EmbedderRenderTarget>
target =
444 render_target_cache.GetRenderTarget(
445 EmbedderExternalView::RenderTargetDescriptor(frame_size));
451 return create_render_target_callback_(context, aiks_context, config);
466 auto deferred_cleanup_render_targets =
467 render_target_cache.ClearAllRenderTargetsInCache();
492 auto presentation_time_optional =
frame->submit_info().presentation_time;
493 uint64_t presentation_time =
494 presentation_time_optional.has_value()
495 ? presentation_time_optional->ToEpochDelta().ToNanoseconds()
501 EmbedderLayers presented_layers(
502 pending_frame_size_, pending_device_pixel_ratio_,
503 pending_surface_transformation_, presentation_time);
505 builder.PushLayers(presented_layers);
507 presented_layers.InvokePresentCallback(flutter_view_id, present_callback_);
514 deferred_cleanup_render_targets.clear();
516 auto render_targets =
builder.ClearAndCollectRenderTargets();
517 for (
auto& render_target : render_targets) {
518 if (!avoid_backing_store_cache_) {
519 render_target_cache.CacheRenderTarget(std::move(render_target));
static const uint32_t kAll_GrBackendState
void resetContext(uint32_t state=kAll_GrBackendState)
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
bool intersects(const SkIRect &rect) const
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.
std::function< SkMatrix(void)> SurfaceTransformationCallback
~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...
EmbedderExternalView::ViewIdentifier view_identifier
const EmbeddedViewParams * params
#define FML_DLOG(severity)
#define FML_DCHECK(condition)
ClipOpAndAA opAA SkRegion region
sk_sp< SkBlender > blender SkRect rect
static FlutterBackingStoreConfig MakeBackingStoreConfig(int64_t view_id, const SkISize &backing_store_size)
static const auto kRootViewIdentifier
flutter::DlCanvas DlCanvas
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
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.
static constexpr SkISize Make(int32_t w, int32_t h)
constexpr int32_t width() const
constexpr int32_t height() const
static constexpr SkRect MakeEmpty()
bool intersect(const SkRect &r)
static SkRect MakeIWH(int w, int h)
constexpr float height() const
constexpr float width() const