engine.cc 8.4 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"
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/asset_unpacker_job.h"
15
#include "sky/shell/gpu/picture_serializer.h"
16
#include "sky/engine/public/platform/WebInputEvent.h"
A
Adam Barth 已提交
17 18
#include "sky/engine/public/platform/sky_display_metrics.h"
#include "sky/engine/public/platform/sky_display_metrics.h"
19
#include "sky/engine/public/web/Sky.h"
20
#include "sky/engine/public/web/WebRuntimeFeatures.h"
21 22
#include "sky/shell/dart/dart_library_provider_files.h"
#include "sky/shell/dart/dart_library_provider_network.h"
23
#include "sky/shell/service_provider.h"
24
#include "sky/shell/switches.h"
A
Adam Barth 已提交
25
#include "sky/shell/ui/animator.h"
26
#include "sky/shell/ui/input_event_converter.h"
27
#include "sky/shell/ui/internals.h"
A
Adam Barth 已提交
28
#include "sky/shell/ui/platform_impl.h"
A
Adam Barth 已提交
29 30
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
31 32 33

namespace sky {
namespace shell {
34
namespace {
35

36 37
const char kSnapshotKey[] = "snapshot_blob.bin";

38 39 40 41 42 43 44 45 46 47 48
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();
}

49 50
PlatformImpl* g_platform_impl = nullptr;

51 52 53
}  // namespace

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

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

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

A
Adam Barth 已提交
61
Engine::Engine(const Config& config)
62
    : config_(config),
A
Adam Barth 已提交
63
      animator_(new Animator(config, this)),
64
      binding_(this),
65 66
      activity_running_(false),
      have_surface_(false),
A
Adam Barth 已提交
67
      weak_factory_(this) {
68 69 70
  mojo::ServiceProviderPtr service_provider =
      CreateServiceProvider(config.service_provider_context);
  mojo::ConnectToService(service_provider.get(), &network_service_);
71

72
#if defined(OS_ANDROID) || defined(OS_IOS)
A
Adam Barth 已提交
73 74
  // TODO(abarth): Implement VSyncProvider on other platforms.
  vsync::VSyncProviderPtr vsync_provider;
75 76 77
  mojo::ConnectToService(service_provider.get(), &vsync_provider);
  animator_->set_vsync_provider(vsync_provider.Pass());
#endif
78 79 80 81 82 83 84 85 86
}

Engine::~Engine() {
}

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

87
void Engine::Init() {
A
Adam Barth 已提交
88 89
  TRACE_EVENT0("sky", "Engine::Init");

90 91 92
  base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess();
  blink::WebRuntimeFeatures::enableDartCheckedMode(
      command_line.HasSwitch(switches::kEnableCheckedMode));
93 94 95 96

  DCHECK(!g_platform_impl);
  g_platform_impl = new PlatformImpl();
  blink::initialize(g_platform_impl);
97 98
}

A
Adam Barth 已提交
99
void Engine::BeginFrame(base::TimeTicks frame_time) {
A
Adam Barth 已提交
100 101
  TRACE_EVENT0("sky", "Engine::BeginFrame");

102 103
  if (sky_view_)
    sky_view_->BeginFrame(frame_time);
A
Adam Barth 已提交
104 105
}

A
Adam Barth 已提交
106
PassRefPtr<SkPicture> Engine::Paint() {
A
Adam Barth 已提交
107 108
  TRACE_EVENT0("sky", "Engine::Paint");

A
Adam Barth 已提交
109
  if (sky_view_) {
A
Adam Barth 已提交
110
    RefPtr<SkPicture> picture = sky_view_->Paint();
A
Adam Barth 已提交
111
    if (picture)
A
Adam Barth 已提交
112
      return picture.release();
A
Adam Barth 已提交
113 114
  }

A
Adam Barth 已提交
115 116 117 118
  SkPictureRecorder recorder;
  SkCanvas* canvas = recorder.beginRecording(
      physical_size_.width(), physical_size_.height());
  canvas->clear(SK_ColorBLACK);
A
Adam Barth 已提交
119
  return adoptRef(recorder.endRecordingAsPicture());
A
Adam Barth 已提交
120 121
}

122 123
void Engine::ConnectToEngine(mojo::InterfaceRequest<SkyEngine> request) {
  binding_.Bind(request.Pass());
124 125
}

126 127 128 129
void Engine::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) {
  config_.gpu_task_runner->PostTask(
      FROM_HERE, base::Bind(&GPUDelegate::OnAcceleratedWidgetAvailable,
                            config_.gpu_delegate, widget));
130 131
  have_surface_ = true;
  StartAnimatorIfPossible();
132
  if (sky_view_)
133
    ScheduleFrame();
134 135 136
}

void Engine::OnOutputSurfaceDestroyed() {
137 138
  have_surface_ = false;
  StopAnimator();
139 140 141 142 143
  config_.gpu_task_runner->PostTask(
      FROM_HERE,
      base::Bind(&GPUDelegate::OnOutputSurfaceDestroyed, config_.gpu_delegate));
}

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

A
Adam Barth 已提交
147 148 149 150 151 152
  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;
153

A
Adam Barth 已提交
154 155
  if (sky_view_)
    sky_view_->SetDisplayMetrics(display_metrics_);
156 157
}

158
void Engine::OnInputEvent(InputEventPtr event) {
A
Adam Barth 已提交
159
  TRACE_EVENT0("sky", "Engine::OnInputEvent");
160
  scoped_ptr<blink::WebInputEvent> web_event =
A
Adam Barth 已提交
161
      ConvertEvent(event, display_metrics_.device_pixel_ratio);
162 163
  if (!web_event)
    return;
A
Adam Barth 已提交
164 165
  if (sky_view_)
    sky_view_->HandleInputEvent(*web_event);
166 167
}

168 169 170 171
void Engine::OnPointerPacket(pointer::PointerPacketPtr packet) {
  // TODO(abarth): Process pointer events in packets.
}

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

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

189 190
void Engine::RunFromNetwork(const mojo::String& url) {
  dart_library_provider_.reset(
191
      new DartLibraryProviderNetwork(network_service_.get()));
192 193 194 195 196
  RunFromLibrary(url);
}

void Engine::RunFromFile(const mojo::String& main,
                         const mojo::String& package_root) {
197
  std::string package_root_str = package_root;
198
  dart_library_provider_.reset(
199
      new DartLibraryProviderFiles(base::FilePath(package_root_str)));
200 201 202
  RunFromLibrary(main);
}

203
void Engine::RunFromSnapshot(const mojo::String& path) {
204 205 206 207 208 209 210 211 212 213 214 215
  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));
216 217
}

218 219 220 221 222 223 224 225 226 227
void Engine::OnActivityPaused() {
  activity_running_ = false;
  StopAnimator();
}

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

228 229
void Engine::DidCreateIsolate(Dart_Isolate isolate) {
  Internals::Create(isolate,
230 231
                    CreateServiceProvider(config_.service_provider_context),
                    root_bundle_.Pass());
232 233
}

234 235 236 237 238 239 240 241 242
void Engine::StopAnimator() {
  animator_->Stop();
}

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

243
void Engine::ScheduleFrame() {
A
Adam Barth 已提交
244 245 246
  animator_->RequestFrame();
}

247 248 249 250 251 252 253
mojo::NavigatorHost* Engine::NavigatorHost() {
  return this;
}

void Engine::RequestNavigate(mojo::Target target,
                             mojo::URLRequestPtr request) {
  // Ignoring target for now.
254 255 256
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&Engine::RunFromNetwork, GetWeakPtr(), request->url));
257 258 259 260 261
}

void Engine::DidNavigateLocally(const mojo::String& url) {
}

B
Benjamin Lerman 已提交
262 263 264 265
void Engine::RequestNavigateHistory(int32_t delta) {
  NOTIMPLEMENTED();
}

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

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

274
void Engine::SaveFrameToSkPicture(const base::FilePath& destination) {
275 276 277 278
  PassRefPtr<SkPicture> picture = Paint();
  SerializePicture(destination.AsUTF8Unsafe().c_str(), picture.get());
}

279 280
}  // namespace shell
}  // namespace sky