engine.cc 10.6 KB
Newer Older
1 2 3 4 5 6
// Copyright 2015 The Chromium 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 "sky/shell/ui/engine.h"

A
Adam Barth 已提交
7
#include "base/bind.h"
8 9
#include "base/files/file_path.h"
#include "base/threading/worker_pool.h"
10
#include "base/time/time.h"
A
Adam Barth 已提交
11
#include "base/trace_event/trace_event.h"
12
#include "mojo/data_pipe_utils/data_pipe_utils.h"
13
#include "mojo/public/cpp/application/connect.h"
14
#include "services/asset_bundle/zip_asset_bundle.h"
A
Adam Barth 已提交
15
#include "sky/engine/bindings/mojo_services.h"
16 17
#include "sky/engine/core/script/dart_init.h"
#include "sky/engine/core/script/dom_dart_state.h"
A
Adam Barth 已提交
18
#include "sky/engine/public/platform/sky_display_metrics.h"
19
#include "sky/engine/public/platform/WebInputEvent.h"
20
#include "sky/engine/public/web/Sky.h"
21
#include "sky/shell/dart/dart_library_provider_files.h"
22
#include "sky/shell/shell.h"
A
Adam Barth 已提交
23
#include "sky/shell/ui/animator.h"
J
Jason Simmons 已提交
24
#include "sky/shell/ui/flutter_font_selector.h"
A
Adam Barth 已提交
25
#include "sky/shell/ui/platform_impl.h"
A
Adam Barth 已提交
26 27
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
28 29 30

namespace sky {
namespace shell {
31
namespace {
32

33 34
PlatformImpl* g_platform_impl = nullptr;

35 36
}  // namespace

37
using mojo::asset_bundle::ZipAssetBundle;
J
Jason Simmons 已提交
38
using mojo::asset_bundle::ZipAssetService;
E
Eric Seidel 已提交
39

40
Engine::Config::Config() {}
A
Adam Barth 已提交
41

42
Engine::Config::~Config() {}
A
Adam Barth 已提交
43

F
Florian Loitsch 已提交
44
Engine::Engine(const Config& config, rasterizer::RasterizerPtr rasterizer)
45
    : config_(config),
F
Florian Loitsch 已提交
46
      animator_(new Animator(config, rasterizer.Pass(), this)),
47
      binding_(this),
48 49
      activity_running_(false),
      have_surface_(false),
50
      weak_factory_(this) {}
51

52
Engine::~Engine() {}
53 54 55 56 57

base::WeakPtr<Engine> Engine::GetWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

58
void Engine::Init() {
59
  TRACE_EVENT0("flutter", "Engine::Init");
A
Adam Barth 已提交
60

61 62 63
  DCHECK(!g_platform_impl);
  g_platform_impl = new PlatformImpl();
  blink::initialize(g_platform_impl);
C
Chinmay Garde 已提交
64
  Shell::Shared().tracing_controller().SetDartInitialized();
65 66
}

A
Adam Barth 已提交
67
std::unique_ptr<flow::LayerTree> Engine::BeginFrame(
68
    base::TimeTicks frame_time) {
69
  TRACE_EVENT0("flutter", "Engine::BeginFrame");
A
Adam Barth 已提交
70

71 72
  if (!sky_view_)
    return nullptr;
A
Adam Barth 已提交
73

74
  auto begin_time = base::TimeTicks::Now();
A
Adam Barth 已提交
75
  std::unique_ptr<flow::LayerTree> layer_tree =
76
      sky_view_->BeginFrame(frame_time);
77
  if (layer_tree) {
78 79
    layer_tree->set_frame_size(SkISize::Make(display_metrics_.physical_width,
                                             display_metrics_.physical_height));
80
    layer_tree->set_construction_time(base::TimeTicks::Now() - begin_time);
A
Adam Barth 已提交
81
  }
82
  return layer_tree;
A
Adam Barth 已提交
83 84
}

85 86
void Engine::ConnectToEngine(mojo::InterfaceRequest<SkyEngine> request) {
  binding_.Bind(request.Pass());
87 88
}

A
Adam Barth 已提交
89 90
void Engine::OnOutputSurfaceCreated(const base::Closure& gpu_continuation) {
  config_.gpu_task_runner->PostTask(FROM_HERE, gpu_continuation);
91 92
  have_surface_ = true;
  StartAnimatorIfPossible();
93
  if (sky_view_)
94
    ScheduleFrame();
95 96
}

A
Adam Barth 已提交
97
void Engine::OnOutputSurfaceDestroyed(const base::Closure& gpu_continuation) {
98 99
  have_surface_ = false;
  StopAnimator();
A
Adam Barth 已提交
100
  config_.gpu_task_runner->PostTask(FROM_HERE, gpu_continuation);
101 102
}

103 104 105
void Engine::SetServices(ServicesDataPtr services) {
  services_ = services.Pass();

106 107 108 109 110 111 112
  if (services_->services_provided_by_embedder) {
    services_provided_by_embedder_ =
        services_->services_provided_by_embedder.Pass();
    service_provider_impl_.set_fallback_service_provider(
        services_provided_by_embedder_.get());
  }

A
Adam Barth 已提交
113
  if (services_->scene_scheduler) {
114
    animator_->Reset();
A
Adam Barth 已提交
115
    animator_->set_scene_scheduler(services_->scene_scheduler.Pass());
A
Adam Barth 已提交
116
  } else {
A
Adam Barth 已提交
117 118 119 120 121 122
#if defined(OS_ANDROID) || defined(OS_IOS)
    vsync::VSyncProviderPtr vsync_provider;
    if (services_->shell) {
      mojo::ConnectToService(services_->shell.get(), "mojo:vsync",
                             &vsync_provider);
    } else {
123
      mojo::ConnectToService(services_provided_by_embedder_.get(),
A
Adam Barth 已提交
124 125
                             &vsync_provider);
    }
126
    animator_->Reset();
A
Adam Barth 已提交
127
    animator_->set_vsync_provider(vsync_provider.Pass());
128
#endif
A
Adam Barth 已提交
129
  }
130 131
}

A
Adam Barth 已提交
132 133
void Engine::OnViewportMetricsChanged(ViewportMetricsPtr metrics) {
  display_metrics_.device_pixel_ratio = metrics->device_pixel_ratio;
134 135
  display_metrics_.physical_width = metrics->physical_width;
  display_metrics_.physical_height = metrics->physical_height;
136 137 138 139
  display_metrics_.physical_padding_top = metrics->physical_padding_top;
  display_metrics_.physical_padding_right = metrics->physical_padding_right;
  display_metrics_.physical_padding_bottom = metrics->physical_padding_bottom;
  display_metrics_.physical_padding_left = metrics->physical_padding_left;
140

A
Adam Barth 已提交
141 142
  if (sky_view_)
    sky_view_->SetDisplayMetrics(display_metrics_);
143 144
}

145
void Engine::OnLocaleChanged(const mojo::String& language_code,
146
                             const mojo::String& country_code) {
147 148 149 150 151 152
  language_code_ = language_code;
  country_code_ = country_code;
  if (sky_view_)
    sky_view_->SetLocale(language_code_, country_code_);
}

153
void Engine::OnPointerPacket(pointer::PointerPacketPtr packet) {
154
  TRACE_EVENT0("flutter", "Engine::OnPointerPacket");
155 156 157 158 159 160 161 162 163

  // Convert the pointers' x and y coordinates to logical pixels.
  for (auto it = packet->pointers.begin(); it != packet->pointers.end(); ++it) {
    (*it)->x /= display_metrics_.device_pixel_ratio;
    (*it)->y /= display_metrics_.device_pixel_ratio;
  }

  if (sky_view_)
    sky_view_->HandlePointerPacket(packet);
164 165
}

166
void Engine::RunFromLibrary(const std::string& name) {
C
Chinmay Garde 已提交
167
  TRACE_EVENT0("flutter", "Engine::RunFromLibrary");
168
  sky_view_ = blink::SkyView::Create(this);
169 170
  sky_view_->CreateView(name);
  sky_view_->RunFromLibrary(name, dart_library_provider_.get());
A
Adam Barth 已提交
171
  sky_view_->SetDisplayMetrics(display_metrics_);
172
  sky_view_->SetLocale(language_code_, country_code_);
A
Adam Barth 已提交
173 174
  if (!initial_route_.empty())
    sky_view_->PushRoute(initial_route_);
175 176
}

177
void Engine::RunFromSnapshotStream(
178
    const std::string& bundle_path,
179
    mojo::ScopedDataPipeConsumerHandle snapshot) {
180
  TRACE_EVENT0("flutter", "Engine::RunFromSnapshotStream");
181
  std::string script_uri = std::string("file://") + bundle_path;
182
  sky_view_ = blink::SkyView::Create(this);
183 184
  sky_view_->CreateView(script_uri);
  sky_view_->RunFromSnapshot(snapshot.Pass());
A
Adam Barth 已提交
185
  sky_view_->SetDisplayMetrics(display_metrics_);
186
  sky_view_->SetLocale(language_code_, country_code_);
A
Adam Barth 已提交
187 188
  if (!initial_route_.empty())
    sky_view_->PushRoute(initial_route_);
189 190
}

191 192 193 194 195 196
void Engine::ConfigureZipAssetBundle(const mojo::String& path) {
  zip_asset_bundle_ = new ZipAssetBundle(base::FilePath(std::string{path}),
                                         base::WorkerPool::GetTaskRunner(true));
  ZipAssetService::Create(mojo::GetProxy(&root_bundle_), zip_asset_bundle_);
}

197
void Engine::RunFromPrecompiledSnapshot(const mojo::String& bundle_path) {
C
Chinmay Garde 已提交
198
  TRACE_EVENT0("flutter", "Engine::RunFromPrecompiledSnapshot");
199

200
  ConfigureZipAssetBundle(bundle_path);
201

202
  sky_view_ = blink::SkyView::Create(this);
203
  sky_view_->CreateView("http://localhost");
204 205
  sky_view_->RunFromPrecompiledSnapshot();
  sky_view_->SetDisplayMetrics(display_metrics_);
206
  sky_view_->SetLocale(language_code_, country_code_);
A
Adam Barth 已提交
207 208
  if (!initial_route_.empty())
    sky_view_->PushRoute(initial_route_);
209 210
}

211
void Engine::RunFromFile(const mojo::String& main,
212 213
                         const mojo::String& package_root,
                         const mojo::String& bundle) {
C
Chinmay Garde 已提交
214
  TRACE_EVENT0("flutter", "Engine::RunFromFile");
215 216 217 218
  if (bundle.size() != 0) {
    // The specification of an FLX bundle is optional.
    ConfigureZipAssetBundle(bundle);
  }
219
  std::string package_root_str = package_root;
220
  dart_library_provider_.reset(
221
      new DartLibraryProviderFiles(base::FilePath(package_root_str)));
222 223 224
  RunFromLibrary(main);
}

225
void Engine::RunFromBundle(const mojo::String& path) {
226
  TRACE_EVENT0("flutter", "Engine::RunFromBundle");
227

228 229 230 231 232 233
  ConfigureZipAssetBundle(path);

  root_bundle_->GetAsStream(
      blink::kSnapshotAssetKey,
      base::Bind(&Engine::RunFromSnapshotStream, weak_factory_.GetWeakPtr(),
                 std::string{path}));
234 235
}

236 237 238
void Engine::RunFromBundleAndSnapshot(const mojo::String& bundle_path,
                                      const mojo::String& snapshot_path) {
  TRACE_EVENT0("flutter", "Engine::RunFromBundleAndSnapshot");
239 240

  ConfigureZipAssetBundle(bundle_path);
241 242

  std::string snapshot_path_str = snapshot_path;
243
  zip_asset_bundle_->AddOverlayFile(blink::kSnapshotAssetKey,
J
Jason Simmons 已提交
244
                                    base::FilePath(snapshot_path_str));
245

246 247 248 249
  root_bundle_->GetAsStream(
      blink::kSnapshotAssetKey,
      base::Bind(&Engine::RunFromSnapshotStream, weak_factory_.GetWeakPtr(),
                 std::string{bundle_path}));
250 251
}

A
Adam Barth 已提交
252 253 254 255 256 257 258 259 260 261 262 263
void Engine::PushRoute(const mojo::String& route) {
  if (sky_view_)
    sky_view_->PushRoute(route);
  else
    initial_route_ = route;
}

void Engine::PopRoute() {
  if (sky_view_)
    sky_view_->PopRoute();
}

264 265 266 267 268 269 270 271 272 273 274 275
void Engine::OnAppLifecycleStateChanged(sky::AppLifecycleState state) {
  switch (state) {
    case sky::AppLifecycleState::PAUSED:
      activity_running_ = false;
      StopAnimator();
      break;

    case sky::AppLifecycleState::RESUMED:
      activity_running_ = true;
      StartAnimatorIfPossible();
      break;
  }
276

277 278
  if (sky_view_)
    sky_view_->OnAppLifecycleStateChanged(state);
279 280
}

281 282 283 284 285 286 287 288
void Engine::DidCreateMainIsolate(Dart_Isolate isolate) {
  mojo::ServiceProviderPtr services_from_embedder;
  service_provider_bindings_.AddBinding(
      &service_provider_impl_, mojo::GetProxy(&services_from_embedder));

  blink::MojoServices::Create(
      isolate, services_.Pass(), services_from_embedder.Pass(),
      root_bundle_.Pass());
J
Jason Simmons 已提交
289

290
  if (zip_asset_bundle_) {
J
Jason Simmons 已提交
291
    FlutterFontSelector::install(zip_asset_bundle_);
292
  }
293 294
}

295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
void Engine::DidCreateSecondaryIsolate(Dart_Isolate isolate) {
  mojo::ServiceProviderPtr services_from_embedder;
  mojo::InterfaceRequest<mojo::ServiceProvider> request =
      mojo::GetProxy(&services_from_embedder);
  blink::Platform::current()->GetUITaskRunner()->PostTask(FROM_HERE,
      base::Bind(&Engine::BindToServiceProvider,
                 weak_factory_.GetWeakPtr(),
                 base::Passed(&request)));

  blink::MojoServices::Create(
      isolate, nullptr, services_from_embedder.Pass(), nullptr);
}

void Engine::BindToServiceProvider(
    mojo::InterfaceRequest<mojo::ServiceProvider> request) {
  service_provider_bindings_.AddBinding(&service_provider_impl_,
                                        request.Pass());
}

314 315 316 317 318 319 320 321 322
void Engine::StopAnimator() {
  animator_->Stop();
}

void Engine::StartAnimatorIfPossible() {
  if (activity_running_ && have_surface_)
    animator_->Start();
}

323
void Engine::ScheduleFrame() {
A
Adam Barth 已提交
324 325 326
  animator_->RequestFrame();
}

327 328 329 330
void Engine::FlushRealTimeEvents() {
  animator_->FlushRealTimeEvents();
}

331
void Engine::Render(std::unique_ptr<flow::LayerTree> layer_tree) {}
332

333 334
}  // namespace shell
}  // namespace sky