Flutter Engine
 
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 192 of file rasterizer.cc.

192 {
193 if (external_view_embedder_) {
194 external_view_embedder_->CollectView(view_id);
195 }
196 view_records_.erase(view_id);
197}
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 165 of file rasterizer.cc.

165 {
166 if (raster_thread_merger_) {
167 raster_thread_merger_->Disable();
168 }
169}

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

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

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

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

159 {
160 if (raster_thread_merger_) {
161 raster_thread_merger_->Enable();
162 }
163}

References fml::RasterThreadMerger::Enable().

◆ GetGrContext()

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

Implements flutter::SnapshotDelegate.

Definition at line 203 of file rasterizer.cc.

203 {
204 return surface_ ? surface_->GetContext() : nullptr;
205}

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

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

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

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

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

1102 {
1103 return raster_thread_merger_;
1104}

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

1143 {
1144#if SLIMPELLER
1145 return std::nullopt;
1146#else // SLIMPELLER
1147 if (!surface_) {
1148 return std::nullopt;
1149 }
1150 GrDirectContext* context = surface_->GetContext();
1151 if (context) {
1152 return context->getResourceCacheLimit();
1153 }
1154 return std::nullopt;
1155#endif // SLIMPELLER
1156}

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

199 {
200 return compositor_context_->texture_registry();
201}

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

145 {
146 return is_torn_down_;
147}

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

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

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

1025 {
1026 if (delegate_.GetSettings().enable_impeller &&
1028 FML_DCHECK(false);
1029 FML_LOG(ERROR) << "Last layer tree cannot be screenshotted as a "
1030 "SkiaPicture when using Impeller.";
1031 return {};
1032 }
1033 // TODO(dkwingsmt): Support screenshotting all last layer trees
1034 // when the shell protocol supports multi-views.
1035 // https://github.com/flutter/flutter/issues/135534
1036 // https://github.com/flutter/flutter/issues/135535
1037 auto* layer_tree = GetLastLayerTree(kFlutterImplicitViewId);
1038 if (layer_tree == nullptr) {
1039 FML_LOG(ERROR) << "Last layer tree was null when screenshotting.";
1040 return {};
1041 }
1042
1043 std::pair<sk_sp<SkData>, ScreenshotFormat> data{nullptr,
1045 std::string format;
1046
1047 switch (type) {
1049 format = "ScreenshotType::SkiaPicture";
1050 data.first =
1051 ScreenshotLayerTreeAsPicture(layer_tree, *compositor_context_);
1052 break;
1054 format = "ScreenshotType::UncompressedImage";
1055 data =
1056 ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_, false);
1057 break;
1059 format = "ScreenshotType::CompressedImage";
1060 data = ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_, true);
1061 break;
1063 Surface::SurfaceData surface_data = surface_->GetSurfaceData();
1064 format = surface_data.pixel_format;
1065 data.first = surface_data.data;
1066 break;
1067 }
1068 }
1069
1070 if (data.first == nullptr) {
1071 FML_LOG(ERROR) << "Screenshot data was null.";
1072 return {};
1073 }
1074
1075 if (base64_encode) {
1076 size_t b64_size = Base64::EncodedSize(data.first->size());
1077 auto b64_data = SkData::MakeUninitialized(b64_size);
1078 Base64::Encode(data.first->data(), data.first->size(),
1079 b64_data->writable_data());
1080 return Rasterizer::Screenshot{b64_data, layer_tree->frame_size(), format,
1081 data.second};
1082 }
1083
1084 return Rasterizer::Screenshot{data.first, layer_tree->frame_size(), format,
1085 data.second};
1086}
GLenum type
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
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, 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 1092 of file rasterizer.cc.

1093 {
1094 external_view_embedder_ = view_embedder;
1095}

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

1088 {
1089 next_frame_callback_ = callback;
1090}
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 1116 of file rasterizer.cc.

1116 {
1117#if !SLIMPELLER
1118 user_override_resource_cache_bytes_ |= from_user;
1119
1120 if (!from_user && user_override_resource_cache_bytes_) {
1121 // We should not update the setting here if a user has explicitly set a
1122 // value for this over the flutter/skia channel.
1123 return;
1124 }
1125
1126 max_cache_bytes_ = max_bytes;
1127 if (!surface_) {
1128 return;
1129 }
1130
1131 GrDirectContext* context = surface_->GetContext();
1132 if (context) {
1133 auto context_switch = surface_->MakeRenderContextCurrent();
1134 if (!context_switch->GetResult()) {
1135 return;
1136 }
1137
1138 context->setResourceCacheLimit(max_bytes);
1139 }
1140#endif // !SLIMPELLER
1141}

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

1098 {
1099 snapshot_surface_producer_ = std::move(producer);
1100}

◆ 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 surface_.reset();
133 }
134
135 view_records_.clear();
136
137 if (raster_thread_merger_.get() != nullptr &&
138 raster_thread_merger_.get()->IsMerged()) {
139 FML_DCHECK(raster_thread_merger_->IsEnabled());
140 raster_thread_merger_->UnMergeNowIfLastOne();
141 raster_thread_merger_->SetMergeUnmergeCallback(nullptr);
142 }
143}
T * get() const
Definition ref_ptr.h:117

References 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: