engine.cc 8.5 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
#include "base/command_line.h"
9 10
#include "base/files/file_path.h"
#include "base/threading/worker_pool.h"
11
#include "base/time/time.h"
A
Adam Barth 已提交
12
#include "base/trace_event/trace_event.h"
13
#include "mojo/data_pipe_utils/data_pipe_utils.h"
14
#include "mojo/public/cpp/application/connect.h"
15
#include "services/asset_bundle/asset_unpacker_job.h"
A
Adam Barth 已提交
16
#include "sky/engine/public/platform/sky_display_metrics.h"
17
#include "sky/engine/public/platform/WebInputEvent.h"
18
#include "sky/engine/public/web/Sky.h"
19
#include "sky/engine/public/web/WebRuntimeFeatures.h"
20 21
#include "sky/shell/dart/dart_library_provider_files.h"
#include "sky/shell/dart/dart_library_provider_network.h"
22
#include "sky/shell/switches.h"
23
#include "sky/shell/switches.h"
A
Adam Barth 已提交
24
#include "sky/shell/ui/animator.h"
25
#include "sky/shell/ui/internals.h"
A
Adam Barth 已提交
26
#include "sky/shell/ui/platform_impl.h"
A
Adam Barth 已提交
27 28
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
29 30 31

namespace sky {
namespace shell {
32
namespace {
33

34 35
const char kSnapshotKey[] = "snapshot_blob.bin";

36 37 38 39 40 41 42 43 44 45 46
void Ignored(bool) {
}

mojo::ScopedDataPipeConsumerHandle Fetch(const base::FilePath& path) {
  mojo::DataPipe pipe;
  auto runner = base::WorkerPool::GetTaskRunner(true);
  mojo::common::CopyFromFile(base::FilePath(path), pipe.producer_handle.Pass(),
                             0, runner.get(), base::Bind(&Ignored));
  return pipe.consumer_handle.Pass();
}

47 48
PlatformImpl* g_platform_impl = nullptr;

49 50 51
}  // namespace

using mojo::asset_bundle::AssetUnpackerJob;
E
Eric Seidel 已提交
52

A
Adam Barth 已提交
53 54 55 56 57 58
Engine::Config::Config() {
}

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

A
Adam Barth 已提交
59
Engine::Engine(const Config& config)
60
    : config_(config),
A
Adam Barth 已提交
61
      animator_(new Animator(config, this)),
62
      binding_(this),
63 64
      activity_running_(false),
      have_surface_(false),
A
Adam Barth 已提交
65
      weak_factory_(this) {
66 67 68 69 70 71 72 73 74
}

Engine::~Engine() {
}

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

75
void Engine::Init() {
76
  TRACE_EVENT0("flutter", "Engine::Init");
A
Adam Barth 已提交
77

78 79 80
  base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
  blink::WebRuntimeFeatures::enableDartCheckedMode(
      command_line.HasSwitch(switches::kEnableCheckedMode));
81 82 83 84

  DCHECK(!g_platform_impl);
  g_platform_impl = new PlatformImpl();
  blink::initialize(g_platform_impl);
85 86
}

87 88
std::unique_ptr<compositor::LayerTree> Engine::BeginFrame(
    base::TimeTicks frame_time) {
89
  TRACE_EVENT0("flutter", "Engine::BeginFrame");
A
Adam Barth 已提交
90

91 92
  if (!sky_view_)
    return nullptr;
A
Adam Barth 已提交
93

94
  auto begin_time = base::TimeTicks::Now();
95 96
  std::unique_ptr<compositor::LayerTree> layer_tree =
      sky_view_->BeginFrame(frame_time);
97
  if (layer_tree) {
98 99 100
    layer_tree->set_frame_size(
        SkISize::Make(physical_size_.width(), physical_size_.height()));
    layer_tree->set_construction_time(base::TimeTicks::Now() - begin_time);
A
Adam Barth 已提交
101
  }
102
  return layer_tree;
A
Adam Barth 已提交
103 104
}

105 106
void Engine::ConnectToEngine(mojo::InterfaceRequest<SkyEngine> request) {
  binding_.Bind(request.Pass());
107 108
}

A
Adam Barth 已提交
109 110
void Engine::OnOutputSurfaceCreated(const base::Closure& gpu_continuation) {
  config_.gpu_task_runner->PostTask(FROM_HERE, gpu_continuation);
111 112
  have_surface_ = true;
  StartAnimatorIfPossible();
113
  if (sky_view_)
114
    ScheduleFrame();
115 116
}

A
Adam Barth 已提交
117
void Engine::OnOutputSurfaceDestroyed(const base::Closure& gpu_continuation) {
118 119
  have_surface_ = false;
  StopAnimator();
A
Adam Barth 已提交
120
  config_.gpu_task_runner->PostTask(FROM_HERE, gpu_continuation);
121 122
}

123 124 125 126
void Engine::SetServices(ServicesDataPtr services) {
  services_ = services.Pass();

#if defined(OS_ANDROID) || defined(OS_IOS)
A
Adam Barth 已提交
127 128 129 130 131 132
  if (services_->services_provided_by_embedder) {
    // TODO(abarth): Implement VSyncProvider on other platforms.
    vsync::VSyncProviderPtr vsync_provider;
    mojo::ConnectToService(services_->services_provided_by_embedder.get(), &vsync_provider);
    animator_->set_vsync_provider(vsync_provider.Pass());
  }
133 134 135
#endif
}

A
Adam Barth 已提交
136 137
void Engine::OnViewportMetricsChanged(ViewportMetricsPtr metrics) {
  physical_size_.SetSize(metrics->physical_width, metrics->physical_height);
A
Adam Barth 已提交
138

A
Adam Barth 已提交
139 140 141 142 143 144
  display_metrics_.physical_size = physical_size_;
  display_metrics_.device_pixel_ratio = metrics->device_pixel_ratio;
  display_metrics_.padding_top = metrics->padding_top;
  display_metrics_.padding_right = metrics->padding_right;
  display_metrics_.padding_bottom = metrics->padding_bottom;
  display_metrics_.padding_left = metrics->padding_left;
145

A
Adam Barth 已提交
146 147
  if (sky_view_)
    sky_view_->SetDisplayMetrics(display_metrics_);
148 149
}

150
void Engine::OnInputEvent(InputEventPtr event) {
151
  TRACE_EVENT0("flutter", "Engine::OnInputEvent");
152 153

  if (event->type != EventType::BACK)
154
    return;
155 156 157 158

  scoped_ptr<blink::WebInputEvent> web_event(blink::WebInputEvent::create());
  web_event->type = blink::WebInputEvent::Back;
  web_event->timeStampMS = currentTimeMS();
A
Adam Barth 已提交
159 160
  if (sky_view_)
    sky_view_->HandleInputEvent(*web_event);
161 162
}

163
void Engine::OnPointerPacket(pointer::PointerPacketPtr packet) {
164
  TRACE_EVENT0("flutter", "Engine::OnPointerPacket");
165 166 167 168 169 170 171 172 173

  // 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);
174 175
}

176
void Engine::RunFromLibrary(const std::string& name) {
177
  sky_view_ = blink::SkyView::Create(this);
A
Alhaad Gokhale 已提交
178
  sky_view_->CreateView(blink::WebString::fromUTF8(name));
179 180
  sky_view_->RunFromLibrary(blink::WebString::fromUTF8(name),
                            dart_library_provider_.get());
A
Adam Barth 已提交
181
  sky_view_->SetDisplayMetrics(display_metrics_);
182 183
}

184 185 186 187
void Engine::RunFromSnapshotStream(
    const std::string& name,
    mojo::ScopedDataPipeConsumerHandle snapshot) {
  sky_view_ = blink::SkyView::Create(this);
A
Alhaad Gokhale 已提交
188
  sky_view_->CreateView(blink::WebString::fromUTF8(name));
189
  sky_view_->RunFromSnapshot(blink::WebString::fromUTF8(name), snapshot.Pass());
A
Adam Barth 已提交
190
  sky_view_->SetDisplayMetrics(display_metrics_);
191 192
}

193 194 195 196 197 198
void Engine::RunFromPrecompiledSnapshot(const mojo::String& bundle_path) {
  AssetUnpackerJob* unpacker = new AssetUnpackerJob(
      mojo::GetProxy(&root_bundle_), base::WorkerPool::GetTaskRunner(true));
  std::string path_str = bundle_path;
  unpacker->Unpack(Fetch(base::FilePath(path_str)));

199
  sky_view_ = blink::SkyView::Create(this);
200
  sky_view_->CreateView("http://localhost");
201 202 203 204
  sky_view_->RunFromPrecompiledSnapshot();
  sky_view_->SetDisplayMetrics(display_metrics_);
}

205 206
void Engine::RunFromFile(const mojo::String& main,
                         const mojo::String& package_root) {
207
  std::string package_root_str = package_root;
208
  dart_library_provider_.reset(
209
      new DartLibraryProviderFiles(base::FilePath(package_root_str)));
210 211 212
  RunFromLibrary(main);
}

213
void Engine::RunFromSnapshot(const mojo::String& path) {
214 215 216 217 218 219 220 221 222 223 224 225
  std::string path_str = path;
  RunFromSnapshotStream(path_str, Fetch(base::FilePath(path_str)));
}

void Engine::RunFromBundle(const mojo::String& path) {
  AssetUnpackerJob* unpacker = new AssetUnpackerJob(
      mojo::GetProxy(&root_bundle_), base::WorkerPool::GetTaskRunner(true));
  std::string path_str = path;
  unpacker->Unpack(Fetch(base::FilePath(path_str)));
  root_bundle_->GetAsStream(kSnapshotKey,
                            base::Bind(&Engine::RunFromSnapshotStream,
                                       weak_factory_.GetWeakPtr(), path_str));
226 227
}

228 229 230 231 232 233 234 235 236
void Engine::RunFromAssetBundle(const mojo::String& url,
                                mojo::asset_bundle::AssetBundlePtr bundle) {
  std::string url_str = url;
  root_bundle_ = bundle.Pass();
  root_bundle_->GetAsStream(kSnapshotKey,
                            base::Bind(&Engine::RunFromSnapshotStream,
                                       weak_factory_.GetWeakPtr(), url_str));
}

237 238 239 240 241 242 243 244 245 246
void Engine::OnActivityPaused() {
  activity_running_ = false;
  StopAnimator();
}

void Engine::OnActivityResumed() {
  activity_running_ = true;
  StartAnimatorIfPossible();
}

247
void Engine::DidCreateIsolate(Dart_Isolate isolate) {
248
  Internals::Create(isolate, services_.Pass(), root_bundle_.Pass());
249 250
}

251 252 253 254 255 256 257 258 259
void Engine::StopAnimator() {
  animator_->Stop();
}

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

260
void Engine::ScheduleFrame() {
A
Adam Barth 已提交
261 262 263
  animator_->RequestFrame();
}

264 265 266
void Engine::Render(std::unique_ptr<compositor::LayerTree> layer_tree) {
}

267 268 269 270 271 272 273 274
void Engine::StartDartTracing() {
  sky_view_->StartDartTracing();
}

void Engine::StopDartTracing(mojo::ScopedDataPipeProducerHandle producer) {
  sky_view_->StopDartTracing(producer.Pass());
}

275 276
}  // namespace shell
}  // namespace sky