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" |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 if (surface) | 365 if (surface) |
366 surface->OnUpdateVSyncParameters(timebase, interval); | 366 surface->OnUpdateVSyncParameters(timebase, interval); |
367 } | 367 } |
368 | 368 |
369 class GpuProcessTransportFactory | 369 class GpuProcessTransportFactory |
370 : public ui::ContextFactory, | 370 : public ui::ContextFactory, |
371 public ImageTransportFactory, | 371 public ImageTransportFactory, |
372 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { | 372 public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { |
373 public: | 373 public: |
374 GpuProcessTransportFactory() | 374 GpuProcessTransportFactory() |
375 : ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { | 375 : lost_context_callbacks_(0), |
| 376 ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) { |
376 output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy(); | 377 output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy(); |
377 } | 378 } |
378 | 379 |
379 virtual ~GpuProcessTransportFactory() { | 380 virtual ~GpuProcessTransportFactory() { |
380 DCHECK(per_compositor_data_.empty()); | 381 DCHECK(per_compositor_data_.empty()); |
381 } | 382 } |
382 | 383 |
383 virtual WebGraphicsContext3DCommandBufferImpl* CreateOffscreenContext() | 384 virtual WebGraphicsContext3DCommandBufferImpl* CreateOffscreenContext() |
384 OVERRIDE { | 385 OVERRIDE { |
385 base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client; | 386 base::WeakPtr<WebGraphicsContext3DSwapBuffersClient> swap_client; |
(...skipping 30 matching lines...) Expand all Loading... |
416 } | 417 } |
417 | 418 |
418 virtual ui::ContextFactory* AsContextFactory() OVERRIDE { | 419 virtual ui::ContextFactory* AsContextFactory() OVERRIDE { |
419 return this; | 420 return this; |
420 } | 421 } |
421 | 422 |
422 virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle() OVERRIDE { | 423 virtual gfx::GLSurfaceHandle CreateSharedSurfaceHandle() OVERRIDE { |
423 CreateSharedContextLazy(); | 424 CreateSharedContextLazy(); |
424 gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle( | 425 gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle( |
425 gfx::kNullPluginWindow, true); | 426 gfx::kNullPluginWindow, true); |
426 handle.parent_gpu_process_id = shared_context_->GetGPUProcessID(); | 427 handle.parent_gpu_process_id = |
427 handle.parent_client_id = shared_context_->GetChannelID(); | 428 shared_context_main_thread_->GetGPUProcessID(); |
| 429 handle.parent_client_id = shared_context_main_thread_->GetChannelID(); |
428 | 430 |
429 return handle; | 431 return handle; |
430 } | 432 } |
431 | 433 |
432 virtual void DestroySharedSurfaceHandle( | 434 virtual void DestroySharedSurfaceHandle( |
433 gfx::GLSurfaceHandle surface) OVERRIDE { | 435 gfx::GLSurfaceHandle surface) OVERRIDE { |
434 } | 436 } |
435 | 437 |
436 virtual scoped_refptr<ui::Texture> CreateTransportClient( | 438 virtual scoped_refptr<ui::Texture> CreateTransportClient( |
437 float device_scale_factor) { | 439 float device_scale_factor) { |
438 if (!shared_context_.get()) | 440 if (!shared_context_main_thread_.get()) |
439 return NULL; | 441 return NULL; |
440 scoped_refptr<ImageTransportClientTexture> image( | 442 scoped_refptr<ImageTransportClientTexture> image( |
441 new ImageTransportClientTexture(shared_context_.get(), | 443 new ImageTransportClientTexture(shared_context_main_thread_.get(), |
442 device_scale_factor)); | 444 device_scale_factor)); |
443 return image; | 445 return image; |
444 } | 446 } |
445 | 447 |
446 virtual scoped_refptr<ui::Texture> CreateOwnedTexture( | 448 virtual scoped_refptr<ui::Texture> CreateOwnedTexture( |
447 const gfx::Size& size, | 449 const gfx::Size& size, |
448 float device_scale_factor, | 450 float device_scale_factor, |
449 unsigned int texture_id) OVERRIDE { | 451 unsigned int texture_id) OVERRIDE { |
450 if (!shared_context_.get()) | 452 if (!shared_context_main_thread_.get()) |
451 return NULL; | 453 return NULL; |
452 scoped_refptr<OwnedTexture> image( | 454 scoped_refptr<OwnedTexture> image(new OwnedTexture( |
453 new OwnedTexture(shared_context_.get(), size, device_scale_factor, | 455 shared_context_main_thread_.get(), |
454 texture_id)); | 456 size, |
| 457 device_scale_factor, |
| 458 texture_id)); |
455 return image; | 459 return image; |
456 } | 460 } |
457 | 461 |
458 virtual GLHelper* GetGLHelper() { | 462 virtual GLHelper* GetGLHelper() { |
459 if (!gl_helper_.get()) { | 463 if (!gl_helper_.get()) { |
460 CreateSharedContextLazy(); | 464 CreateSharedContextLazy(); |
461 WebKit::WebGraphicsContext3D* context_for_thread = | 465 WebKit::WebGraphicsContext3D* context_for_thread = |
462 CreateOffscreenContext(); | 466 CreateOffscreenContext(); |
463 if (!context_for_thread) | 467 if (!context_for_thread) |
464 return NULL; | 468 return NULL; |
465 gl_helper_.reset(new GLHelper(shared_context_.get(), | 469 gl_helper_.reset(new GLHelper(shared_context_main_thread_.get(), |
466 context_for_thread)); | 470 context_for_thread)); |
467 } | 471 } |
468 return gl_helper_.get(); | 472 return gl_helper_.get(); |
469 } | 473 } |
470 | 474 |
471 virtual uint32 InsertSyncPoint() OVERRIDE { | 475 virtual uint32 InsertSyncPoint() OVERRIDE { |
472 if (!shared_context_.get()) | 476 if (!shared_context_main_thread_.get()) |
473 return 0; | 477 return 0; |
474 return shared_context_->insertSyncPoint(); | 478 return shared_context_main_thread_->insertSyncPoint(); |
475 } | 479 } |
476 | 480 |
477 virtual void AddObserver(ImageTransportFactoryObserver* observer) { | 481 virtual void AddObserver(ImageTransportFactoryObserver* observer) { |
478 observer_list_.AddObserver(observer); | 482 observer_list_.AddObserver(observer); |
479 } | 483 } |
480 | 484 |
481 virtual void RemoveObserver(ImageTransportFactoryObserver* observer) { | 485 virtual void RemoveObserver(ImageTransportFactoryObserver* observer) { |
482 observer_list_.RemoveObserver(observer); | 486 observer_list_.RemoveObserver(observer); |
483 } | 487 } |
484 | 488 |
485 // WebGraphicsContextLostCallback implementation, called for the shared | 489 // WebGraphicsContextLostCallback implementation, called for the shared |
486 // context. | 490 // context. |
487 virtual void onContextLost() { | 491 virtual void onContextLost() { |
| 492 // Wait until we get the callback for each of our shared contexts. |
| 493 ++lost_context_callbacks_; |
| 494 int expected_callbacks = (shared_context_main_thread_ ? 1 : 0) + |
| 495 (shared_context_compositor_thread_ ? 1 : 0); |
| 496 DCHECK(expected_callbacks); |
| 497 if (lost_context_callbacks_ < expected_callbacks) |
| 498 return; |
| 499 |
488 MessageLoop::current()->PostTask( | 500 MessageLoop::current()->PostTask( |
489 FROM_HERE, | 501 FROM_HERE, |
490 base::Bind(&GpuProcessTransportFactory::OnLostSharedContext, | 502 base::Bind(&GpuProcessTransportFactory::OnLostSharedContexts, |
491 callback_factory_.GetWeakPtr())); | 503 callback_factory_.GetWeakPtr())); |
492 } | 504 } |
493 | 505 |
494 void OnLostContext(ui::Compositor* compositor) { | 506 void OnLostContext(ui::Compositor* compositor) { |
495 LOG(ERROR) << "Lost UI compositor context."; | 507 LOG(ERROR) << "Lost UI compositor context."; |
496 PerCompositorData* data = per_compositor_data_[compositor]; | 508 PerCompositorData* data = per_compositor_data_[compositor]; |
497 DCHECK(data); | 509 DCHECK(data); |
498 | 510 |
499 // Prevent callbacks from other contexts in the same share group from | 511 // Prevent callbacks from other contexts in the same share group from |
500 // calling us again. | 512 // calling us again. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 factory, | 565 factory, |
554 swap_client)); | 566 swap_client)); |
555 if (!context->Initialize( | 567 if (!context->Initialize( |
556 attrs, | 568 attrs, |
557 false, | 569 false, |
558 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) | 570 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) |
559 return NULL; | 571 return NULL; |
560 return context.release(); | 572 return context.release(); |
561 } | 573 } |
562 | 574 |
| 575 virtual WebKit::WebGraphicsContext3D* OffscreenContextForMainThread() |
| 576 OVERRIDE { |
| 577 CreateSharedContextLazy(); |
| 578 return shared_context_main_thread_.get(); |
| 579 } |
| 580 |
| 581 virtual WebKit::WebGraphicsContext3D* OffscreenContextForCompositorThread() |
| 582 OVERRIDE { |
| 583 if (shared_context_compositor_thread_) |
| 584 return shared_context_compositor_thread_.get(); |
| 585 |
| 586 shared_context_compositor_thread_.reset(CreateOffscreenContext()); |
| 587 if (!shared_context_compositor_thread_->makeContextCurrent()) |
| 588 shared_context_compositor_thread_.reset(); |
| 589 if (!shared_context_compositor_thread_) |
| 590 return NULL; |
| 591 |
| 592 shared_context_compositor_thread_->setContextLostCallback(this); |
| 593 return shared_context_compositor_thread_.get(); |
| 594 } |
| 595 |
563 void CreateSharedContextLazy() { | 596 void CreateSharedContextLazy() { |
564 if (shared_context_.get()) | 597 if (shared_context_main_thread_.get()) |
565 return; | 598 return; |
566 | 599 |
567 shared_context_.reset(CreateOffscreenContext()); | 600 shared_context_main_thread_.reset(CreateOffscreenContext()); |
568 if (!shared_context_.get()) { | 601 if (!shared_context_main_thread_.get()) { |
569 // If we can't recreate contexts, we won't be able to show the UI. Better | 602 // If we can't recreate contexts, we won't be able to show the UI. Better |
570 // crash at this point. | 603 // crash at this point. |
571 LOG(FATAL) << "Failed to initialize UI shared context."; | 604 LOG(FATAL) << "Failed to initialize UI shared context."; |
572 } | 605 } |
573 if (!shared_context_->makeContextCurrent()) { | 606 if (!shared_context_main_thread_->makeContextCurrent()) { |
574 // If we can't recreate contexts, we won't be able to show the UI. Better | 607 // If we can't recreate contexts, we won't be able to show the UI. Better |
575 // crash at this point. | 608 // crash at this point. |
576 LOG(FATAL) << "Failed to make UI shared context current."; | 609 LOG(FATAL) << "Failed to make UI shared context current."; |
577 } | 610 } |
578 shared_context_->setContextLostCallback(this); | 611 shared_context_main_thread_->setContextLostCallback(this); |
579 } | 612 } |
580 | 613 |
581 void OnLostSharedContext() { | 614 void OnLostSharedContexts() { |
582 // Keep old resources around while we call the observers, but ensure that | 615 // Keep old resources around while we call the observers, but ensure that |
583 // new resources are created if needed. | 616 // new resources are created if needed. |
584 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> old_shared_context( | 617 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> |
585 shared_context_.release()); | 618 old_shared_context_main_thread(shared_context_main_thread_.release()); |
| 619 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> |
| 620 old_shared_context_compositor_thread( |
| 621 shared_context_compositor_thread_.release()); |
586 scoped_ptr<GLHelper> old_helper(gl_helper_.release()); | 622 scoped_ptr<GLHelper> old_helper(gl_helper_.release()); |
587 | 623 |
| 624 lost_context_callbacks_ = 0; |
| 625 |
588 FOR_EACH_OBSERVER(ImageTransportFactoryObserver, | 626 FOR_EACH_OBSERVER(ImageTransportFactoryObserver, |
589 observer_list_, | 627 observer_list_, |
590 OnLostResources()); | 628 OnLostResources()); |
591 } | 629 } |
592 | 630 |
593 typedef std::map<ui::Compositor*, PerCompositorData*> PerCompositorDataMap; | 631 typedef std::map<ui::Compositor*, PerCompositorData*> PerCompositorDataMap; |
594 PerCompositorDataMap per_compositor_data_; | 632 PerCompositorDataMap per_compositor_data_; |
595 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> shared_context_; | 633 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> shared_context_main_thread_; |
| 634 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> |
| 635 shared_context_compositor_thread_; |
| 636 int lost_context_callbacks_; |
596 scoped_ptr<GLHelper> gl_helper_; | 637 scoped_ptr<GLHelper> gl_helper_; |
597 ObserverList<ImageTransportFactoryObserver> observer_list_; | 638 ObserverList<ImageTransportFactoryObserver> observer_list_; |
598 base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_; | 639 base::WeakPtrFactory<GpuProcessTransportFactory> callback_factory_; |
599 scoped_refptr<BrowserCompositorOutputSurfaceProxy> output_surface_proxy_; | 640 scoped_refptr<BrowserCompositorOutputSurfaceProxy> output_surface_proxy_; |
600 | 641 |
601 DISALLOW_COPY_AND_ASSIGN(GpuProcessTransportFactory); | 642 DISALLOW_COPY_AND_ASSIGN(GpuProcessTransportFactory); |
602 }; | 643 }; |
603 | 644 |
604 void CompositorSwapClient::OnLostContext() { | 645 void CompositorSwapClient::OnLostContext() { |
605 factory_->OnLostContext(compositor_); | 646 factory_->OnLostContext(compositor_); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 delete g_factory; | 678 delete g_factory; |
638 g_factory = NULL; | 679 g_factory = NULL; |
639 } | 680 } |
640 | 681 |
641 // static | 682 // static |
642 ImageTransportFactory* ImageTransportFactory::GetInstance() { | 683 ImageTransportFactory* ImageTransportFactory::GetInstance() { |
643 return g_factory; | 684 return g_factory; |
644 } | 685 } |
645 | 686 |
646 } // namespace content | 687 } // namespace content |
OLD | NEW |