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