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/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/observer_list.h" | 14 #include "base/observer_list.h" |
15 #include "base/threading/non_thread_safe.h" | 15 #include "base/threading/non_thread_safe.h" |
16 #include "cc/output_surface.h" | 16 #include "cc/output_surface.h" |
17 #include "cc/output_surface_client.h" | 17 #include "cc/output_surface_client.h" |
18 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" | 18 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" |
19 #include "content/browser/gpu/gpu_data_manager_impl.h" | 19 #include "content/browser/gpu/gpu_data_manager_impl.h" |
20 #include "content/browser/gpu/gpu_process_host.h" | 20 #include "content/browser/gpu/gpu_process_host.h" |
21 #include "content/browser/gpu/gpu_surface_tracker.h" | 21 #include "content/browser/gpu/gpu_surface_tracker.h" |
| 22 #include "content/common/gpu/client/context_provider_command_buffer.h" |
22 #include "content/common/gpu/client/gl_helper.h" | 23 #include "content/common/gpu/client/gl_helper.h" |
23 #include "content/common/gpu/client/gpu_channel_host.h" | 24 #include "content/common/gpu/client/gpu_channel_host.h" |
24 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" | 25 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" |
25 #include "content/common/gpu/gpu_messages.h" | 26 #include "content/common/gpu/gpu_messages.h" |
26 #include "content/common/gpu/gpu_process_launch_causes.h" | 27 #include "content/common/gpu/gpu_process_launch_causes.h" |
27 #include "content/common/webkitplatformsupport_impl.h" | 28 #include "content/common/webkitplatformsupport_impl.h" |
28 #include "content/public/common/content_switches.h" | 29 #include "content/public/common/content_switches.h" |
29 #include "gpu/GLES2/gl2extchromium.h" | 30 #include "gpu/GLES2/gl2extchromium.h" |
30 #include "gpu/ipc/command_buffer_proxy.h" | 31 #include "gpu/ipc/command_buffer_proxy.h" |
31 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3
D.h" | |
32 #include "third_party/khronos/GLES2/gl2.h" | 32 #include "third_party/khronos/GLES2/gl2.h" |
33 #include "third_party/khronos/GLES2/gl2ext.h" | 33 #include "third_party/khronos/GLES2/gl2ext.h" |
34 #include "ui/compositor/compositor.h" | 34 #include "ui/compositor/compositor.h" |
35 #include "ui/compositor/compositor_setup.h" | 35 #include "ui/compositor/compositor_setup.h" |
36 #include "ui/compositor/test_web_graphics_context_3d.h" | 36 #include "ui/compositor/test_web_graphics_context_3d.h" |
37 #include "ui/gfx/native_widget_types.h" | 37 #include "ui/gfx/native_widget_types.h" |
38 #include "ui/gfx/size.h" | 38 #include "ui/gfx/size.h" |
39 | 39 |
40 #if defined(OS_WIN) | 40 #if defined(OS_WIN) |
41 #include "ui/surface/accelerated_surface_win.h" | 41 #include "ui/surface/accelerated_surface_win.h" |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 | 344 |
345 void BrowserCompositorOutputSurfaceProxy::OnUpdateVSyncParameters( | 345 void BrowserCompositorOutputSurfaceProxy::OnUpdateVSyncParameters( |
346 int surface_id, base::TimeTicks timebase, base::TimeDelta interval) { | 346 int surface_id, base::TimeTicks timebase, base::TimeDelta interval) { |
347 BrowserCompositorOutputSurface* surface = surface_map_.Lookup(surface_id); | 347 BrowserCompositorOutputSurface* surface = surface_map_.Lookup(surface_id); |
348 if (surface) | 348 if (surface) |
349 surface->OnUpdateVSyncParameters(timebase, interval); | 349 surface->OnUpdateVSyncParameters(timebase, interval); |
350 } | 350 } |
351 | 351 |
352 class GpuProcessTransportFactory | 352 class GpuProcessTransportFactory |
353 : public ui::ContextFactory, | 353 : public ui::ContextFactory, |
354 public ImageTransportFactory, | 354 public ImageTransportFactory { |
355 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { | |
356 public: | 355 public: |
357 GpuProcessTransportFactory() | 356 GpuProcessTransportFactory() |
358 : ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { | 357 : ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { |
359 output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy(); | 358 output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy(); |
360 } | 359 } |
361 | 360 |
362 virtual ~GpuProcessTransportFactory() { | 361 virtual ~GpuProcessTransportFactory() { |
363 DCHECK(per_compositor_data_.empty()); | 362 DCHECK(per_compositor_data_.empty()); |
364 } | 363 } |
365 | 364 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
401 } | 400 } |
402 | 401 |
403 virtual ui::ContextFactory* AsContextFactory() OVERRIDE { | 402 virtual ui::ContextFactory* AsContextFactory() OVERRIDE { |
404 return this; | 403 return this; |
405 } | 404 } |
406 | 405 |
407 virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle() OVERRIDE { | 406 virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle() OVERRIDE { |
408 CreateSharedContextLazy(); | 407 CreateSharedContextLazy(); |
409 gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle( | 408 gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle( |
410 gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT); | 409 gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT); |
411 handle.parent_gpu_process_id = shared_context_->GetGPUProcessID(); | 410 handle.parent_gpu_process_id = |
412 handle.parent_client_id = shared_context_->GetChannelID(); | 411 shared_contexts_main_thread_->Context3d()->GetGPUProcessID(); |
413 | 412 handle.parent_client_id = |
| 413 shared_contexts_main_thread_->Context3d()->GetChannelID(); |
414 return handle; | 414 return handle; |
415 } | 415 } |
416 | 416 |
417 virtual void DestroySharedSurfaceHandle( | 417 virtual void DestroySharedSurfaceHandle( |
418 gfx::GLSurfaceHandle surface) OVERRIDE { | 418 gfx::GLSurfaceHandle surface) OVERRIDE { |
419 } | 419 } |
420 | 420 |
421 virtual scoped_refptr<ui::Texture> CreateTransportClient( | 421 virtual scoped_refptr<ui::Texture> CreateTransportClient( |
422 float device_scale_factor) OVERRIDE { | 422 float device_scale_factor) OVERRIDE { |
423 if (!shared_context_.get()) | 423 if (!shared_contexts_main_thread_) |
424 return NULL; | 424 return NULL; |
425 scoped_refptr<ImageTransportClientTexture> image( | 425 scoped_refptr<ImageTransportClientTexture> image( |
426 new ImageTransportClientTexture(shared_context_.get(), | 426 new ImageTransportClientTexture( |
427 device_scale_factor)); | 427 shared_contexts_main_thread_->Context3d(), |
| 428 device_scale_factor)); |
428 return image; | 429 return image; |
429 } | 430 } |
430 | 431 |
431 virtual scoped_refptr<ui::Texture> CreateOwnedTexture( | 432 virtual scoped_refptr<ui::Texture> CreateOwnedTexture( |
432 const gfx::Size& size, | 433 const gfx::Size& size, |
433 float device_scale_factor, | 434 float device_scale_factor, |
434 unsigned int texture_id) OVERRIDE { | 435 unsigned int texture_id) OVERRIDE { |
435 if (!shared_context_.get()) | 436 if (!shared_contexts_main_thread_) |
436 return NULL; | 437 return NULL; |
437 scoped_refptr<OwnedTexture> image( | 438 scoped_refptr<OwnedTexture> image(new OwnedTexture( |
438 new OwnedTexture(shared_context_.get(), size, device_scale_factor, | 439 shared_contexts_main_thread_->Context3d(), |
439 texture_id)); | 440 size, |
| 441 device_scale_factor, |
| 442 texture_id)); |
440 return image; | 443 return image; |
441 } | 444 } |
442 | 445 |
443 virtual GLHelper* GetGLHelper() OVERRIDE { | 446 virtual GLHelper* GetGLHelper() OVERRIDE { |
444 if (!gl_helper_.get()) { | 447 if (!gl_helper_.get()) { |
445 CreateSharedContextLazy(); | 448 CreateSharedContextLazy(); |
| 449 WebKit::WebGraphicsContext3D* context_for_main_thread = |
| 450 shared_contexts_main_thread_->Context3d(); |
446 WebKit::WebGraphicsContext3D* context_for_thread = | 451 WebKit::WebGraphicsContext3D* context_for_thread = |
447 CreateOffscreenContext(); | 452 CreateOffscreenContext(); |
448 if (!context_for_thread) | 453 if (!context_for_thread) |
449 return NULL; | 454 return NULL; |
450 gl_helper_.reset(new GLHelper(shared_context_.get(), | 455 |
| 456 gl_helper_.reset(new GLHelper(context_for_main_thread, |
451 context_for_thread)); | 457 context_for_thread)); |
452 } | 458 } |
453 return gl_helper_.get(); | 459 return gl_helper_.get(); |
454 } | 460 } |
455 | 461 |
456 virtual uint32 InsertSyncPoint() OVERRIDE { | 462 virtual uint32 InsertSyncPoint() OVERRIDE { |
457 if (!shared_context_.get()) | 463 if (!shared_contexts_main_thread_) |
458 return 0; | 464 return 0; |
459 return shared_context_->insertSyncPoint(); | 465 return shared_contexts_main_thread_->Context3d()->insertSyncPoint(); |
460 } | 466 } |
461 | 467 |
462 virtual void AddObserver(ImageTransportFactoryObserver* observer) OVERRIDE { | 468 virtual void AddObserver(ImageTransportFactoryObserver* observer) OVERRIDE { |
463 observer_list_.AddObserver(observer); | 469 observer_list_.AddObserver(observer); |
464 } | 470 } |
465 | 471 |
466 virtual void RemoveObserver( | 472 virtual void RemoveObserver( |
467 ImageTransportFactoryObserver* observer) OVERRIDE { | 473 ImageTransportFactoryObserver* observer) OVERRIDE { |
468 observer_list_.RemoveObserver(observer); | 474 observer_list_.RemoveObserver(observer); |
469 } | 475 } |
470 | 476 |
471 // WebGraphicsContextLostCallback implementation, called for the shared | |
472 // context. | |
473 virtual void onContextLost() { | |
474 MessageLoop::current()->PostTask( | |
475 FROM_HERE, | |
476 base::Bind(&GpuProcessTransportFactory::OnLostSharedContext, | |
477 callback_factory_.GetWeakPtr())); | |
478 } | |
479 | |
480 void OnLostContext(ui::Compositor* compositor) { | 477 void OnLostContext(ui::Compositor* compositor) { |
481 LOG(ERROR) << "Lost UI compositor context."; | 478 LOG(ERROR) << "Lost UI compositor context."; |
482 PerCompositorData* data = per_compositor_data_[compositor]; | 479 PerCompositorData* data = per_compositor_data_[compositor]; |
483 DCHECK(data); | 480 DCHECK(data); |
484 | 481 |
485 // Prevent callbacks from other contexts in the same share group from | 482 // Prevent callbacks from other contexts in the same share group from |
486 // calling us again. | 483 // calling us again. |
487 data->swap_client.reset(new CompositorSwapClient(compositor, this)); | 484 data->swap_client.reset(new CompositorSwapClient(compositor, this)); |
488 compositor->OnSwapBuffersAborted(); | 485 compositor->OnSwapBuffersAborted(); |
489 } | 486 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 factory, | 536 factory, |
540 swap_client)); | 537 swap_client)); |
541 if (!context->Initialize( | 538 if (!context->Initialize( |
542 attrs, | 539 attrs, |
543 false, | 540 false, |
544 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) | 541 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) |
545 return NULL; | 542 return NULL; |
546 return context.release(); | 543 return context.release(); |
547 } | 544 } |
548 | 545 |
| 546 class MainThreadContextProvider : public ContextProviderCommandBuffer { |
| 547 public: |
| 548 explicit MainThreadContextProvider(GpuProcessTransportFactory* factory) |
| 549 : factory_(factory) {} |
| 550 |
| 551 protected: |
| 552 virtual ~MainThreadContextProvider() {} |
| 553 |
| 554 virtual scoped_ptr<WebGraphicsContext3DCommandBufferImpl> |
| 555 CreateOffscreenContext3d() { |
| 556 return make_scoped_ptr(factory_->CreateOffscreenContext()); |
| 557 } |
| 558 |
| 559 virtual void OnLostContext() OVERRIDE { |
| 560 ContextProviderCommandBuffer::OnLostContext(); |
| 561 |
| 562 MessageLoop::current()->PostTask( |
| 563 FROM_HERE, |
| 564 base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext, |
| 565 factory_->callback_factory_.GetWeakPtr())); |
| 566 } |
| 567 |
| 568 private: |
| 569 GpuProcessTransportFactory* factory_; |
| 570 }; |
| 571 |
| 572 virtual scoped_refptr<ui::ContextProvider> |
| 573 OffscreenContextProviderForMainThread() OVERRIDE { |
| 574 if (!shared_contexts_main_thread_ || |
| 575 shared_contexts_main_thread_->destroyed()) { |
| 576 shared_contexts_main_thread_ = new MainThreadContextProvider(this); |
| 577 } |
| 578 return shared_contexts_main_thread_; |
| 579 } |
| 580 |
| 581 class CompositorThreadContextProvider : public ContextProviderCommandBuffer { |
| 582 public: |
| 583 explicit CompositorThreadContextProvider( |
| 584 GpuProcessTransportFactory* factory) : factory_(factory) {} |
| 585 |
| 586 protected: |
| 587 virtual ~CompositorThreadContextProvider() {} |
| 588 |
| 589 virtual scoped_ptr<WebGraphicsContext3DCommandBufferImpl> |
| 590 CreateOffscreenContext3d() { |
| 591 return make_scoped_ptr(factory_->CreateOffscreenContext()); |
| 592 } |
| 593 |
| 594 private: |
| 595 GpuProcessTransportFactory* factory_; |
| 596 }; |
| 597 |
| 598 virtual scoped_refptr<ui::ContextProvider> |
| 599 OffscreenContextProviderForCompositorThread() OVERRIDE { |
| 600 if (!shared_contexts_compositor_thread_ || |
| 601 shared_contexts_compositor_thread_->destroyed()) { |
| 602 shared_contexts_compositor_thread_ = |
| 603 new CompositorThreadContextProvider(this); |
| 604 } |
| 605 return shared_contexts_compositor_thread_; |
| 606 } |
| 607 |
549 void CreateSharedContextLazy() { | 608 void CreateSharedContextLazy() { |
550 if (shared_context_.get()) | 609 scoped_refptr<ui::ContextProvider> provider = |
551 return; | 610 OffscreenContextProviderForMainThread(); |
552 | 611 if (!provider->InitializeOnMainThread()) { |
553 shared_context_.reset(CreateOffscreenContext()); | 612 // If we can't recreate contexts, we won't be able to show the UI. |
554 if (!shared_context_.get()) { | 613 // Better crash at this point. |
555 // If we can't recreate contexts, we won't be able to show the UI. Better | |
556 // crash at this point. | |
557 LOG(FATAL) << "Failed to initialize UI shared context."; | 614 LOG(FATAL) << "Failed to initialize UI shared context."; |
558 } | 615 } |
559 if (!shared_context_->makeContextCurrent()) { | 616 if (!provider->BindToCurrentThread()) { |
560 // If we can't recreate contexts, we won't be able to show the UI. Better | 617 // If we can't recreate contexts, we won't be able to show the UI. |
561 // crash at this point. | 618 // Better crash at this point. |
562 LOG(FATAL) << "Failed to make UI shared context current."; | 619 LOG(FATAL) << "Failed to make UI shared context current."; |
563 } | 620 } |
564 shared_context_->setContextLostCallback(this); | |
565 } | 621 } |
566 | 622 |
567 void OnLostSharedContext() { | 623 void OnLostMainThreadSharedContext() { |
568 // Keep old resources around while we call the observers, but ensure that | 624 // Keep old resources around while we call the observers, but ensure that |
569 // new resources are created if needed. | 625 // new resources are created if needed. |
570 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> old_shared_context( | 626 |
571 shared_context_.release()); | 627 scoped_refptr<MainThreadContextProvider> old_contexts_main_thread = |
| 628 shared_contexts_main_thread_; |
| 629 shared_contexts_main_thread_ = NULL; |
| 630 |
572 scoped_ptr<GLHelper> old_helper(gl_helper_.release()); | 631 scoped_ptr<GLHelper> old_helper(gl_helper_.release()); |
573 | 632 |
574 FOR_EACH_OBSERVER(ImageTransportFactoryObserver, | 633 FOR_EACH_OBSERVER(ImageTransportFactoryObserver, |
575 observer_list_, | 634 observer_list_, |
576 OnLostResources()); | 635 OnLostResources()); |
577 } | 636 } |
578 | 637 |
579 typedef std::map<ui::Compositor*, PerCompositorData*> PerCompositorDataMap; | 638 typedef std::map<ui::Compositor*, PerCompositorData*> PerCompositorDataMap; |
580 PerCompositorDataMap per_compositor_data_; | 639 PerCompositorDataMap per_compositor_data_; |
581 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> shared_context_; | 640 scoped_refptr<MainThreadContextProvider> shared_contexts_main_thread_; |
| 641 scoped_refptr<CompositorThreadContextProvider> |
| 642 shared_contexts_compositor_thread_; |
582 scoped_ptr<GLHelper> gl_helper_; | 643 scoped_ptr<GLHelper> gl_helper_; |
583 ObserverList<ImageTransportFactoryObserver> observer_list_; | 644 ObserverList<ImageTransportFactoryObserver> observer_list_; |
584 base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_; | 645 base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_; |
585 scoped_refptr<BrowserCompositorOutputSurfaceProxy> output_surface_proxy_; | 646 scoped_refptr<BrowserCompositorOutputSurfaceProxy> output_surface_proxy_; |
586 | 647 |
587 DISALLOW_COPY_AND_ASSIGN(GpuProcessTransportFactory); | 648 DISALLOW_COPY_AND_ASSIGN(GpuProcessTransportFactory); |
588 }; | 649 }; |
589 | 650 |
590 void CompositorSwapClient::OnLostContext() { | 651 void CompositorSwapClient::OnLostContext() { |
591 factory_->OnLostContext(compositor_); | 652 factory_->OnLostContext(compositor_); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 delete g_factory; | 684 delete g_factory; |
624 g_factory = NULL; | 685 g_factory = NULL; |
625 } | 686 } |
626 | 687 |
627 // static | 688 // static |
628 ImageTransportFactory* ImageTransportFactory::GetInstance() { | 689 ImageTransportFactory* ImageTransportFactory::GetInstance() { |
629 return g_factory; | 690 return g_factory; |
630 } | 691 } |
631 | 692 |
632 } // namespace content | 693 } // namespace content |
OLD | NEW |