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 |