gpu_process_transport_factory.cc revision 5c02ac1a9c1b504631c0a3d2b6e737b5d738bae1
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) 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/compositor/overlay_candidate_validator_ozone.h" 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_output_device_ozone.h" 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/gfx/ozone/surface_factory_ozone.h" 46558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#elif defined(USE_X11) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_output_device_x11.h" 48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif 49558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using cc::ContextProvider; 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using gpu::gles2::GLES2Interface; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace content { 54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstruct GpuProcessTransportFactory::PerCompositorData { 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch int surface_id; 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<ReflectorImpl> reflector; 58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}; 59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 60558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::GpuProcessTransportFactory() 615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu : callback_factory_(this) { 62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy( 63d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch &output_surface_map_); 64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 65558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 66558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::~GpuProcessTransportFactory() { 67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(per_compositor_data_.empty()); 68fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch 69fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch // Make sure the lost context callback doesn't try to run during destruction. 70fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch callback_factory_.InvalidateWeakPtrs(); 71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 72558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 73558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<WebGraphicsContext3DCommandBufferImpl> 74558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::CreateOffscreenCommandBufferContext() { 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return CreateContextCommon(0); 76558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 77558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 78bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochscoped_ptr<cc::SoftwareOutputDevice> CreateSoftwareOutputDevice( 79bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch ui::Compositor* compositor) { 80bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#if defined(OS_WIN) 81bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceWin( 82bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch compositor)); 831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#elif defined(USE_OZONE) 841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceOzone( 851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) compositor)); 86bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#elif defined(USE_X11) 87bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceX11( 88bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch compositor)); 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else 90bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch NOTREACHED(); 91bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return scoped_ptr<cc::SoftwareOutputDevice>(); 9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif 93bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 94bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_ptr<cc::OverlayCandidateValidator> CreateOverlayCandidateValidator( 96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::AcceleratedWidget widget) { 97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(USE_OZONE) 98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::OverlayCandidatesOzone* overlay_candidates = 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::SurfaceFactoryOzone::GetInstance()->GetOverlayCandidates(widget); 100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (overlay_candidates && CommandLine::ForCurrentProcess()->HasSwitch( 101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch switches::kEnableHardwareOverlays)) { 102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return scoped_ptr<cc::OverlayCandidateValidator>( 103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new OverlayCandidateValidatorOzone(widget, overlay_candidates)); 104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif 106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return scoped_ptr<cc::OverlayCandidateValidator>(); 107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 109558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface( 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ui::Compositor* compositor, bool software_fallback) { 111558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = per_compositor_data_[compositor]; 112558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!data) 113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data = CreatePerCompositorData(compositor); 114558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool create_software_renderer = software_fallback; 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_CHROMEOS) 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Software fallback does not happen on Chrome OS. 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_software_renderer = false; 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#elif defined(OS_WIN) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (::GetProp(compositor->widget(), kForceSoftwareCompositor)) { 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (::RemoveProp(compositor->widget(), kForceSoftwareCompositor)) 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) create_software_renderer = true; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_refptr<ContextProviderCommandBuffer> context_provider; 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!create_software_renderer) { 1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) context_provider = ContextProviderCommandBuffer::Create( 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GpuProcessTransportFactory::CreateContextCommon(data->surface_id), 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "Compositor"); 131558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 132d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 133d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor", !!context_provider); 134d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!context_provider.get()) { 136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (ui::Compositor::WasInitializedWithThread()) { 1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) LOG(FATAL) << "Failed to create UI context, but can't use software" 138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch " compositing with browser threaded compositing. Aborting."; 139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch } 140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<SoftwareBrowserCompositorOutputSurface> surface( 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new SoftwareBrowserCompositorOutputSurface( 143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) output_surface_proxy_, 144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateSoftwareOutputDevice(compositor), 145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) per_compositor_data_[compositor]->surface_id, 146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &output_surface_map_, 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) compositor->vsync_manager())); 148bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return surface.PassAs<cc::OutputSurface>(); 149bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 150558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 151558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_task_runner = 152558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ui::Compositor::GetCompositorMessageLoop(); 153558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!compositor_thread_task_runner.get()) 154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch compositor_thread_task_runner = base::MessageLoopProxy::current(); 155558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 156558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Here we know the GpuProcessHost has been set up, because we created a 157558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // context. 158558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch output_surface_proxy_->ConnectToGpuProcessHost( 159558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch compositor_thread_task_runner.get()); 160558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 161558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<BrowserCompositorOutputSurface> surface( 162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new GpuBrowserCompositorOutputSurface( 1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) context_provider, 164558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch per_compositor_data_[compositor]->surface_id, 165d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch &output_surface_map_, 166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch compositor->vsync_manager(), 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch CreateOverlayCandidateValidator(compositor->widget()))); 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (data->reflector.get()) 169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) data->reflector->ReattachToOutputSurfaceFromMainThread(surface.get()); 170558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 171558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return surface.PassAs<cc::OutputSurface>(); 172558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 173558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 174558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_refptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector( 175558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ui::Compositor* source, 176558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ui::Layer* target) { 177558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = per_compositor_data_[source]; 178558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(data); 179558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 180558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->reflector = new ReflectorImpl( 181d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch source, target, &output_surface_map_, data->surface_id); 182558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return data->reflector; 183558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 184558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 185558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::RemoveReflector( 186558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_refptr<ui::Reflector> reflector) { 187558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ReflectorImpl* reflector_impl = 188558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch static_cast<ReflectorImpl*>(reflector.get()); 189558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = 190558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch per_compositor_data_[reflector_impl->mirrored_compositor()]; 191558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(data); 192558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->reflector->Shutdown(); 193558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->reflector = NULL; 194558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 195558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 196558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) { 197558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor); 198558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (it == per_compositor_data_.end()) 199558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return; 200558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = it->second; 201558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(data); 202558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id); 203558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch delete data; 204558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch per_compositor_data_.erase(it); 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (per_compositor_data_.empty()) { 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Destroying the GLHelper may cause some async actions to be cancelled, 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // causing things to request a new GLHelper. Due to crbug.com/176091 the 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // GLHelper created in this case would be lost/leaked if we just reset() 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // on the |gl_helper_| variable directly. So instead we call reset() on a 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // local scoped_ptr. 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<GLHelper> helper = gl_helper_.Pass(); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) helper.reset(); 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!gl_helper_) << "Destroying the GLHelper should not cause a new " 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "GLHelper to be created."; 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 216558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 217558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 218c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochbool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; } 219c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 220558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochui::ContextFactory* GpuProcessTransportFactory::AsContextFactory() { 221558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return this; 222558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 223558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::GLSurfaceHandle GpuProcessTransportFactory::GetSharedSurfaceHandle() { 225558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle( 226558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT); 227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) handle.parent_client_id = 228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) BrowserGpuChannelHostFactory::instance()->GetGpuChannelId(); 229558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return handle; 230558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 231558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 232558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGLHelper* GpuProcessTransportFactory::GetGLHelper() { 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!gl_helper_ && !per_compositor_data_.empty()) { 2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<cc::ContextProvider> provider = 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) SharedMainThreadContextProvider(); 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (provider.get()) 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gl_helper_.reset(new GLHelper(provider->ContextGL(), 2388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) provider->ContextSupport())); 239558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 240558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return gl_helper_.get(); 241558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 242558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 243558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::AddObserver( 244558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ImageTransportFactoryObserver* observer) { 245558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch observer_list_.AddObserver(observer); 246558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 247558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 248558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::RemoveObserver( 249558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ImageTransportFactoryObserver* observer) { 250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch observer_list_.RemoveObserver(observer); 251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 253558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_refptr<cc::ContextProvider> 2544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GpuProcessTransportFactory::SharedMainThreadContextProvider() { 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (shared_main_thread_contexts_.get()) 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return shared_main_thread_contexts_; 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // In threaded compositing mode, we have to create our own context for the 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // main thread since the compositor's context will be bound to the 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // compositor thread. When not in threaded mode, we still need a separate 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // context so that skia and gl_helper don't step on each other. 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) shared_main_thread_contexts_ = ContextProviderCommandBuffer::Create( 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(), 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Offscreen-MainThread"); 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (shared_main_thread_contexts_) { 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) shared_main_thread_contexts_->SetLostContextCallback( 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::Bind(&GpuProcessTransportFactory:: 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OnLostMainThreadSharedContextInsideCallback, 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) callback_factory_.GetWeakPtr())); 2715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!shared_main_thread_contexts_->BindToCurrentThread()) 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) shared_main_thread_contexts_ = NULL; 273558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return shared_main_thread_contexts_; 275558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 276558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 277558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::PerCompositorData* 278558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::CreatePerCompositorData( 279558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ui::Compositor* compositor) { 280558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(!per_compositor_data_[compositor]); 281558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 282558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch gfx::AcceleratedWidget widget = compositor->widget(); 283558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get(); 284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 285558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch PerCompositorData* data = new PerCompositorData; 286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->surface_id = tracker->AddSurfaceForNativeWidget(widget); 287558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch tracker->SetSurfaceHandle( 288558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch data->surface_id, 289558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch gfx::GLSurfaceHandle(widget, gfx::NATIVE_DIRECT)); 290558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 291558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch per_compositor_data_[compositor] = data; 292558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 293558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return data; 294558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 295558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 296558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<WebGraphicsContext3DCommandBufferImpl> 297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)GpuProcessTransportFactory::CreateContextCommon(int surface_id) { 298558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) 299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); 300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebGraphicsContext3D::Attributes attrs; 301558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.shareResources = true; 302558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.depth = false; 303558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.stencil = false; 304558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.antialias = false; 305558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch attrs.noAutomaticFlushes = true; 306e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool lose_context_when_out_of_memory = true; 307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CauseForGpuLaunch cause = 308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE; 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_refptr<GpuChannelHost> gpu_channel_host( 310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause)); 311a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!gpu_channel_host) { 312a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "Failed to establish GPU channel."; 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>(); 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 315558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon"); 316558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context( 317558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch new WebGraphicsContext3DCommandBufferImpl( 318558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch surface_id, 319558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch url, 3201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) gpu_channel_host.get(), 3211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) attrs, 322e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch lose_context_when_out_of_memory, 323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(), 324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NULL)); 325558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return context.Pass(); 326558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 327558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 328fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() { 329558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::MessageLoop::current()->PostTask( 330558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch FROM_HERE, 331558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext, 332fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch callback_factory_.GetWeakPtr())); 333558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 334558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 335558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::OnLostMainThreadSharedContext() { 336558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch LOG(ERROR) << "Lost UI shared context."; 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 338558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Keep old resources around while we call the observers, but ensure that 339558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // new resources are created if needed. 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Kill shared contexts for both threads in tandem so they are always in 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // the same share group. 3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<cc::ContextProvider> lost_shared_main_thread_contexts = 3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) shared_main_thread_contexts_; 3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) shared_main_thread_contexts_ = NULL; 345558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 3463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<GLHelper> lost_gl_helper = gl_helper_.Pass(); 347558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 348558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch FOR_EACH_OBSERVER(ImageTransportFactoryObserver, 349558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch observer_list_, 350558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch OnLostResources()); 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Kill things that use the shared context before killing the shared context. 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) lost_gl_helper.reset(); 3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) lost_shared_main_thread_contexts = NULL; 355558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 356558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 357558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} // namespace content 358