Flutter Engine
 
Loading...
Searching...
No Matches
rasterizer.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_SHELL_COMMON_RASTERIZER_H_
6#define FLUTTER_SHELL_COMMON_RASTERIZER_H_
7
8#include <future>
9#include <memory>
10#include <optional>
11#include <unordered_map>
12
21#include "flutter/fml/closure.h"
28#if IMPELLER_SUPPORTS_RENDERING
29#include "impeller/core/formats.h" // nogncheck
30#include "impeller/display_list/aiks_context.h" // nogncheck
31#include "impeller/renderer/context.h" // nogncheck
33#endif // IMPELLER_SUPPORTS_RENDERING
38#include "third_party/skia/include/core/SkData.h"
39#include "third_party/skia/include/core/SkImage.h"
40#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
41
42#if !IMPELLER_SUPPORTS_RENDERING
43namespace impeller {
44class Context;
45class AiksContext;
46class ImpellerContextFuture;
47} // namespace impeller
48#endif // !IMPELLER_SUPPORTS_RENDERING
49
50namespace flutter {
51
52// The result status of Rasterizer::Draw. This is only used for unit tests.
53enum class DrawStatus {
54 // The drawing was done without any specified status.
55 kDone,
56 // Failed to rasterize the frame because the Rasterizer is not set up.
58 // Nothing was done, because the call was not on the raster thread. Yielded to
59 // let this frame be serviced on the right thread.
61 // Nothing was done, because the pipeline was empty.
63 // Nothing was done, because the GPU was unavailable.
65};
66
67// The result status of drawing to a view. This is only used for unit tests.
69 // The layer tree was successfully rasterized.
71 // The layer tree must be submitted again.
72 //
73 // This can occur on Android when switching the background surface to
74 // FlutterImageView. On Android, the first frame doesn't make the image
75 // available to the ImageReader right away. The second frame does.
76 // TODO(egarciad): https://github.com/flutter/flutter/issues/65652
77 //
78 // This can also occur when the frame is dropped to wait for the thread
79 // merger to merge the raster and platform threads.
80 kRetry,
81 // Failed to rasterize the frame.
82 kFailed,
83 // Layer tree was discarded because its size does not match the view size.
84 // This typically occurs during resizing.
86};
87
88// The information to draw to all views of a frame.
89struct FrameItem {
90 FrameItem(std::vector<std::unique_ptr<LayerTreeTask>> tasks,
91 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder)
92 : layer_tree_tasks(std::move(tasks)),
94 std::vector<std::unique_ptr<LayerTreeTask>> layer_tree_tasks;
95 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder;
96};
97
99
100//------------------------------------------------------------------------------
101/// The rasterizer is a component owned by the shell that resides on the raster
102/// task runner. Each shell owns exactly one instance of a rasterizer. The
103/// rasterizer may only be created, used and collected on the raster task
104/// runner.
105///
106/// The rasterizer owns the instance of the currently active on-screen render
107/// surface. On this surface, it renders the contents of layer trees submitted
108/// to it by the `Engine` (which lives on the UI task runner).
109///
110/// The primary components owned by the rasterizer are the compositor context
111/// and the on-screen render surface. The compositor context has all the GPU
112/// state necessary to render frames to the render surface.
113///
114class Rasterizer final : public SnapshotDelegate,
117 public:
118 //----------------------------------------------------------------------------
119 /// @brief Used to forward events from the rasterizer to interested
120 /// subsystems. Currently, the shell sets itself up as the
121 /// rasterizer delegate to listen for frame rasterization events.
122 /// It can then forward these events to the engine.
123 ///
124 /// Like all rasterizer operation, the rasterizer delegate call
125 /// are made on the raster task runner. Any delegate must ensure
126 /// that they can handle the threading implications.
127 ///
128 class Delegate {
129 public:
130 //--------------------------------------------------------------------------
131 /// @brief Notifies the delegate that a frame has been rendered. The
132 /// rasterizer collects profiling information for each part of
133 /// the frame workload. This profiling information is made
134 /// available to the delegate for forwarding to subsystems
135 /// interested in collecting such profiles. Currently, the shell
136 /// (the delegate) forwards this to the engine where Dart code
137 /// can react to this information.
138 ///
139 /// @see `FrameTiming`
140 ///
141 /// @param[in] frame_timing Instrumentation information for each phase of
142 /// the frame workload.
143 ///
144 virtual void OnFrameRasterized(const FrameTiming& frame_timing) = 0;
145
146 /// Time limit for a smooth frame.
147 ///
148 /// See: `DisplayManager::GetMainDisplayRefreshRate`.
150
151 /// Target time for the latest frame. See also `Shell::OnAnimatorBeginFrame`
152 /// for when this time gets updated.
154
155 /// Task runners used by the shell.
156 virtual const TaskRunners& GetTaskRunners() const = 0;
157
158 /// The raster thread merger from parent shell's rasterizer.
161
162 /// Accessor for the shell's GPU sync switch, which determines whether GPU
163 /// operations are allowed on the current thread.
164 ///
165 /// For example, on some platforms when the application is backgrounded it
166 /// is critical that GPU operations are not processed.
167 virtual std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch()
168 const = 0;
169
170 virtual const Settings& GetSettings() const = 0;
171
172 virtual bool ShouldDiscardLayerTree(int64_t view_id,
173 const flutter::LayerTree& tree) = 0;
174 };
175
176 //----------------------------------------------------------------------------
177 /// @brief How to handle calls to MakeSkiaGpuImage.
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 };
185
186 //----------------------------------------------------------------------------
187 /// @brief Creates a new instance of a rasterizer. Rasterizers may only
188 /// be created on the raster task runner. Rasterizers are
189 /// currently only created by the shell (which also sets itself up
190 /// as the rasterizer delegate).
191 ///
192 /// @param[in] delegate The rasterizer delegate.
193 /// @param[in] gpu_image_behavior How to handle calls to
194 /// MakeSkiaGpuImage.
195 ///
196 explicit Rasterizer(
197 Delegate& delegate,
199
200 //----------------------------------------------------------------------------
201 /// @brief Destroys the rasterizer. This must happen on the raster task
202 /// runner. All GPU resources are collected before this call
203 /// returns. Any context set up by the embedder to hold these
204 /// resources can be immediately collected as well.
205 ///
207
209 std::shared_ptr<impeller::ImpellerContextFuture> impeller_context);
210
211 //----------------------------------------------------------------------------
212 /// @brief Rasterizers may be created well before an on-screen surface is
213 /// available for rendering. Shells usually create a rasterizer in
214 /// their constructors. Once an on-screen surface is available
215 /// however, one may be provided to the rasterizer using this
216 /// call. No rendering may occur before this call. The surface is
217 /// held till the balancing call to `Rasterizer::Teardown` is
218 /// made. Calling a setup before tearing down the previous surface
219 /// (if this is not the first time the surface has been set up) is
220 /// user error.
221 ///
222 /// @see `Rasterizer::Teardown`
223 ///
224 /// @param[in] surface The on-screen render surface.
225 ///
226 void Setup(std::unique_ptr<Surface> surface);
227
228 //----------------------------------------------------------------------------
229 /// @brief Releases the previously set up on-screen render surface and
230 /// collects associated resources. No more rendering may occur
231 /// till the next call to `Rasterizer::Setup` with a new render
232 /// surface. Calling a teardown without a setup is user error.
233 /// Calling this method multiple times is safe.
234 ///
235 void Teardown();
236
237 //----------------------------------------------------------------------------
238 /// @brief Releases any resource used by the external view embedder.
239 /// For example, overlay surfaces or Android views.
240 /// On Android, this method post a task to the platform thread,
241 /// and waits until it completes.
243
244 //----------------------------------------------------------------------------
245 /// @brief Notifies the rasterizer that there is a low memory situation
246 /// and it must purge as many unnecessary resources as possible.
247 /// Currently, the Skia context associated with onscreen rendering
248 /// is told to free GPU resources.
249 ///
250 void NotifyLowMemoryWarning() const;
251
252 //----------------------------------------------------------------------------
253 /// @brief Gets a weak pointer to the rasterizer. The rasterizer may only
254 /// be accessed on the raster task runner.
255 ///
256 /// @return The weak pointer to the rasterizer.
257 ///
259
261
262 //----------------------------------------------------------------------------
263 /// @brief Deallocate the resources for displaying a view.
264 ///
265 /// This method must be called on the raster task runner when a
266 /// view is removed from the engine.
267 ///
268 /// When the rasterizer is requested to draw an unrecognized view,
269 /// it implicitly allocates necessary resources. These resources
270 /// must be explicitly deallocated.
271 ///
272 /// @param[in] view_id The ID of the view.
273 ///
274 void CollectView(int64_t view_id);
275
276 //----------------------------------------------------------------------------
277 /// @brief Returns the last successfully drawn layer tree for the given
278 /// view, or nullptr if there isn't any. This is useful during
279 /// `DrawLastLayerTrees` and computing frame damage.
280 ///
281 /// @bug https://github.com/flutter/flutter/issues/33939
282 ///
283 /// @return A pointer to the last layer or `nullptr` if this rasterizer
284 /// has never rendered a frame to the given view.
285 ///
287
288 //----------------------------------------------------------------------------
289 /// @brief Draws the last layer trees with their last configuration. This
290 /// may seem entirely redundant at first glance. After all, on
291 /// surface loss and re-acquisition, the framework generates a new
292 /// layer tree. Otherwise, why render the same contents to the
293 /// screen again? This is used as an optimization in cases where
294 /// there are external textures (video or camera streams for
295 /// example) in referenced in the layer tree. These textures may
296 /// be updated at a cadence different from that of the Flutter
297 /// application. Flutter can re-render the layer tree with just
298 /// the updated textures instead of waiting for the framework to
299 /// do the work to generate the layer tree describing the same
300 /// contents.
301 ///
302 /// Calling this method clears all last layer trees
303 /// (GetLastLayerTree).
304 ///
306 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder);
307
308 // |SnapshotDelegate|
309 GrDirectContext* GetGrContext() override;
310
311 std::shared_ptr<flutter::TextureRegistry> GetTextureRegistry() override;
312
313 //----------------------------------------------------------------------------
314 /// @brief Takes the next item from the layer tree pipeline and executes
315 /// the raster thread frame workload for that pipeline item to
316 /// render a frame on the on-screen surface.
317 ///
318 /// Why does the draw call take a layer tree pipeline and not the
319 /// layer tree directly?
320 ///
321 /// The pipeline is the way book-keeping of frame workloads
322 /// distributed across the multiple threads is managed. The
323 /// rasterizer deals with the pipelines directly (instead of layer
324 /// trees which is what it actually renders) because the pipeline
325 /// consumer's workload must be accounted for within the pipeline
326 /// itself. If the rasterizer took the layer tree directly, it
327 /// would have to be taken out of the pipeline. That would signal
328 /// the end of the frame workload and the pipeline would be ready
329 /// for new frames. But the last frame has not been rendered by
330 /// the frame yet! On the other hand, the pipeline must own the
331 /// layer tree it renders because it keeps a reference to the last
332 /// layer tree around till a new frame is rendered. So a simple
333 /// reference wont work either. The `Rasterizer::DoDraw` method
334 /// actually performs the GPU operations within the layer tree
335 /// pipeline.
336 ///
337 /// @see `Rasterizer::DoDraw`
338 ///
339 /// @param[in] pipeline The layer tree pipeline to take the next layer tree
340 /// to render from.
341 ///
342 DrawStatus Draw(const std::shared_ptr<FramePipeline>& pipeline);
343
344 //----------------------------------------------------------------------------
345 /// @brief The type of the screenshot to obtain of the previously
346 /// rendered layer tree.
347 ///
348 enum class ScreenshotType {
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 };
382
383 // Specifies the format of pixel data in a Screenshot.
384 enum class ScreenshotFormat {
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 };
394
395 //----------------------------------------------------------------------------
396 /// @brief A POD type used to return the screenshot data along with the
397 /// size of the frame.
398 ///
399 struct Screenshot {
400 //--------------------------------------------------------------------------
401 /// The data used to describe the screenshot. The data format depends on the
402 /// type of screenshot taken and any further encoding done to the same.
403 ///
404 /// @see `ScreenshotType`
405 ///
406 sk_sp<SkData> data;
407
408 //--------------------------------------------------------------------------
409 /// The size of the screenshot in texels.
410 ///
412
413 //--------------------------------------------------------------------------
414 /// Characterization of the format of the data in `data`.
415 ///
416 std::string format;
417
418 //--------------------------------------------------------------------------
419 /// The pixel format of the data in `data`.
420 ///
421 /// If the impeller backend is not used, this value is always kUnknown and
422 /// the data is in RGBA8888 format.
424
425 //--------------------------------------------------------------------------
426 /// @brief Creates an empty screenshot
427 ///
428 Screenshot();
429
430 //--------------------------------------------------------------------------
431 /// @brief Creates a screenshot with the specified data and size.
432 ///
433 /// @param[in] p_data The screenshot data
434 /// @param[in] p_size The screenshot size.
435 /// @param[in] p_format The screenshot format.
436 /// @param[in] p_pixel_format The screenshot format.
437 ///
438 Screenshot(sk_sp<SkData> p_data,
439 DlISize p_size,
440 const std::string& p_format,
441 ScreenshotFormat p_pixel_format);
442
443 //--------------------------------------------------------------------------
444 /// @brief The copy constructor for a screenshot.
445 ///
446 /// @param[in] other The screenshot to copy from.
447 ///
448 Screenshot(const Screenshot& other);
449
450 //--------------------------------------------------------------------------
451 /// @brief Destroys the screenshot object and releases underlying data.
452 ///
454 };
455
456 //----------------------------------------------------------------------------
457 /// @brief Screenshots the last layer tree to one of the supported
458 /// screenshot types and optionally Base 64 encodes that data for
459 /// easier transmission and packaging (usually over the service
460 /// protocol for instrumentation tools running on the host).
461 ///
462 /// @param[in] type The type of the screenshot to gather.
463 /// @param[in] base64_encode Whether Base 64 encoding must be applied to the
464 /// data after a screenshot has been captured.
465 ///
466 /// @return A non-empty screenshot if one could be captured. A screenshot
467 /// capture may fail if there were no layer trees previously
468 /// rendered by this rasterizer, or, due to an unspecified
469 /// internal error. Internal error will be logged to the console.
470 ///
472
473 //----------------------------------------------------------------------------
474 /// @brief Sets a callback that will be executed when the next layer tree
475 /// in rendered to the on-screen surface. This is used by
476 /// embedders to listen for one time operations like listening for
477 /// when the first frame is rendered so that they may hide splash
478 /// screens.
479 ///
480 /// The callback is only executed once and dropped on the GPU
481 /// thread when executed (lambda captures must be able to deal
482 /// with the threading repercussions of this behavior).
483 ///
484 /// @param[in] callback The callback to execute when the next layer tree is
485 /// rendered on-screen.
486 ///
488
489 //----------------------------------------------------------------------------
490 /// @brief Set the External View Embedder. This is done on shell
491 /// initialization. This is non-null on platforms that support
492 /// embedding externally composited views.
493 ///
494 /// @param[in] view_embedder The external view embedder object.
495 ///
497 const std::shared_ptr<ExternalViewEmbedder>& view_embedder);
498
499 //----------------------------------------------------------------------------
500 /// @brief Set the snapshot surface producer. This is done on shell
501 /// initialization. This is non-null on platforms that support taking
502 /// GPU accelerated raster snapshots in the background.
503 ///
504 /// @param[in] producer A surface producer for raster snapshotting when the
505 /// onscreen surface is not available.
506 ///
508 std::unique_ptr<SnapshotSurfaceProducer> producer);
509
510 //----------------------------------------------------------------------------
511 /// @brief Returns a pointer to the compositor context used by this
512 /// rasterizer. This pointer will never be `nullptr`.
513 ///
514 /// @return The compositor context used by this rasterizer.
515 ///
517 return compositor_context_.get();
518 }
519
520 //----------------------------------------------------------------------------
521 /// @brief Returns the raster thread merger used by this rasterizer.
522 /// This may be `nullptr`.
523 ///
524 /// @return The raster thread merger used by this rasterizer.
525 ///
527
528 //----------------------------------------------------------------------------
529 /// @brief Skia has no notion of time. To work around the performance
530 /// implications of this, it may cache GPU resources to reference
531 /// them from one frame to the next. Using this call, embedders
532 /// may set the maximum bytes cached by Skia in its caches
533 /// dedicated to on-screen rendering.
534 ///
535 /// @attention This cache setting will be invalidated when the surface is
536 /// torn down via `Rasterizer::Teardown`. This call must be made
537 /// again with new limits after surface re-acquisition.
538 ///
539 /// @attention This cache does not describe the entirety of GPU resources
540 /// that may be cached. The `RasterCache` also holds very large
541 /// GPU resources.
542 ///
543 /// @see `RasterCache`
544 ///
545 /// @param[in] max_bytes The maximum byte size of resource that may be
546 /// cached for GPU rendering.
547 /// @param[in] from_user Whether this request was from user code, e.g. via
548 /// the flutter/skia message channel, in which case
549 /// it should not be overridden by the platform.
550 ///
551 void SetResourceCacheMaxBytes(size_t max_bytes, bool from_user);
552
553 //----------------------------------------------------------------------------
554 /// @brief The current value of Skia's resource cache size, if a surface
555 /// is present.
556 ///
557 /// @attention This cache does not describe the entirety of GPU resources
558 /// that may be cached. The `RasterCache` also holds very large
559 /// GPU resources.
560 ///
561 /// @see `RasterCache`
562 ///
563 /// @return The size of Skia's resource cache, if available.
564 ///
565 std::optional<size_t> GetResourceCacheMaxBytes() const;
566
567 //----------------------------------------------------------------------------
568 /// @brief Enables the thread merger if the external view embedder
569 /// supports dynamic thread merging.
570 ///
571 /// @attention This method is thread-safe. When the thread merger is enabled,
572 /// the raster task queue can run in the platform thread at any
573 /// time.
574 ///
575 /// @see `ExternalViewEmbedder`
576 ///
578
579 //----------------------------------------------------------------------------
580 /// @brief Disables the thread merger if the external view embedder
581 /// supports dynamic thread merging.
582 ///
583 /// @attention This method is thread-safe. When the thread merger is
584 /// disabled, the raster task queue will continue to run in the
585 /// same thread until |EnableThreadMergerIfNeeded| is called.
586 ///
587 /// @see `ExternalViewEmbedder`
588 ///
590
591 //----------------------------------------------------------------------------
592 /// @brief Returns whether TearDown has been called.
593 ///
594 /// This method is used only in unit tests.
595 ///
596 bool IsTornDown();
597
598 //----------------------------------------------------------------------------
599 /// @brief Returns the last status of drawing the specific view.
600 ///
601 /// This method is used only in unit tests.
602 ///
603 std::optional<DrawSurfaceStatus> GetLastDrawStatus(int64_t view_id);
604
605 private:
606 // The result status of DoDraw, DrawToSurfaces, and DrawToSurfacesUnsafe.
607 enum class DoDrawStatus {
608 // The drawing was done without any specified status.
609 kDone,
610 // Frame has been successfully rasterized, but there are additional items
611 // in the pipeline waiting to be consumed. This is currently only used when
612 // thread configuration change occurs.
613 kEnqueuePipeline,
614 // Failed to rasterize the frame because the Rasterizer is not set up.
615 kNotSetUp,
616 // Nothing was done, because GPU was unavailable.
618 };
619
620 // The result of DoDraw.
621 struct DoDrawResult {
622 // The overall status of the drawing process.
623 //
624 // The status of drawing a specific view is available at GetLastDrawStatus.
625 DoDrawStatus status = DoDrawStatus::kDone;
626
627 // The frame item that needs to be submitted again.
628 //
629 // See RasterStatus::kResubmit and kSkipAndRetry for when it happens.
630 //
631 // If `resubmitted_item` is not null, its `tasks` is guaranteed to be
632 // non-empty.
633 std::unique_ptr<FrameItem> resubmitted_item;
634 };
635
636 struct ViewRecord {
637 std::unique_ptr<LayerTreeTask> last_successful_task;
638 std::optional<DrawSurfaceStatus> last_draw_status;
639 };
640
641 // |SnapshotDelegate|
642 std::unique_ptr<GpuImageResult> MakeSkiaGpuImage(
643 sk_sp<DisplayList> display_list,
644 const SkImageInfo& image_info) override;
645
646 // |SnapshotDelegate|
647 void MakeRasterSnapshot(
648 sk_sp<DisplayList> display_list,
649 DlISize picture_size,
650 std::function<void(sk_sp<DlImage>)> callback) override;
651
652 // |SnapshotDelegate|
653 sk_sp<DlImage> MakeRasterSnapshotSync(sk_sp<DisplayList> display_list,
654 DlISize picture_size) override;
655
656 // |SnapshotDelegate|
657 sk_sp<SkImage> ConvertToRasterImage(sk_sp<SkImage> image) override;
658
659 // |SnapshotDelegate|
660 void CacheRuntimeStage(
661 const std::shared_ptr<impeller::RuntimeStage>& runtime_stage) override;
662
663 // |SnapshotDelegate|
664 bool MakeRenderContextCurrent() override;
665
666 // |Stopwatch::Delegate|
667 /// Time limit for a smooth frame.
668 ///
669 /// See: `DisplayManager::GetMainDisplayRefreshRate`.
670 fml::Milliseconds GetFrameBudget() const override;
671
672 // |SnapshotController::Delegate|
673 const std::unique_ptr<Surface>& GetSurface() const override {
674 return surface_;
675 }
676
677 // |SnapshotController::Delegate|
678 bool IsAiksContextInitialized() const override {
679#if IMPELLER_SUPPORTS_RENDERING
680 return surface_ && surface_->GetAiksContext();
681#else
682 return false;
683#endif
684 }
685
686 // |SnapshotController::Delegate|
687 std::shared_ptr<impeller::AiksContext> GetAiksContext() const override {
688#if IMPELLER_SUPPORTS_RENDERING
689 if (surface_) {
690 return surface_->GetAiksContext();
691 }
692 if (auto context = impeller_context_->GetContext()) {
693 return std::make_shared<impeller::AiksContext>(
695 }
696#endif
697 return nullptr;
698 }
699
700 // |SnapshotController::Delegate|
701 const std::unique_ptr<SnapshotSurfaceProducer>& GetSnapshotSurfaceProducer()
702 const override {
703 return snapshot_surface_producer_;
704 }
705
706 // |SnapshotController::Delegate|
707 std::shared_ptr<const fml::SyncSwitch> GetIsGpuDisabledSyncSwitch()
708 const override {
709 return delegate_.GetIsGpuDisabledSyncSwitch();
710 }
711
712 std::pair<sk_sp<SkData>, ScreenshotFormat> ScreenshotLayerTreeAsImage(
713 flutter::LayerTree* tree,
715 bool compressed);
716
717 // This method starts with the frame timing recorder at build end. This
718 // method might push it to raster end and get the recorded time, or abort in
719 // the middle and not get the recorded time.
720 DoDrawResult DoDraw(
721 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder,
722 std::vector<std::unique_ptr<LayerTreeTask>> tasks);
723
724 // This method pushes the frame timing recorder from build end to raster end.
725 DoDrawResult DrawToSurfaces(
726 FrameTimingsRecorder& frame_timings_recorder,
727 std::vector<std::unique_ptr<LayerTreeTask>> tasks);
728
729 // Draws the specified layer trees to views, assuming we have access to the
730 // GPU.
731 //
732 // If any layer trees need resubmitting, this method returns the frame item to
733 // be resubmitted. Otherwise, it returns nullptr.
734 //
735 // Unsafe because it assumes we have access to the GPU which isn't the case
736 // when iOS is backgrounded, for example.
737 //
738 // This method pushes the frame timing recorder from build end to raster end.
739 std::unique_ptr<FrameItem> DrawToSurfacesUnsafe(
740 FrameTimingsRecorder& frame_timings_recorder,
741 std::vector<std::unique_ptr<LayerTreeTask>> tasks);
742
743 // Draws the layer tree to the specified view, assuming we have access to the
744 // GPU.
745 //
746 // This method is not affiliated with the frame timing recorder, but must be
747 // included between the RasterStart and RasterEnd.
748 DrawSurfaceStatus DrawToSurfaceUnsafe(
749 int64_t view_id,
750 flutter::LayerTree& layer_tree,
751 float device_pixel_ratio,
752 std::optional<fml::TimePoint> presentation_time);
753
754 ViewRecord& EnsureViewRecord(int64_t view_id);
755
756 void FireNextFrameCallbackIfPresent();
757
758 static bool ShouldResubmitFrame(const DoDrawResult& result);
759 static DrawStatus ToDrawStatus(DoDrawStatus status);
760
761 bool is_torn_down_ = false;
762 Delegate& delegate_;
763 [[maybe_unused]] MakeGpuImageBehavior gpu_image_behavior_;
764 std::shared_ptr<impeller::ImpellerContextFuture> impeller_context_;
765 std::unique_ptr<Surface> surface_;
766 std::unique_ptr<SnapshotSurfaceProducer> snapshot_surface_producer_;
767 std::unique_ptr<flutter::CompositorContext> compositor_context_;
768 std::unordered_map<int64_t, ViewRecord> view_records_;
769 fml::closure next_frame_callback_;
770 bool user_override_resource_cache_bytes_ = false;
771 std::optional<size_t> max_cache_bytes_;
772 fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger_;
773 std::shared_ptr<ExternalViewEmbedder> external_view_embedder_;
774 std::unique_ptr<SnapshotController> snapshot_controller_;
775
776 // WeakPtrFactory must be the last member.
779};
780
781} // namespace flutter
782
783#endif // FLUTTER_SHELL_COMMON_RASTERIZER_H_
GLenum type
Used to forward events from the rasterizer to interested subsystems. Currently, the shell sets itself...
Definition rasterizer.h:128
virtual const TaskRunners & GetTaskRunners() const =0
Task runners used by the shell.
virtual void OnFrameRasterized(const FrameTiming &frame_timing)=0
Notifies the delegate that a frame has been rendered. The rasterizer collects profiling information f...
virtual const Settings & GetSettings() const =0
virtual std::shared_ptr< const fml::SyncSwitch > GetIsGpuDisabledSyncSwitch() const =0
virtual const fml::RefPtr< fml::RasterThreadMerger > GetParentRasterThreadMerger() const =0
The raster thread merger from parent shell's rasterizer.
virtual bool ShouldDiscardLayerTree(int64_t view_id, const flutter::LayerTree &tree)=0
virtual fml::Milliseconds GetFrameBudget()=0
virtual fml::TimePoint GetLatestFrameTargetTime() const =0
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....
fml::RefPtr< fml::RasterThreadMerger > GetRasterThreadMerger()
Returns the raster thread merger used by this rasterizer. This may be nullptr.
bool IsTornDown()
Returns whether TearDown has been called.
void SetSnapshotSurfaceProducer(std::unique_ptr< SnapshotSurfaceProducer > producer)
Set the snapshot surface producer. This is done on shell initialization. This is non-null on platform...
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....
ScreenshotType
The type of the screenshot to obtain of the previously rendered layer tree.
Definition rasterizer.h:348
void DisableThreadMergerIfNeeded()
Disables the thread merger if the external view embedder supports dynamic thread merging.
~Rasterizer()
Destroys the rasterizer. This must happen on the raster task runner. All GPU resources are collected ...
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 th...
fml::TaskRunnerAffineWeakPtr< Rasterizer > GetWeakPtr() const
Gets a weak pointer to the rasterizer. The rasterizer may only be accessed on the raster task runner.
Definition rasterizer.cc:67
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...
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 g...
MakeGpuImageBehavior
How to handle calls to MakeSkiaGpuImage.
Definition rasterizer.h:178
@ kGpu
MakeSkiaGpuImage returns a GPU resident image, if possible.
void TeardownExternalViewEmbedder()
Releases any resource used by the external view embedder. For example, overlay surfaces or Android vi...
void EnableThreadMergerIfNeeded()
Enables the thread merger if the external view embedder supports dynamic thread merging.
fml::TaskRunnerAffineWeakPtr< SnapshotDelegate > GetSnapshotDelegate() const
Definition rasterizer.cc:71
std::shared_ptr< flutter::TextureRegistry > GetTextureRegistry() override
Gets the registry of external textures currently in use by the rasterizer. These textures may be upda...
void SetImpellerContext(std::shared_ptr< impeller::ImpellerContextFuture > impeller_context)
Definition rasterizer.cc:76
std::optional< size_t > GetResourceCacheMaxBytes() const
The current value of Skia's resource cache size, if a surface is present.
void Teardown()
Releases the previously set up on-screen render surface and collects associated resources....
GrDirectContext * GetGrContext() override
void CollectView(int64_t view_id)
Deallocate the resources for displaying a view.
void Setup(std::unique_ptr< Surface > surface)
Rasterizers may be created well before an on-screen surface is available for rendering....
Definition rasterizer.cc:81
std::optional< DrawSurfaceStatus > GetLastDrawStatus(int64_t view_id)
Returns the last status of drawing the specific view.
void NotifyLowMemoryWarning() const
Notifies the rasterizer that there is a low memory situation and it must purge as many unnecessary re...
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 t...
Screenshot ScreenshotLastLayerTree(ScreenshotType type, bool base64_encode)
Screenshots the last layer tree to one of the supported screenshot types and optionally Base 64 encod...
flutter::CompositorContext * compositor_context()
Returns a pointer to the compositor context used by this rasterizer. This pointer will never be nullp...
Definition rasterizer.h:516
The refresh rate interface for Stopwatch.
Definition stopwatch.h:23
Describes the fixed function and programmable aspects of rendering and compute operations performed b...
Definition pipeline.h:52
static std::shared_ptr< TypographerContext > Make()
FlutterVulkanImage * image
G_BEGIN_DECLS FlutterViewId view_id
FlutterDesktopBinaryReply callback
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition macros.h:27
impeller::ISize32 DlISize
DrawSurfaceStatus
Definition rasterizer.h:68
std::chrono::duration< double, std::milli > Milliseconds
Definition time_delta.h:18
std::function< void()> closure
Definition closure.h:14
Definition ref_ptr.h:261
std::unique_ptr< FrameTimingsRecorder > frame_timings_recorder
Definition rasterizer.h:95
FrameItem(std::vector< std::unique_ptr< LayerTreeTask > > tasks, std::unique_ptr< FrameTimingsRecorder > frame_timings_recorder)
Definition rasterizer.h:90
std::vector< std::unique_ptr< LayerTreeTask > > layer_tree_tasks
Definition rasterizer.h:94
A POD type used to return the screenshot data along with the size of the frame.
Definition rasterizer.h:399
Screenshot(const Screenshot &other)
The copy constructor for a screenshot.
Screenshot()
Creates an empty screenshot.
~Screenshot()
Destroys the screenshot object and releases underlying data.