1212#include " flutter/impeller/display_list/dl_image_impeller.h"
1313#include " flutter/impeller/geometry/size.h"
1414#include " flutter/shell/common/snapshot_controller.h"
15+ #include " impeller/renderer/render_target.h"
1516
1617namespace flutter {
1718
@@ -21,37 +22,84 @@ sk_sp<DlImage> DoMakeRasterSnapshot(
2122 SkISize size,
2223 const std::shared_ptr<impeller::AiksContext>& context) {
2324 TRACE_EVENT0 (" flutter" , __FUNCTION__);
25+ if (!context) {
26+ return nullptr ;
27+ }
28+ // Determine render target size.
29+ auto max_size = context->GetContext ()
30+ ->GetResourceAllocator ()
31+ ->GetMaxTextureSizeSupported ();
32+ double scale_factor_x =
33+ static_cast <double >(max_size.width ) / static_cast <double >(size.width ());
34+ double scale_factor_y =
35+ static_cast <double >(max_size.height ) / static_cast <double >(size.height ());
36+ double scale_factor = std::min ({1.0 , scale_factor_x, scale_factor_y});
37+
38+ auto render_target_size = impeller::ISize (size.width (), size.height ());
39+
40+ // Scale down the render target size to the max supported by the
41+ // GPU if necessary. Exceeding the max would otherwise cause a
42+ // null result.
43+ if (scale_factor < 1.0 ) {
44+ render_target_size.width *= scale_factor;
45+ render_target_size.height *= scale_factor;
46+ }
47+
48+ #if EXPERIMENTAL_CANVAS
49+ // Do not use the render target cache as the lifecycle of this texture
50+ // will outlive a particular frame.
51+ impeller::ISize impeller_size = impeller::ISize (size.width (), size.height ());
52+ impeller::RenderTargetAllocator render_target_allocator =
53+ impeller::RenderTargetAllocator (
54+ context->GetContext ()->GetResourceAllocator ());
55+ impeller::RenderTarget target;
56+ if (context->GetContext ()->GetCapabilities ()->SupportsOffscreenMSAA ()) {
57+ target = render_target_allocator.CreateOffscreenMSAA (
58+ *context->GetContext (), // context
59+ impeller_size, // size
60+ /* mip_count=*/ 1 ,
61+ " Picture Snapshot MSAA" , // label
62+ impeller::RenderTarget::
63+ kDefaultColorAttachmentConfigMSAA // color_attachment_config
64+ );
65+ } else {
66+ target = render_target_allocator.CreateOffscreen (
67+ *context->GetContext (), // context
68+ impeller_size, // size
69+ /* mip_count=*/ 1 ,
70+ " Picture Snapshot" , // label
71+ impeller::RenderTarget::
72+ kDefaultColorAttachmentConfig // color_attachment_config
73+ );
74+ }
75+
76+ impeller::TextFrameDispatcher collector (context->GetContentContext (),
77+ impeller::Matrix ());
78+ display_list->Dispatch (collector, SkIRect::MakeSize (size));
79+ impeller::ExperimentalDlDispatcher impeller_dispatcher (
80+ context->GetContentContext (), target,
81+ display_list->root_has_backdrop_filter (),
82+ display_list->max_root_blend_mode (),
83+ impeller::IRect::MakeSize (impeller_size));
84+ display_list->Dispatch (impeller_dispatcher, SkIRect::MakeSize (size));
85+ impeller_dispatcher.FinishRecording ();
86+
87+ context->GetContentContext ().GetLazyGlyphAtlas ()->ResetTextFrames ();
88+
89+ return impeller::DlImageImpeller::Make (target.GetRenderTargetTexture (),
90+ DlImage::OwningContext::kRaster );
91+ #else
2492 impeller::DlDispatcher dispatcher;
2593 display_list->Dispatch (dispatcher);
2694 impeller::Picture picture = dispatcher.EndRecordingAsPicture ();
27- if (context) {
28- auto max_size = context->GetContext ()
29- ->GetResourceAllocator ()
30- ->GetMaxTextureSizeSupported ();
31- double scale_factor_x =
32- static_cast <double >(max_size.width ) / static_cast <double >(size.width ());
33- double scale_factor_y = static_cast <double >(max_size.height ) /
34- static_cast <double >(size.height ());
35- double scale_factor =
36- std::min (1.0 , std::min (scale_factor_x, scale_factor_y));
37-
38- auto render_target_size = impeller::ISize (size.width (), size.height ());
39-
40- // Scale down the render target size to the max supported by the
41- // GPU if necessary. Exceeding the max would otherwise cause a
42- // null result.
43- if (scale_factor < 1.0 ) {
44- render_target_size.width *= scale_factor;
45- render_target_size.height *= scale_factor;
46- }
47-
48- std::shared_ptr<impeller::Image> image =
49- picture.ToImage (*context, render_target_size);
50- if (image) {
51- return impeller::DlImageImpeller::Make (image->GetTexture (),
52- DlImage::OwningContext::kRaster );
53- }
95+
96+ std::shared_ptr<impeller::Image> image =
97+ picture.ToImage (*context, render_target_size);
98+ if (image) {
99+ return impeller::DlImageImpeller::Make (image->GetTexture (),
100+ DlImage::OwningContext::kRaster );
54101 }
102+ #endif // EXPERIMENTAL_CANVAS
55103
56104 return nullptr ;
57105}
0 commit comments