OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/browser/renderer_host/image_transport_factory.h" | 5 #include "content/browser/renderer_host/image_transport_factory.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/memory/ref_counted.h" | 12 #include "base/memory/ref_counted.h" |
13 #include "base/observer_list.h" | 13 #include "base/observer_list.h" |
| 14 #include "base/threading/non_thread_safe.h" |
14 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" | 15 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" |
15 #include "content/browser/gpu/gpu_data_manager_impl.h" | 16 #include "content/browser/gpu/gpu_data_manager_impl.h" |
| 17 #include "content/browser/gpu/gpu_process_host.h" |
16 #include "content/browser/gpu/gpu_surface_tracker.h" | 18 #include "content/browser/gpu/gpu_surface_tracker.h" |
17 #include "content/common/gpu/client/gl_helper.h" | 19 #include "content/common/gpu/client/gl_helper.h" |
18 #include "content/common/gpu/client/gpu_channel_host.h" | 20 #include "content/common/gpu/client/gpu_channel_host.h" |
19 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" | 21 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
| 22 #include "content/common/gpu/gpu_messages.h" |
20 #include "content/common/gpu/gpu_process_launch_causes.h" | 23 #include "content/common/gpu/gpu_process_launch_causes.h" |
21 #include "content/common/webkitplatformsupport_impl.h" | 24 #include "content/common/webkitplatformsupport_impl.h" |
22 #include "content/public/common/content_switches.h" | 25 #include "content/public/common/content_switches.h" |
23 #include "gpu/ipc/command_buffer_proxy.h" | 26 #include "gpu/ipc/command_buffer_proxy.h" |
| 27 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutput
Surface.h" |
| 28 #include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorOutput
SurfaceClient.h" |
24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGraphicsC
ontext3D.h" | 29 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebGraphicsC
ontext3D.h" |
25 #include "ui/compositor/compositor.h" | 30 #include "ui/compositor/compositor.h" |
26 #include "ui/compositor/compositor_setup.h" | 31 #include "ui/compositor/compositor_setup.h" |
27 #include "ui/compositor/test_web_graphics_context_3d.h" | 32 #include "ui/compositor/test_web_graphics_context_3d.h" |
28 #include "ui/gfx/native_widget_types.h" | 33 #include "ui/gfx/native_widget_types.h" |
29 #include "ui/gfx/size.h" | 34 #include "ui/gfx/size.h" |
30 | 35 |
31 #if defined(OS_WIN) | 36 #if defined(OS_WIN) |
32 #include "ui/surface/accelerated_surface_win.h" | 37 #include "ui/surface/accelerated_surface_win.h" |
33 #endif | 38 #endif |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 } | 212 } |
208 | 213 |
209 private: | 214 private: |
210 void OnLostContext(); | 215 void OnLostContext(); |
211 ui::Compositor* compositor_; | 216 ui::Compositor* compositor_; |
212 GpuProcessTransportFactory* factory_; | 217 GpuProcessTransportFactory* factory_; |
213 | 218 |
214 DISALLOW_COPY_AND_ASSIGN(CompositorSwapClient); | 219 DISALLOW_COPY_AND_ASSIGN(CompositorSwapClient); |
215 }; | 220 }; |
216 | 221 |
| 222 class BrowserCompositorOutputSurface; |
| 223 |
| 224 // Directs vsync updates to the appropriate BrowserCompositorOutputSurface. |
| 225 class BrowserCompositorOutputSurfaceProxy : |
| 226 public base::RefCountedThreadSafe<BrowserCompositorOutputSurfaceProxy> { |
| 227 public: |
| 228 BrowserCompositorOutputSurfaceProxy() |
| 229 : message_handler_set_(false) { |
| 230 } |
| 231 |
| 232 void AddSurface(BrowserCompositorOutputSurface* surface, int surface_id) { |
| 233 if (!message_handler_set_) { |
| 234 uint32 messages_to_filter[] = {GpuHostMsg_UpdateVSyncParameters::ID}; |
| 235 BrowserGpuChannelHostFactory::instance()->SetHandlerForControlMessages( |
| 236 messages_to_filter, |
| 237 arraysize(messages_to_filter), |
| 238 base::Bind(&BrowserCompositorOutputSurfaceProxy::OnMessageReceived, |
| 239 this), |
| 240 MessageLoop::current()->message_loop_proxy()); |
| 241 message_handler_set_ = true; |
| 242 } |
| 243 surface_map_.AddWithID(surface, surface_id); |
| 244 } |
| 245 |
| 246 void RemoveSurface(int surface_id) { |
| 247 surface_map_.Remove(surface_id); |
| 248 } |
| 249 |
| 250 private: |
| 251 void OnMessageReceived(const IPC::Message& message) { |
| 252 IPC_BEGIN_MESSAGE_MAP(BrowserCompositorOutputSurfaceProxy, message) |
| 253 IPC_MESSAGE_HANDLER(GpuHostMsg_UpdateVSyncParameters, |
| 254 OnUpdateVSyncParameters); |
| 255 IPC_END_MESSAGE_MAP() |
| 256 } |
| 257 |
| 258 void OnUpdateVSyncParameters(int surface_id, |
| 259 base::TimeTicks timebase, |
| 260 base::TimeDelta interval); |
| 261 |
| 262 friend class |
| 263 base::RefCountedThreadSafe<BrowserCompositorOutputSurfaceProxy>; |
| 264 ~BrowserCompositorOutputSurfaceProxy() {} |
| 265 IDMap<BrowserCompositorOutputSurface> surface_map_; |
| 266 bool message_handler_set_; |
| 267 |
| 268 DISALLOW_COPY_AND_ASSIGN(BrowserCompositorOutputSurfaceProxy); |
| 269 }; |
| 270 |
| 271 |
| 272 // Adapts a WebGraphicsContext3DCommandBufferImpl into a |
| 273 // WebCompositorOutputSurface that also handles vsync parameter updates |
| 274 // arriving from the GPU process. |
| 275 class BrowserCompositorOutputSurface : |
| 276 public WebKit::WebCompositorOutputSurface, |
| 277 public base::NonThreadSafe { |
| 278 public: |
| 279 explicit BrowserCompositorOutputSurface( |
| 280 WebGraphicsContext3DCommandBufferImpl* context, |
| 281 int surface_id, |
| 282 BrowserCompositorOutputSurfaceProxy* output_surface_proxy) |
| 283 : context3D_(context), |
| 284 surface_id_(surface_id), |
| 285 client_(NULL), |
| 286 output_surface_proxy_(output_surface_proxy) { |
| 287 DetachFromThread(); |
| 288 } |
| 289 |
| 290 virtual ~BrowserCompositorOutputSurface() { |
| 291 DCHECK(CalledOnValidThread()); |
| 292 if (!client_) |
| 293 return; |
| 294 output_surface_proxy_->RemoveSurface(surface_id_); |
| 295 } |
| 296 |
| 297 virtual bool bindToClient( |
| 298 WebKit::WebCompositorOutputSurfaceClient* client) OVERRIDE { |
| 299 DCHECK(CalledOnValidThread()); |
| 300 DCHECK(client); |
| 301 DCHECK(!client_); |
| 302 if (context3D_.get()) { |
| 303 if (!context3D_->makeContextCurrent()) |
| 304 return false; |
| 305 } |
| 306 |
| 307 client_ = client; |
| 308 output_surface_proxy_->AddSurface(this, surface_id_); |
| 309 return true; |
| 310 } |
| 311 |
| 312 virtual const Capabilities& capabilities() const OVERRIDE { |
| 313 DCHECK(CalledOnValidThread()); |
| 314 return capabilities_; |
| 315 } |
| 316 |
| 317 virtual WebKit::WebGraphicsContext3D* context3D() const OVERRIDE { |
| 318 DCHECK(CalledOnValidThread()); |
| 319 return context3D_.get(); |
| 320 } |
| 321 |
| 322 virtual void sendFrameToParentCompositor( |
| 323 const WebKit::WebCompositorFrame&) OVERRIDE { |
| 324 } |
| 325 |
| 326 void OnUpdateVSyncParameters( |
| 327 base::TimeTicks timebase, base::TimeDelta interval) { |
| 328 DCHECK(CalledOnValidThread()); |
| 329 DCHECK(client_); |
| 330 double monotonicTimebase = timebase.ToInternalValue() / |
| 331 static_cast<double>(base::Time::kMicrosecondsPerSecond); |
| 332 double intervalInSeconds = interval.ToInternalValue() / |
| 333 static_cast<double>(base::Time::kMicrosecondsPerSecond); |
| 334 client_->onVSyncParametersChanged(monotonicTimebase, intervalInSeconds); |
| 335 } |
| 336 |
| 337 private: |
| 338 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context3D_; |
| 339 int surface_id_; |
| 340 Capabilities capabilities_; |
| 341 WebKit::WebCompositorOutputSurfaceClient* client_; |
| 342 scoped_refptr<BrowserCompositorOutputSurfaceProxy> output_surface_proxy_; |
| 343 }; |
| 344 |
| 345 void BrowserCompositorOutputSurfaceProxy::OnUpdateVSyncParameters( |
| 346 int surface_id, base::TimeTicks timebase, base::TimeDelta interval) { |
| 347 BrowserCompositorOutputSurface* surface = surface_map_.Lookup(surface_id); |
| 348 if (surface) |
| 349 surface->OnUpdateVSyncParameters(timebase, interval); |
| 350 } |
| 351 |
217 class GpuProcessTransportFactory : | 352 class GpuProcessTransportFactory : |
218 public ui::ContextFactory, | 353 public ui::ContextFactory, |
219 public ImageTransportFactory, | 354 public ImageTransportFactory, |
220 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { | 355 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { |
221 public: | 356 public: |
222 GpuProcessTransportFactory() | 357 GpuProcessTransportFactory() |
223 : ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { | 358 : ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { |
| 359 output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy(); |
224 } | 360 } |
225 | 361 |
226 virtual ~GpuProcessTransportFactory() { | 362 virtual ~GpuProcessTransportFactory() { |
227 DCHECK(per_compositor_data_.empty()); | 363 DCHECK(per_compositor_data_.empty()); |
228 } | 364 } |
229 | 365 |
230 virtual WebKit::WebGraphicsContext3D* CreateContext( | |
231 ui::Compositor* compositor) OVERRIDE { | |
232 PerCompositorData* data = per_compositor_data_[compositor]; | |
233 if (!data) | |
234 data = CreatePerCompositorData(compositor); | |
235 return CreateContextCommon(data->swap_client->AsWeakPtr(), | |
236 data->surface_id); | |
237 } | |
238 | |
239 virtual WebGraphicsContext3DCommandBufferImpl* CreateOffscreenContext() | 366 virtual WebGraphicsContext3DCommandBufferImpl* CreateOffscreenContext() |
240 OVERRIDE { | 367 OVERRIDE { |
241 base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client; | 368 base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client; |
242 return CreateContextCommon(swap_client, 0); | 369 return CreateContextCommon(swap_client, 0); |
243 } | 370 } |
244 | 371 |
| 372 virtual WebKit::WebCompositorOutputSurface* CreateOutputSurface( |
| 373 ui::Compositor* compositor) OVERRIDE { |
| 374 PerCompositorData* data = per_compositor_data_[compositor]; |
| 375 if (!data) |
| 376 data = CreatePerCompositorData(compositor); |
| 377 WebGraphicsContext3DCommandBufferImpl* context = |
| 378 CreateContextCommon(data->swap_client->AsWeakPtr(), |
| 379 data->surface_id); |
| 380 return new BrowserCompositorOutputSurface( |
| 381 context, |
| 382 per_compositor_data_[compositor]->surface_id, |
| 383 output_surface_proxy_); |
| 384 } |
| 385 |
245 virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE { | 386 virtual void RemoveCompositor(ui::Compositor* compositor) OVERRIDE { |
246 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); | 387 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); |
247 if (it == per_compositor_data_.end()) | 388 if (it == per_compositor_data_.end()) |
248 return; | 389 return; |
249 PerCompositorData* data = it->second; | 390 PerCompositorData* data = it->second; |
250 DCHECK(data); | 391 DCHECK(data); |
251 GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id); | 392 GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id); |
252 delete data; | 393 delete data; |
253 per_compositor_data_.erase(it); | 394 per_compositor_data_.erase(it); |
254 if (per_compositor_data_.empty()) { | 395 if (per_compositor_data_.empty()) { |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 observer_list_, | 596 observer_list_, |
456 OnLostResources()); | 597 OnLostResources()); |
457 } | 598 } |
458 | 599 |
459 typedef std::map<ui::Compositor*, PerCompositorData*> PerCompositorDataMap; | 600 typedef std::map<ui::Compositor*, PerCompositorData*> PerCompositorDataMap; |
460 PerCompositorDataMap per_compositor_data_; | 601 PerCompositorDataMap per_compositor_data_; |
461 scoped_ptr<GLHelper> gl_helper_; | 602 scoped_ptr<GLHelper> gl_helper_; |
462 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> shared_context_; | 603 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> shared_context_; |
463 ObserverList<ImageTransportFactoryObserver> observer_list_; | 604 ObserverList<ImageTransportFactoryObserver> observer_list_; |
464 base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_; | 605 base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_; |
| 606 scoped_refptr<BrowserCompositorOutputSurfaceProxy> output_surface_proxy_; |
465 | 607 |
466 DISALLOW_COPY_AND_ASSIGN(GpuProcessTransportFactory); | 608 DISALLOW_COPY_AND_ASSIGN(GpuProcessTransportFactory); |
467 }; | 609 }; |
468 | 610 |
469 void CompositorSwapClient::OnLostContext() { | 611 void CompositorSwapClient::OnLostContext() { |
470 factory_->OnLostContext(compositor_); | 612 factory_->OnLostContext(compositor_); |
471 // Note: previous line destroyed this. Don't access members from now on. | 613 // Note: previous line destroyed this. Don't access members from now on. |
472 } | 614 } |
473 | 615 |
474 WebKit::WebGraphicsContext3D* CreateTestContext() { | 616 WebKit::WebGraphicsContext3D* CreateTestContext() { |
(...skipping 27 matching lines...) Expand all Loading... |
502 delete g_factory; | 644 delete g_factory; |
503 g_factory = NULL; | 645 g_factory = NULL; |
504 } | 646 } |
505 | 647 |
506 // static | 648 // static |
507 ImageTransportFactory* ImageTransportFactory::GetInstance() { | 649 ImageTransportFactory* ImageTransportFactory::GetInstance() { |
508 return g_factory; | 650 return g_factory; |
509 } | 651 } |
510 | 652 |
511 } // namespace content | 653 } // namespace content |
OLD | NEW |