| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "flutter/lib/ui/compositing/scene.h" |
| |
| #include "flutter/fml/trace_event.h" |
| #include "flutter/lib/ui/painting/display_list_deferred_image_gpu_skia.h" |
| #include "flutter/lib/ui/painting/image.h" |
| #include "flutter/lib/ui/painting/picture.h" |
| #include "flutter/lib/ui/ui_dart_state.h" |
| #include "flutter/lib/ui/window/platform_configuration.h" |
| #if IMPELLER_SUPPORTS_RENDERING |
| #include "flutter/lib/ui/painting/display_list_deferred_image_gpu_impeller.h" |
| #endif // IMPELLER_SUPPORTS_RENDERING |
| #include "third_party/skia/include/core/SkImageInfo.h" |
| #include "third_party/skia/include/core/SkSurface.h" |
| #include "third_party/tonic/converter/dart_converter.h" |
| #include "third_party/tonic/dart_args.h" |
| #include "third_party/tonic/dart_binding_macros.h" |
| #include "third_party/tonic/dart_library_natives.h" |
| |
| namespace flutter { |
| |
| IMPLEMENT_WRAPPERTYPEINFO(ui, Scene); |
| |
| void Scene::create(Dart_Handle scene_handle, |
| std::shared_ptr<flutter::Layer> rootLayer, |
| uint32_t rasterizerTracingThreshold, |
| bool checkerboardRasterCacheImages, |
| bool checkerboardOffscreenLayers) { |
| auto scene = fml::MakeRefCounted<Scene>( |
| std::move(rootLayer), rasterizerTracingThreshold, |
| checkerboardRasterCacheImages, checkerboardOffscreenLayers); |
| scene->AssociateWithDartWrapper(scene_handle); |
| } |
| |
| Scene::Scene(std::shared_ptr<flutter::Layer> rootLayer, |
| uint32_t rasterizerTracingThreshold, |
| bool checkerboardRasterCacheImages, |
| bool checkerboardOffscreenLayers) { |
| layer_tree_config_.root_layer = std::move(rootLayer); |
| layer_tree_config_.rasterizer_tracing_threshold = rasterizerTracingThreshold; |
| layer_tree_config_.checkerboard_raster_cache_images = |
| checkerboardRasterCacheImages; |
| layer_tree_config_.checkerboard_offscreen_layers = |
| checkerboardOffscreenLayers; |
| } |
| |
| Scene::~Scene() {} |
| |
| bool Scene::valid() { |
| return layer_tree_config_.root_layer != nullptr; |
| } |
| |
| void Scene::dispose() { |
| layer_tree_config_.root_layer.reset(); |
| ClearDartWrapper(); |
| } |
| |
| Dart_Handle Scene::toImageSync(uint32_t width, |
| uint32_t height, |
| Dart_Handle raw_image_handle) { |
| TRACE_EVENT0("flutter", "Scene::toImageSync"); |
| |
| if (!valid()) { |
| return tonic::ToDart("Scene has been disposed."); |
| } |
| |
| Scene::RasterizeToImage(width, height, raw_image_handle); |
| return Dart_Null(); |
| } |
| |
| Dart_Handle Scene::toImage(uint32_t width, |
| uint32_t height, |
| Dart_Handle raw_image_callback) { |
| TRACE_EVENT0("flutter", "Scene::toImage"); |
| |
| if (!valid()) { |
| return tonic::ToDart("Scene has been disposed."); |
| } |
| |
| return Picture::RasterizeLayerTreeToImage(BuildLayerTree(width, height), |
| raw_image_callback); |
| } |
| |
| static sk_sp<DlImage> CreateDeferredImage( |
| bool impeller, |
| std::unique_ptr<LayerTree> layer_tree, |
| fml::TaskRunnerAffineWeakPtr<SnapshotDelegate> snapshot_delegate, |
| fml::RefPtr<fml::TaskRunner> raster_task_runner, |
| fml::RefPtr<SkiaUnrefQueue> unref_queue) { |
| #if IMPELLER_SUPPORTS_RENDERING |
| if (impeller) { |
| return DlDeferredImageGPUImpeller::Make(std::move(layer_tree), |
| std::move(snapshot_delegate), |
| std::move(raster_task_runner)); |
| } |
| #endif // IMPELLER_SUPPORTS_RENDERING |
| |
| const auto& frame_size = layer_tree->frame_size(); |
| const SkImageInfo image_info = |
| SkImageInfo::Make(frame_size.width(), frame_size.height(), |
| kRGBA_8888_SkColorType, kPremul_SkAlphaType); |
| return DlDeferredImageGPUSkia::MakeFromLayerTree( |
| image_info, std::move(layer_tree), std::move(snapshot_delegate), |
| raster_task_runner, std::move(unref_queue)); |
| } |
| |
| void Scene::RasterizeToImage(uint32_t width, |
| uint32_t height, |
| Dart_Handle raw_image_handle) { |
| auto* dart_state = UIDartState::Current(); |
| if (!dart_state) { |
| return; |
| } |
| auto unref_queue = dart_state->GetSkiaUnrefQueue(); |
| auto snapshot_delegate = dart_state->GetSnapshotDelegate(); |
| auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner(); |
| |
| auto image = CanvasImage::Create(); |
| auto dl_image = CreateDeferredImage( |
| dart_state->IsImpellerEnabled(), BuildLayerTree(width, height), |
| std::move(snapshot_delegate), std::move(raster_task_runner), |
| std::move(unref_queue)); |
| image->set_image(dl_image); |
| image->AssociateWithDartWrapper(raw_image_handle); |
| } |
| |
| std::unique_ptr<flutter::LayerTree> Scene::takeLayerTree(uint64_t width, |
| uint64_t height) { |
| return BuildLayerTree(width, height); |
| } |
| |
| std::unique_ptr<LayerTree> Scene::BuildLayerTree(uint32_t width, |
| uint32_t height) { |
| if (!valid()) { |
| return nullptr; |
| } |
| return std::make_unique<LayerTree>(layer_tree_config_, |
| SkISize::Make(width, height)); |
| } |
| |
| } // namespace flutter |