gpu_process_transport_factory.cc revision 6d86b77056ed63eb6871182f42a9fd5f07550f90
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"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/threading/thread.h"
15558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "cc/output/compositor_frame.h"
16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "cc/output/output_surface.h"
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "cc/surfaces/surface_manager.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/browser_compositor_output_surface.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/browser_compositor_output_surface_proxy.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/browser/compositor/onscreen_display_client.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/reflector_impl.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_browser_compositor_output_surface.h"
2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/browser/compositor/surface_display_output_surface.h"
25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
26558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/gpu/gpu_data_manager_impl.h"
27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/gpu/gpu_surface_tracker.h"
28558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/browser/renderer_host/render_widget_host_impl.h"
29fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch#include "content/common/gpu/client/context_provider_command_buffer.h"
30558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/gpu/client/gl_helper.h"
31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/gpu/client/gpu_channel_host.h"
32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/gpu/gpu_process_launch_causes.h"
34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "content/common/host_shared_bitmap_manager.h"
3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "content/public/common/content_switches.h"
36558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "gpu/GLES2/gl2extchromium.h"
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h"
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox.h"
39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "third_party/khronos/GLES2/gl2.h"
40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/compositor/compositor.h"
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/compositor_constants.h"
42558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/compositor/compositor_switches.h"
43558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/gfx/native_widget_types.h"
44558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "ui/gfx/size.h"
45558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
46558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_WIN)
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_output_device_win.h"
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#elif defined(USE_OZONE)
49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/compositor/overlay_candidate_validator_ozone.h"
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_output_device_ozone.h"
516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "ui/ozone/public/surface_factory_ozone.h"
52558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#elif defined(USE_X11)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/compositor/software_output_device_x11.h"
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#elif defined(OS_MACOSX)
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/browser/compositor/software_output_device_mac.h"
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using cc::ContextProvider;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using gpu::gles2::GLES2Interface;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace content {
62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstruct GpuProcessTransportFactory::PerCompositorData {
64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  int surface_id;
65558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  scoped_refptr<ReflectorImpl> reflector;
6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scoped_ptr<OnscreenDisplayClient> display_client;
67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch};
68558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
69558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::GpuProcessTransportFactory()
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    : callback_factory_(this) {
71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  output_surface_proxy_ = new BrowserCompositorOutputSurfaceProxy(
72d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      &output_surface_map_);
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_CHROMEOS)
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool use_thread = !CommandLine::ForCurrentProcess()->HasSwitch(
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      switches::kUIDisableThreadedCompositing);
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#else
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool use_thread = false;
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (use_thread) {
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    compositor_thread_.reset(new base::Thread("Browser Compositor"));
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    compositor_thread_->Start();
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          switches::kUseSurfaces)) {
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    surface_manager_ = make_scoped_ptr(new cc::SurfaceManager);
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
88558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
89558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::~GpuProcessTransportFactory() {
90558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(per_compositor_data_.empty());
91fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch
92fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  // Make sure the lost context callback doesn't try to run during destruction.
93fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch  callback_factory_.InvalidateWeakPtrs();
94558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
95558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
96558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<WebGraphicsContext3DCommandBufferImpl>
97558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::CreateOffscreenCommandBufferContext() {
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return CreateContextCommon(0);
99558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
100558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
101bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochscoped_ptr<cc::SoftwareOutputDevice> CreateSoftwareOutputDevice(
102bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    ui::Compositor* compositor) {
103bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#if defined(OS_WIN)
104bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceWin(
105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      compositor));
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#elif defined(USE_OZONE)
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceOzone(
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      compositor));
109bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#elif defined(USE_X11)
110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceX11(
111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      compositor));
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#elif defined(OS_MACOSX)
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return scoped_ptr<cc::SoftwareOutputDevice>(
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      new SoftwareOutputDeviceMac(compositor));
11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else
116bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  NOTREACHED();
117bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return scoped_ptr<cc::SoftwareOutputDevice>();
11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
120bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_ptr<cc::OverlayCandidateValidator> CreateOverlayCandidateValidator(
122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    gfx::AcceleratedWidget widget) {
123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(USE_OZONE)
1246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ui::OverlayCandidatesOzone* overlay_candidates =
1256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      ui::SurfaceFactoryOzone::GetInstance()->GetOverlayCandidates(widget);
126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (overlay_candidates && CommandLine::ForCurrentProcess()->HasSwitch(
127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                switches::kEnableHardwareOverlays)) {
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return scoped_ptr<cc::OverlayCandidateValidator>(
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        new OverlayCandidateValidatorOzone(widget, overlay_candidates));
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return scoped_ptr<cc::OverlayCandidateValidator>();
133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
135558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<cc::OutputSurface> GpuProcessTransportFactory::CreateOutputSurface(
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ui::Compositor* compositor, bool software_fallback) {
137558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerCompositorData* data = per_compositor_data_[compositor];
138558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!data)
139558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    data = CreatePerCompositorData(compositor);
140558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool create_software_renderer = software_fallback;
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_CHROMEOS)
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Software fallback does not happen on Chrome OS.
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  create_software_renderer = false;
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#elif defined(OS_WIN)
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (::GetProp(compositor->widget(), kForceSoftwareCompositor)) {
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (::RemoveProp(compositor->widget(), kForceSoftwareCompositor))
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      create_software_renderer = true;
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<ContextProviderCommandBuffer> context_provider;
15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!create_software_renderer) {
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    context_provider = ContextProviderCommandBuffer::Create(
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        GpuProcessTransportFactory::CreateContextCommon(data->surface_id),
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        "Compositor");
158558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
159d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
160d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor", !!context_provider);
161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          switches::kUseSurfaces)) {
16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // This gets a bit confusing. Here we have a ContextProvider configured to
16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // render directly to this widget. We need to make an OnscreenDisplayClient
16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // associated with this context, then return a SurfaceDisplayOutputSurface
16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // set up to draw to the display's surface.
16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    cc::SurfaceManager* manager = surface_manager_.get();
16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<cc::OutputSurface> software_surface;
17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!context_provider) {
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      software_surface =
17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface(
17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              output_surface_proxy_,
17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              CreateSoftwareOutputDevice(compositor),
17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              per_compositor_data_[compositor]->surface_id,
17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              &output_surface_map_,
17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              compositor->vsync_manager()));
17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<OnscreenDisplayClient> display_client(new OnscreenDisplayClient(
18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        context_provider, software_surface.Pass(), manager));
18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // TODO(jamesr): Need to set up filtering for the
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    // GpuHostMsg_UpdateVSyncParameters message.
18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_refptr<cc::ContextProvider> offscreen_context_provider;
18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (context_provider) {
18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      offscreen_context_provider = ContextProviderCommandBuffer::Create(
18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(),
18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)          "Offscreen-Compositor");
18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    scoped_ptr<SurfaceDisplayOutputSurface> output_surface(
19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        new SurfaceDisplayOutputSurface(
19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)            display_client->display(), manager, offscreen_context_provider));
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    data->display_client = display_client.Pass();
19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return output_surface.PassAs<cc::OutputSurface>();
19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!context_provider.get()) {
198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (compositor_thread_.get()) {
1993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      LOG(FATAL) << "Failed to create UI context, but can't use software"
200ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                 " compositing with browser threaded compositing. Aborting.";
201ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    }
202ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<SoftwareBrowserCompositorOutputSurface> surface(
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new SoftwareBrowserCompositorOutputSurface(
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            output_surface_proxy_,
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            CreateSoftwareOutputDevice(compositor),
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            per_compositor_data_[compositor]->surface_id,
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            &output_surface_map_,
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            compositor->vsync_manager()));
210bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return surface.PassAs<cc::OutputSurface>();
211bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
212558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
213558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_task_runner =
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GetCompositorMessageLoop();
215558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!compositor_thread_task_runner.get())
216558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    compositor_thread_task_runner = base::MessageLoopProxy::current();
217558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
218558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Here we know the GpuProcessHost has been set up, because we created a
219558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // context.
220558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  output_surface_proxy_->ConnectToGpuProcessHost(
221558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      compositor_thread_task_runner.get());
222558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
223558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  scoped_ptr<BrowserCompositorOutputSurface> surface(
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new GpuBrowserCompositorOutputSurface(
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          context_provider,
226558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          per_compositor_data_[compositor]->surface_id,
227d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch          &output_surface_map_,
228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          compositor->vsync_manager(),
229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          CreateOverlayCandidateValidator(compositor->widget())));
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (data->reflector.get())
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    data->reflector->ReattachToOutputSurfaceFromMainThread(surface.get());
232558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
233558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return surface.PassAs<cc::OutputSurface>();
234558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
235558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
236558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_refptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector(
237558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ui::Compositor* source,
238558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ui::Layer* target) {
239558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerCompositorData* data = per_compositor_data_[source];
240558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(data);
241558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  data->reflector = new ReflectorImpl(source,
243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      target,
244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      &output_surface_map_,
245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      GetCompositorMessageLoop(),
246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      data->surface_id);
247558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return data->reflector;
248558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
249558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::RemoveReflector(
251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    scoped_refptr<ui::Reflector> reflector) {
252558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ReflectorImpl* reflector_impl =
253558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      static_cast<ReflectorImpl*>(reflector.get());
254558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerCompositorData* data =
255558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      per_compositor_data_[reflector_impl->mirrored_compositor()];
256558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(data);
257558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  data->reflector->Shutdown();
258558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  data->reflector = NULL;
259558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
260558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
261558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
262558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
263558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (it == per_compositor_data_.end())
264558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return;
265558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerCompositorData* data = it->second;
266558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(data);
267558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id);
268558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delete data;
269558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  per_compositor_data_.erase(it);
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (per_compositor_data_.empty()) {
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Destroying the GLHelper may cause some async actions to be cancelled,
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // causing things to request a new GLHelper. Due to crbug.com/176091 the
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // GLHelper created in this case would be lost/leaked if we just reset()
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // on the |gl_helper_| variable directly. So instead we call reset() on a
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // local scoped_ptr.
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<GLHelper> helper = gl_helper_.Pass();
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // If there are any observer left at this point, make sure they clean up
279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // before we destroy the GLHelper.
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    FOR_EACH_OBSERVER(
281f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        ImageTransportFactoryObserver, observer_list_, OnLostResources());
282f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    helper.reset();
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(!gl_helper_) << "Destroying the GLHelper should not cause a new "
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           "GLHelper to be created.";
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
287558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
288558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
289c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochbool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; }
290c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
291010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)cc::SharedBitmapManager* GpuProcessTransportFactory::GetSharedBitmapManager() {
292010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return HostSharedBitmapManager::current();
293558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
294558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2950de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)ui::ContextFactory* GpuProcessTransportFactory::GetContextFactory() {
2960de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  return this;
2970de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)}
2980de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)
299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::MessageLoopProxy* GpuProcessTransportFactory::GetCompositorMessageLoop() {
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!compositor_thread_)
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return NULL;
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return compositor_thread_->message_loop_proxy();
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::GLSurfaceHandle GpuProcessTransportFactory::GetSharedSurfaceHandle() {
306558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle(
307558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      gfx::kNullPluginWindow, gfx::TEXTURE_TRANSPORT);
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  handle.parent_client_id =
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
310558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return handle;
311558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
312558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
313558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGLHelper* GpuProcessTransportFactory::GetGLHelper() {
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!gl_helper_ && !per_compositor_data_.empty()) {
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    scoped_refptr<cc::ContextProvider> provider =
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        SharedMainThreadContextProvider();
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (provider.get())
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gl_helper_.reset(new GLHelper(provider->ContextGL(),
3198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                    provider->ContextSupport()));
320558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
321558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return gl_helper_.get();
322558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
323558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
324558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::AddObserver(
325558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ImageTransportFactoryObserver* observer) {
326558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  observer_list_.AddObserver(observer);
327558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
328558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
329558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::RemoveObserver(
330558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ImageTransportFactoryObserver* observer) {
331558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  observer_list_.RemoveObserver(observer);
332558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
333558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_MACOSX)
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void GpuProcessTransportFactory::OnSurfaceDisplayed(int surface_id) {
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  BrowserCompositorOutputSurface* surface = output_surface_map_.Lookup(
337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      surface_id);
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (surface)
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    surface->OnSurfaceDisplayed();
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
343558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_refptr<cc::ContextProvider>
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)GpuProcessTransportFactory::SharedMainThreadContextProvider() {
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (shared_main_thread_contexts_.get())
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return shared_main_thread_contexts_;
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // In threaded compositing mode, we have to create our own context for the
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // main thread since the compositor's context will be bound to the
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // compositor thread. When not in threaded mode, we still need a separate
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // context so that skia and gl_helper don't step on each other.
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  shared_main_thread_contexts_ = ContextProviderCommandBuffer::Create(
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(),
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      "Offscreen-MainThread");
3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (shared_main_thread_contexts_) {
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    shared_main_thread_contexts_->SetLostContextCallback(
3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        base::Bind(&GpuProcessTransportFactory::
3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                        OnLostMainThreadSharedContextInsideCallback,
3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                   callback_factory_.GetWeakPtr()));
3615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (!shared_main_thread_contexts_->BindToCurrentThread())
3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      shared_main_thread_contexts_ = NULL;
363558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return shared_main_thread_contexts_;
365558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
366558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
367558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::PerCompositorData*
368558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochGpuProcessTransportFactory::CreatePerCompositorData(
369558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    ui::Compositor* compositor) {
370558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK(!per_compositor_data_[compositor]);
371558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
372558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  gfx::AcceleratedWidget widget = compositor->widget();
373558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get();
374558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
375558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  PerCompositorData* data = new PerCompositorData;
376558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  data->surface_id = tracker->AddSurfaceForNativeWidget(widget);
377558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  tracker->SetSurfaceHandle(
378558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      data->surface_id,
379558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      gfx::GLSurfaceHandle(widget, gfx::NATIVE_DIRECT));
380558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
381558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  per_compositor_data_[compositor] = data;
382558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
383558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return data;
384558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
385558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
386558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochscoped_ptr<WebGraphicsContext3DCommandBufferImpl>
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)GpuProcessTransportFactory::CreateContextCommon(int surface_id) {
388558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
389558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  blink::WebGraphicsContext3D::Attributes attrs;
391558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  attrs.shareResources = true;
392558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  attrs.depth = false;
393558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  attrs.stencil = false;
394558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  attrs.antialias = false;
395558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  attrs.noAutomaticFlushes = true;
396e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  bool lose_context_when_out_of_memory = true;
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  CauseForGpuLaunch cause =
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
3991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_refptr<GpuChannelHost> gpu_channel_host(
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause));
401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!gpu_channel_host) {
402a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    LOG(ERROR) << "Failed to establish GPU channel.";
4031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
404a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
405558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
406558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
407558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      new WebGraphicsContext3DCommandBufferImpl(
408558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          surface_id,
409558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          url,
4101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          gpu_channel_host.get(),
4111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          attrs,
412e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch          lose_context_when_out_of_memory,
413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          NULL));
415558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return context.Pass();
416558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
417558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
418fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdochvoid GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
419558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  base::MessageLoop::current()->PostTask(
420558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      FROM_HERE,
421558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext,
422fb250657ef40d7500f20882d5c9909c1013367d3Ben Murdoch                 callback_factory_.GetWeakPtr()));
423558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
424558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
425558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
426558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  LOG(ERROR) << "Lost UI shared context.";
4273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
428558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Keep old resources around while we call the observers, but ensure that
429558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // new resources are created if needed.
4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Kill shared contexts for both threads in tandem so they are always in
4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // the same share group.
4324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<cc::ContextProvider> lost_shared_main_thread_contexts =
4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      shared_main_thread_contexts_;
4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  shared_main_thread_contexts_  = NULL;
435558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<GLHelper> lost_gl_helper = gl_helper_.Pass();
437558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
438558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  FOR_EACH_OBSERVER(ImageTransportFactoryObserver,
439558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                    observer_list_,
440558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                    OnLostResources());
4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Kill things that use the shared context before killing the shared context.
4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  lost_gl_helper.reset();
4444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  lost_shared_main_thread_contexts  = NULL;
445558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
446558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
447558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}  // namespace content
448