Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: content/browser/renderer_host/image_transport_factory.cc

Issue 12212007: cc: Route offscreen context creation for compositor to the browser. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cc::ContextProvider Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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<cc::ContextProvider>
573 OffscreenContextProviderForMainThread() OVERRIDE {
574 if (!shared_contexts_main_thread_ ||
575 shared_contexts_main_thread_->DestroyedOnMainThread()) {
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<cc::ContextProvider>
599 OffscreenContextProviderForCompositorThread() OVERRIDE {
600 if (!shared_contexts_compositor_thread_ ||
601 shared_contexts_compositor_thread_->DestroyedOnMainThread()) {
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<cc::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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698