Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Private Member Functions | List of all members
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::weak_ptr< impeller::Context > 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.
 
GrDirectContextGetGrContext () 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
 

Private Member Functions

std::unique_ptr< GpuImageResultMakeSkiaGpuImage (sk_sp< DisplayList > display_list, const SkImageInfo &image_info) override
 Attempts to create a GrBackendTexture for the specified DisplayList. May result in a raster bitmap if no GPU context is available.
 
sk_sp< DlImageMakeRasterSnapshot (sk_sp< DisplayList > display_list, SkISize picture_size) override
 
sk_sp< SkImageConvertToRasterImage (sk_sp< SkImage > image) override
 
void CacheRuntimeStage (const std::shared_ptr< impeller::RuntimeStage > &runtime_stage) override
 
fml::Milliseconds GetFrameBudget () const override
 
const std::unique_ptr< Surface > & GetSurface () const override
 
std::shared_ptr< impeller::AiksContextGetAiksContext () const override
 
const std::unique_ptr< SnapshotSurfaceProducer > & GetSnapshotSurfaceProducer () const override
 
std::shared_ptr< const fml::SyncSwitchGetIsGpuDisabledSyncSwitch () const override
 

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 383 of file rasterizer.h.

383 {
384 // Unknown format, or Skia default.
385 kUnknown,
386 // RGBA 8 bits per channel.
388 // BGRA 8 bits per channel.
390 // RGBA 16 bit floating point per channel.
392 };

◆ 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 347 of file rasterizer.h.

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

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 52 of file rasterizer.cc.

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

◆ ~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

◆ CacheRuntimeStage()

void flutter::Rasterizer::CacheRuntimeStage ( const std::shared_ptr< impeller::RuntimeStage > &  runtime_stage)
overrideprivatevirtual

Load and compile and initial PSO for the provided [runtime_stage].

Impeller only.

Implements flutter::SnapshotDelegate.

Definition at line 436 of file rasterizer.cc.

437 {
438 snapshot_controller_->CacheRuntimeStage(runtime_stage);
439}

◆ 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 186 of file rasterizer.cc.

186 {
187 if (external_view_embedder_) {
188 external_view_embedder_->CollectView(view_id);
189 }
190 view_records_.erase(view_id);
191}

◆ 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 515 of file rasterizer.h.

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

◆ ConvertToRasterImage()

sk_sp< SkImage > flutter::Rasterizer::ConvertToRasterImage ( sk_sp< SkImage image)
overrideprivatevirtual

Implements flutter::SnapshotDelegate.

Definition at line 430 of file rasterizer.cc.

430 {
431 TRACE_EVENT0("flutter", __FUNCTION__);
432 return snapshot_controller_->ConvertToRasterImage(image);
433}
sk_sp< SkImage > image
Definition examples.cpp:29
#define TRACE_EVENT0(category_group, name)

◆ 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 161 of file rasterizer.cc.

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

◆ 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 240 of file rasterizer.cc.

240 {
241 TRACE_EVENT0("flutter", "GPURasterizer::Draw");
242 if (raster_thread_merger_ &&
243 !raster_thread_merger_->IsOnRasterizingThread()) {
244 // we yield and let this frame be serviced on the right thread.
246 }
247 FML_DCHECK(delegate_.GetTaskRunners()
250
251 DoDrawResult draw_result;
252 FramePipeline::Consumer consumer = [&draw_result,
253 this](std::unique_ptr<FrameItem> item) {
254 draw_result = DoDraw(std::move(item->frame_timings_recorder),
255 std::move(item->layer_tree_tasks));
256 };
257
258 PipelineConsumeResult consume_result = pipeline->Consume(consumer);
259 if (consume_result == PipelineConsumeResult::NoneAvailable) {
261 }
262 // if the raster status is to resubmit the frame, we push the frame to the
263 // front of the queue and also change the consume status to more available.
264
265 bool should_resubmit_frame = ShouldResubmitFrame(draw_result);
266 if (should_resubmit_frame) {
267 FML_CHECK(draw_result.resubmitted_item);
268 auto front_continuation = pipeline->ProduceIfEmpty();
269 PipelineProduceResult pipeline_result =
270 front_continuation.Complete(std::move(draw_result.resubmitted_item));
271 if (pipeline_result.success) {
273 }
274 } else if (draw_result.status == DoDrawStatus::kEnqueuePipeline) {
276 }
277
278 // EndFrame should perform cleanups for the external_view_embedder.
279 if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) {
280 external_view_embedder_->SetUsedThisFrame(false);
281 external_view_embedder_->EndFrame(should_resubmit_frame,
282 raster_thread_merger_);
283 }
284
285 // Consume as many pipeline items as possible. But yield the event loop
286 // between successive tries.
287 switch (consume_result) {
290 [weak_this = weak_factory_.GetWeakPtr(), pipeline]() {
291 if (weak_this) {
292 weak_this->Draw(pipeline);
293 }
294 });
295 break;
296 }
297 default:
298 break;
299 }
300
301 return ToDrawStatus(draw_result.status);
302}
std::function< void(ResourcePtr)> Consumer
Definition pipeline.h:180
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:85
PipelineConsumeResult
Definition pipeline.h:29

◆ 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 213 of file rasterizer.cc.

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

◆ 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 155 of file rasterizer.cc.

155 {
156 if (raster_thread_merger_) {
157 raster_thread_merger_->Enable();
158 }
159}

◆ GetAiksContext()

std::shared_ptr< impeller::AiksContext > flutter::Rasterizer::GetAiksContext ( ) const
inlineoverrideprivatevirtual

Implements flutter::SnapshotController::Delegate.

Definition at line 668 of file rasterizer.h.

668 {
669#if IMPELLER_SUPPORTS_RENDERING
670 if (surface_) {
671 return surface_->GetAiksContext();
672 }
673 if (auto context = impeller_context_.lock()) {
674 return std::make_shared<impeller::AiksContext>(
676 }
677#endif
678 return nullptr;
679 }
static std::shared_ptr< TypographerContext > Make()

◆ GetFrameBudget()

fml::Milliseconds flutter::Rasterizer::GetFrameBudget ( ) const
overrideprivatevirtual

Time limit for a smooth frame.

See: DisplayManager::GetMainDisplayRefreshRate.

Implements flutter::Stopwatch::RefreshRateUpdater.

Definition at line 441 of file rasterizer.cc.

441 {
442 return delegate_.GetFrameBudget();
443};
virtual fml::Milliseconds GetFrameBudget()=0

◆ GetGrContext()

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

Implements flutter::SnapshotDelegate.

Definition at line 197 of file rasterizer.cc.

197 {
198 return surface_ ? surface_->GetContext() : nullptr;
199}

◆ GetIsGpuDisabledSyncSwitch()

std::shared_ptr< const fml::SyncSwitch > flutter::Rasterizer::GetIsGpuDisabledSyncSwitch ( ) const
inlineoverrideprivatevirtual

Implements flutter::SnapshotController::Delegate.

Definition at line 688 of file rasterizer.h.

689 {
690 return delegate_.GetIsGpuDisabledSyncSwitch();
691 }
virtual std::shared_ptr< const fml::SyncSwitch > GetIsGpuDisabledSyncSwitch() const =0

◆ 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 145 of file rasterizer.cc.

146 {
147 auto found = view_records_.find(view_id);
148 if (found != view_records_.end()) {
149 return found->second.last_draw_status;
150 } else {
151 return std::optional<DrawSurfaceStatus>();
152 }
153}

◆ 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.

Bug:
https://github.com/flutter/flutter/issues/33939
Returns
A pointer to the last layer or nullptr if this rasterizer has never rendered a frame to the given view.

Definition at line 201 of file rasterizer.cc.

201 {
202 auto found = view_records_.find(view_id);
203 if (found == view_records_.end()) {
204 return nullptr;
205 }
206 auto& last_task = found->second.last_successful_task;
207 if (last_task == nullptr) {
208 return nullptr;
209 }
210 return last_task->layer_tree.get();
211}

◆ 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 1058 of file rasterizer.cc.

1058 {
1059 return raster_thread_merger_;
1060}

◆ 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 1097 of file rasterizer.cc.

1097 {
1098 if (!surface_) {
1099 return std::nullopt;
1100 }
1101 GrDirectContext* context = surface_->GetContext();
1102 if (context) {
1103 return context->getResourceCacheLimit();
1104 }
1105 return std::nullopt;
1106}
size_t getResourceCacheLimit() const

◆ GetSnapshotDelegate()

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

Definition at line 69 of file rasterizer.cc.

70 {
71 return weak_factory_.GetWeakPtr();
72}

◆ GetSnapshotSurfaceProducer()

const std::unique_ptr< SnapshotSurfaceProducer > & flutter::Rasterizer::GetSnapshotSurfaceProducer ( ) const
inlineoverrideprivatevirtual

Implements flutter::SnapshotController::Delegate.

Definition at line 682 of file rasterizer.h.

683 {
684 return snapshot_surface_producer_;
685 }

◆ GetSurface()

const std::unique_ptr< Surface > & flutter::Rasterizer::GetSurface ( ) const
inlineoverrideprivatevirtual

Implements flutter::SnapshotController::Delegate.

Definition at line 663 of file rasterizer.h.

663 {
664 return surface_;
665 }

◆ 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 193 of file rasterizer.cc.

193 {
194 return compositor_context_->texture_registry();
195}

◆ 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 65 of file rasterizer.cc.

65 {
66 return weak_factory_.GetWeakPtr();
67}

◆ IsTornDown()

bool flutter::Rasterizer::IsTornDown ( )

Returns whether TearDown has been called.

        This method is used only in unit tests.

Definition at line 141 of file rasterizer.cc.

141 {
142 return is_torn_down_;
143}

◆ MakeRasterSnapshot()

sk_sp< DlImage > flutter::Rasterizer::MakeRasterSnapshot ( sk_sp< DisplayList display_list,
SkISize  picture_size 
)
overrideprivatevirtual

Implements flutter::SnapshotDelegate.

Definition at line 425 of file rasterizer.cc.

426 {
427 return snapshot_controller_->MakeRasterSnapshot(display_list, picture_size);
428}

◆ MakeSkiaGpuImage()

std::unique_ptr< Rasterizer::GpuImageResult > flutter::Rasterizer::MakeSkiaGpuImage ( sk_sp< DisplayList display_list,
const SkImageInfo image_info 
)
overrideprivatevirtual

Attempts to create a GrBackendTexture for the specified DisplayList. May result in a raster bitmap if no GPU context is available.

Implements flutter::SnapshotDelegate.

Definition at line 356 of file rasterizer.cc.

358 {
359 TRACE_EVENT0("flutter", "Rasterizer::MakeGpuImage");
360 FML_DCHECK(display_list);
361
362 std::unique_ptr<SnapshotDelegate::GpuImageResult> result;
363 delegate_.GetIsGpuDisabledSyncSwitch()->Execute(
365 .SetIfTrue([&result, &image_info, &display_list] {
366 // TODO(dnfield): This isn't safe if display_list contains any GPU
367 // resources like an SkImage_gpu.
368 result = MakeBitmapImage(display_list, image_info);
369 })
370 .SetIfFalse([&result, &image_info, &display_list,
371 surface = surface_.get(),
372 gpu_image_behavior = gpu_image_behavior_] {
373 if (!surface ||
374 gpu_image_behavior == MakeGpuImageBehavior::kBitmap) {
375 // TODO(dnfield): This isn't safe if display_list contains any GPU
376 // resources like an SkImage_gpu.
377 result = MakeBitmapImage(display_list, image_info);
378 return;
379 }
380
381 auto context_switch = surface->MakeRenderContextCurrent();
382 if (!context_switch->GetResult()) {
383 result = MakeBitmapImage(display_list, image_info);
384 return;
385 }
386
387 auto* context = surface->GetContext();
388 if (!context) {
389 result = MakeBitmapImage(display_list, image_info);
390 return;
391 }
392
393 GrBackendTexture texture = context->createBackendTexture(
394 image_info.width(), image_info.height(), image_info.colorType(),
395 skgpu::Mipmapped::kNo, GrRenderable::kYes);
396 if (!texture.isValid()) {
397 result = std::make_unique<SnapshotDelegate::GpuImageResult>(
398 GrBackendTexture(), nullptr, nullptr,
399 "unable to create texture render target at specified size " +
400 std::to_string(image_info.width()) + "x" +
401 std::to_string(image_info.height()));
402 return;
403 }
404
406 context, texture, kTopLeft_GrSurfaceOrigin, /*sampleCnt=*/0,
407 image_info.colorType(), image_info.refColorSpace(), nullptr);
408 if (!sk_surface) {
409 result = std::make_unique<SnapshotDelegate::GpuImageResult>(
410 GrBackendTexture(), nullptr, nullptr,
411 "unable to create rendering surface for image");
412 return;
413 }
414
415 auto canvas = DlSkCanvasAdapter(sk_surface->getCanvas());
416 canvas.Clear(DlColor::kTransparent());
417 canvas.DrawDisplayList(display_list);
418
419 result = std::make_unique<SnapshotDelegate::GpuImageResult>(
420 texture, sk_ref_sp(context), nullptr, "");
421 }));
422 return result;
423}
@ kTopLeft_GrSurfaceOrigin
Definition GrTypes.h:148
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
VkSurfaceKHR surface
Definition main.cc:49
FlTexture * texture
SK_API sk_sp< SkSurface > WrapBackendTexture(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, int sampleCnt, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)
sk_sp< SkColorSpace > refColorSpace() const
int width() const
SkColorType colorType() const
int height() const
static constexpr DlColor kTransparent()
Definition dl_color.h:21
Represents the 2 code paths available when calling |SyncSwitchExecute|.
Definition sync_switch.h:35

◆ 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 167 of file rasterizer.cc.

167 {
168 if (!surface_) {
169 FML_DLOG(INFO)
170 << "Rasterizer::NotifyLowMemoryWarning called with no surface.";
171 return;
172 }
173 auto context = surface_->GetContext();
174 if (!context) {
175 FML_DLOG(INFO)
176 << "Rasterizer::NotifyLowMemoryWarning called with no GrContext.";
177 return;
178 }
179 auto context_switch = surface_->MakeRenderContextCurrent();
180 if (!context_switch->GetResult()) {
181 return;
182 }
183 context->performDeferredCleanup(std::chrono::milliseconds(0));
184}
#define FML_DLOG(severity)
Definition logging.h:102

◆ 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 979 of file rasterizer.cc.

981 {
982 if (delegate_.GetSettings().enable_impeller &&
984 FML_DCHECK(false);
985 FML_LOG(ERROR) << "Last layer tree cannot be screenshotted as a "
986 "SkiaPicture when using Impeller.";
987 return {};
988 }
989 // TODO(dkwingsmt): Support screenshotting all last layer trees
990 // when the shell protocol supports multi-views.
991 // https://github.com/flutter/flutter/issues/135534
992 // https://github.com/flutter/flutter/issues/135535
993 auto* layer_tree = GetLastLayerTree(kFlutterImplicitViewId);
994 if (layer_tree == nullptr) {
995 FML_LOG(ERROR) << "Last layer tree was null when screenshotting.";
996 return {};
997 }
998
999 std::pair<sk_sp<SkData>, ScreenshotFormat> data{nullptr,
1001 std::string format;
1002
1003 switch (type) {
1005 format = "ScreenshotType::SkiaPicture";
1006 data.first =
1007 ScreenshotLayerTreeAsPicture(layer_tree, *compositor_context_);
1008 break;
1010 format = "ScreenshotType::UncompressedImage";
1011 data =
1012 ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_, false);
1013 break;
1015 format = "ScreenshotType::CompressedImage";
1016 data = ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_, true);
1017 break;
1019 Surface::SurfaceData surface_data = surface_->GetSurfaceData();
1020 format = surface_data.pixel_format;
1021 data.first = surface_data.data;
1022 break;
1023 }
1024 }
1025
1026 if (data.first == nullptr) {
1027 FML_LOG(ERROR) << "Screenshot data was null.";
1028 return {};
1029 }
1030
1031 if (base64_encode) {
1032 size_t b64_size = Base64::EncodedSize(data.first->size());
1033 auto b64_data = SkData::MakeUninitialized(b64_size);
1034 Base64::Encode(data.first->data(), data.first->size(),
1035 b64_data->writable_data());
1036 return Rasterizer::Screenshot{b64_data, layer_tree->frame_size(), format,
1037 data.second};
1038 }
1039
1040 return Rasterizer::Screenshot{data.first, layer_tree->frame_size(), format,
1041 data.second};
1042}
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition SkData.cpp:116
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....
#define FML_LOG(severity)
Definition logging.h:82
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 switches.h:41
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent Remove all existing persistent cache This is mainly for debugging purposes such as reproducing the shader compilation jank trace to Write the timeline trace to a file at the specified path The file will be in Perfetto s proto format
Definition switches.h:203
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
#define ERROR(message)

◆ 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 1048 of file rasterizer.cc.

1049 {
1050 external_view_embedder_ = view_embedder;
1051}

◆ SetImpellerContext()

void flutter::Rasterizer::SetImpellerContext ( std::weak_ptr< impeller::Context impeller_context)

Definition at line 74 of file rasterizer.cc.

75 {
76 impeller_context_ = std::move(impeller_context);
77}

◆ 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 1044 of file rasterizer.cc.

1044 {
1045 next_frame_callback_ = callback;
1046}
FlKeyEvent uint64_t FlKeyResponderAsyncCallback 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 1072 of file rasterizer.cc.

1072 {
1073 user_override_resource_cache_bytes_ |= from_user;
1074
1075 if (!from_user && user_override_resource_cache_bytes_) {
1076 // We should not update the setting here if a user has explicitly set a
1077 // value for this over the flutter/skia channel.
1078 return;
1079 }
1080
1081 max_cache_bytes_ = max_bytes;
1082 if (!surface_) {
1083 return;
1084 }
1085
1086 GrDirectContext* context = surface_->GetContext();
1087 if (context) {
1088 auto context_switch = surface_->MakeRenderContextCurrent();
1089 if (!context_switch->GetResult()) {
1090 return;
1091 }
1092
1093 context->setResourceCacheLimit(max_bytes);
1094 }
1095}
void setResourceCacheLimit(size_t maxResourceBytes)

◆ 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 1053 of file rasterizer.cc.

1054 {
1055 snapshot_surface_producer_ = std::move(producer);
1056}

◆ 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 79 of file rasterizer.cc.

79 {
80 surface_ = std::move(surface);
81
82 if (max_cache_bytes_.has_value()) {
83 SetResourceCacheMaxBytes(max_cache_bytes_.value(),
84 user_override_resource_cache_bytes_);
85 }
86
87 auto context_switch = surface_->MakeRenderContextCurrent();
88 if (context_switch->GetResult()) {
89 compositor_context_->OnGrContextCreated();
90 }
91
92 if (external_view_embedder_ &&
93 external_view_embedder_->SupportsDynamicThreadMerging() &&
94 !raster_thread_merger_) {
95 const auto platform_id =
97 const auto gpu_id =
100 delegate_.GetParentRasterThreadMerger(), platform_id, gpu_id);
101 }
102 if (raster_thread_merger_) {
103 raster_thread_merger_->SetMergeUnmergeCallback([this]() {
104 // Clear the GL context after the thread configuration has changed.
105 if (surface_) {
106 surface_->ClearRenderContext();
107 }
108 });
109 }
110}
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()

◆ 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 118 of file rasterizer.cc.

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

◆ 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 112 of file rasterizer.cc.

112 {
113 if (external_view_embedder_) {
114 external_view_embedder_->Teardown();
115 }
116}

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