engine.cc 9.2 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/public/platform/sky_display_metrics.h"
16
#include "sky/engine/public/platform/WebInputEvent.h"
17
#include "sky/engine/public/web/Sky.h"
18
#include "sky/shell/dart/dart_library_provider_files.h"
19
#include "sky/shell/shell.h"
A
Adam Barth 已提交
20
#include "sky/shell/ui/animator.h"
21
#include "sky/shell/ui/internals.h"
A
Adam Barth 已提交
22
#include "sky/shell/ui/platform_impl.h"
A
Adam Barth 已提交
23 24
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
25 26 27

namespace sky {
namespace shell {
28
namespace {
29

30 31
const char kSnapshotKey[] = "snapshot_blob.bin";

32 33
PlatformImpl* g_platform_impl = nullptr;

34 35
}  // namespace

36
using mojo::asset_bundle::ZipAssetBundle;
E
Eric Seidel 已提交
37

A
Adam Barth 已提交
38 39 40 41 42 43
Engine::Config::Config() {
}

Engine::Config::~Config() {
}

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),
A
Adam Barth 已提交
50
      weak_factory_(this) {
51 52 53 54 55 56 57 58 59
}

Engine::~Engine() {
}

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

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

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

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

73 74
  if (!sky_view_)
    return nullptr;
A
Adam Barth 已提交
75

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

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

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

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

105 106 107
void Engine::SetServices(ServicesDataPtr services) {
  services_ = services.Pass();

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

A
Adam Barth 已提交
127 128
void Engine::OnViewportMetricsChanged(ViewportMetricsPtr metrics) {
  display_metrics_.device_pixel_ratio = metrics->device_pixel_ratio;
129 130
  display_metrics_.physical_width = metrics->physical_width;
  display_metrics_.physical_height = metrics->physical_height;
131 132 133 134
  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;
135

A
Adam Barth 已提交
136 137
  if (sky_view_)
    sky_view_->SetDisplayMetrics(display_metrics_);
138 139
}

140 141 142 143 144 145 146 147
void Engine::OnLocaleChanged(const mojo::String& language_code,
			     const mojo::String& country_code) {
  language_code_ = language_code;
  country_code_ = country_code;
  if (sky_view_)
    sky_view_->SetLocale(language_code_, country_code_);
}

148
void Engine::OnPointerPacket(pointer::PointerPacketPtr packet) {
149
  TRACE_EVENT0("flutter", "Engine::OnPointerPacket");
150 151 152 153 154 155 156 157 158

  // 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);
159 160
}

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

172 173 174
void Engine::RunFromSnapshotStream(
    const std::string& name,
    mojo::ScopedDataPipeConsumerHandle snapshot) {
175
  TRACE_EVENT0("flutter", "Engine::RunFromSnapshotStream");
176
  sky_view_ = blink::SkyView::Create(this);
177 178
  sky_view_->CreateView(name);
  sky_view_->RunFromSnapshot(name, snapshot.Pass());
A
Adam Barth 已提交
179
  sky_view_->SetDisplayMetrics(display_metrics_);
180
  sky_view_->SetLocale(language_code_, country_code_);
A
Adam Barth 已提交
181 182
  if (!initial_route_.empty())
    sky_view_->PushRoute(initial_route_);
183 184
}

185
void Engine::RunFromPrecompiledSnapshot(const mojo::String& bundle_path) {
C
Chinmay Garde 已提交
186
  TRACE_EVENT0("flutter", "Engine::RunFromPrecompiledSnapshot");
187

188
  std::string path_str = bundle_path;
189 190 191
  ZipAssetBundle::Create(mojo::GetProxy(&root_bundle_),
                         base::FilePath(path_str),
                         base::WorkerPool::GetTaskRunner(true));
192

193
  sky_view_ = blink::SkyView::Create(this);
194
  sky_view_->CreateView("http://localhost");
195 196
  sky_view_->RunFromPrecompiledSnapshot();
  sky_view_->SetDisplayMetrics(display_metrics_);
197
  sky_view_->SetLocale(language_code_, country_code_);
A
Adam Barth 已提交
198 199
  if (!initial_route_.empty())
    sky_view_->PushRoute(initial_route_);
200 201
}

202 203
void Engine::RunFromFile(const mojo::String& main,
                         const mojo::String& package_root) {
C
Chinmay Garde 已提交
204
  TRACE_EVENT0("flutter", "Engine::RunFromFile");
205
  std::string package_root_str = package_root;
206
  dart_library_provider_.reset(
207
      new DartLibraryProviderFiles(base::FilePath(package_root_str)));
208 209 210
  RunFromLibrary(main);
}

211
void Engine::RunFromBundle(const mojo::String& path) {
212
  TRACE_EVENT0("flutter", "Engine::RunFromBundle");
213
  std::string path_str = path;
214 215 216 217
  ZipAssetBundle::Create(mojo::GetProxy(&root_bundle_),
                         base::FilePath(path_str),
                         base::WorkerPool::GetTaskRunner(true));

218 219 220
  root_bundle_->GetAsStream(kSnapshotKey,
                            base::Bind(&Engine::RunFromSnapshotStream,
                                       weak_factory_.GetWeakPtr(), path_str));
221 222
}

223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
void Engine::RunFromBundleAndSnapshot(const mojo::String& bundle_path,
                                      const mojo::String& snapshot_path) {
  TRACE_EVENT0("flutter", "Engine::RunFromBundleAndSnapshot");
  std::string bundle_path_str = bundle_path;
  ZipAssetBundle* asset_bundle = ZipAssetBundle::Create(
      mojo::GetProxy(&root_bundle_),
      base::FilePath(bundle_path_str),
      base::WorkerPool::GetTaskRunner(true));

  std::string snapshot_path_str = snapshot_path;
  asset_bundle->AddOverlayFile(kSnapshotKey,
                               base::FilePath(snapshot_path_str));

  root_bundle_->GetAsStream(kSnapshotKey,
                            base::Bind(&Engine::RunFromSnapshotStream,
                                       weak_factory_.GetWeakPtr(),
                                       bundle_path_str));
}

A
Adam Barth 已提交
242 243 244 245 246 247 248 249 250 251 252 253
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();
}

254 255 256 257 258 259 260 261 262 263 264 265
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;
  }
266

267 268
  if (sky_view_)
    sky_view_->OnAppLifecycleStateChanged(state);
269 270
}

271
void Engine::DidCreateIsolate(Dart_Isolate isolate) {
272
  Internals::Create(isolate, services_.Pass(), root_bundle_.Pass());
273 274
}

275 276 277 278 279 280 281 282 283
void Engine::StopAnimator() {
  animator_->Stop();
}

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

284
void Engine::ScheduleFrame() {
A
Adam Barth 已提交
285 286 287
  animator_->RequestFrame();
}

288 289 290 291
void Engine::FlushRealTimeEvents() {
  animator_->FlushRealTimeEvents();
}

A
Adam Barth 已提交
292
void Engine::Render(std::unique_ptr<flow::LayerTree> layer_tree) {
293 294
}

295 296
}  // namespace shell
}  // namespace sky