| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sky/shell/ui/engine.h" | 5 #include "sky/shell/ui/engine.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/threading/worker_pool.h" | 9 #include "base/threading/worker_pool.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| 11 #include "mojo/common/data_pipe_utils.h" | 11 #include "mojo/common/data_pipe_utils.h" |
| 12 #include "mojo/public/cpp/application/connect.h" | 12 #include "mojo/public/cpp/application/connect.h" |
| 13 #include "sky/engine/public/platform/WebInputEvent.h" | 13 #include "sky/engine/public/platform/WebInputEvent.h" |
| 14 #include "sky/engine/public/platform/sky_display_metrics.h" | 14 #include "sky/engine/public/platform/sky_display_metrics.h" |
| 15 #include "sky/engine/public/platform/sky_display_metrics.h" | 15 #include "sky/engine/public/platform/sky_display_metrics.h" |
| 16 #include "sky/engine/public/web/Sky.h" | 16 #include "sky/engine/public/web/Sky.h" |
| 17 #include "sky/engine/public/web/WebLocalFrame.h" | |
| 18 #include "sky/engine/public/web/WebSettings.h" | |
| 19 #include "sky/engine/public/web/WebView.h" | |
| 20 #include "sky/services/platform/platform_impl.h" | 17 #include "sky/services/platform/platform_impl.h" |
| 21 #include "sky/shell/dart/dart_library_provider_files.h" | 18 #include "sky/shell/dart/dart_library_provider_files.h" |
| 22 #include "sky/shell/dart/dart_library_provider_network.h" | 19 #include "sky/shell/dart/dart_library_provider_network.h" |
| 23 #include "sky/shell/service_provider.h" | 20 #include "sky/shell/service_provider.h" |
| 24 #include "sky/shell/ui/animator.h" | 21 #include "sky/shell/ui/animator.h" |
| 25 #include "sky/shell/ui/input_event_converter.h" | 22 #include "sky/shell/ui/input_event_converter.h" |
| 26 #include "sky/shell/ui/internals.h" | 23 #include "sky/shell/ui/internals.h" |
| 27 #include "third_party/skia/include/core/SkCanvas.h" | 24 #include "third_party/skia/include/core/SkCanvas.h" |
| 28 #include "third_party/skia/include/core/SkPictureRecorder.h" | 25 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 29 | 26 |
| 30 namespace sky { | 27 namespace sky { |
| 31 namespace shell { | 28 namespace shell { |
| 32 | 29 |
| 33 namespace { | 30 namespace { |
| 34 | 31 |
| 35 void Ignored(bool) { | 32 void Ignored(bool) { |
| 36 } | 33 } |
| 37 | 34 |
| 38 mojo::ScopedDataPipeConsumerHandle Fetch(const base::FilePath& path) { | 35 mojo::ScopedDataPipeConsumerHandle Fetch(const base::FilePath& path) { |
| 39 mojo::DataPipe pipe; | 36 mojo::DataPipe pipe; |
| 40 auto runner = base::WorkerPool::GetTaskRunner(true); | 37 auto runner = base::WorkerPool::GetTaskRunner(true); |
| 41 mojo::common::CopyFromFile(base::FilePath(path), pipe.producer_handle.Pass(), | 38 mojo::common::CopyFromFile(base::FilePath(path), pipe.producer_handle.Pass(), |
| 42 0, runner.get(), base::Bind(&Ignored)); | 39 0, runner.get(), base::Bind(&Ignored)); |
| 43 return pipe.consumer_handle.Pass(); | 40 return pipe.consumer_handle.Pass(); |
| 44 } | 41 } |
| 45 | 42 |
| 46 void ConfigureSettings(blink::WebSettings* settings) { | |
| 47 settings->setDefaultFixedFontSize(13); | |
| 48 settings->setDefaultFontSize(16); | |
| 49 settings->setLoadsImagesAutomatically(true); | |
| 50 } | |
| 51 | |
| 52 PlatformImpl* g_platform_impl = nullptr; | 43 PlatformImpl* g_platform_impl = nullptr; |
| 53 | 44 |
| 54 } | 45 } |
| 55 | 46 |
| 56 Engine::Config::Config() { | 47 Engine::Config::Config() { |
| 57 } | 48 } |
| 58 | 49 |
| 59 Engine::Config::~Config() { | 50 Engine::Config::~Config() { |
| 60 } | 51 } |
| 61 | 52 |
| 62 Engine::Engine(const Config& config) | 53 Engine::Engine(const Config& config) |
| 63 : config_(config), | 54 : config_(config), |
| 64 animator_(new Animator(config, this)), | 55 animator_(new Animator(config, this)), |
| 65 web_view_(nullptr), | |
| 66 device_pixel_ratio_(1.0f), | 56 device_pixel_ratio_(1.0f), |
| 67 viewport_observer_binding_(this), | 57 viewport_observer_binding_(this), |
| 68 weak_factory_(this) { | 58 weak_factory_(this) { |
| 69 } | 59 } |
| 70 | 60 |
| 71 Engine::~Engine() { | 61 Engine::~Engine() { |
| 72 if (web_view_) | |
| 73 web_view_->close(); | |
| 74 } | 62 } |
| 75 | 63 |
| 76 base::WeakPtr<Engine> Engine::GetWeakPtr() { | 64 base::WeakPtr<Engine> Engine::GetWeakPtr() { |
| 77 return weak_factory_.GetWeakPtr(); | 65 return weak_factory_.GetWeakPtr(); |
| 78 } | 66 } |
| 79 | 67 |
| 80 void Engine::Init(ServiceProviderContext* service_provider_context) { | 68 void Engine::Init(ServiceProviderContext* service_provider_context) { |
| 81 TRACE_EVENT0("sky", "Engine::Init"); | 69 TRACE_EVENT0("sky", "Engine::Init"); |
| 82 | 70 |
| 83 mojo::ServiceProviderPtr service_provider = | 71 mojo::ServiceProviderPtr service_provider = |
| 84 CreateServiceProvider(service_provider_context); | 72 CreateServiceProvider(service_provider_context); |
| 85 mojo::NetworkServicePtr network_service; | 73 mojo::NetworkServicePtr network_service; |
| 86 mojo::ConnectToService(service_provider.get(), &network_service); | 74 mojo::ConnectToService(service_provider.get(), &network_service); |
| 87 | 75 |
| 88 DCHECK(!g_platform_impl); | 76 DCHECK(!g_platform_impl); |
| 89 g_platform_impl = new PlatformImpl(network_service.Pass()); | 77 g_platform_impl = new PlatformImpl(network_service.Pass()); |
| 90 blink::initialize(g_platform_impl); | 78 blink::initialize(g_platform_impl); |
| 91 } | 79 } |
| 92 | 80 |
| 93 void Engine::BeginFrame(base::TimeTicks frame_time) { | 81 void Engine::BeginFrame(base::TimeTicks frame_time) { |
| 94 TRACE_EVENT0("sky", "Engine::BeginFrame"); | 82 TRACE_EVENT0("sky", "Engine::BeginFrame"); |
| 95 | 83 |
| 96 if (sky_view_) | 84 if (sky_view_) |
| 97 sky_view_->BeginFrame(frame_time); | 85 sky_view_->BeginFrame(frame_time); |
| 98 | |
| 99 if (web_view_) { | |
| 100 double frame_time_sec = (frame_time - base::TimeTicks()).InSecondsF(); | |
| 101 double deadline_sec = frame_time_sec; | |
| 102 double interval_sec = 1.0 / 60; | |
| 103 blink::WebBeginFrameArgs args(frame_time_sec, deadline_sec, interval_sec); | |
| 104 web_view_->beginFrame(args); | |
| 105 web_view_->layout(); | |
| 106 } | |
| 107 } | 86 } |
| 108 | 87 |
| 109 skia::RefPtr<SkPicture> Engine::Paint() { | 88 skia::RefPtr<SkPicture> Engine::Paint() { |
| 110 TRACE_EVENT0("sky", "Engine::Paint"); | 89 TRACE_EVENT0("sky", "Engine::Paint"); |
| 111 | 90 |
| 112 SkRTreeFactory factory; | 91 SkRTreeFactory factory; |
| 113 SkPictureRecorder recorder; | 92 SkPictureRecorder recorder; |
| 114 auto canvas = skia::SharePtr(recorder.beginRecording( | 93 auto canvas = skia::SharePtr(recorder.beginRecording( |
| 115 physical_size_.width(), physical_size_.height(), &factory, | 94 physical_size_.width(), physical_size_.height(), &factory, |
| 116 SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag)); | 95 SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag)); |
| 117 | 96 |
| 118 if (sky_view_) { | 97 if (sky_view_) { |
| 119 skia::RefPtr<SkPicture> picture = sky_view_->Paint(); | 98 skia::RefPtr<SkPicture> picture = sky_view_->Paint(); |
| 120 canvas->clear(SK_ColorBLACK); | 99 canvas->clear(SK_ColorBLACK); |
| 121 canvas->scale(device_pixel_ratio_, device_pixel_ratio_); | 100 canvas->scale(device_pixel_ratio_, device_pixel_ratio_); |
| 122 if (picture) | 101 if (picture) |
| 123 canvas->drawPicture(picture.get()); | 102 canvas->drawPicture(picture.get()); |
| 124 } | 103 } |
| 125 | 104 |
| 126 if (web_view_) | |
| 127 web_view_->paint(canvas.get(), blink::WebRect(gfx::Rect(physical_size_))); | |
| 128 | |
| 129 return skia::AdoptRef(recorder.endRecordingAsPicture()); | 105 return skia::AdoptRef(recorder.endRecordingAsPicture()); |
| 130 } | 106 } |
| 131 | 107 |
| 132 void Engine::ConnectToViewportObserver( | 108 void Engine::ConnectToViewportObserver( |
| 133 mojo::InterfaceRequest<ViewportObserver> request) { | 109 mojo::InterfaceRequest<ViewportObserver> request) { |
| 134 viewport_observer_binding_.Bind(request.Pass()); | 110 viewport_observer_binding_.Bind(request.Pass()); |
| 135 } | 111 } |
| 136 | 112 |
| 137 void Engine::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) { | 113 void Engine::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) { |
| 138 config_.gpu_task_runner->PostTask( | 114 config_.gpu_task_runner->PostTask( |
| 139 FROM_HERE, base::Bind(&GPUDelegate::OnAcceleratedWidgetAvailable, | 115 FROM_HERE, base::Bind(&GPUDelegate::OnAcceleratedWidgetAvailable, |
| 140 config_.gpu_delegate, widget)); | 116 config_.gpu_delegate, widget)); |
| 141 if (sky_view_) | 117 if (sky_view_) |
| 142 scheduleVisualUpdate(); | 118 ScheduleFrame(); |
| 143 if (web_view_) | |
| 144 scheduleVisualUpdate(); | |
| 145 } | 119 } |
| 146 | 120 |
| 147 void Engine::OnOutputSurfaceDestroyed() { | 121 void Engine::OnOutputSurfaceDestroyed() { |
| 148 config_.gpu_task_runner->PostTask( | 122 config_.gpu_task_runner->PostTask( |
| 149 FROM_HERE, | 123 FROM_HERE, |
| 150 base::Bind(&GPUDelegate::OnOutputSurfaceDestroyed, config_.gpu_delegate)); | 124 base::Bind(&GPUDelegate::OnOutputSurfaceDestroyed, config_.gpu_delegate)); |
| 151 } | 125 } |
| 152 | 126 |
| 153 void Engine::OnViewportMetricsChanged(int width, int height, | 127 void Engine::OnViewportMetricsChanged(int width, int height, |
| 154 float device_pixel_ratio) { | 128 float device_pixel_ratio) { |
| 155 physical_size_.SetSize(width, height); | 129 physical_size_.SetSize(width, height); |
| 156 device_pixel_ratio_ = device_pixel_ratio; | 130 device_pixel_ratio_ = device_pixel_ratio; |
| 157 | 131 |
| 158 if (sky_view_) | 132 if (sky_view_) |
| 159 UpdateSkyViewSize(); | 133 UpdateSkyViewSize(); |
| 160 | |
| 161 if (web_view_) | |
| 162 UpdateWebViewSize(); | |
| 163 } | 134 } |
| 164 | 135 |
| 165 void Engine::UpdateSkyViewSize() { | 136 void Engine::UpdateSkyViewSize() { |
| 166 CHECK(sky_view_); | 137 CHECK(sky_view_); |
| 167 blink::SkyDisplayMetrics metrics; | 138 blink::SkyDisplayMetrics metrics; |
| 168 metrics.physical_size = physical_size_; | 139 metrics.physical_size = physical_size_; |
| 169 metrics.device_pixel_ratio = device_pixel_ratio_; | 140 metrics.device_pixel_ratio = device_pixel_ratio_; |
| 170 sky_view_->SetDisplayMetrics(metrics); | 141 sky_view_->SetDisplayMetrics(metrics); |
| 171 } | 142 } |
| 172 | 143 |
| 173 void Engine::UpdateWebViewSize() { | |
| 174 CHECK(web_view_); | |
| 175 web_view_->setDeviceScaleFactor(device_pixel_ratio_); | |
| 176 gfx::SizeF size = gfx::ScaleSize(physical_size_, 1 / device_pixel_ratio_); | |
| 177 // FIXME: We should be able to set the size of the WebView in floating point | |
| 178 // because its in logical pixels. | |
| 179 web_view_->resize(blink::WebSize(size.width(), size.height())); | |
| 180 } | |
| 181 | |
| 182 // TODO(eseidel): This is likely not needed anymore. | |
| 183 blink::WebScreenInfo Engine::screenInfo() { | |
| 184 blink::WebScreenInfo screen; | |
| 185 screen.rect = blink::WebRect(gfx::Rect(physical_size_)); | |
| 186 screen.availableRect = screen.rect; | |
| 187 screen.deviceScaleFactor = device_pixel_ratio_; | |
| 188 return screen; | |
| 189 } | |
| 190 | |
| 191 void Engine::OnInputEvent(InputEventPtr event) { | 144 void Engine::OnInputEvent(InputEventPtr event) { |
| 192 TRACE_EVENT0("sky", "Engine::OnInputEvent"); | 145 TRACE_EVENT0("sky", "Engine::OnInputEvent"); |
| 193 scoped_ptr<blink::WebInputEvent> web_event = | 146 scoped_ptr<blink::WebInputEvent> web_event = |
| 194 ConvertEvent(event, device_pixel_ratio_); | 147 ConvertEvent(event, device_pixel_ratio_); |
| 195 if (!web_event) | 148 if (!web_event) |
| 196 return; | 149 return; |
| 197 if (sky_view_) | 150 if (sky_view_) |
| 198 sky_view_->HandleInputEvent(*web_event); | 151 sky_view_->HandleInputEvent(*web_event); |
| 199 if (web_view_) | |
| 200 web_view_->handleInputEvent(*web_event); | |
| 201 } | |
| 202 | |
| 203 void Engine::CloseWebViewIfNeeded() { | |
| 204 if (web_view_) { | |
| 205 web_view_->close(); | |
| 206 web_view_ = nullptr; | |
| 207 } | |
| 208 } | 152 } |
| 209 | 153 |
| 210 void Engine::RunFromLibrary(const mojo::String& name) { | 154 void Engine::RunFromLibrary(const mojo::String& name) { |
| 211 CloseWebViewIfNeeded(); | |
| 212 sky_view_ = blink::SkyView::Create(this); | 155 sky_view_ = blink::SkyView::Create(this); |
| 213 sky_view_->RunFromLibrary(blink::WebString::fromUTF8(name), | 156 sky_view_->RunFromLibrary(blink::WebString::fromUTF8(name), |
| 214 dart_library_provider_.get()); | 157 dart_library_provider_.get()); |
| 215 UpdateSkyViewSize(); | 158 UpdateSkyViewSize(); |
| 216 } | 159 } |
| 217 | 160 |
| 218 void Engine::RunFromNetwork(const mojo::String& url) { | 161 void Engine::RunFromNetwork(const mojo::String& url) { |
| 219 if (blink::WebView::shouldUseWebView(GURL(url))) { | |
| 220 LoadUsingWebView(url); | |
| 221 return; | |
| 222 } | |
| 223 dart_library_provider_.reset( | 162 dart_library_provider_.reset( |
| 224 new DartLibraryProviderNetwork(g_platform_impl->networkService())); | 163 new DartLibraryProviderNetwork(g_platform_impl->networkService())); |
| 225 RunFromLibrary(url); | 164 RunFromLibrary(url); |
| 226 } | 165 } |
| 227 | 166 |
| 228 void Engine::RunFromFile(const mojo::String& main, | 167 void Engine::RunFromFile(const mojo::String& main, |
| 229 const mojo::String& package_root) { | 168 const mojo::String& package_root) { |
| 230 dart_library_provider_.reset( | 169 dart_library_provider_.reset( |
| 231 new DartLibraryProviderFiles(base::FilePath(package_root))); | 170 new DartLibraryProviderFiles(base::FilePath(package_root))); |
| 232 RunFromLibrary(main); | 171 RunFromLibrary(main); |
| 233 } | 172 } |
| 234 | 173 |
| 235 void Engine::RunFromSnapshot(const mojo::String& path) { | 174 void Engine::RunFromSnapshot(const mojo::String& path) { |
| 236 CloseWebViewIfNeeded(); | |
| 237 sky_view_ = blink::SkyView::Create(this); | 175 sky_view_ = blink::SkyView::Create(this); |
| 238 sky_view_->RunFromSnapshot(blink::WebString::fromUTF8(path), | 176 sky_view_->RunFromSnapshot(blink::WebString::fromUTF8(path), |
| 239 Fetch(base::FilePath(path))); | 177 Fetch(base::FilePath(path))); |
| 240 UpdateSkyViewSize(); | 178 UpdateSkyViewSize(); |
| 241 } | 179 } |
| 242 | 180 |
| 243 void Engine::LoadUsingWebView(const mojo::String& mojo_url) { | |
| 244 GURL url(mojo_url); | |
| 245 DCHECK(blink::WebView::shouldUseWebView(url)); | |
| 246 | |
| 247 if (sky_view_) | |
| 248 sky_view_ = nullptr; | |
| 249 | |
| 250 LOG(WARNING) << ".sky support is deprecated, please use .dart for main()"; | |
| 251 | |
| 252 // Something bad happens if you try to call WebView::close and replace | |
| 253 // the webview. So for now we just load into the existing one. :/ | |
| 254 if (!web_view_) | |
| 255 web_view_ = blink::WebView::create(this); | |
| 256 ConfigureSettings(web_view_->settings()); | |
| 257 web_view_->setMainFrame(blink::WebLocalFrame::create(this)); | |
| 258 UpdateWebViewSize(); | |
| 259 web_view_->mainFrame()->load(url); | |
| 260 } | |
| 261 | |
| 262 void Engine::frameDetached(blink::WebFrame* frame) { | |
| 263 // |frame| is invalid after here. | |
| 264 frame->close(); | |
| 265 } | |
| 266 | |
| 267 void Engine::initializeLayerTreeView() { | |
| 268 } | |
| 269 | |
| 270 void Engine::scheduleVisualUpdate() { | |
| 271 animator_->RequestFrame(); | |
| 272 } | |
| 273 | |
| 274 void Engine::didCreateIsolate(blink::WebLocalFrame* frame, | |
| 275 Dart_Isolate isolate) { | |
| 276 Internals::Create(isolate, | |
| 277 CreateServiceProvider(config_.service_provider_context)); | |
| 278 } | |
| 279 | |
| 280 void Engine::DidCreateIsolate(Dart_Isolate isolate) { | 181 void Engine::DidCreateIsolate(Dart_Isolate isolate) { |
| 281 Internals::Create(isolate, | 182 Internals::Create(isolate, |
| 282 CreateServiceProvider(config_.service_provider_context)); | 183 CreateServiceProvider(config_.service_provider_context)); |
| 283 } | 184 } |
| 284 | 185 |
| 285 void Engine::ScheduleFrame() { | 186 void Engine::ScheduleFrame() { |
| 286 animator_->RequestFrame(); | 187 animator_->RequestFrame(); |
| 287 } | 188 } |
| 288 | 189 |
| 289 blink::ServiceProvider* Engine::services() { | |
| 290 return this; | |
| 291 } | |
| 292 | |
| 293 mojo::NavigatorHost* Engine::NavigatorHost() { | 190 mojo::NavigatorHost* Engine::NavigatorHost() { |
| 294 return this; | 191 return this; |
| 295 } | 192 } |
| 296 | 193 |
| 297 void Engine::RequestNavigate(mojo::Target target, | 194 void Engine::RequestNavigate(mojo::Target target, |
| 298 mojo::URLRequestPtr request) { | 195 mojo::URLRequestPtr request) { |
| 299 // Ignoring target for now. | 196 // Ignoring target for now. |
| 300 base::MessageLoop::current()->PostTask( | 197 base::MessageLoop::current()->PostTask( |
| 301 FROM_HERE, | 198 FROM_HERE, |
| 302 base::Bind(&Engine::RunFromNetwork, GetWeakPtr(), request->url)); | 199 base::Bind(&Engine::RunFromNetwork, GetWeakPtr(), request->url)); |
| 303 } | 200 } |
| 304 | 201 |
| 305 void Engine::DidNavigateLocally(const mojo::String& url) { | 202 void Engine::DidNavigateLocally(const mojo::String& url) { |
| 306 } | 203 } |
| 307 | 204 |
| 308 void Engine::RequestNavigateHistory(int32_t delta) { | 205 void Engine::RequestNavigateHistory(int32_t delta) { |
| 309 NOTIMPLEMENTED(); | 206 NOTIMPLEMENTED(); |
| 310 } | 207 } |
| 311 | 208 |
| 312 } // namespace shell | 209 } // namespace shell |
| 313 } // namespace sky | 210 } // namespace sky |
| OLD | NEW |