5#include "flutter/shell/common/rasterizer.h"
13#include "flutter/common/constants.h"
14#include "flutter/common/graphics/persistent_cache.h"
15#include "flutter/flow/layers/offscreen_surface.h"
16#include "flutter/fml/time/time_delta.h"
17#include "flutter/fml/time/time_point.h"
18#include "flutter/shell/common/base64.h"
19#include "flutter/shell/common/serialization_callbacks.h"
40#if IMPELLER_SUPPORTS_RENDERING
55 gpu_image_behavior_(gpu_image_behavior),
66 return weak_factory_.GetWeakPtr();
71 return weak_factory_.GetWeakPtr();
75 std::weak_ptr<impeller::Context> impeller_context) {
76 impeller_context_ = std::move(impeller_context);
82 if (max_cache_bytes_.has_value()) {
84 user_override_resource_cache_bytes_);
87 auto context_switch = surface_->MakeRenderContextCurrent();
88 if (context_switch->GetResult()) {
89 compositor_context_->OnGrContextCreated();
92 if (external_view_embedder_ &&
93 external_view_embedder_->SupportsDynamicThreadMerging() &&
94 !raster_thread_merger_) {
95 const auto platform_id =
102 if (raster_thread_merger_) {
106 surface_->ClearRenderContext();
113 if (external_view_embedder_) {
114 external_view_embedder_->Teardown();
119 is_torn_down_ =
true;
121 auto context_switch = surface_->MakeRenderContextCurrent();
122 if (context_switch->GetResult()) {
123 compositor_context_->OnGrContextDestroyed();
124 if (
auto* context = surface_->GetContext()) {
131 view_records_.clear();
133 if (raster_thread_merger_.
get() !=
nullptr &&
142 return is_torn_down_;
147 auto found = view_records_.find(view_id);
148 if (found != view_records_.end()) {
149 return found->second.last_draw_status;
151 return std::optional<DrawSurfaceStatus>();
156 if (raster_thread_merger_) {
157 raster_thread_merger_->
Enable();
162 if (raster_thread_merger_) {
163 raster_thread_merger_->
Disable();
170 <<
"Rasterizer::NotifyLowMemoryWarning called with no surface.";
173 auto context = surface_->GetContext();
176 <<
"Rasterizer::NotifyLowMemoryWarning called with no GrContext.";
179 auto context_switch = surface_->MakeRenderContextCurrent();
180 if (!context_switch->GetResult()) {
183 context->performDeferredCleanup(std::chrono::milliseconds(0));
187 if (external_view_embedder_) {
188 external_view_embedder_->CollectView(view_id);
190 view_records_.erase(view_id);
194 return compositor_context_->texture_registry();
198 return surface_ ? surface_->GetContext() :
nullptr;
202 auto found = view_records_.find(view_id);
203 if (found == view_records_.end()) {
206 auto& last_task = found->second.last_successful_task;
207 if (last_task ==
nullptr) {
210 return last_task->layer_tree.get();
214 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
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));
229 DrawToSurfaces(*frame_timings_recorder, std::move(tasks));
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_);
242 if (raster_thread_merger_ &&
251 DoDrawResult 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));
265 bool should_resubmit_frame = ShouldResubmitFrame(draw_result);
266 if (should_resubmit_frame) {
268 auto front_continuation = pipeline->ProduceIfEmpty();
270 front_continuation.Complete(std::move(draw_result.resubmitted_item));
274 }
else if (draw_result.status == DoDrawStatus::kEnqueuePipeline) {
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_);
287 switch (consume_result) {
290 [weak_this = weak_factory_.GetWeakPtr(), pipeline]() {
292 weak_this->Draw(pipeline);
301 return ToDrawStatus(draw_result.status);
304bool Rasterizer::ShouldResubmitFrame(
const DoDrawResult&
result) {
305 if (
result.resubmitted_item) {
312DrawStatus Rasterizer::ToDrawStatus(DoDrawStatus status) {
314 case DoDrawStatus::kEnqueuePipeline:
315 return DrawStatus::kDone;
316 case DoDrawStatus::kNotSetUp:
317 return DrawStatus::kNotSetUp;
318 case DoDrawStatus::kGpuUnavailable:
319 return DrawStatus::kGpuUnavailable;
320 case DoDrawStatus::kDone:
321 return DrawStatus::kDone;
327std::unique_ptr<SnapshotDelegate::GpuImageResult> MakeBitmapImage(
336 if (image_info.
width() > 16384 || image_info.
height() > 16384) {
337 return std::make_unique<SnapshotDelegate::GpuImageResult>(
339 "unable to create bitmap render target at specified size " +
340 std::to_string(image_info.
width()) +
"x" +
341 std::to_string(image_info.
height()));
345 auto canvas = DlSkCanvasAdapter(
surface->getCanvas());
346 canvas.Clear(DlColor::kTransparent());
347 canvas.DrawDisplayList(display_list);
350 return std::make_unique<SnapshotDelegate::GpuImageResult>(
352 image ?
"" :
"Unable to create image");
356std::unique_ptr<Rasterizer::GpuImageResult> Rasterizer::MakeSkiaGpuImage(
362 std::unique_ptr<SnapshotDelegate::GpuImageResult>
result;
363 delegate_.GetIsGpuDisabledSyncSwitch()->Execute(
365 .SetIfTrue([&
result, &image_info, &display_list] {
368 result = MakeBitmapImage(display_list, image_info);
370 .SetIfFalse([&
result, &image_info, &display_list,
372 gpu_image_behavior = gpu_image_behavior_] {
374 gpu_image_behavior == MakeGpuImageBehavior::kBitmap) {
377 result = MakeBitmapImage(display_list, image_info);
381 auto context_switch =
surface->MakeRenderContextCurrent();
382 if (!context_switch->GetResult()) {
383 result = MakeBitmapImage(display_list, image_info);
387 auto* context =
surface->GetContext();
389 result = MakeBitmapImage(display_list, image_info);
395 skgpu::Mipmapped::kNo, GrRenderable::kYes);
397 result = std::make_unique<SnapshotDelegate::GpuImageResult>(
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()));
409 result = std::make_unique<SnapshotDelegate::GpuImageResult>(
411 "unable to create rendering surface for image");
416 canvas.Clear(DlColor::kTransparent());
417 canvas.DrawDisplayList(display_list);
419 result = std::make_unique<SnapshotDelegate::GpuImageResult>(
427 return snapshot_controller_->MakeRasterSnapshot(display_list, picture_size);
432 return snapshot_controller_->ConvertToRasterImage(
image);
436void Rasterizer::CacheRuntimeStage(
437 const std::shared_ptr<impeller::RuntimeStage>& runtime_stage) {
438 snapshot_controller_->CacheRuntimeStage(runtime_stage);
445Rasterizer::DoDrawResult Rasterizer::DoDraw(
446 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder,
447 std::vector<std::unique_ptr<LayerTreeTask>> tasks) {
449 "Rasterizer::DoDraw", 0,
452 .GetRasterTaskRunner()
453 ->RunsTasksOnCurrentThread());
454 frame_timings_recorder->AssertInState(FrameTimingsRecorder::State::kBuildEnd);
457 return DoDrawResult{DoDrawStatus::kDone};
460 return DoDrawResult{DoDrawStatus::kNotSetUp};
463 PersistentCache* persistent_cache = PersistentCache::GetCacheForProcess();
464 persistent_cache->ResetStoredNewShaders();
467 DrawToSurfaces(*frame_timings_recorder, std::move(tasks));
470 if (
result.status == DoDrawStatus::kGpuUnavailable) {
471 return DoDrawResult{DoDrawStatus::kGpuUnavailable};
474 if (persistent_cache->IsDumpingSkp() &&
475 persistent_cache->StoredNewShaders()) {
477 ScreenshotLastLayerTree(ScreenshotType::SkiaPicture,
false);
478 persistent_cache->DumpSkp(*screenshot.data);
484 delegate_.OnFrameRasterized(frame_timings_recorder->GetRecordedTime());
488#if !defined(OS_FUCHSIA)
490 frame_timings_recorder->GetRasterEndTime();
492 frame_timings_recorder->GetVsyncTargetTime();
493 if (raster_finish_time > frame_target_time) {
496 const auto frame_budget_millis =
delegate_.GetFrameBudget().count();
497 if (latest_frame_target_time < raster_finish_time) {
498 latest_frame_target_time =
499 latest_frame_target_time +
502 const auto frame_lag =
503 (latest_frame_target_time - frame_target_time).ToMillisecondsF();
504 const int vsync_transitions_missed =
round(frame_lag / frame_budget_millis);
509 latest_frame_target_time,
512 "current_frame_target_time",
513 latest_frame_target_time,
514 "vsync_transitions_missed",
515 vsync_transitions_missed
536 if (raster_thread_merger_) {
537 if (raster_thread_merger_->DecrementLease() ==
540 .status = DoDrawStatus::kEnqueuePipeline,
541 .resubmitted_item = std::move(
result.resubmitted_item),
549Rasterizer::DoDrawResult Rasterizer::DrawToSurfaces(
550 FrameTimingsRecorder& frame_timings_recorder,
551 std::vector<std::unique_ptr<LayerTreeTask>> tasks) {
554 frame_timings_recorder.AssertInState(FrameTimingsRecorder::State::kBuildEnd);
557 .status = DoDrawStatus::kDone,
559 if (
surface_->AllowsDrawingWhenGpuDisabled()) {
561 DrawToSurfacesUnsafe(frame_timings_recorder, std::move(tasks));
563 delegate_.GetIsGpuDisabledSyncSwitch()->Execute(
566 result.status = DoDrawStatus::kGpuUnavailable;
568 frame_timings_recorder.RecordRasterEnd();
571 result.resubmitted_item = DrawToSurfacesUnsafe(
572 frame_timings_recorder, std::move(tasks));
575 frame_timings_recorder.AssertInState(FrameTimingsRecorder::State::kRasterEnd);
580std::unique_ptr<FrameItem> Rasterizer::DrawToSurfacesUnsafe(
581 FrameTimingsRecorder& frame_timings_recorder,
582 std::vector<std::unique_ptr<LayerTreeTask>> tasks) {
583 compositor_context_->ui_time().SetLapTime(
584 frame_timings_recorder.GetBuildDuration());
587 auto task_iter = tasks.begin();
588 while (task_iter != tasks.end()) {
589 LayerTreeTask& task = **task_iter;
590 if (
delegate_.ShouldDiscardLayerTree(task.view_id, *task.layer_tree)) {
591 EnsureViewRecord(task.view_id).last_draw_status =
592 DrawSurfaceStatus::kDiscarded;
593 task_iter = tasks.erase(task_iter);
600 frame_timings_recorder.RecordRasterEnd();
604 if (external_view_embedder_) {
605 FML_DCHECK(!external_view_embedder_->GetUsedThisFrame());
606 external_view_embedder_->SetUsedThisFrame(
true);
607 external_view_embedder_->BeginFrame(
surface_->GetContext(),
608 raster_thread_merger_);
611 std::optional<fml::TimePoint> presentation_time = std::nullopt;
617 const auto vsync_target_time = frame_timings_recorder.GetVsyncTargetTime();
619 presentation_time = vsync_target_time;
626 std::vector<std::unique_ptr<LayerTreeTask>> resubmitted_tasks;
627 for (std::unique_ptr<LayerTreeTask>& task : tasks) {
628 int64_t view_id = task->view_id;
629 std::unique_ptr<LayerTree> layer_tree = std::move(task->layer_tree);
630 float device_pixel_ratio = task->device_pixel_ratio;
633 view_id, *layer_tree, device_pixel_ratio, presentation_time);
634 FML_DCHECK(status != DrawSurfaceStatus::kDiscarded);
636 auto& view_record = EnsureViewRecord(task->view_id);
637 view_record.last_draw_status = status;
638 if (status == DrawSurfaceStatus::kSuccess) {
639 view_record.last_successful_task = std::make_unique<LayerTreeTask>(
640 view_id, std::move(layer_tree), device_pixel_ratio);
641 }
else if (status == DrawSurfaceStatus::kRetry) {
642 resubmitted_tasks.push_back(std::make_unique<LayerTreeTask>(
643 view_id, std::move(layer_tree), device_pixel_ratio));
648 frame_timings_recorder.RecordRasterEnd(&compositor_context_->raster_cache());
649 FireNextFrameCallbackIfPresent();
652 surface_->GetContext()->performDeferredCleanup(kSkiaCleanupExpiration);
655 if (resubmitted_tasks.empty()) {
658 return std::make_unique<FrameItem>(
659 std::move(resubmitted_tasks),
660 frame_timings_recorder.CloneUntil(
661 FrameTimingsRecorder::State::kBuildEnd));
669 float device_pixel_ratio,
670 std::optional<fml::TimePoint> presentation_time) {
673 DlCanvas* embedder_root_canvas =
nullptr;
674 if (external_view_embedder_) {
675 external_view_embedder_->PrepareFlutterView(layer_tree.
frame_size(),
678 embedder_root_canvas = external_view_embedder_->GetRootCanvas();
686 if (
frame ==
nullptr) {
687 return DrawSurfaceStatus::kFailed;
693 SkMatrix root_surface_transformation =
696 auto root_surface_canvas =
697 embedder_root_canvas ? embedder_root_canvas :
frame->Canvas();
698 auto compositor_frame = compositor_context_->AcquireFrame(
701 external_view_embedder_.get(),
702 root_surface_transformation,
704 frame->framebuffer_info()
706 raster_thread_merger_,
709 if (compositor_frame) {
710 compositor_context_->raster_cache().BeginFrame();
712 std::unique_ptr<FrameDamage> damage;
715 if (
frame->framebuffer_info().supports_partial_repaint &&
721 bool force_full_repaint =
722 external_view_embedder_ &&
723 (!raster_thread_merger_ || raster_thread_merger_->IsMerged());
725 damage = std::make_unique<FrameDamage>();
726 auto existing_damage =
frame->framebuffer_info().existing_damage;
727 if (existing_damage.has_value() && !force_full_repaint) {
728 damage->SetPreviousLayerTree(GetLastLayerTree(view_id));
729 damage->AddAdditionalDamage(existing_damage.value());
730 damage->SetClipAlignment(
731 frame->framebuffer_info().horizontal_clip_alignment,
732 frame->framebuffer_info().vertical_clip_alignment);
736 bool ignore_raster_cache =
true;
737 if (
surface_->EnableRasterCache() &&
739 ignore_raster_cache =
false;
743 compositor_frame->Raster(layer_tree,
747 if (frame_status == RasterStatus::kSkipAndRetry) {
748 return DrawSurfaceStatus::kRetry;
751 SurfaceFrame::SubmitInfo submit_info;
752 submit_info.presentation_time = presentation_time;
754 submit_info.frame_damage = damage->GetFrameDamage();
755 submit_info.buffer_damage = damage->GetBufferDamage();
758 frame->set_submit_info(submit_info);
760 if (external_view_embedder_ &&
761 (!raster_thread_merger_ || raster_thread_merger_->IsMerged())) {
763 external_view_embedder_->SubmitFlutterView(
772 if (frame_status != RasterStatus::kResubmit) {
773 compositor_context_->raster_cache().EndFrame();
776 if (frame_status == RasterStatus::kResubmit) {
777 return DrawSurfaceStatus::kRetry;
779 FML_CHECK(frame_status == RasterStatus::kSuccess);
780 return DrawSurfaceStatus::kSuccess;
784 return DrawSurfaceStatus::kFailed;
787Rasterizer::ViewRecord& Rasterizer::EnsureViewRecord(int64_t view_id) {
788 return view_records_[view_id];
799 SkMatrix root_surface_transformation;
800 root_surface_transformation.
reset();
806 root_surface_transformation,
807 false,
true,
nullptr,
nullptr);
808 frame->Raster(*tree,
true,
nullptr);
810#if defined(OS_FUCHSIA)
830 const std::shared_ptr<impeller::AiksContext>& aiks_context) {
833 SkMatrix root_surface_transformation;
834 root_surface_transformation.
reset();
840 root_surface_transformation,
845 canvas->
Clear(DlColor::kTransparent());
846 frame->Raster(*tree,
true,
nullptr);
850#if IMPELLER_SUPPORTS_RENDERING
867 return Rasterizer::ScreenshotFormat::kUnknown;
869 return Rasterizer::ScreenshotFormat::kR8G8B8A8UNormInt;
871 return Rasterizer::ScreenshotFormat::kB8G8R8A8UNormInt;
873 return Rasterizer::ScreenshotFormat::kR16G16B16A16Float;
877static std::pair<sk_sp<SkData>, Rasterizer::ScreenshotFormat>
878ScreenshotLayerTreeAsImageImpeller(
879 const std::shared_ptr<impeller::AiksContext>& aiks_context,
884 FML_LOG(
ERROR) <<
"Compressed screenshots not supported for Impeller";
885 return {
nullptr, Rasterizer::ScreenshotFormat::kUnknown};
895 builder.Build()->Dispatch(dispatcher);
904 texture->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
905 auto impeller_context = aiks_context->GetContext();
907 impeller_context->GetResourceAllocator()->CreateBuffer(buffer_desc);
908 auto command_buffer = impeller_context->CreateCommandBuffer();
909 command_buffer->SetLabel(
"BlitTextureToBuffer Command Buffer");
910 auto pass = command_buffer->CreateBlitPass();
912 pass->EncodeCommands(impeller_context->GetResourceAllocator());
915 auto completion = [
buffer, &buffer_desc, &sk_data,
925 if (!impeller_context->GetCommandQueue()
926 ->Submit({command_buffer}, completion)
931 return std::make_pair(
932 sk_data, ToScreenshotFormat(
texture->GetTextureDescriptor().format));
936std::pair<sk_sp<SkData>, Rasterizer::ScreenshotFormat>
937Rasterizer::ScreenshotLayerTreeAsImage(
941#if IMPELLER_SUPPORTS_RENDERING
942 if (
delegate_.GetSettings().enable_impeller) {
943 return ScreenshotLayerTreeAsImageImpeller(GetAiksContext(), tree,
944 compositor_context, compressed);
951 std::unique_ptr<OffscreenSurface> snapshot_surface =
952 std::make_unique<OffscreenSurface>(surface_context, tree->
frame_size());
954 if (!snapshot_surface->IsValid()) {
955 FML_LOG(
ERROR) <<
"Screenshot: unable to create snapshot surface";
956 return {
nullptr, ScreenshotFormat::kUnknown};
960 DlCanvas* canvas = snapshot_surface->GetCanvas();
966 auto context_switch =
surface_->MakeRenderContextCurrent();
967 if (!context_switch->GetResult()) {
968 FML_LOG(
ERROR) <<
"Screenshot: unable to make image screenshot";
969 return {
nullptr, ScreenshotFormat::kUnknown};
975 return std::make_pair(snapshot_surface->GetRasterData(compressed),
976 ScreenshotFormat::kUnknown);
981 bool base64_encode) {
982 if (
delegate_.GetSettings().enable_impeller &&
983 type == ScreenshotType::SkiaPicture) {
985 FML_LOG(
ERROR) <<
"Last layer tree cannot be screenshotted as a "
986 "SkiaPicture when using Impeller.";
994 if (layer_tree ==
nullptr) {
995 FML_LOG(
ERROR) <<
"Last layer tree was null when screenshotting.";
1000 ScreenshotFormat::kUnknown};
1004 case ScreenshotType::SkiaPicture:
1005 format =
"ScreenshotType::SkiaPicture";
1009 case ScreenshotType::UncompressedImage:
1010 format =
"ScreenshotType::UncompressedImage";
1012 ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_,
false);
1014 case ScreenshotType::CompressedImage:
1015 format =
"ScreenshotType::CompressedImage";
1016 data = ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_,
true);
1018 case ScreenshotType::SurfaceData: {
1026 if (
data.first ==
nullptr) {
1031 if (base64_encode) {
1032 size_t b64_size = Base64::EncodedSize(
data.first->size());
1034 Base64::Encode(
data.first->data(),
data.first->size(),
1035 b64_data->writable_data());
1048void Rasterizer::SetExternalViewEmbedder(
1049 const std::shared_ptr<ExternalViewEmbedder>& view_embedder) {
1050 external_view_embedder_ = view_embedder;
1053void Rasterizer::SetSnapshotSurfaceProducer(
1054 std::unique_ptr<SnapshotSurfaceProducer> producer) {
1055 snapshot_surface_producer_ = std::move(producer);
1059 return raster_thread_merger_;
1062void Rasterizer::FireNextFrameCallbackIfPresent() {
1063 if (!next_frame_callback_) {
1067 auto callback = next_frame_callback_;
1068 next_frame_callback_ =
nullptr;
1072void Rasterizer::SetResourceCacheMaxBytes(
size_t max_bytes,
bool from_user) {
1073 user_override_resource_cache_bytes_ |= from_user;
1075 if (!from_user && user_override_resource_cache_bytes_) {
1081 max_cache_bytes_ = max_bytes;
1088 auto context_switch =
surface_->MakeRenderContextCurrent();
1089 if (!context_switch->GetResult()) {
1097std::optional<size_t> Rasterizer::GetResourceCacheMaxBytes()
const {
1099 return std::nullopt;
1105 return std::nullopt;
1108Rasterizer::Screenshot::Screenshot() {}
1112 const std::string& p_format,
1117 pixel_format(p_pixel_format) {}
static void round(SkPoint *p)
@ kTopLeft_GrSurfaceOrigin
static std::unique_ptr< SkEncoder > Make(SkWStream *dst, const SkPixmap *src, const SkYUVAPixmaps *srcYUVA, const SkColorSpace *srcYUVAColorSpace, const SkJpegEncoder::Options &options)
sk_sp< T > sk_ref_sp(T *obj)
size_t getResourceCacheLimit() const
void setResourceCacheLimit(size_t maxResourceBytes)
static sk_sp< SkData > MakeUninitialized(size_t length)
static sk_sp< SkData > MakeWithCopy(const void *data, size_t length)
SkScalar get(int index) const
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
SkCanvas * getRecordingCanvas()
sk_sp< SkPicture > finishRecordingAsPicture()
sk_sp< SkData > serialize(const SkSerialProcs *procs=nullptr) const
virtual std::unique_ptr< ScopedFrame > AcquireFrame(GrDirectContext *gr_context, DlCanvas *canvas, ExternalViewEmbedder *view_embedder, const SkMatrix &root_surface_transformation, bool instrumentation_enabled, bool surface_supports_readback, fml::RefPtr< fml::RasterThreadMerger > raster_thread_merger, impeller::AiksContext *aiks_context)
Developer-facing API for rendering anything within the engine.
void Clear(DlColor color)
Backend implementation of |DlCanvas| for |SkCanvas|.
const SkISize & frame_size() const
bool is_leaf_layer_tracing_enabled() const
std::function< void(ResourcePtr)> Consumer
Used to forward events from the rasterizer to interested subsystems. Currently, the shell sets itself...
virtual const TaskRunners & GetTaskRunners() const =0
Task runners used by the shell.
virtual const fml::RefPtr< fml::RasterThreadMerger > GetParentRasterThreadMerger() const =0
The raster thread merger from parent shell's rasterizer.
bool IsTornDown()
Returns whether TearDown has been called.
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.
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 ...
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....
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.
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.
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
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 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....
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 SetImpellerContext(std::weak_ptr< impeller::Context > impeller_context)
fml::RefPtr< fml::TaskRunner > GetRasterTaskRunner() const
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)
void UnMergeNowIfLastOne()
bool IsOnRasterizingThread()
Wraps a closure that is invoked in the destructor unless released by the caller.
virtual void PostTask(const fml::closure &task) override
virtual bool RunsTasksOnCurrentThread()
virtual TaskQueueId GetTaskQueueId()
static constexpr TimeDelta FromMillisecondsF(double millis)
Picture EndRecordingAsPicture()
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
static const uint8_t buffer[]
uint32_t uint32_t * format
#define FML_DLOG(severity)
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_UNREACHABLE()
#define FML_DCHECK(condition)
#define TRACE_EVENT_WITH_FRAME_NUMBER(recorder, category_group, name, flow_id_count, flow_ids)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
sk_sp< const SkPicture > picture
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
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< SkData > SerializeTypefaceWithData(SkTypeface *typeface, void *ctx)
constexpr int64_t kFlutterImplicitViewId
static sk_sp< SkData > ScreenshotLayerTreeAsPicture(flutter::LayerTree *tree, flutter::CompositorContext &compositor_context)
sk_sp< SkData > SerializeTypefaceWithoutData(SkTypeface *typeface, void *ctx)
static void RenderFrameForScreenshot(flutter::CompositorContext &compositor_context, DlCanvas *canvas, flutter::LayerTree *tree, GrDirectContext *surface_context, const std::shared_ptr< impeller::AiksContext > &aiks_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
sk_sp< SkData > SerializeImageWithoutData(SkImage *image, void *ctx)
static constexpr std::chrono::milliseconds kSkiaCleanupExpiration(15000)
void TraceEventAsyncComplete(TraceArg category_group, TraceArg name, TimePoint begin, TimePoint end)
std::chrono::duration< double, std::milli > Milliseconds
std::function< void()> closure
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
constexpr int32_t width() const
constexpr int32_t height() const
sk_sp< SkColorSpace > refColorSpace() const
SkColorType colorType() const
static constexpr SkRect MakeSize(const SkSize &size)
static constexpr SkRect MakeWH(float w, float h)
SkSerialImageProc fImageProc
SkSerialTypefaceProc fTypefaceProc
static constexpr SkSize Make(SkScalar w, SkScalar h)
A POD type used to return the screenshot data along with the size of the frame.
Screenshot()
Creates an empty screenshot.
~Screenshot()
Destroys the screenshot object and releases underlying data.
A screenshot of the surface's raw data.
Represents the 2 code paths available when calling |SyncSwitchExecute|.
#define TRACE_EVENT0(category_group, name)