Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
flutter::Rasterizer Class Referencefinal

#include <rasterizer.h>

Inheritance diagram for flutter::Rasterizer:
flutter::SnapshotDelegate flutter::Stopwatch::RefreshRateUpdater flutter::SnapshotController::Delegate

Classes

class  Delegate
 Used to forward events from the rasterizer to interested subsystems. Currently, the shell sets itself up as the rasterizer delegate to listen for frame rasterization events. It can then forward these events to the engine. More...
 
struct  Screenshot
 A POD type used to return the screenshot data along with the size of the frame. More...
 

Public Types

enum class  MakeGpuImageBehavior {
  kGpu ,
  kBitmap
}
 How to handle calls to MakeSkiaGpuImage. More...
 
enum class  ScreenshotType {
  SkiaPicture ,
  UncompressedImage ,
  CompressedImage ,
  SurfaceData
}
 The type of the screenshot to obtain of the previously rendered layer tree. More...
 
enum class  ScreenshotFormat {
  kUnknown ,
  kR8G8B8A8UNormInt ,
  kB8G8R8A8UNormInt ,
  kR16G16B16A16Float
}
 

Public Member Functions

 Rasterizer (Delegate &delegate, MakeGpuImageBehavior gpu_image_behavior=MakeGpuImageBehavior::kGpu)
 Creates a new instance of a rasterizer. Rasterizers may only be created on the raster task runner. Rasterizers are currently only created by the shell (which also sets itself up as the rasterizer delegate).
 
 ~Rasterizer ()
 Destroys the rasterizer. This must happen on the raster task runner. All GPU resources are collected before this call returns. Any context set up by the embedder to hold these resources can be immediately collected as well.
 
void SetImpellerContext (std::shared_ptr< impeller::ImpellerContextFuture > impeller_context)
 
void Setup (std::unique_ptr< Surface > surface)
 Rasterizers may be created well before an on-screen surface is available for rendering. Shells usually create a rasterizer in their constructors. Once an on-screen surface is available however, one may be provided to the rasterizer using this call. No rendering may occur before this call. The surface is held till the balancing call to Rasterizer::Teardown is made. Calling a setup before tearing down the previous surface (if this is not the first time the surface has been set up) is user error.
 
void Teardown ()
 Releases the previously set up on-screen render surface and collects associated resources. No more rendering may occur till the next call to Rasterizer::Setup with a new render surface. Calling a teardown without a setup is user error. Calling this method multiple times is safe.
 
void TeardownExternalViewEmbedder ()
 Releases any resource used by the external view embedder. For example, overlay surfaces or Android views. On Android, this method post a task to the platform thread, and waits until it completes.
 
void NotifyLowMemoryWarning () const
 Notifies the rasterizer that there is a low memory situation and it must purge as many unnecessary resources as possible. Currently, the Skia context associated with onscreen rendering is told to free GPU resources.
 
fml::TaskRunnerAffineWeakPtr< RasterizerGetWeakPtr () const
 Gets a weak pointer to the rasterizer. The rasterizer may only be accessed on the raster task runner.
 
fml::TaskRunnerAffineWeakPtr< SnapshotDelegateGetSnapshotDelegate () const
 
void CollectView (int64_t view_id)
 Deallocate the resources for displaying a view.
 
flutter::LayerTreeGetLastLayerTree (int64_t view_id)
 Returns the last successfully drawn layer tree for the given view, or nullptr if there isn't any. This is useful during DrawLastLayerTrees and computing frame damage.
 
void DrawLastLayerTrees (std::unique_ptr< FrameTimingsRecorder > frame_timings_recorder)
 Draws the last layer trees with their last configuration. This may seem entirely redundant at first glance. After all, on surface loss and re-acquisition, the framework generates a new layer tree. Otherwise, why render the same contents to the screen again? This is used as an optimization in cases where there are external textures (video or camera streams for example) in referenced in the layer tree. These textures may be updated at a cadence different from that of the Flutter application. Flutter can re-render the layer tree with just the updated textures instead of waiting for the framework to do the work to generate the layer tree describing the same contents.
 
GrDirectContext * GetGrContext () override
 
std::shared_ptr< flutter::TextureRegistryGetTextureRegistry () override
 Gets the registry of external textures currently in use by the rasterizer. These textures may be updated at a cadence different from that of the Flutter application. When an external texture is referenced in the Flutter layer tree, that texture is composited within the Flutter layer tree.
 
DrawStatus Draw (const std::shared_ptr< FramePipeline > &pipeline)
 Takes the next item from the layer tree pipeline and executes the raster thread frame workload for that pipeline item to render a frame on the on-screen surface.
 
Screenshot ScreenshotLastLayerTree (ScreenshotType type, bool base64_encode)
 Screenshots the last layer tree to one of the supported screenshot types and optionally Base 64 encodes that data for easier transmission and packaging (usually over the service protocol for instrumentation tools running on the host).
 
void SetNextFrameCallback (const fml::closure &callback)
 Sets a callback that will be executed when the next layer tree in rendered to the on-screen surface. This is used by embedders to listen for one time operations like listening for when the first frame is rendered so that they may hide splash screens.
 
void SetExternalViewEmbedder (const std::shared_ptr< ExternalViewEmbedder > &view_embedder)
 Set the External View Embedder. This is done on shell initialization. This is non-null on platforms that support embedding externally composited views.
 
void SetSnapshotSurfaceProducer (std::unique_ptr< SnapshotSurfaceProducer > producer)
 Set the snapshot surface producer. This is done on shell initialization. This is non-null on platforms that support taking GPU accelerated raster snapshots in the background.
 
flutter::CompositorContextcompositor_context ()
 Returns a pointer to the compositor context used by this rasterizer. This pointer will never be nullptr.
 
fml::RefPtr< fml::RasterThreadMergerGetRasterThreadMerger ()
 Returns the raster thread merger used by this rasterizer. This may be nullptr.
 
void SetResourceCacheMaxBytes (size_t max_bytes, bool from_user)
 Skia has no notion of time. To work around the performance implications of this, it may cache GPU resources to reference them from one frame to the next. Using this call, embedders may set the maximum bytes cached by Skia in its caches dedicated to on-screen rendering.
 
std::optional< size_t > GetResourceCacheMaxBytes () const
 The current value of Skia's resource cache size, if a surface is present.
 
void EnableThreadMergerIfNeeded ()
 Enables the thread merger if the external view embedder supports dynamic thread merging.
 
void DisableThreadMergerIfNeeded ()
 Disables the thread merger if the external view embedder supports dynamic thread merging.
 
bool IsTornDown ()
 Returns whether TearDown has been called.
 
std::optional< DrawSurfaceStatusGetLastDrawStatus (int64_t view_id)
 Returns the last status of drawing the specific view.
 
- Public Member Functions inherited from flutter::SnapshotController::Delegate
virtual ~Delegate ()=default
 

Detailed Description

The rasterizer is a component owned by the shell that resides on the raster task runner. Each shell owns exactly one instance of a rasterizer. The rasterizer may only be created, used and collected on the raster task runner.

The rasterizer owns the instance of the currently active on-screen render surface. On this surface, it renders the contents of layer trees submitted to it by the Engine (which lives on the UI task runner).

The primary components owned by the rasterizer are the compositor context and the on-screen render surface. The compositor context has all the GPU state necessary to render frames to the render surface.

Definition at line 114 of file rasterizer.h.

Member Enumeration Documentation

◆ MakeGpuImageBehavior

How to handle calls to MakeSkiaGpuImage.

Enumerator
kGpu 

MakeSkiaGpuImage returns a GPU resident image, if possible.

kBitmap 

MakeSkiaGpuImage returns a checkerboard bitmap. This is useful in test contexts where no GPU surface is available.

Definition at line 178 of file rasterizer.h.

178 {
179 /// MakeSkiaGpuImage returns a GPU resident image, if possible.
180 kGpu,
181 /// MakeSkiaGpuImage returns a checkerboard bitmap. This is useful in test
182 /// contexts where no GPU surface is available.
183 kBitmap,
184 };
@ kGpu
MakeSkiaGpuImage returns a GPU resident image, if possible.

◆ ScreenshotFormat

Enumerator
kUnknown 
kR8G8B8A8UNormInt 
kB8G8R8A8UNormInt 
kR16G16B16A16Float 

Definition at line 384 of file rasterizer.h.

384 {
385 // Unknown format, or Skia default.
386 kUnknown,
387 // RGBA 8 bits per channel.
389 // BGRA 8 bits per channel.
391 // RGBA 16 bit floating point per channel.
393 };

◆ ScreenshotType

The type of the screenshot to obtain of the previously rendered layer tree.

Enumerator
SkiaPicture 

A format used to denote a Skia picture. A Skia picture is a serialized representation of an SkPicture that can be used to introspect the series of commands used to draw that picture.

Skia pictures are typically stored as files with the .skp extension on disk. These files may be viewed in an interactive debugger available at https://debugger.skia.org/

UncompressedImage 

A format used to denote uncompressed image data. For Skia, this format is 32 bits per pixel, 8 bits per component and denoted by the kN32_SkColorType Skia color type. For Impeller, its format is specified in Screenshot::pixel_format.

CompressedImage 

A format used to denote compressed image data. The PNG compressed container is used.

SurfaceData 

Reads the data directly from the Rasterizer's surface. The pixel format is determined from the surface. This is the only way to read wide gamut color data, but isn't supported everywhere.

Definition at line 348 of file rasterizer.h.

348 {
349 // NOLINTBEGIN(readability-identifier-naming)
350 //--------------------------------------------------------------------------
351 /// A format used to denote a Skia picture. A Skia picture is a serialized
352 /// representation of an `SkPicture` that can be used to introspect the
353 /// series of commands used to draw that picture.
354 ///
355 /// Skia pictures are typically stored as files with the .skp extension on
356 /// disk. These files may be viewed in an interactive debugger available at
357 /// https://debugger.skia.org/
358 ///
360
361 //--------------------------------------------------------------------------
362 /// A format used to denote uncompressed image data. For Skia, this format
363 /// is 32 bits per pixel, 8 bits per component and
364 /// denoted by the `kN32_SkColorType ` Skia color type. For Impeller, its
365 /// format is specified in Screenshot::pixel_format.
366 ///
368
369 //--------------------------------------------------------------------------
370 /// A format used to denote compressed image data. The PNG compressed
371 /// container is used.
372 ///
374
375 //--------------------------------------------------------------------------
376 /// Reads the data directly from the Rasterizer's surface. The pixel format
377 /// is determined from the surface. This is the only way to read wide gamut
378 /// color data, but isn't supported everywhere.
380 // NOLINTEND(readability-identifier-naming)
381 };

Constructor & Destructor Documentation

◆ Rasterizer()

flutter::Rasterizer::Rasterizer ( Delegate delegate,
MakeGpuImageBehavior  gpu_image_behavior = MakeGpuImageBehavior::kGpu 
)
explicit

Creates a new instance of a rasterizer. Rasterizers may only be created on the raster task runner. Rasterizers are currently only created by the shell (which also sets itself up as the rasterizer delegate).

Parameters
[in]delegateThe rasterizer delegate.
[in]gpu_image_behaviorHow to handle calls to MakeSkiaGpuImage.

Definition at line 54 of file rasterizer.cc.

56 : delegate_(delegate),
57 gpu_image_behavior_(gpu_image_behavior),
58 compositor_context_(std::make_unique<flutter::CompositorContext>(*this)),
59 snapshot_controller_(
60 SnapshotController::Make(*this, delegate.GetSettings())),
61 weak_factory_(this) {
62 FML_DCHECK(compositor_context_);
63}
static std::unique_ptr< SnapshotController > Make(const Delegate &delegate, const Settings &settings)
#define FML_DCHECK(condition)
Definition logging.h:122

References FML_DCHECK.

◆ ~Rasterizer()

flutter::Rasterizer::~Rasterizer ( )
default

Destroys the rasterizer. This must happen on the raster task runner. All GPU resources are collected before this call returns. Any context set up by the embedder to hold these resources can be immediately collected as well.

Member Function Documentation

◆ CollectView()

void flutter::Rasterizer::CollectView ( int64_t  view_id)

Deallocate the resources for displaying a view.

        This method must be called on the raster task runner when a
        view is removed from the engine.

        When the rasterizer is requested to draw an unrecognized view,
        it implicitly allocates necessary resources. These resources
        must be explicitly deallocated.
Parameters
[in]view_idThe ID of the view.

Definition at line 194 of file rasterizer.cc.

194 {
195 if (external_view_embedder_) {
196 external_view_embedder_->CollectView(view_id);
197 }
198 view_records_.erase(view_id);
199}
G_BEGIN_DECLS FlutterViewId view_id

References view_id.

◆ compositor_context()

flutter::CompositorContext * flutter::Rasterizer::compositor_context ( )
inline

Returns a pointer to the compositor context used by this rasterizer. This pointer will never be nullptr.

Returns
The compositor context used by this rasterizer.

Definition at line 516 of file rasterizer.h.

516 {
517 return compositor_context_.get();
518 }

◆ DisableThreadMergerIfNeeded()

void flutter::Rasterizer::DisableThreadMergerIfNeeded ( )

Disables the thread merger if the external view embedder supports dynamic thread merging.

Attention
This method is thread-safe. When the thread merger is disabled, the raster task queue will continue to run in the same thread until |EnableThreadMergerIfNeeded| is called.
See also
ExternalViewEmbedder

Definition at line 167 of file rasterizer.cc.

167 {
168 if (raster_thread_merger_) {
169 raster_thread_merger_->Disable();
170 }
171}

References fml::RasterThreadMerger::Disable().

◆ Draw()

DrawStatus flutter::Rasterizer::Draw ( const std::shared_ptr< FramePipeline > &  pipeline)

Takes the next item from the layer tree pipeline and executes the raster thread frame workload for that pipeline item to render a frame on the on-screen surface.

Why does the draw call take a layer tree pipeline and not the layer tree directly?

The pipeline is the way book-keeping of frame workloads distributed across the multiple threads is managed. The rasterizer deals with the pipelines directly (instead of layer trees which is what it actually renders) because the pipeline consumer's workload must be accounted for within the pipeline itself. If the rasterizer took the layer tree directly, it would have to be taken out of the pipeline. That would signal the end of the frame workload and the pipeline would be ready for new frames. But the last frame has not been rendered by the frame yet! On the other hand, the pipeline must own the layer tree it renders because it keeps a reference to the last layer tree around till a new frame is rendered. So a simple reference wont work either. The Rasterizer::DoDraw method actually performs the GPU operations within the layer tree pipeline.

See also
Rasterizer::DoDraw
Parameters
[in]pipelineThe layer tree pipeline to take the next layer tree to render from.

Definition at line 248 of file rasterizer.cc.

248 {
249 TRACE_EVENT0("flutter", "GPURasterizer::Draw");
250 if (raster_thread_merger_ &&
251 !raster_thread_merger_->IsOnRasterizingThread()) {
252 // we yield and let this frame be serviced on the right thread.
254 }
255 FML_DCHECK(delegate_.GetTaskRunners()
258
259 DoDrawResult draw_result;
260 FramePipeline::Consumer consumer = [&draw_result,
261 this](std::unique_ptr<FrameItem> item) {
262 draw_result = DoDraw(std::move(item->frame_timings_recorder),
263 std::move(item->layer_tree_tasks));
264 };
265
266 PipelineConsumeResult consume_result = pipeline->Consume(consumer);
267 if (consume_result == PipelineConsumeResult::NoneAvailable) {
269 }
270 // if the raster status is to resubmit the frame, we push the frame to the
271 // front of the queue and also change the consume status to more available.
272
273 bool should_resubmit_frame = ShouldResubmitFrame(draw_result);
274 if (should_resubmit_frame) {
275 FML_CHECK(draw_result.resubmitted_item);
276 auto front_continuation = pipeline->ProduceIfEmpty();
277 PipelineProduceResult pipeline_result =
278 front_continuation.Complete(std::move(draw_result.resubmitted_item));
279 if (pipeline_result.success) {
281 }
282 } else if (draw_result.status == DoDrawStatus::kEnqueuePipeline) {
284 }
285
286 // EndFrame should perform cleanups for the external_view_embedder.
287 if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) {
288 external_view_embedder_->SetUsedThisFrame(false);
289 external_view_embedder_->EndFrame(should_resubmit_frame,
290 raster_thread_merger_);
291 }
292
293 // Consume as many pipeline items as possible. But yield the event loop
294 // between successive tries.
295 switch (consume_result) {
298 [weak_this = weak_factory_.GetWeakPtr(), pipeline]() {
299 if (weak_this) {
300 weak_this->Draw(pipeline);
301 }
302 });
303 break;
304 }
305 default:
306 break;
307 }
308
309 return ToDrawStatus(draw_result.status);
310}
virtual const TaskRunners & GetTaskRunners() const =0
Task runners used by the shell.
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
virtual void PostTask(const fml::closure &task) override
virtual bool RunsTasksOnCurrentThread()
#define FML_CHECK(condition)
Definition logging.h:104
PipelineConsumeResult
Definition pipeline.h:29
std::shared_ptr< PipelineGLES > pipeline
#define TRACE_EVENT0(category_group, name)

References FML_CHECK, FML_DCHECK, flutter::TaskRunners::GetRasterTaskRunner(), flutter::Rasterizer::Delegate::GetTaskRunners(), fml::RasterThreadMerger::IsOnRasterizingThread(), flutter::kPipelineEmpty, flutter::kYielded, flutter::MoreAvailable, flutter::NoneAvailable, pipeline, fml::TaskRunner::PostTask(), fml::TaskRunner::RunsTasksOnCurrentThread(), flutter::PipelineProduceResult::success, and TRACE_EVENT0.

◆ DrawLastLayerTrees()

void flutter::Rasterizer::DrawLastLayerTrees ( std::unique_ptr< FrameTimingsRecorder frame_timings_recorder)

Draws the last layer trees with their last configuration. This may seem entirely redundant at first glance. After all, on surface loss and re-acquisition, the framework generates a new layer tree. Otherwise, why render the same contents to the screen again? This is used as an optimization in cases where there are external textures (video or camera streams for example) in referenced in the layer tree. These textures may be updated at a cadence different from that of the Flutter application. Flutter can re-render the layer tree with just the updated textures instead of waiting for the framework to do the work to generate the layer tree describing the same contents.

Calling this method clears all last layer trees (GetLastLayerTree).

Definition at line 221 of file rasterizer.cc.

222 {
223 if (!surface_) {
224 return;
225 }
226 std::vector<std::unique_ptr<LayerTreeTask>> tasks;
227 for (auto& [view_id, view_record] : view_records_) {
228 if (view_record.last_successful_task) {
229 tasks.push_back(std::move(view_record.last_successful_task));
230 }
231 }
232 if (tasks.empty()) {
233 return;
234 }
235
236 DoDrawResult result =
237 DrawToSurfaces(*frame_timings_recorder, std::move(tasks));
238
239 // EndFrame should perform cleanups for the external_view_embedder.
240 if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) {
241 bool should_resubmit_frame = ShouldResubmitFrame(result);
242 external_view_embedder_->SetUsedThisFrame(false);
243 external_view_embedder_->EndFrame(should_resubmit_frame,
244 raster_thread_merger_);
245 }
246}

References view_id.

◆ EnableThreadMergerIfNeeded()

void flutter::Rasterizer::EnableThreadMergerIfNeeded ( )

Enables the thread merger if the external view embedder supports dynamic thread merging.

Attention
This method is thread-safe. When the thread merger is enabled, the raster task queue can run in the platform thread at any time.
See also
ExternalViewEmbedder

Definition at line 161 of file rasterizer.cc.

161 {
162 if (raster_thread_merger_) {
163 raster_thread_merger_->Enable();
164 }
165}

References fml::RasterThreadMerger::Enable().

◆ GetGrContext()

GrDirectContext * flutter::Rasterizer::GetGrContext ( )
overridevirtual

Implements flutter::SnapshotDelegate.

Definition at line 205 of file rasterizer.cc.

205 {
206 return surface_ ? surface_->GetContext() : nullptr;
207}

◆ GetLastDrawStatus()

std::optional< DrawSurfaceStatus > flutter::Rasterizer::GetLastDrawStatus ( int64_t  view_id)

Returns the last status of drawing the specific view.

        This method is used only in unit tests.

Definition at line 151 of file rasterizer.cc.

152 {
153 auto found = view_records_.find(view_id);
154 if (found != view_records_.end()) {
155 return found->second.last_draw_status;
156 } else {
157 return std::optional<DrawSurfaceStatus>();
158 }
159}

References view_id.

◆ GetLastLayerTree()

flutter::LayerTree * flutter::Rasterizer::GetLastLayerTree ( int64_t  view_id)

Returns the last successfully drawn layer tree for the given view, or nullptr if there isn't any. This is useful during DrawLastLayerTrees and computing frame damage.

Returns
A pointer to the last layer or nullptr if this rasterizer has never rendered a frame to the given view.

Definition at line 209 of file rasterizer.cc.

209 {
210 auto found = view_records_.find(view_id);
211 if (found == view_records_.end()) {
212 return nullptr;
213 }
214 auto& last_task = found->second.last_successful_task;
215 if (last_task == nullptr) {
216 return nullptr;
217 }
218 return last_task->layer_tree.get();
219}

References view_id.

◆ GetRasterThreadMerger()

fml::RefPtr< fml::RasterThreadMerger > flutter::Rasterizer::GetRasterThreadMerger ( )

Returns the raster thread merger used by this rasterizer. This may be nullptr.

Returns
The raster thread merger used by this rasterizer.

Definition at line 1154 of file rasterizer.cc.

1154 {
1155 return raster_thread_merger_;
1156}

◆ GetResourceCacheMaxBytes()

std::optional< size_t > flutter::Rasterizer::GetResourceCacheMaxBytes ( ) const

The current value of Skia's resource cache size, if a surface is present.

Attention
This cache does not describe the entirety of GPU resources that may be cached. The RasterCache also holds very large GPU resources.
See also
RasterCache
Returns
The size of Skia's resource cache, if available.

Definition at line 1195 of file rasterizer.cc.

1195 {
1196#if SLIMPELLER
1197 return std::nullopt;
1198#else // SLIMPELLER
1199 if (!surface_) {
1200 return std::nullopt;
1201 }
1202 GrDirectContext* context = surface_->GetContext();
1203 if (context) {
1204 return context->getResourceCacheLimit();
1205 }
1206 return std::nullopt;
1207#endif // SLIMPELLER
1208}
std::shared_ptr< ContextGLES > context

References context, and surface_.

◆ GetSnapshotDelegate()

fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > flutter::Rasterizer::GetSnapshotDelegate ( ) const

Definition at line 71 of file rasterizer.cc.

72 {
73 return weak_factory_.GetWeakPtr();
74}

◆ GetTextureRegistry()

std::shared_ptr< flutter::TextureRegistry > flutter::Rasterizer::GetTextureRegistry ( )
overridevirtual

Gets the registry of external textures currently in use by the rasterizer. These textures may be updated at a cadence different from that of the Flutter application. When an external texture is referenced in the Flutter layer tree, that texture is composited within the Flutter layer tree.

Returns
A pointer to the external texture registry.

Implements flutter::SnapshotDelegate.

Definition at line 201 of file rasterizer.cc.

201 {
202 return compositor_context_->texture_registry();
203}

◆ GetWeakPtr()

fml::TaskRunnerAffineWeakPtr< Rasterizer > flutter::Rasterizer::GetWeakPtr ( ) const

Gets a weak pointer to the rasterizer. The rasterizer may only be accessed on the raster task runner.

Returns
The weak pointer to the rasterizer.

Definition at line 67 of file rasterizer.cc.

67 {
68 return weak_factory_.GetWeakPtr();
69}

◆ IsTornDown()

bool flutter::Rasterizer::IsTornDown ( )

Returns whether TearDown has been called.

        This method is used only in unit tests.

Definition at line 147 of file rasterizer.cc.

147 {
148 return is_torn_down_;
149}

◆ NotifyLowMemoryWarning()

void flutter::Rasterizer::NotifyLowMemoryWarning ( ) const

Notifies the rasterizer that there is a low memory situation and it must purge as many unnecessary resources as possible. Currently, the Skia context associated with onscreen rendering is told to free GPU resources.

Definition at line 173 of file rasterizer.cc.

173 {
174#if !SLIMPELLER
175 if (!surface_) {
176 FML_DLOG(INFO)
177 << "Rasterizer::NotifyLowMemoryWarning called with no surface.";
178 return;
179 }
180 auto context = surface_->GetContext();
181 if (!context) {
182 FML_DLOG(INFO)
183 << "Rasterizer::NotifyLowMemoryWarning called with no GrContext.";
184 return;
185 }
186 auto context_switch = surface_->MakeRenderContextCurrent();
187 if (!context_switch->GetResult()) {
188 return;
189 }
190 context->performDeferredCleanup(std::chrono::milliseconds(0));
191#endif // !SLIMPELLER
192}
#define FML_DLOG(severity)
Definition logging.h:121

References context, and FML_DLOG.

◆ ScreenshotLastLayerTree()

Rasterizer::Screenshot flutter::Rasterizer::ScreenshotLastLayerTree ( Rasterizer::ScreenshotType  type,
bool  base64_encode 
)

Screenshots the last layer tree to one of the supported screenshot types and optionally Base 64 encodes that data for easier transmission and packaging (usually over the service protocol for instrumentation tools running on the host).

Parameters
[in]typeThe type of the screenshot to gather.
[in]base64_encodeWhether Base 64 encoding must be applied to the data after a screenshot has been captured.
Returns
A non-empty screenshot if one could be captured. A screenshot capture may fail if there were no layer trees previously rendered by this rasterizer, or, due to an unspecified internal error. Internal error will be logged to the console.

Definition at line 1075 of file rasterizer.cc.

1077 {
1078 if (delegate_.GetSettings().enable_impeller &&
1080 FML_DCHECK(false);
1081 FML_LOG(ERROR) << "Last layer tree cannot be screenshotted as a "
1082 "SkiaPicture when using Impeller.";
1083 return {};
1084 }
1085 // TODO(dkwingsmt): Support screenshotting all last layer trees
1086 // when the shell protocol supports multi-views.
1087 // https://github.com/flutter/flutter/issues/135534
1088 // https://github.com/flutter/flutter/issues/135535
1089 auto* layer_tree = GetLastLayerTree(kFlutterImplicitViewId);
1090 if (layer_tree == nullptr) {
1091 FML_LOG(ERROR) << "Last layer tree was null when screenshotting.";
1092 return {};
1093 }
1094
1095 std::pair<sk_sp<SkData>, ScreenshotFormat> data{nullptr,
1097 std::string format;
1098
1099 switch (type) {
1101 format = "ScreenshotType::SkiaPicture";
1102 data.first =
1103 ScreenshotLayerTreeAsPicture(layer_tree, *compositor_context_);
1104 break;
1106 format = "ScreenshotType::UncompressedImage";
1107 data =
1108 ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_, false);
1109 break;
1111 format = "ScreenshotType::CompressedImage";
1112 data = ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_, true);
1113 break;
1115 Surface::SurfaceData surface_data = surface_->GetSurfaceData();
1116 format = surface_data.pixel_format;
1117 data.first = surface_data.data;
1118 break;
1119 }
1120 }
1121
1122 if (data.first == nullptr) {
1123 FML_LOG(ERROR) << "Screenshot data was null.";
1124 return {};
1125 }
1126
1127 if (base64_encode) {
1128 size_t b64_size = Base64::EncodedSize(data.first->size());
1129 auto b64_data = SkData::MakeUninitialized(b64_size);
1130 Base64::Encode(data.first->data(), data.first->size(),
1131 b64_data->writable_data());
1132 return Rasterizer::Screenshot{b64_data, layer_tree->frame_size(), format,
1133 data.second};
1134 }
1135
1136 return Rasterizer::Screenshot{data.first, layer_tree->frame_size(), format,
1137 data.second};
1138}
virtual const Settings & GetSettings() const =0
flutter::LayerTree * GetLastLayerTree(int64_t view_id)
Returns the last successfully drawn layer tree for the given view, or nullptr if there isn't any....
uint32_t uint32_t * format
#define FML_LOG(severity)
Definition logging.h:101
constexpr int64_t kFlutterImplicitViewId
Definition constants.h:35
static sk_sp< SkData > ScreenshotLayerTreeAsPicture(flutter::LayerTree *tree, flutter::CompositorContext &compositor_context)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switch_defs.h:36
impeller::ShaderType type
static size_t Encode(const void *src, size_t length, void *dst)
Definition base64.cc:118
static size_t EncodedSize(size_t srcDataLength)
Definition base64.h:33

References flutter::Surface::SurfaceData::data, flutter::data, delegate_, FML_DCHECK, FML_LOG, format, flutter::LayerTree::frame_size(), flutter::kFlutterImplicitViewId, flutter::Surface::SurfaceData::pixel_format, flutter::ScreenshotLayerTreeAsPicture(), surface_, and type.

◆ SetExternalViewEmbedder()

void flutter::Rasterizer::SetExternalViewEmbedder ( const std::shared_ptr< ExternalViewEmbedder > &  view_embedder)

Set the External View Embedder. This is done on shell initialization. This is non-null on platforms that support embedding externally composited views.

Parameters
[in]view_embedderThe external view embedder object.

Definition at line 1144 of file rasterizer.cc.

1145 {
1146 external_view_embedder_ = view_embedder;
1147}

◆ SetImpellerContext()

void flutter::Rasterizer::SetImpellerContext ( std::shared_ptr< impeller::ImpellerContextFuture impeller_context)

Definition at line 76 of file rasterizer.cc.

77 {
78 impeller_context_ = std::move(impeller_context);
79}

◆ SetNextFrameCallback()

void flutter::Rasterizer::SetNextFrameCallback ( const fml::closure callback)

Sets a callback that will be executed when the next layer tree in rendered to the on-screen surface. This is used by embedders to listen for one time operations like listening for when the first frame is rendered so that they may hide splash screens.

The callback is only executed once and dropped on the GPU thread when executed (lambda captures must be able to deal with the threading repercussions of this behavior).

Parameters
[in]callbackThe callback to execute when the next layer tree is rendered on-screen.

Definition at line 1140 of file rasterizer.cc.

1140 {
1141 next_frame_callback_ = callback;
1142}
FlutterDesktopBinaryReply callback

References callback.

◆ SetResourceCacheMaxBytes()

void flutter::Rasterizer::SetResourceCacheMaxBytes ( size_t  max_bytes,
bool  from_user 
)

Skia has no notion of time. To work around the performance implications of this, it may cache GPU resources to reference them from one frame to the next. Using this call, embedders may set the maximum bytes cached by Skia in its caches dedicated to on-screen rendering.

Attention
This cache setting will be invalidated when the surface is torn down via Rasterizer::Teardown. This call must be made again with new limits after surface re-acquisition.
This cache does not describe the entirety of GPU resources that may be cached. The RasterCache also holds very large GPU resources.
See also
RasterCache
Parameters
[in]max_bytesThe maximum byte size of resource that may be cached for GPU rendering.
[in]from_userWhether this request was from user code, e.g. via the flutter/skia message channel, in which case it should not be overridden by the platform.

Definition at line 1168 of file rasterizer.cc.

1168 {
1169#if !SLIMPELLER
1170 user_override_resource_cache_bytes_ |= from_user;
1171
1172 if (!from_user && user_override_resource_cache_bytes_) {
1173 // We should not update the setting here if a user has explicitly set a
1174 // value for this over the flutter/skia channel.
1175 return;
1176 }
1177
1178 max_cache_bytes_ = max_bytes;
1179 if (!surface_) {
1180 return;
1181 }
1182
1183 GrDirectContext* context = surface_->GetContext();
1184 if (context) {
1185 auto context_switch = surface_->MakeRenderContextCurrent();
1186 if (!context_switch->GetResult()) {
1187 return;
1188 }
1189
1190 context->setResourceCacheLimit(max_bytes);
1191 }
1192#endif // !SLIMPELLER
1193}

References context, and surface_.

Referenced by Setup().

◆ SetSnapshotSurfaceProducer()

void flutter::Rasterizer::SetSnapshotSurfaceProducer ( std::unique_ptr< SnapshotSurfaceProducer producer)

Set the snapshot surface producer. This is done on shell initialization. This is non-null on platforms that support taking GPU accelerated raster snapshots in the background.

Parameters
[in]producerA surface producer for raster snapshotting when the onscreen surface is not available.

Definition at line 1149 of file rasterizer.cc.

1150 {
1151 snapshot_surface_producer_ = std::move(producer);
1152}

◆ Setup()

void flutter::Rasterizer::Setup ( std::unique_ptr< Surface surface)

Rasterizers may be created well before an on-screen surface is available for rendering. Shells usually create a rasterizer in their constructors. Once an on-screen surface is available however, one may be provided to the rasterizer using this call. No rendering may occur before this call. The surface is held till the balancing call to Rasterizer::Teardown is made. Calling a setup before tearing down the previous surface (if this is not the first time the surface has been set up) is user error.

See also
Rasterizer::Teardown
Parameters
[in]surfaceThe on-screen render surface.

Definition at line 81 of file rasterizer.cc.

81 {
82 surface_ = std::move(surface);
83
84 if (max_cache_bytes_.has_value()) {
85 SetResourceCacheMaxBytes(max_cache_bytes_.value(),
86 user_override_resource_cache_bytes_);
87 }
88
89 auto context_switch = surface_->MakeRenderContextCurrent();
90 if (context_switch->GetResult()) {
91 compositor_context_->OnGrContextCreated();
92 }
93
94 if (external_view_embedder_ &&
95 external_view_embedder_->SupportsDynamicThreadMerging() &&
96 !raster_thread_merger_) {
97 const auto platform_id =
99 const auto gpu_id =
102 delegate_.GetParentRasterThreadMerger(), platform_id, gpu_id);
103 }
104 if (raster_thread_merger_) {
105 raster_thread_merger_->SetMergeUnmergeCallback([this]() {
106 // Clear the GL context after the thread configuration has changed.
107 if (surface_) {
108 surface_->ClearRenderContext();
109 }
110 });
111 }
112}
virtual const fml::RefPtr< fml::RasterThreadMerger > GetParentRasterThreadMerger() const =0
The raster thread merger from parent shell's rasterizer.
void SetResourceCacheMaxBytes(size_t max_bytes, bool from_user)
Skia has no notion of time. To work around the performance implications of this, it may cache GPU res...
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
static fml::RefPtr< fml::RasterThreadMerger > CreateOrShareThreadMerger(const fml::RefPtr< fml::RasterThreadMerger > &parent_merger, TaskQueueId platform_id, TaskQueueId raster_id)
void SetMergeUnmergeCallback(const fml::closure &callback)
virtual TaskQueueId GetTaskQueueId()

References fml::RasterThreadMerger::CreateOrShareThreadMerger(), flutter::Rasterizer::Delegate::GetParentRasterThreadMerger(), flutter::TaskRunners::GetPlatformTaskRunner(), flutter::TaskRunners::GetRasterTaskRunner(), fml::TaskRunner::GetTaskQueueId(), flutter::Rasterizer::Delegate::GetTaskRunners(), fml::RasterThreadMerger::SetMergeUnmergeCallback(), SetResourceCacheMaxBytes(), and surface.

◆ Teardown()

void flutter::Rasterizer::Teardown ( )

Releases the previously set up on-screen render surface and collects associated resources. No more rendering may occur till the next call to Rasterizer::Setup with a new render surface. Calling a teardown without a setup is user error. Calling this method multiple times is safe.

Definition at line 120 of file rasterizer.cc.

120 {
121 is_torn_down_ = true;
122 if (surface_) {
123 auto context_switch = surface_->MakeRenderContextCurrent();
124 if (context_switch->GetResult()) {
125 compositor_context_->OnGrContextDestroyed();
126#if !SLIMPELLER
127 if (auto* context = surface_->GetContext()) {
128 context->purgeUnlockedResources(GrPurgeResourceOptions::kAllResources);
129 }
130#endif // !SLIMPELLER
131 }
132 context_switch.reset();
133 surface_->ClearRenderContext();
134 surface_.reset();
135 }
136
137 view_records_.clear();
138
139 if (raster_thread_merger_.get() != nullptr &&
140 raster_thread_merger_.get()->IsMerged()) {
141 FML_DCHECK(raster_thread_merger_->IsEnabled());
142 raster_thread_merger_->UnMergeNowIfLastOne();
143 raster_thread_merger_->SetMergeUnmergeCallback(nullptr);
144 }
145}
T * get() const
Definition ref_ptr.h:117

References context, FML_DCHECK, fml::RefPtr< T >::get(), fml::RasterThreadMerger::IsEnabled(), fml::RasterThreadMerger::IsMerged(), fml::RasterThreadMerger::SetMergeUnmergeCallback(), and fml::RasterThreadMerger::UnMergeNowIfLastOne().

◆ TeardownExternalViewEmbedder()

void flutter::Rasterizer::TeardownExternalViewEmbedder ( )

Releases any resource used by the external view embedder. For example, overlay surfaces or Android views. On Android, this method post a task to the platform thread, and waits until it completes.

Definition at line 114 of file rasterizer.cc.

114 {
115 if (external_view_embedder_) {
116 external_view_embedder_->Teardown();
117 }
118}

The documentation for this class was generated from the following files: