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();
197 bool IntersectsPlatformView(
const SkRect& rect) {
208 bool IntersectsPlatformView(
const DlRegion& region) {
220 bool IntersectsFlutterContents(
const SkRect& rect) {
221 return flutter_contents_region_.intersects(
ToDlIRect(rect.roundOut()));
226 bool IntersectsFlutterContents(
const DlRegion& region) {
227 return flutter_contents_region_.intersects(region);
236 void AddFlutterContents(EmbedderExternalView* contents,
237 const DlRegion& contents_region) {
238 flutter_contents_.push_back(contents);
239 flutter_contents_region_ =
243 bool has_flutter_contents()
const {
return !flutter_contents_.empty(); }
245 void SetRenderTarget(std::unique_ptr<EmbedderRenderTarget>
target) {
248 render_target_ = std::move(
target);
253 void RenderFlutterContents() {
255 if (render_target_) {
256 bool clear_surface =
true;
257 for (
auto c : flutter_contents_) {
258 c->Render(*render_target_, clear_surface);
259 clear_surface =
false;
266 const std::vector<PlatformView>& platform_views()
const {
267 return platform_views_;
270 EmbedderRenderTarget* render_target() {
return render_target_.get(); }
272 std::vector<DlIRect> coverage() {
273 return flutter_contents_region_.getRects();
277 std::vector<PlatformView> platform_views_;
278 std::vector<EmbedderExternalView*> flutter_contents_;
279 DlRegion flutter_contents_region_;
280 std::unique_ptr<EmbedderRenderTarget> render_target_;
281 friend class LayerBuilder;
294 using RenderTargetProvider =
295 std::function<std::unique_ptr<EmbedderRenderTarget>(
298 explicit LayerBuilder(
DlISize frame_size) : frame_size_(frame_size) {
299 layers_.push_back(Layer());
307 void AddExternalView(EmbedderExternalView*
view) {
308 if (
view->HasPlatformView()) {
312 if (
view->HasEngineRenderedContents()) {
313 AddFlutterContents(
view);
318 void PrepareBackingStore(
const RenderTargetProvider& target_provider) {
319 for (
auto& layer : layers_) {
320 if (layer.has_flutter_contents()) {
321 layer.SetRenderTarget(target_provider(frame_size_));
329 for (
auto& layer : layers_) {
330 if (layer.has_flutter_contents()) {
331 layer.RenderFlutterContents();
337 void PushLayers(EmbedderLayers&
layers) {
338 for (
auto& layer : layers_) {
339 for (
auto&
view : layer.platform_views()) {
340 auto platform_view_id =
view.view_identifier.platform_view_id;
341 if (platform_view_id.has_value()) {
342 layers.PushPlatformViewLayer(platform_view_id.value(), *
view.params);
345 if (layer.render_target() !=
nullptr) {
346 layers.PushBackingStoreLayer(layer.render_target()->GetBackingStore(),
353 std::vector<std::unique_ptr<EmbedderRenderTarget>>
354 ClearAndCollectRenderTargets() {
355 std::vector<std::unique_ptr<EmbedderRenderTarget>> result;
356 for (
auto& layer : layers_) {
357 if (layer.render_target() !=
nullptr) {
358 result.push_back(std::move(layer.render_target_));
366 void AddPlatformView(PlatformView
view) {
367 GetLayerForPlatformView(
view).AddPlatformView(
view);
370 void AddFlutterContents(EmbedderExternalView* contents) {
371 FML_DCHECK(contents->HasEngineRenderedContents());
373 DlRegion region = contents->GetDlRegion();
374 GetLayerForFlutterContentsRegion(region).AddFlutterContents(contents,
384 Layer& GetLayerForPlatformView(PlatformView
view) {
385 for (
auto iter = layers_.rbegin(); iter != layers_.rend(); ++iter) {
388 if (iter->IntersectsFlutterContents(
view.clipped_frame)) {
389 if (iter == layers_.rbegin()) {
390 layers_.emplace_back();
391 return layers_.back();
397 if (iter->IntersectsPlatformView(
view.clipped_frame)) {
401 return layers_.front();
406 Layer& GetLayerForFlutterContentsRegion(
const DlRegion& region) {
407 for (
auto iter = layers_.rbegin(); iter != layers_.rend(); ++iter) {
408 if (iter->IntersectsPlatformView(region) ||
409 iter->IntersectsFlutterContents(region)) {
413 return layers_.front();
416 std::vector<Layer> layers_;
422void EmbedderExternalViewEmbedder::SubmitFlutterView(
423 int64_t flutter_view_id,
424 GrDirectContext* context,
425 const std::shared_ptr<impeller::AiksContext>& aiks_context,
426 std::unique_ptr<SurfaceFrame> frame) {
429 EmbedderRenderTargetCache& render_target_cache =
430 render_target_caches_[flutter_view_id];
436 for (
auto view_id : composition_order_) {
438 builder.AddExternalView(
view.get());
441 builder.PrepareBackingStore([&](
const DlISize& frame_size) {
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();
474 context->resetContext(kAll_GrBackendState);
487 context->flushAndSubmit();
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 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)
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)