gpu_process_transport_factory.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// found in the LICENSE file. 4558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/gpu_process_transport_factory.h" 6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 7558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include <string> 8558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 9558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/bind.h" 10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/command_line.h" 11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/location.h" 12558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "base/message_loop/message_loop.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/metrics/histogram.h" 14558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "cc/output/compositor_frame.h" 15558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "cc/output/output_surface.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/browser_compositor_output_surface.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/browser_compositor_output_surface_proxy.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/gpu_browser_compositor_output_surface.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/reflector_impl.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_browser_compositor_output_surface.h" 21558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/gpu/browser_gpu_channel_host_factory.h" 22558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/gpu/gpu_data_manager_impl.h" 23558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/gpu/gpu_surface_tracker.h" 24558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/renderer_host/render_widget_host_impl.h" 25fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "content/common/gpu/client/context_provider_command_buffer.h" 26558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/gpu/client/gl_helper.h" 27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/gpu/client/gpu_channel_host.h" 28558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" 29558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/gpu/gpu_process_launch_causes.h" 30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "gpu/GLES2/gl2extchromium.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h" 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h" 33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "third_party/khronos/GLES2/gl2.h" 34558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/compositor/compositor.h" 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/compositor_constants.h" 36558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/compositor/compositor_switches.h" 37558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/gfx/native_widget_types.h" 38558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/gfx/size.h" 39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_output_device_win.h" 421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#elif defined(USE_OZONE) 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_output_device_ozone.h" 44558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#elif defined(USE_X11) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_output_device_x11.h" 46558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif 47558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using cc::ContextProvider; 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using gpu::gles2::GLES2Interface; 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace content { 52558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstruct GpuProcessTransportFactory::PerCompositorData { 54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch int surface_id; 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<ReflectorImpl> reflector; 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}; 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass OwnedTexture : public ui::Texture, ImageTransportFactoryObserver { 59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch public: 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OwnedTexture(const scoped_refptr<ContextProvider>& provider, 61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const gfx::Size& size, 62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch float device_scale_factor, 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint texture_id) 64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch : ui::Texture(true, size, device_scale_factor), 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider_(provider), 66558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch texture_id_(texture_id) { 67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ImageTransportFactory::GetInstance()->AddObserver(this); 68558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 69558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 70558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // ui::Texture overrides: 71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch virtual unsigned int PrepareTexture() OVERRIDE { 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // It's possible that we may have lost the context owning our 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // texture but not yet fired the OnLostResources callback, so poll to see if 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // it's still valid. 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (provider_ && provider_->IsContextLost()) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) texture_id_ = 0u; 77558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return texture_id_; 78558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 79558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 80558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // ImageTransportFactory overrides: 81558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch virtual void OnLostResources() OVERRIDE { 82558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DeleteTexture(); 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider_ = NULL; 84558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 85558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 86558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch protected: 87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch virtual ~OwnedTexture() { 88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ImageTransportFactory::GetInstance()->RemoveObserver(this); 89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DeleteTexture(); 90558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 92558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch protected: 93558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch void DeleteTexture() { 94558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (texture_id_) { 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider_->ContextGL()->DeleteTextures(1, &texture_id_); 96558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch texture_id_ = 0; 97558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 98558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 99558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<cc::ContextProvider> provider_; 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint texture_id_; 102558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 104558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DISALLOW_COPY_AND_ASSIGN(OwnedTexture); 105558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}; 106558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 107558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochclass ImageTransportClientTexture : public OwnedTexture { 108558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch public: 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ImageTransportClientTexture(const scoped_refptr<ContextProvider>& provider, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) float device_scale_factor, 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint texture_id) 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : OwnedTexture(provider, 113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch gfx::Size(0, 0), 114558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch device_scale_factor, 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) texture_id) {} 116558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Consume(const gpu::Mailbox& mailbox, 118558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const gfx::Size& new_size) OVERRIDE { 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mailbox_ = mailbox; 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (mailbox.IsZero()) 121558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return; 122558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(provider_ && texture_id_); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLES2Interface* gl = provider_->ContextGL(); 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gl->BindTexture(GL_TEXTURE_2D, texture_id_); 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gl->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); 127558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch size_ = new_size; 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gl->ShallowFlushCHROMIUM(); 129558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 130558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual gpu::Mailbox Produce() OVERRIDE { return mailbox_; } 132558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 133558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch protected: 134558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch virtual ~ImageTransportClientTexture() {} 135558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 136558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch private: 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gpu::Mailbox mailbox_; 138558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DISALLOW_COPY_AND_ASSIGN(ImageTransportClientTexture); 139558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}; 140558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 141558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::GpuProcessTransportFactory() 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : callback_factory_(this), offscreen_content_bound_to_other_thread_(false) { 143558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy( 144d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch &output_surface_map_); 145558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 146558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 147558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::~GpuProcessTransportFactory() { 148558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(per_compositor_data_.empty()); 149fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 150fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch // Make sure the lost context callback doesn't try to run during destruction. 151fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch callback_factory_.InvalidateWeakPtrs(); 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (offscreen_compositor_contexts_.get() && 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) offscreen_content_bound_to_other_thread_) { 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Leak shared contexts on other threads, as we can not get to the correct 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // thread to destroy them. 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) offscreen_compositor_contexts_->set_leak_on_destroy(); 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 159558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 160558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 161558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<WebGraphicsContext3DCommandBufferImpl> 162558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::CreateOffscreenCommandBufferContext() { 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return CreateContextCommon(0); 164558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 165558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 166bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochscoped_ptr<cc::SoftwareOutputDevice> CreateSoftwareOutputDevice( 167bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ui::Compositor* compositor) { 168bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#if defined(OS_WIN) 169bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceWin( 170bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch compositor)); 1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#elif defined(USE_OZONE) 1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceOzone( 1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) compositor)); 174bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#elif defined(USE_X11) 175bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceX11( 176bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch compositor)); 17723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else 178bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch NOTREACHED(); 179bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return scoped_ptr<cc::SoftwareOutputDevice>(); 18023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif 181bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 182bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 183558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface( 184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::Compositor* compositor, bool software_fallback) { 185558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = per_compositor_data_[compositor]; 186558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!data) 187558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data = CreatePerCompositorData(compositor); 188558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool create_software_renderer = software_fallback; 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_CHROMEOS) 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Software fallback does not happen on Chrome OS. 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_software_renderer = false; 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#elif defined(OS_WIN) 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (::GetProp(compositor->widget(), kForceSoftwareCompositor)) { 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (::RemoveProp(compositor->widget(), kForceSoftwareCompositor)) 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_software_renderer = true; 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<ContextProviderCommandBuffer> context_provider; 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!create_software_renderer) { 2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) context_provider = ContextProviderCommandBuffer::Create( 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GpuProcessTransportFactory::CreateContextCommon(data->surface_id), 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "Compositor"); 205558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 206d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 207d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor", !!context_provider); 208d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!context_provider.get()) { 210ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (ui::Compositor::WasInitializedWithThread()) { 2113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LOG(FATAL) << "Failed to create UI context, but can't use software" 212ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch " compositing with browser threaded compositing. Aborting."; 213ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 214ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<SoftwareBrowserCompositorOutputSurface> surface( 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new SoftwareBrowserCompositorOutputSurface( 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) output_surface_proxy_, 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateSoftwareOutputDevice(compositor), 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) per_compositor_data_[compositor]->surface_id, 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &output_surface_map_, 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) compositor->vsync_manager())); 222bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return surface.PassAs<cc::OutputSurface>(); 223bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 224558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 225558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_task_runner = 226558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ui::Compositor::GetCompositorMessageLoop(); 227558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!compositor_thread_task_runner.get()) 228558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch compositor_thread_task_runner = base::MessageLoopProxy::current(); 229558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 230558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Here we know the GpuProcessHost has been set up, because we created a 231558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // context. 232558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch output_surface_proxy_->ConnectToGpuProcessHost( 233558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch compositor_thread_task_runner.get()); 234558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 235558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<BrowserCompositorOutputSurface> surface( 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new GpuBrowserCompositorOutputSurface( 2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) context_provider, 238558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch per_compositor_data_[compositor]->surface_id, 239d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch &output_surface_map_, 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) compositor->vsync_manager())); 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (data->reflector.get()) 242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data->reflector->ReattachToOutputSurfaceFromMainThread(surface.get()); 243558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 244558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return surface.PassAs<cc::OutputSurface>(); 245558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 246558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 247558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_refptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector( 248558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ui::Compositor* source, 249558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ui::Layer* target) { 250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = per_compositor_data_[source]; 251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(data); 252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 253558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (data->reflector.get()) 254558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch RemoveObserver(data->reflector.get()); 255558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 256558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->reflector = new ReflectorImpl( 257d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch source, target, &output_surface_map_, data->surface_id); 258558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch AddObserver(data->reflector.get()); 259558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return data->reflector; 260558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 261558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 262558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::RemoveReflector( 263558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<ui::Reflector> reflector) { 264558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ReflectorImpl* reflector_impl = 265558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch static_cast<ReflectorImpl*>(reflector.get()); 266558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = 267558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch per_compositor_data_[reflector_impl->mirrored_compositor()]; 268558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(data); 269558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch RemoveObserver(reflector_impl); 270558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->reflector->Shutdown(); 271558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->reflector = NULL; 272558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 273558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 274558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) { 275558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 276558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (it == per_compositor_data_.end()) 277558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return; 278558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = it->second; 279558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(data); 280558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id); 281558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch delete data; 282558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch per_compositor_data_.erase(it); 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (per_compositor_data_.empty()) { 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Destroying the GLHelper may cause some async actions to be cancelled, 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // causing things to request a new GLHelper. Due to crbug.com/176091 the 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // GLHelper created in this case would be lost/leaked if we just reset() 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // on the |gl_helper_| variable directly. So instead we call reset() on a 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // local scoped_ptr. 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<GLHelper> helper = gl_helper_.Pass(); 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) helper.reset(); 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!gl_helper_) << "Destroying the GLHelper should not cause a new " 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "GLHelper to be created."; 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 294558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 295558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 296c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochbool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; } 297c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 298558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochui::ContextFactory* GpuProcessTransportFactory::AsContextFactory() { 299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return this; 300558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 301558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::GLSurfaceHandle GpuProcessTransportFactory::GetSharedSurfaceHandle() { 303558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle( 304558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT); 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) handle.parent_client_id = 306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserGpuChannelHostFactory::instance()->GetGpuChannelId(); 307558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return handle; 308558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 309558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 310558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_refptr<ui::Texture> GpuProcessTransportFactory::CreateTransportClient( 311558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch float device_scale_factor) { 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<cc::ContextProvider> provider = 3134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SharedMainThreadContextProvider(); 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!provider.get()) 315558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return NULL; 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLuint texture_id = 0; 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider->ContextGL()->GenTextures(1, &texture_id); 318558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<ImageTransportClientTexture> image( 319558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch new ImageTransportClientTexture( 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider, device_scale_factor, texture_id)); 321558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return image; 322558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 323558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 324558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_refptr<ui::Texture> GpuProcessTransportFactory::CreateOwnedTexture( 325558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const gfx::Size& size, 326558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch float device_scale_factor, 327558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch unsigned int texture_id) { 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<cc::ContextProvider> provider = 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SharedMainThreadContextProvider(); 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!provider.get()) 331558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return NULL; 332558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<OwnedTexture> image(new OwnedTexture( 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) provider, size, device_scale_factor, texture_id)); 334558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return image; 335558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 336558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 337558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGLHelper* GpuProcessTransportFactory::GetGLHelper() { 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!gl_helper_ && !per_compositor_data_.empty()) { 3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<cc::ContextProvider> provider = 3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SharedMainThreadContextProvider(); 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (provider.get()) 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gl_helper_.reset(new GLHelper(provider->ContextGL(), 3438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) provider->ContextSupport())); 344558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 345558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return gl_helper_.get(); 346558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 347558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 348558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::AddObserver( 349558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ImageTransportFactoryObserver* observer) { 350558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch observer_list_.AddObserver(observer); 351558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 352558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 353558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::RemoveObserver( 354558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ImageTransportFactoryObserver* observer) { 355558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch observer_list_.RemoveObserver(observer); 356558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 357558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 358558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_refptr<cc::ContextProvider> 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GpuProcessTransportFactory::OffscreenCompositorContextProvider() { 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Don't check for DestroyedOnMainThread() here. We hear about context 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // loss for this context through the lost context callback. If the context 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // is lost, we want to leave this ContextProvider available until the lost 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // context notification is sent to the ImageTransportFactoryObserver clients. 3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (offscreen_compositor_contexts_.get()) 3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return offscreen_compositor_contexts_; 3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) offscreen_compositor_contexts_ = ContextProviderCommandBuffer::Create( 3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(), 3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) "Compositor-Offscreen"); 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) offscreen_content_bound_to_other_thread_ = 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::Compositor::WasInitializedWithThread(); 3724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return offscreen_compositor_contexts_; 374558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 375558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 376558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_refptr<cc::ContextProvider> 3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GpuProcessTransportFactory::SharedMainThreadContextProvider() { 3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (shared_main_thread_contexts_.get()) 3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return shared_main_thread_contexts_; 3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // In threaded compositing mode, we have to create our own context for the 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // main thread since the compositor's context will be bound to the 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // compositor thread. When not in threaded mode, we still need a separate 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // context so that skia and gl_helper don't step on each other. 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shared_main_thread_contexts_ = ContextProviderCommandBuffer::Create( 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(), 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Offscreen-MainThread"); 3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (shared_main_thread_contexts_) { 3904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) shared_main_thread_contexts_->SetLostContextCallback( 3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&GpuProcessTransportFactory:: 3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnLostMainThreadSharedContextInsideCallback, 3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback_factory_.GetWeakPtr())); 3948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (!shared_main_thread_contexts_->BindToCurrentThread()) { 3954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) shared_main_thread_contexts_ = NULL; 3968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) offscreen_compositor_contexts_ = NULL; 3978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 398558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return shared_main_thread_contexts_; 400558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 401558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 402558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::PerCompositorData* 403558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::CreatePerCompositorData( 404558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ui::Compositor* compositor) { 405558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(!per_compositor_data_[compositor]); 406558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 407558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch gfx::AcceleratedWidget widget = compositor->widget(); 408558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get(); 409558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 410558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = new PerCompositorData; 411558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->surface_id = tracker->AddSurfaceForNativeWidget(widget); 412558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch tracker->SetSurfaceHandle( 413558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->surface_id, 414558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch gfx::GLSurfaceHandle(widget, gfx::NATIVE_DIRECT)); 415558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 416558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch per_compositor_data_[compositor] = data; 417558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 418558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return data; 419558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 420558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 421558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<WebGraphicsContext3DCommandBufferImpl> 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)GpuProcessTransportFactory::CreateContextCommon(int surface_id) { 423558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) 424558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebGraphicsContext3D::Attributes attrs; 426558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.shareResources = true; 427558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.depth = false; 428558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.stencil = false; 429558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.antialias = false; 430558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.noAutomaticFlushes = true; 431e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool bind_generates_resources = false; 432e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool lose_context_when_out_of_memory = true; 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CauseForGpuLaunch cause = 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE; 4351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<GpuChannelHost> gpu_channel_host( 436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause)); 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!gpu_channel_host) { 438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Failed to establish GPU channel."; 4391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); 440a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 441558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon"); 442558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( 443558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch new WebGraphicsContext3DCommandBufferImpl( 444558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch surface_id, 445558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch url, 4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gpu_channel_host.get(), 4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) attrs, 448e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bind_generates_resources, 449e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch lose_context_when_out_of_memory, 450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), 451a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL)); 452558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return context.Pass(); 453558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 454558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 455fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() { 456558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::MessageLoop::current()->PostTask( 457558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch FROM_HERE, 458558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext, 459fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch callback_factory_.GetWeakPtr())); 460558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 461558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 462558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::OnLostMainThreadSharedContext() { 463558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LOG(ERROR) << "Lost UI shared context."; 4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 465558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Keep old resources around while we call the observers, but ensure that 466558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // new resources are created if needed. 4673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Kill shared contexts for both threads in tandem so they are always in 4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the same share group. 4694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<cc::ContextProvider> lost_offscreen_compositor_contexts = 4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) offscreen_compositor_contexts_; 4714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<cc::ContextProvider> lost_shared_main_thread_contexts = 4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) shared_main_thread_contexts_; 4734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) offscreen_compositor_contexts_ = NULL; 4744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) shared_main_thread_contexts_ = NULL; 475558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<GLHelper> lost_gl_helper = gl_helper_.Pass(); 477558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 478558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch FOR_EACH_OBSERVER(ImageTransportFactoryObserver, 479558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch observer_list_, 480558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch OnLostResources()); 4813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Kill things that use the shared context before killing the shared context. 4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) lost_gl_helper.reset(); 4844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) lost_offscreen_compositor_contexts = NULL; 4854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) lost_shared_main_thread_contexts = NULL; 486558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 487558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 488558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} // namespace content 489