| 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 |