// 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 "engine.h"

#include <lib/async/cpp/task.h>
#include <zircon/status.h>

#include "flutter/common/graphics/persistent_cache.h"
#include "flutter/common/task_runners.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/task_runner.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/run_configuration.h"
#include "flutter/shell/common/serialization_callbacks.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
#include "third_party/skia/include/ports/SkFontMgr_fuchsia.h"

#include "../runtime/dart/utils/files.h"
#include "fuchsia_intl.h"
#include "platform_view.h"
#include "surface.h"
#include "task_runner_adapter.h"

#if defined(LEGACY_FUCHSIA_EMBEDDER)
#include "compositor_context.h"  // nogncheck
#endif

namespace flutter_runner {
namespace {

void UpdateNativeThreadLabelNames(const std::string& label,
                                  const flutter::TaskRunners& runners) {
  auto set_thread_name = [](fml::RefPtr<fml::TaskRunner> runner,
                            std::string prefix, std::string suffix) {
    if (!runner) {
      return;
    }
    fml::TaskRunner::RunNowOrPostTask(runner, [name = prefix + suffix]() {
      zx::thread::self()->set_property(ZX_PROP_NAME, name.c_str(), name.size());
    });
  };
  set_thread_name(runners.GetPlatformTaskRunner(), label, ".platform");
  set_thread_name(runners.GetUITaskRunner(), label, ".ui");
  set_thread_name(runners.GetRasterTaskRunner(), label, ".raster");
  set_thread_name(runners.GetIOTaskRunner(), label, ".io");
}

std::unique_ptr<flutter::PlatformMessage> MakeLocalizationPlatformMessage(
    const fuchsia::intl::Profile& intl_profile) {
  return std::make_unique<flutter::PlatformMessage>(
      "flutter/localization", MakeLocalizationPlatformMessageData(intl_profile),
      nullptr);
}

}  // namespace

Engine::Engine(Delegate& delegate,
               std::string thread_label,
               std::shared_ptr<sys::ServiceDirectory> svc,
               std::shared_ptr<sys::ServiceDirectory> runner_services,
               flutter::Settings settings,
               fuchsia::ui::views::ViewToken view_token,
               scenic::ViewRefPair view_ref_pair,
               UniqueFDIONS fdio_ns,
               fidl::InterfaceRequest<fuchsia::io::Directory> directory_request,
               FlutterRunnerProductConfiguration product_config)
    : delegate_(delegate),
      thread_label_(std::move(thread_label)),
#if defined(LEGACY_FUCHSIA_EMBEDDER)
      use_legacy_renderer_(product_config.use_legacy_renderer()),
#endif
      intercept_all_input_(product_config.get_intercept_all_input()),
      weak_factory_(this) {
  if (zx::event::create(0, &vsync_event_) != ZX_OK) {
    FML_DLOG(ERROR) << "Could not create the vsync event.";
    return;
  }

  // Get the task runners from the managed threads. The current thread will be
  // used as the "platform" thread.
  const flutter::TaskRunners task_runners(
      thread_label_,  // Dart thread labels
      CreateFMLTaskRunner(async_get_default_dispatcher()),  // platform
      CreateFMLTaskRunner(threads_[0].dispatcher()),        // raster
      CreateFMLTaskRunner(threads_[1].dispatcher()),        // ui
      CreateFMLTaskRunner(threads_[2].dispatcher())         // io
  );
  UpdateNativeThreadLabelNames(thread_label_, task_runners);

  // Connect to Scenic.
  auto scenic = svc->Connect<fuchsia::ui::scenic::Scenic>();
  fidl::InterfaceHandle<fuchsia::ui::scenic::Session> session;
  fidl::InterfaceHandle<fuchsia::ui::scenic::SessionListener> session_listener;
  auto session_listener_request = session_listener.NewRequest();
  fidl::InterfaceHandle<fuchsia::ui::views::Focuser> focuser;
  scenic->CreateSession2(session.NewRequest(), session_listener.Bind(),
                         focuser.NewRequest());

  // Make clones of the `ViewRef` before sending it down to Scenic, since the
  // refs are not copyable, and multiple consumers need view refs.
  fuchsia::ui::views::ViewRef platform_view_ref;
  view_ref_pair.view_ref.Clone(&platform_view_ref);
  fuchsia::ui::views::ViewRef isolate_view_ref;
  view_ref_pair.view_ref.Clone(&isolate_view_ref);
  // Input3 keyboard listener registration requires a ViewRef as an event
  // filter. So we clone it here, as ViewRefs can not be reused, only cloned.
  fuchsia::ui::views::ViewRef keyboard_view_ref;
  view_ref_pair.view_ref.Clone(&keyboard_view_ref);

  // Session is terminated on the raster thread, but we must terminate ourselves
  // on the platform thread.
  //
  // This handles the fidl error callback when the Session connection is
  // broken. The SessionListener interface also has an OnError method, which is
  // invoked on the platform thread (in PlatformView).
  fml::closure session_error_callback = [dispatcher =
                                             async_get_default_dispatcher(),
                                         weak = weak_factory_.GetWeakPtr()]() {
    async::PostTask(dispatcher, [weak]() {
      if (weak) {
        weak->Terminate();
      }
    });
  };

  // Set up the session connection and other Scenic helpers on the raster
  // thread. We also need to wait for the external view embedder to be set up
  // before creating the shell.
  fml::AutoResetWaitableEvent view_embedder_latch;
  task_runners.GetRasterTaskRunner()->PostTask(fml::MakeCopyable(
      [this, session = std::move(session),
       session_error_callback = std::move(session_error_callback),
       view_token = std::move(view_token),
       view_ref_pair = std::move(view_ref_pair),
       max_frames_in_flight = product_config.get_max_frames_in_flight(),
       vsync_handle = vsync_event_.get(), &view_embedder_latch]() mutable {
        session_connection_.emplace(
            thread_label_, std::move(session),
            std::move(session_error_callback), [](auto) {}, vsync_handle,
            max_frames_in_flight);
        surface_producer_.emplace(session_connection_->get());
#if defined(LEGACY_FUCHSIA_EMBEDDER)
        if (use_legacy_renderer_) {
          legacy_external_view_embedder_ =
              std::make_shared<flutter::SceneUpdateContext>(
                  thread_label_, std::move(view_token),
                  std::move(view_ref_pair), session_connection_.value(),
                  intercept_all_input_);
        } else
#endif
        {
          external_view_embedder_ =
              std::make_shared<FuchsiaExternalViewEmbedder>(
                  thread_label_, std::move(view_token),
                  std::move(view_ref_pair), session_connection_.value(),
                  surface_producer_.value(), intercept_all_input_);
        }
        view_embedder_latch.Signal();
      }));
  view_embedder_latch.Wait();

  // Grab the parent environment services. The platform view may want to
  // access some of these services.
  fuchsia::sys::EnvironmentPtr environment;
  svc->Connect(environment.NewRequest());
  fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
      parent_environment_service_provider;
  environment->GetServices(parent_environment_service_provider.NewRequest());
  environment.Unbind();

  OnEnableWireframe on_enable_wireframe_callback = std::bind(
      &Engine::DebugWireframeSettingsChanged, this, std::placeholders::_1);

  OnCreateView on_create_view_callback = std::bind(
      &Engine::CreateView, this, std::placeholders::_1, std::placeholders::_2,
      std::placeholders::_3, std::placeholders::_4);

  OnUpdateView on_update_view_callback = std::bind(
      &Engine::UpdateView, this, std::placeholders::_1, std::placeholders::_2,
      std::placeholders::_3, std::placeholders::_4);

  OnDestroyView on_destroy_view_callback = std::bind(
      &Engine::DestroyView, this, std::placeholders::_1, std::placeholders::_2);

  OnCreateSurface on_create_surface_callback =
      std::bind(&Engine::CreateSurface, this);

  // SessionListener has a OnScenicError method; invoke this callback on the
  // platform thread when that happens. The Session itself should also be
  // disconnected when this happens, and it will also attempt to terminate.
  fit::closure on_session_listener_error_callback =
      [dispatcher = async_get_default_dispatcher(),
       weak = weak_factory_.GetWeakPtr()]() {
        async::PostTask(dispatcher, [weak]() {
          if (weak) {
            weak->Terminate();
          }
        });
      };

  // Launch the engine in the appropriate configuration.
  // Note: this initializes the Asset Manager on the global PersistantCache
  // so it must be called before WarmupSkps() is called below.
  auto run_configuration = flutter::RunConfiguration::InferFromSettings(
      settings, task_runners.GetIOTaskRunner());

  // Connect to fuchsia.ui.input3.Keyboard to hand out a listener.
  using fuchsia::ui::input3::Keyboard;
  using fuchsia::ui::input3::KeyboardListener;

  // Keyboard client-side stub.
  keyboard_svc_ = svc->Connect<Keyboard>();
  ZX_ASSERT(keyboard_svc_.is_bound());
  // KeyboardListener handle pair is not initialized until NewRequest() is
  // called.
  fidl::InterfaceHandle<KeyboardListener> keyboard_listener;

  // Server side of KeyboardListener.  Initializes the keyboard_listener
  // handle.
  fidl::InterfaceRequest<KeyboardListener> keyboard_listener_request =
      keyboard_listener.NewRequest();
  ZX_ASSERT(keyboard_listener_request.is_valid());

  keyboard_svc_->AddListener(std::move(keyboard_view_ref),
                             keyboard_listener.Bind(), [] {});

  // Setup the callback that will instantiate the platform view.
  flutter::Shell::CreateCallback<flutter::PlatformView>
      on_create_platform_view = fml::MakeCopyable(
          [debug_label = thread_label_, view_ref = std::move(platform_view_ref),
           runner_services,
           parent_environment_service_provider =
               std::move(parent_environment_service_provider),
           session_listener_request = std::move(session_listener_request),
           focuser = std::move(focuser),
           on_session_listener_error_callback =
               std::move(on_session_listener_error_callback),
           on_enable_wireframe_callback =
               std::move(on_enable_wireframe_callback),
           on_create_view_callback = std::move(on_create_view_callback),
           on_update_view_callback = std::move(on_update_view_callback),
           on_destroy_view_callback = std::move(on_destroy_view_callback),
           on_create_surface_callback = std::move(on_create_surface_callback),
           external_view_embedder = GetExternalViewEmbedder(),
           vsync_offset = product_config.get_vsync_offset(),
           vsync_handle = vsync_event_.get(),
           keyboard_listener_request = std::move(keyboard_listener_request)](
              flutter::Shell& shell) mutable {
            return std::make_unique<flutter_runner::PlatformView>(
                shell,                   // delegate
                debug_label,             // debug label
                std::move(view_ref),     // view ref
                shell.GetTaskRunners(),  // task runners
                std::move(runner_services),
                std::move(parent_environment_service_provider),  // services
                std::move(session_listener_request),  // session listener
                std::move(focuser),
                // Server-side part of the fuchsia.ui.input3.KeyboardListener
                // connection.
                std::move(keyboard_listener_request),
                std::move(on_session_listener_error_callback),
                std::move(on_enable_wireframe_callback),
                std::move(on_create_view_callback),
                std::move(on_update_view_callback),
                std::move(on_destroy_view_callback),
                std::move(on_create_surface_callback),
                external_view_embedder,   // external view embedder
                std::move(vsync_offset),  // vsync offset
                vsync_handle);
          });

  // Setup the callback that will instantiate the rasterizer.
  flutter::Shell::CreateCallback<flutter::Rasterizer> on_create_rasterizer;
#if defined(LEGACY_FUCHSIA_EMBEDDER)
  on_create_rasterizer = [this, &product_config](flutter::Shell& shell) {
    if (use_legacy_renderer_) {
      FML_DCHECK(session_connection_);
      FML_DCHECK(surface_producer_);
      FML_DCHECK(legacy_external_view_embedder_);

      if (product_config.enable_shader_warmup()) {
        FML_DCHECK(surface_producer_);
        WarmupSkps(shell.GetDartVM()
                       ->GetConcurrentMessageLoop()
                       ->GetTaskRunner()
                       .get(),
                   shell.GetTaskRunners().GetRasterTaskRunner().get(),
                   surface_producer_.value());
      }

      auto compositor_context =
          std::make_unique<flutter_runner::CompositorContext>(
              session_connection_.value(), surface_producer_.value(),
              legacy_external_view_embedder_);
      return std::make_unique<flutter::Rasterizer>(
          shell, std::move(compositor_context));
    } else {
      if (product_config.enable_shader_warmup()) {
        FML_DCHECK(surface_producer_);
        WarmupSkps(shell.GetDartVM()
                       ->GetConcurrentMessageLoop()
                       ->GetTaskRunner()
                       .get(),
                   shell.GetTaskRunners().GetRasterTaskRunner().get(),
                   surface_producer_.value());
      }
      return std::make_unique<flutter::Rasterizer>(shell);
    }
  };
#else
  on_create_rasterizer = [this, &product_config](flutter::Shell& shell) {
    if (product_config.enable_shader_warmup()) {
      FML_DCHECK(surface_producer_);
      WarmupSkps(
          shell.GetDartVM()->GetConcurrentMessageLoop()->GetTaskRunner().get(),
          shell.GetTaskRunners().GetRasterTaskRunner().get(),
          surface_producer_.value());
    }
    return std::make_unique<flutter::Rasterizer>(shell);
  };
#endif

  settings.root_isolate_create_callback =
      std::bind(&Engine::OnMainIsolateStart, this);
  settings.root_isolate_shutdown_callback =
      std::bind([weak = weak_factory_.GetWeakPtr(),
                 runner = task_runners.GetPlatformTaskRunner()]() {
        runner->PostTask([weak = std::move(weak)] {
          if (weak) {
            weak->OnMainIsolateShutdown();
          }
        });
      });

  {
    TRACE_EVENT0("flutter", "CreateShell");
    shell_ = flutter::Shell::Create(
        flutter::PlatformData(),             // default window data
        std::move(task_runners),             // host task runners
        std::move(settings),                 // shell launch settings
        std::move(on_create_platform_view),  // platform view create callback
        std::move(on_create_rasterizer)      // rasterizer create callback
    );
  }

  if (!shell_) {
    FML_LOG(ERROR) << "Could not launch the shell.";
    return;
  }

  // Shell has been created. Before we run the engine, set up the isolate
  // configurator.
  {
    fuchsia::sys::EnvironmentPtr environment;
    svc->Connect(environment.NewRequest());

    isolate_configurator_ = std::make_unique<IsolateConfigurator>(
        std::move(fdio_ns),                    //
        std::move(environment),                //
        directory_request.TakeChannel(),       //
        std::move(isolate_view_ref.reference)  //
    );
  }

  //  This platform does not get a separate surface platform view creation
  //  notification. Fire one eagerly.
  shell_->GetPlatformView()->NotifyCreated();

  // Connect to the intl property provider.  If the connection fails, the
  // initialization of the engine will simply proceed, printing a warning
  // message.  The engine will be fully functional, except that the user's
  // locale preferences would not be communicated to flutter engine.
  {
    intl_property_provider_.set_error_handler([](zx_status_t status) {
      FML_LOG(WARNING) << "Failed to connect to "
                       << fuchsia::intl::PropertyProvider::Name_ << ": "
                       << zx_status_get_string(status)
                       << " This is not a fatal error, but the user locale "
                       << " preferences will not be forwarded to flutter apps";
    });

    // Note that we're using the runner's services, not the component's.
    // Flutter locales should be updated regardless of whether the component has
    // direct access to the fuchsia.intl.PropertyProvider service.
    ZX_ASSERT(runner_services->Connect(intl_property_provider_.NewRequest()) ==
              ZX_OK);

    auto get_profile_callback = [flutter_runner_engine =
                                     weak_factory_.GetWeakPtr()](
                                    const fuchsia::intl::Profile& profile) {
      if (!flutter_runner_engine) {
        return;
      }
      if (!profile.has_locales()) {
        FML_LOG(WARNING) << "Got intl Profile without locales";
      }
      auto message = MakeLocalizationPlatformMessage(profile);
      FML_VLOG(-1) << "Sending LocalizationPlatformMessage";
      flutter_runner_engine->shell_->GetPlatformView()->DispatchPlatformMessage(
          std::move(message));
    };

    FML_VLOG(-1) << "Requesting intl Profile";

    // Make the initial request
    intl_property_provider_->GetProfile(get_profile_callback);

    // And register for changes
    intl_property_provider_.events().OnChange = [this, runner_services,
                                                 get_profile_callback]() {
      FML_VLOG(-1) << fuchsia::intl::PropertyProvider::Name_ << ": OnChange";
      runner_services->Connect(intl_property_provider_.NewRequest());
      intl_property_provider_->GetProfile(get_profile_callback);
    };
  }

  auto on_run_failure = [weak = weak_factory_.GetWeakPtr()]() {
    // The engine could have been killed by the caller right after the
    // constructor was called but before it could run on the UI thread.
    if (weak) {
      weak->Terminate();
    }
  };

  // Connect to the system font provider.
  fuchsia::fonts::ProviderSyncPtr sync_font_provider;
  svc->Connect(sync_font_provider.NewRequest());

  shell_->GetTaskRunners().GetUITaskRunner()->PostTask(
      fml::MakeCopyable([engine = shell_->GetEngine(),                        //
                         run_configuration = std::move(run_configuration),    //
                         sync_font_provider = std::move(sync_font_provider),  //
                         on_run_failure                                       //
  ]() mutable {
        if (!engine) {
          return;
        }

        // Set default font manager.
        engine->GetFontCollection().GetFontCollection()->SetDefaultFontManager(
            SkFontMgr_New_Fuchsia(std::move(sync_font_provider)));

        if (engine->Run(std::move(run_configuration)) ==
            flutter::Engine::RunStatus::Failure) {
          on_run_failure();
        }
      }));
}

Engine::~Engine() {
  shell_.reset();
  for (auto& thread : threads_) {
    thread.Quit();
  }
  for (auto& thread : threads_) {
    thread.Join();
  }
}

std::optional<uint32_t> Engine::GetEngineReturnCode() const {
  if (!shell_) {
    return std::nullopt;
  }
  std::optional<uint32_t> code;
  fml::AutoResetWaitableEvent latch;
  fml::TaskRunner::RunNowOrPostTask(
      shell_->GetTaskRunners().GetUITaskRunner(),
      [&latch, &code, engine = shell_->GetEngine()]() {
        if (engine) {
          code = engine->GetUIIsolateReturnCode();
        }
        latch.Signal();
      });
  latch.Wait();
  return code;
}

static void CreateCompilationTrace(Dart_Isolate isolate) {
  Dart_EnterIsolate(isolate);

  {
    Dart_EnterScope();
    uint8_t* trace = nullptr;
    intptr_t trace_length = 0;
    Dart_Handle result = Dart_SaveCompilationTrace(&trace, &trace_length);
    tonic::LogIfError(result);

    for (intptr_t start = 0; start < trace_length;) {
      intptr_t end = start;
      while ((end < trace_length) && trace[end] != '\n')
        end++;

      std::string line(reinterpret_cast<char*>(&trace[start]), end - start);
      FML_LOG(INFO) << "compilation-trace: " << line;

      start = end + 1;
    }

    Dart_ExitScope();
  }

  // Re-enter Dart scope to release the compilation trace's memory.

  {
    Dart_EnterScope();
    uint8_t* feedback = nullptr;
    intptr_t feedback_length = 0;
    Dart_Handle result = Dart_SaveTypeFeedback(&feedback, &feedback_length);
    tonic::LogIfError(result);
    const std::string kTypeFeedbackFile = "/data/dart_type_feedback.bin";
    if (dart_utils::WriteFile(kTypeFeedbackFile,
                              reinterpret_cast<const char*>(feedback),
                              feedback_length)) {
      FML_LOG(INFO) << "Dart type feedback written to " << kTypeFeedbackFile;
    } else {
      FML_LOG(ERROR) << "Could not write Dart type feedback to "
                     << kTypeFeedbackFile;
    }
    Dart_ExitScope();
  }

  Dart_ExitIsolate();
}

void Engine::OnMainIsolateStart() {
  if (!isolate_configurator_ ||
      !isolate_configurator_->ConfigureCurrentIsolate()) {
    FML_LOG(ERROR) << "Could not configure some native embedder bindings for a "
                      "new root isolate.";
  }
  FML_DLOG(INFO) << "Main isolate for engine '" << thread_label_
                 << "' was started.";

  const intptr_t kCompilationTraceDelayInSeconds = 0;
  if (kCompilationTraceDelayInSeconds != 0) {
    Dart_Isolate isolate = Dart_CurrentIsolate();
    FML_CHECK(isolate);
    shell_->GetTaskRunners().GetUITaskRunner()->PostDelayedTask(
        [engine = shell_->GetEngine(), isolate]() {
          if (!engine) {
            return;
          }
          CreateCompilationTrace(isolate);
        },
        fml::TimeDelta::FromSeconds(kCompilationTraceDelayInSeconds));
  }
}

void Engine::OnMainIsolateShutdown() {
  FML_DLOG(INFO) << "Main isolate for engine '" << thread_label_
                 << "' shutting down.";
  Terminate();
}

void Engine::Terminate() {
  delegate_.OnEngineTerminate(this);
  // Warning. Do not do anything after this point as the delegate may have
  // collected this object.
}

void Engine::DebugWireframeSettingsChanged(bool enabled) {
  FML_CHECK(shell_);

  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask([this, enabled]() {
#if defined(LEGACY_FUCHSIA_EMBEDDER)
    if (use_legacy_renderer_) {
      FML_CHECK(legacy_external_view_embedder_);
      legacy_external_view_embedder_->EnableWireframe(enabled);
    } else
#endif
    {
      FML_CHECK(external_view_embedder_);
      external_view_embedder_->EnableWireframe(enabled);
    }
  });
}

void Engine::CreateView(int64_t view_id,
                        ViewIdCallback on_view_bound,
                        bool hit_testable,
                        bool focusable) {
  FML_CHECK(shell_);

  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
      [this, view_id, hit_testable, focusable,
       on_view_bound = std::move(on_view_bound)]() {
#if defined(LEGACY_FUCHSIA_EMBEDDER)
        if (use_legacy_renderer_) {
          FML_CHECK(legacy_external_view_embedder_);
          legacy_external_view_embedder_->CreateView(
              view_id, std::move(on_view_bound), hit_testable, focusable);
        } else
#endif
        {
          FML_CHECK(external_view_embedder_);
          external_view_embedder_->CreateView(view_id,
                                              std::move(on_view_bound));
          external_view_embedder_->SetViewProperties(
              view_id, SkRect::MakeEmpty(), hit_testable, focusable);
        }
      });
}

void Engine::UpdateView(int64_t view_id,
                        SkRect occlusion_hint,
                        bool hit_testable,
                        bool focusable) {
  FML_CHECK(shell_);

  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
      [this, view_id, occlusion_hint, hit_testable, focusable]() {
#if defined(LEGACY_FUCHSIA_EMBEDDER)
        if (use_legacy_renderer_) {
          FML_CHECK(legacy_external_view_embedder_);
          legacy_external_view_embedder_->UpdateView(view_id, occlusion_hint,
                                                     hit_testable, focusable);
        } else
#endif
        {
          FML_CHECK(external_view_embedder_);
          external_view_embedder_->SetViewProperties(view_id, occlusion_hint,
                                                     hit_testable, focusable);
        }
      });
}

void Engine::DestroyView(int64_t view_id, ViewIdCallback on_view_unbound) {
  FML_CHECK(shell_);

  shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask(
      [this, view_id, on_view_unbound = std::move(on_view_unbound)]() {
#if defined(LEGACY_FUCHSIA_EMBEDDER)
        if (use_legacy_renderer_) {
          FML_CHECK(legacy_external_view_embedder_);
          legacy_external_view_embedder_->DestroyView(
              view_id, std::move(on_view_unbound));
        } else
#endif
        {
          FML_CHECK(external_view_embedder_);
          external_view_embedder_->DestroyView(view_id,
                                               std::move(on_view_unbound));
        }
      });
}

std::unique_ptr<flutter::Surface> Engine::CreateSurface() {
  return std::make_unique<Surface>(thread_label_, GetExternalViewEmbedder(),
                                   surface_producer_->gr_context());
}

std::shared_ptr<flutter::ExternalViewEmbedder>
Engine::GetExternalViewEmbedder() {
  std::shared_ptr<flutter::ExternalViewEmbedder> external_view_embedder =
      nullptr;

#if defined(LEGACY_FUCHSIA_EMBEDDER)
  if (use_legacy_renderer_) {
    FML_CHECK(legacy_external_view_embedder_);
    external_view_embedder = legacy_external_view_embedder_;
  } else
#endif
  {
    FML_CHECK(external_view_embedder_);
    external_view_embedder = external_view_embedder_;
  }
  FML_CHECK(external_view_embedder);

  return external_view_embedder;
}

#if !defined(DART_PRODUCT)
void Engine::WriteProfileToTrace() const {
  Dart_Port main_port = shell_->GetEngine()->GetUIIsolateMainPort();
  char* error = NULL;
  bool success = Dart_WriteProfileToTimeline(main_port, &error);
  if (!success) {
    FML_LOG(ERROR) << "Failed to write Dart profile to trace: " << error;
    free(error);
  }
}
#endif  // !defined(DART_PRODUCT)

void Engine::WarmupSkps(fml::BasicTaskRunner* concurrent_task_runner,
                        fml::BasicTaskRunner* raster_task_runner,
                        VulkanSurfaceProducer& surface_producer) {
  SkISize size = SkISize::Make(1024, 600);
  // We use a raw pointer here because we want to keep this alive until all gpu
  // work is done and the callbacks skia takes for this are function pointers
  // so we are unable to use a lambda that captures the smart pointer.
  SurfaceProducerSurface* skp_warmup_surface =
      surface_producer.ProduceOffscreenSurface(size).release();
  if (!skp_warmup_surface) {
    FML_LOG(ERROR) << "Failed to create offscreen warmup surface";
    return;
  }

  // tell concurrent task runner to deserialize all skps available from
  // the asset manager
  concurrent_task_runner->PostTask([raster_task_runner, skp_warmup_surface,
                                    &surface_producer]() {
    TRACE_DURATION("flutter", "DeserializeSkps");
    std::vector<std::unique_ptr<fml::Mapping>> skp_mappings =
        flutter::PersistentCache::GetCacheForProcess()
            ->GetSkpsFromAssetManager();

    size_t total_size = 0;
    for (auto& mapping : skp_mappings) {
      total_size += mapping->GetSize();
    }

    FML_LOG(INFO) << "Shader warmup got " << skp_mappings.size()
                  << " skp's with a total size of " << total_size << " bytes";

    std::vector<sk_sp<SkPicture>> pictures;
    unsigned int i = 0;
    for (auto& mapping : skp_mappings) {
      std::unique_ptr<SkMemoryStream> stream =
          SkMemoryStream::MakeDirect(mapping->GetMapping(), mapping->GetSize());
      SkDeserialProcs procs = {0};
      procs.fImageProc = flutter::DeserializeImageWithoutData;
      procs.fTypefaceProc = flutter::DeserializeTypefaceWithoutData;
      sk_sp<SkPicture> picture =
          SkPicture::MakeFromStream(stream.get(), &procs);
      if (!picture) {
        FML_LOG(ERROR) << "Failed to deserialize picture " << i;
        continue;
      }

      // Tell raster task runner to warmup have the compositor
      // context warm up the newly deserialized picture
      raster_task_runner->PostTask([skp_warmup_surface, picture,
                                    &surface_producer, i,
                                    count = skp_mappings.size()] {
        TRACE_DURATION("flutter", "WarmupSkp");
        skp_warmup_surface->GetSkiaSurface()->getCanvas()->drawPicture(picture);

        if (i < count - 1) {
          // For all but the last skp we fire and forget
          surface_producer.gr_context()->flushAndSubmit();
        } else {
          // For the last skp we provide a callback that frees the warmup
          // surface
          struct GrFlushInfo flush_info;
          flush_info.fFinishedContext = skp_warmup_surface;
          flush_info.fFinishedProc = [](void* skp_warmup_surface) {
            delete static_cast<SurfaceProducerSurface*>(skp_warmup_surface);
          };

          surface_producer.gr_context()->flush(flush_info);
          surface_producer.gr_context()->submit();
        }
      });
      i++;
    }
  });
}

}  // namespace flutter_runner
