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
50[[maybe_unused]]
static constexpr std::chrono::milliseconds
56 gpu_image_behavior_(gpu_image_behavior),
67 return weak_factory_.GetWeakPtr();
72 return weak_factory_.GetWeakPtr();
76 std::weak_ptr<impeller::Context> impeller_context) {
77 impeller_context_ = std::move(impeller_context);
83 if (max_cache_bytes_.has_value()) {
85 user_override_resource_cache_bytes_);
88 auto context_switch = surface_->MakeRenderContextCurrent();
89 if (context_switch->GetResult()) {
90 compositor_context_->OnGrContextCreated();
93 if (external_view_embedder_ &&
94 external_view_embedder_->SupportsDynamicThreadMerging() &&
95 !raster_thread_merger_) {
96 const auto platform_id =
103 if (raster_thread_merger_) {
107 surface_->ClearRenderContext();
114 if (external_view_embedder_) {
115 external_view_embedder_->Teardown();
120 is_torn_down_ =
true;
122 auto context_switch = surface_->MakeRenderContextCurrent();
123 if (context_switch->GetResult()) {
124 compositor_context_->OnGrContextDestroyed();
126 if (
auto* context = surface_->GetContext()) {
134 view_records_.clear();
136 if (raster_thread_merger_.
get() !=
nullptr &&
145 return is_torn_down_;
150 auto found = view_records_.find(view_id);
151 if (found != view_records_.end()) {
152 return found->second.last_draw_status;
154 return std::optional<DrawSurfaceStatus>();
159 if (raster_thread_merger_) {
160 raster_thread_merger_->
Enable();
165 if (raster_thread_merger_) {
166 raster_thread_merger_->
Disable();
174 <<
"Rasterizer::NotifyLowMemoryWarning called with no surface.";
177 auto context = surface_->GetContext();
180 <<
"Rasterizer::NotifyLowMemoryWarning called with no GrContext.";
183 auto context_switch = surface_->MakeRenderContextCurrent();
184 if (!context_switch->GetResult()) {
187 context->performDeferredCleanup(std::chrono::milliseconds(0));
192 if (external_view_embedder_) {
193 external_view_embedder_->CollectView(view_id);
195 view_records_.erase(view_id);
199 return compositor_context_->texture_registry();
203 return surface_ ? surface_->GetContext() :
nullptr;
207 auto found = view_records_.find(view_id);
208 if (found == view_records_.end()) {
211 auto& last_task = found->second.last_successful_task;
212 if (last_task ==
nullptr) {
215 return last_task->layer_tree.get();
219 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder) {
223 std::vector<std::unique_ptr<LayerTreeTask>> tasks;
224 for (
auto& [view_id, view_record] : view_records_) {
225 if (view_record.last_successful_task) {
226 tasks.push_back(std::move(view_record.last_successful_task));
234 DrawToSurfaces(*frame_timings_recorder, std::move(tasks));
237 if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) {
238 bool should_resubmit_frame = ShouldResubmitFrame(
result);
239 external_view_embedder_->SetUsedThisFrame(
false);
240 external_view_embedder_->EndFrame(should_resubmit_frame,
241 raster_thread_merger_);
247 if (raster_thread_merger_ &&
256 DoDrawResult draw_result;
258 this](std::unique_ptr<FrameItem> item) {
259 draw_result = DoDraw(std::move(item->frame_timings_recorder),
260 std::move(item->layer_tree_tasks));
270 bool should_resubmit_frame = ShouldResubmitFrame(draw_result);
271 if (should_resubmit_frame) {
273 auto front_continuation = pipeline->ProduceIfEmpty();
275 front_continuation.Complete(std::move(draw_result.resubmitted_item));
279 }
else if (draw_result.status == DoDrawStatus::kEnqueuePipeline) {
284 if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) {
285 external_view_embedder_->SetUsedThisFrame(
false);
286 external_view_embedder_->EndFrame(should_resubmit_frame,
287 raster_thread_merger_);
292 switch (consume_result) {
295 [weak_this = weak_factory_.GetWeakPtr(), pipeline]() {
297 weak_this->Draw(pipeline);
306 return ToDrawStatus(draw_result.status);
309bool Rasterizer::ShouldResubmitFrame(
const DoDrawResult&
result) {
310 if (
result.resubmitted_item) {
317DrawStatus Rasterizer::ToDrawStatus(DoDrawStatus status) {
319 case DoDrawStatus::kEnqueuePipeline:
320 return DrawStatus::kDone;
321 case DoDrawStatus::kNotSetUp:
322 return DrawStatus::kNotSetUp;
323 case DoDrawStatus::kGpuUnavailable:
324 return DrawStatus::kGpuUnavailable;
325 case DoDrawStatus::kDone:
326 return DrawStatus::kDone;
333std::unique_ptr<SnapshotDelegate::GpuImageResult> MakeBitmapImage(
342 if (image_info.
width() > 16384 || image_info.
height() > 16384) {
343 return std::make_unique<SnapshotDelegate::GpuImageResult>(
345 "unable to create bitmap render target at specified size " +
351 auto canvas = DlSkCanvasAdapter(
surface->getCanvas());
353 canvas.DrawDisplayList(display_list);
356 return std::make_unique<SnapshotDelegate::GpuImageResult>(
358 image ?
"" :
"Unable to create image");
363std::unique_ptr<Rasterizer::GpuImageResult> Rasterizer::MakeSkiaGpuImage(
373 std::unique_ptr<SnapshotDelegate::GpuImageResult>
result;
374 delegate_.GetIsGpuDisabledSyncSwitch()->Execute(
376 .SetIfTrue([&
result, &image_info, &display_list] {
379 result = MakeBitmapImage(display_list, image_info);
381 .SetIfFalse([&
result, &image_info, &display_list,
383 gpu_image_behavior = gpu_image_behavior_] {
385 gpu_image_behavior == MakeGpuImageBehavior::kBitmap) {
388 result = MakeBitmapImage(display_list, image_info);
392 auto context_switch =
surface->MakeRenderContextCurrent();
393 if (!context_switch->GetResult()) {
394 result = MakeBitmapImage(display_list, image_info);
398 auto* context =
surface->GetContext();
400 result = MakeBitmapImage(display_list, image_info);
408 result = std::make_unique<SnapshotDelegate::GpuImageResult>(
410 "unable to create texture render target at specified size " +
420 result = std::make_unique<SnapshotDelegate::GpuImageResult>(
422 "unable to create rendering surface for image");
426 auto canvas = DlSkCanvasAdapter(sk_surface->
getCanvas());
428 canvas.DrawDisplayList(display_list);
430 result = std::make_unique<SnapshotDelegate::GpuImageResult>(
437void Rasterizer::MakeRasterSnapshot(
441 return snapshot_controller_->MakeRasterSnapshot(display_list, picture_size,
448 return snapshot_controller_->MakeRasterSnapshotSync(display_list,
454 return snapshot_controller_->ConvertToRasterImage(
image);
458void Rasterizer::CacheRuntimeStage(
459 const std::shared_ptr<impeller::RuntimeStage>& runtime_stage) {
460 snapshot_controller_->CacheRuntimeStage(runtime_stage);
467Rasterizer::DoDrawResult Rasterizer::DoDraw(
468 std::unique_ptr<FrameTimingsRecorder> frame_timings_recorder,
469 std::vector<std::unique_ptr<LayerTreeTask>> tasks) {
471 "Rasterizer::DoDraw", 0,
474 .GetRasterTaskRunner()
475 ->RunsTasksOnCurrentThread());
476 frame_timings_recorder->AssertInState(FrameTimingsRecorder::State::kBuildEnd);
479 return DoDrawResult{DoDrawStatus::kDone};
482 return DoDrawResult{DoDrawStatus::kNotSetUp};
486 PersistentCache* persistent_cache = PersistentCache::GetCacheForProcess();
487 persistent_cache->ResetStoredNewShaders();
491 DrawToSurfaces(*frame_timings_recorder, std::move(tasks));
494 if (
result.status == DoDrawStatus::kGpuUnavailable) {
495 return DoDrawResult{DoDrawStatus::kGpuUnavailable};
499 if (persistent_cache->IsDumpingSkp() &&
500 persistent_cache->StoredNewShaders()) {
502 ScreenshotLastLayerTree(ScreenshotType::SkiaPicture,
false);
503 persistent_cache->DumpSkp(*screenshot.data);
510 delegate_.OnFrameRasterized(frame_timings_recorder->GetRecordedTime());
514#if !defined(OS_FUCHSIA)
516 frame_timings_recorder->GetRasterEndTime();
518 frame_timings_recorder->GetVsyncTargetTime();
519 if (raster_finish_time > frame_target_time) {
522 const auto frame_budget_millis =
delegate_.GetFrameBudget().count();
523 if (latest_frame_target_time < raster_finish_time) {
524 latest_frame_target_time =
525 latest_frame_target_time +
528 const auto frame_lag =
529 (latest_frame_target_time - frame_target_time).ToMillisecondsF();
530 const int vsync_transitions_missed =
round(frame_lag / frame_budget_millis);
535 latest_frame_target_time,
538 "current_frame_target_time",
539 latest_frame_target_time,
540 "vsync_transitions_missed",
541 vsync_transitions_missed
562 if (raster_thread_merger_) {
563 if (raster_thread_merger_->DecrementLease() ==
566 .status = DoDrawStatus::kEnqueuePipeline,
567 .resubmitted_item = std::move(
result.resubmitted_item),
575Rasterizer::DoDrawResult Rasterizer::DrawToSurfaces(
576 FrameTimingsRecorder& frame_timings_recorder,
577 std::vector<std::unique_ptr<LayerTreeTask>> tasks) {
580 frame_timings_recorder.AssertInState(FrameTimingsRecorder::State::kBuildEnd);
583 .status = DoDrawStatus::kDone,
585 if (
surface_->AllowsDrawingWhenGpuDisabled()) {
587 DrawToSurfacesUnsafe(frame_timings_recorder, std::move(tasks));
589 delegate_.GetIsGpuDisabledSyncSwitch()->Execute(
592 result.status = DoDrawStatus::kGpuUnavailable;
594 frame_timings_recorder.RecordRasterEnd();
597 result.resubmitted_item = DrawToSurfacesUnsafe(
598 frame_timings_recorder, std::move(tasks));
601 frame_timings_recorder.AssertInState(FrameTimingsRecorder::State::kRasterEnd);
606std::unique_ptr<FrameItem> Rasterizer::DrawToSurfacesUnsafe(
607 FrameTimingsRecorder& frame_timings_recorder,
608 std::vector<std::unique_ptr<LayerTreeTask>> tasks) {
609 compositor_context_->ui_time().SetLapTime(
610 frame_timings_recorder.GetBuildDuration());
613 auto task_iter = tasks.begin();
614 while (task_iter != tasks.end()) {
615 LayerTreeTask& task = **task_iter;
616 if (
delegate_.ShouldDiscardLayerTree(task.view_id, *task.layer_tree)) {
617 EnsureViewRecord(task.view_id).last_draw_status =
618 DrawSurfaceStatus::kDiscarded;
619 task_iter = tasks.erase(task_iter);
626 frame_timings_recorder.RecordRasterEnd();
630 if (external_view_embedder_) {
631 FML_DCHECK(!external_view_embedder_->GetUsedThisFrame());
632 external_view_embedder_->SetUsedThisFrame(
true);
633 external_view_embedder_->BeginFrame(
surface_->GetContext(),
634 raster_thread_merger_);
637 std::optional<fml::TimePoint> presentation_time = std::nullopt;
643 const auto vsync_target_time = frame_timings_recorder.GetVsyncTargetTime();
645 presentation_time = vsync_target_time;
652 std::vector<std::unique_ptr<LayerTreeTask>> resubmitted_tasks;
653 for (std::unique_ptr<LayerTreeTask>& task : tasks) {
654 int64_t view_id = task->view_id;
655 std::unique_ptr<LayerTree> layer_tree = std::move(task->layer_tree);
656 float device_pixel_ratio = task->device_pixel_ratio;
659 view_id, *layer_tree, device_pixel_ratio, presentation_time);
660 FML_DCHECK(status != DrawSurfaceStatus::kDiscarded);
662 auto& view_record = EnsureViewRecord(task->view_id);
663 view_record.last_draw_status = status;
665 view_record.last_successful_task = std::make_unique<LayerTreeTask>(
666 view_id, std::move(layer_tree), device_pixel_ratio);
667 }
else if (status == DrawSurfaceStatus::kRetry) {
668 resubmitted_tasks.push_back(std::make_unique<LayerTreeTask>(
669 view_id, std::move(layer_tree), device_pixel_ratio));
674 frame_timings_recorder.RecordRasterEnd(
677 FireNextFrameCallbackIfPresent();
685 if (resubmitted_tasks.empty()) {
688 return std::make_unique<FrameItem>(
689 std::move(resubmitted_tasks),
690 frame_timings_recorder.CloneUntil(
691 FrameTimingsRecorder::State::kBuildEnd));
699 float device_pixel_ratio,
700 std::optional<fml::TimePoint> presentation_time) {
703 DlCanvas* embedder_root_canvas =
nullptr;
704 if (external_view_embedder_) {
705 external_view_embedder_->PrepareFlutterView(layer_tree.
frame_size(),
708 embedder_root_canvas = external_view_embedder_->GetRootCanvas();
716 if (
frame ==
nullptr) {
717 return DrawSurfaceStatus::kFailed;
723 SkMatrix root_surface_transformation =
726 auto root_surface_canvas =
727 embedder_root_canvas ? embedder_root_canvas :
frame->Canvas();
728 auto compositor_frame = compositor_context_->AcquireFrame(
731 external_view_embedder_.get(),
732 root_surface_transformation,
734 frame->framebuffer_info()
736 raster_thread_merger_,
739 if (compositor_frame) {
742 std::unique_ptr<FrameDamage> damage;
745 if (
frame->framebuffer_info().supports_partial_repaint &&
751 bool force_full_repaint =
752 external_view_embedder_ &&
753 (!raster_thread_merger_ || raster_thread_merger_->IsMerged());
755 damage = std::make_unique<FrameDamage>();
756 auto existing_damage =
frame->framebuffer_info().existing_damage;
757 if (existing_damage.has_value() && !force_full_repaint) {
758 damage->SetPreviousLayerTree(GetLastLayerTree(view_id));
759 damage->AddAdditionalDamage(existing_damage.value());
760 damage->SetClipAlignment(
761 frame->framebuffer_info().horizontal_clip_alignment,
762 frame->framebuffer_info().vertical_clip_alignment);
766 bool ignore_raster_cache =
true;
767 if (
surface_->EnableRasterCache() &&
769 ignore_raster_cache =
false;
773 compositor_frame->Raster(layer_tree,
777 if (frame_status == RasterStatus::kSkipAndRetry) {
778 return DrawSurfaceStatus::kRetry;
781 SurfaceFrame::SubmitInfo submit_info;
782 submit_info.presentation_time = presentation_time;
784 submit_info.frame_damage = damage->GetFrameDamage();
785 submit_info.buffer_damage = damage->GetBufferDamage();
788 frame->set_submit_info(submit_info);
790 if (external_view_embedder_ &&
791 (!raster_thread_merger_ || raster_thread_merger_->IsMerged())) {
793 external_view_embedder_->SubmitFlutterView(
803 if (frame_status != RasterStatus::kResubmit) {
804 compositor_context_->raster_cache().EndFrame();
808 if (frame_status == RasterStatus::kResubmit) {
809 return DrawSurfaceStatus::kRetry;
816 return DrawSurfaceStatus::kFailed;
819Rasterizer::ViewRecord& Rasterizer::EnsureViewRecord(int64_t view_id) {
820 return view_records_[view_id];
834 SkMatrix root_surface_transformation;
835 root_surface_transformation.
reset();
841 root_surface_transformation,
842 false,
true,
nullptr,
nullptr);
843 frame->Raster(*tree,
true,
nullptr);
845#if defined(OS_FUCHSIA)
866 const std::shared_ptr<impeller::AiksContext>& aiks_context) {
869 SkMatrix root_surface_transformation;
870 root_surface_transformation.
reset();
876 root_surface_transformation,
882 frame->Raster(*tree,
true,
nullptr);
886#if IMPELLER_SUPPORTS_RENDERING
905 return Rasterizer::ScreenshotFormat::kR8G8B8A8UNormInt;
907 return Rasterizer::ScreenshotFormat::kB8G8R8A8UNormInt;
909 return Rasterizer::ScreenshotFormat::kR16G16B16A16Float;
913static std::pair<sk_sp<SkData>, Rasterizer::ScreenshotFormat>
914ScreenshotLayerTreeAsImageImpeller(
915 const std::shared_ptr<impeller::AiksContext>& aiks_context,
920 FML_LOG(
ERROR) <<
"Compressed screenshots not supported for Impeller";
931 builder.Build()->Dispatch(dispatcher);
940 texture->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
941 auto impeller_context = aiks_context->GetContext();
943 impeller_context->GetResourceAllocator()->CreateBuffer(buffer_desc);
944 auto command_buffer = impeller_context->CreateCommandBuffer();
945 command_buffer->SetLabel(
"BlitTextureToBuffer Command Buffer");
946 auto pass = command_buffer->CreateBlitPass();
948 pass->EncodeCommands(impeller_context->GetResourceAllocator());
951 auto completion = [
buffer, &buffer_desc, &sk_data,
961 if (!impeller_context->GetCommandQueue()
962 ->Submit({command_buffer}, completion)
967 return std::make_pair(
968 sk_data, ToScreenshotFormat(
texture->GetTextureDescriptor().format));
972std::pair<sk_sp<SkData>, Rasterizer::ScreenshotFormat>
973Rasterizer::ScreenshotLayerTreeAsImage(
977#if IMPELLER_SUPPORTS_RENDERING
978 if (
delegate_.GetSettings().enable_impeller) {
979 return ScreenshotLayerTreeAsImageImpeller(GetAiksContext(), tree,
980 compositor_context, compressed);
991 std::unique_ptr<OffscreenSurface> snapshot_surface =
992 std::make_unique<OffscreenSurface>(surface_context, tree->
frame_size());
994 if (!snapshot_surface->IsValid()) {
995 FML_LOG(
ERROR) <<
"Screenshot: unable to create snapshot surface";
1000 DlCanvas* canvas = snapshot_surface->GetCanvas();
1006 auto context_switch =
surface_->MakeRenderContextCurrent();
1007 if (!context_switch->GetResult()) {
1008 FML_LOG(
ERROR) <<
"Screenshot: unable to make image screenshot";
1015 return std::make_pair(snapshot_surface->GetRasterData(compressed),
1022 bool base64_encode) {
1023 if (
delegate_.GetSettings().enable_impeller &&
1024 type == ScreenshotType::SkiaPicture) {
1026 FML_LOG(
ERROR) <<
"Last layer tree cannot be screenshotted as a "
1027 "SkiaPicture when using Impeller.";
1035 if (layer_tree ==
nullptr) {
1036 FML_LOG(
ERROR) <<
"Last layer tree was null when screenshotting.";
1045 case ScreenshotType::SkiaPicture:
1046 format =
"ScreenshotType::SkiaPicture";
1050 case ScreenshotType::UncompressedImage:
1051 format =
"ScreenshotType::UncompressedImage";
1053 ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_,
false);
1055 case ScreenshotType::CompressedImage:
1056 format =
"ScreenshotType::CompressedImage";
1057 data = ScreenshotLayerTreeAsImage(layer_tree, *compositor_context_,
true);
1059 case ScreenshotType::SurfaceData: {
1067 if (
data.first ==
nullptr) {
1072 if (base64_encode) {
1073 size_t b64_size = Base64::EncodedSize(
data.first->size());
1076 b64_data->writable_data());
1089void Rasterizer::SetExternalViewEmbedder(
1090 const std::shared_ptr<ExternalViewEmbedder>& view_embedder) {
1091 external_view_embedder_ = view_embedder;
1094void Rasterizer::SetSnapshotSurfaceProducer(
1095 std::unique_ptr<SnapshotSurfaceProducer> producer) {
1096 snapshot_surface_producer_ = std::move(producer);
1100 return raster_thread_merger_;
1103void Rasterizer::FireNextFrameCallbackIfPresent() {
1104 if (!next_frame_callback_) {
1108 auto callback = next_frame_callback_;
1109 next_frame_callback_ =
nullptr;
1113void Rasterizer::SetResourceCacheMaxBytes(
size_t max_bytes,
bool from_user) {
1115 user_override_resource_cache_bytes_ |= from_user;
1117 if (!from_user && user_override_resource_cache_bytes_) {
1123 max_cache_bytes_ = max_bytes;
1130 auto context_switch =
surface_->MakeRenderContextCurrent();
1131 if (!context_switch->GetResult()) {
1140std::optional<size_t> Rasterizer::GetResourceCacheMaxBytes()
const {
1142 return std::nullopt;
1145 return std::nullopt;
1151 return std::nullopt;
1155Rasterizer::Screenshot::Screenshot() {}
1159 const std::string& p_format,
1164 pixel_format(p_pixel_format) {}
static void round(SkPoint *p)
@ kTopLeft_GrSurfaceOrigin
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()
#define NOT_SLIMPELLER(code)
static constexpr FlutterViewId kFlutterImplicitViewId
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
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)
Dart_NativeFunction function
constexpr SkColor4f kTransparent
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
SK_API sk_sp< SkDocument > Make(SkWStream *dst, const SkSerialProcs *=nullptr, std::function< void(const SkPicture *)> onEndPage=nullptr)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
sk_sp< const SkImage > image
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)
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 The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
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,...
flutter::DlCanvas DlCanvas
static SkString to_string(int n)
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 |SyncSwitch::Execute|.
std::shared_ptr< const fml::Mapping > data
#define TRACE_EVENT0(category_group, name)