Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / content / browser / compositor / gpu_process_transport_factory.cc
blobf73e8a3015bf44e56d98e4dad6be4c67f223b508
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/compositor/gpu_process_transport_factory.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/location.h"
12 #include "base/metrics/histogram.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "base/threading/simple_thread.h"
16 #include "base/threading/thread.h"
17 #include "cc/output/compositor_frame.h"
18 #include "cc/output/output_surface.h"
19 #include "cc/raster/task_graph_runner.h"
20 #include "cc/surfaces/onscreen_display_client.h"
21 #include "cc/surfaces/surface_display_output_surface.h"
22 #include "cc/surfaces/surface_manager.h"
23 #include "content/browser/compositor/browser_compositor_output_surface.h"
24 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator.h"
25 #include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
26 #include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h"
27 #include "content/browser/compositor/offscreen_browser_compositor_output_surface.h"
28 #include "content/browser/compositor/reflector_impl.h"
29 #include "content/browser/compositor/software_browser_compositor_output_surface.h"
30 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
31 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
32 #include "content/browser/gpu/compositor_util.h"
33 #include "content/browser/gpu/gpu_data_manager_impl.h"
34 #include "content/browser/gpu/gpu_surface_tracker.h"
35 #include "content/browser/renderer_host/render_widget_host_impl.h"
36 #include "content/common/gpu/client/context_provider_command_buffer.h"
37 #include "content/common/gpu/client/gl_helper.h"
38 #include "content/common/gpu/client/gpu_channel_host.h"
39 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
40 #include "content/common/gpu/gpu_process_launch_causes.h"
41 #include "content/common/host_shared_bitmap_manager.h"
42 #include "content/public/common/content_switches.h"
43 #include "gpu/GLES2/gl2extchromium.h"
44 #include "gpu/command_buffer/client/gles2_interface.h"
45 #include "gpu/command_buffer/common/mailbox.h"
46 #include "third_party/khronos/GLES2/gl2.h"
47 #include "ui/compositor/compositor.h"
48 #include "ui/compositor/compositor_constants.h"
49 #include "ui/compositor/compositor_switches.h"
50 #include "ui/compositor/layer.h"
51 #include "ui/gfx/geometry/size.h"
52 #include "ui/gfx/native_widget_types.h"
54 #if defined(OS_WIN)
55 #include "content/browser/compositor/software_output_device_win.h"
56 #elif defined(USE_OZONE)
57 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h"
58 #include "content/browser/compositor/software_output_device_ozone.h"
59 #include "ui/ozone/public/overlay_candidates_ozone.h"
60 #include "ui/ozone/public/overlay_manager_ozone.h"
61 #include "ui/ozone/public/ozone_platform.h"
62 #include "ui/ozone/public/ozone_switches.h"
63 #elif defined(USE_X11)
64 #include "content/browser/compositor/software_output_device_x11.h"
65 #elif defined(OS_MACOSX)
66 #include "content/browser/compositor/software_output_device_mac.h"
67 #endif
69 using cc::ContextProvider;
70 using gpu::gles2::GLES2Interface;
72 static const int kNumRetriesBeforeSoftwareFallback = 4;
74 namespace content {
75 namespace {
77 class RasterThread : public base::SimpleThread {
78 public:
79 RasterThread(cc::TaskGraphRunner* task_graph_runner)
80 : base::SimpleThread("CompositorTileWorker1"),
81 task_graph_runner_(task_graph_runner) {}
83 // Overridden from base::SimpleThread:
84 void Run() override { task_graph_runner_->Run(); }
86 private:
87 cc::TaskGraphRunner* task_graph_runner_;
89 DISALLOW_COPY_AND_ASSIGN(RasterThread);
92 } // namespace
94 struct GpuProcessTransportFactory::PerCompositorData {
95 int surface_id;
96 BrowserCompositorOutputSurface* surface;
97 ReflectorImpl* reflector;
98 scoped_ptr<cc::OnscreenDisplayClient> display_client;
100 PerCompositorData() : surface_id(0), surface(nullptr), reflector(nullptr) {}
103 GpuProcessTransportFactory::GpuProcessTransportFactory()
104 : next_surface_id_namespace_(1u),
105 task_graph_runner_(new cc::TaskGraphRunner),
106 callback_factory_(this) {
107 ui::Layer::InitializeUILayerSettings();
109 if (UseSurfacesEnabled())
110 surface_manager_ = make_scoped_ptr(new cc::SurfaceManager);
112 raster_thread_.reset(new RasterThread(task_graph_runner_.get()));
113 raster_thread_->Start();
114 #if defined(OS_WIN)
115 software_backing_.reset(new OutputDeviceBacking);
116 #endif
119 GpuProcessTransportFactory::~GpuProcessTransportFactory() {
120 DCHECK(per_compositor_data_.empty());
122 // Make sure the lost context callback doesn't try to run during destruction.
123 callback_factory_.InvalidateWeakPtrs();
125 task_graph_runner_->Shutdown();
126 if (raster_thread_)
127 raster_thread_->Join();
130 scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
131 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() {
132 CauseForGpuLaunch cause =
133 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
134 scoped_refptr<GpuChannelHost> gpu_channel_host(
135 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause));
136 return CreateContextCommon(gpu_channel_host, 0);
139 scoped_ptr<cc::SoftwareOutputDevice>
140 GpuProcessTransportFactory::CreateSoftwareOutputDevice(
141 ui::Compositor* compositor) {
142 #if defined(OS_WIN)
143 return scoped_ptr<cc::SoftwareOutputDevice>(
144 new SoftwareOutputDeviceWin(software_backing_.get(), compositor));
145 #elif defined(USE_OZONE)
146 return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceOzone(
147 compositor));
148 #elif defined(USE_X11)
149 return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceX11(
150 compositor));
151 #elif defined(OS_MACOSX)
152 return scoped_ptr<cc::SoftwareOutputDevice>(
153 new SoftwareOutputDeviceMac(compositor));
154 #else
155 NOTREACHED();
156 return scoped_ptr<cc::SoftwareOutputDevice>();
157 #endif
160 scoped_ptr<BrowserCompositorOverlayCandidateValidator>
161 CreateOverlayCandidateValidator(gfx::AcceleratedWidget widget) {
162 #if defined(USE_OZONE)
163 scoped_ptr<ui::OverlayCandidatesOzone> overlay_candidates =
164 ui::OzonePlatform::GetInstance()
165 ->GetOverlayManager()
166 ->CreateOverlayCandidates(widget);
167 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
168 if (overlay_candidates &&
169 (command_line->HasSwitch(switches::kEnableHardwareOverlays) ||
170 command_line->HasSwitch(switches::kOzoneTestSingleOverlaySupport))) {
171 return scoped_ptr<BrowserCompositorOverlayCandidateValidator>(
172 new BrowserCompositorOverlayCandidateValidatorOzone(
173 widget, overlay_candidates.Pass()));
175 #endif
176 return scoped_ptr<BrowserCompositorOverlayCandidateValidator>();
179 static bool ShouldCreateGpuOutputSurface(ui::Compositor* compositor) {
180 #if defined(OS_CHROMEOS)
181 // Software fallback does not happen on Chrome OS.
182 return true;
183 #endif
185 #if defined(OS_WIN)
186 if (::GetProp(compositor->widget(), kForceSoftwareCompositor) &&
187 ::RemoveProp(compositor->widget(), kForceSoftwareCompositor))
188 return false;
189 #endif
191 return GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor();
194 void GpuProcessTransportFactory::CreateOutputSurface(
195 base::WeakPtr<ui::Compositor> compositor) {
196 DCHECK(!!compositor);
197 PerCompositorData* data = per_compositor_data_[compositor.get()];
198 if (!data) {
199 data = CreatePerCompositorData(compositor.get());
200 } else {
201 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
202 // output_surface_map_ here.
203 output_surface_map_.Remove(data->surface_id);
204 data->surface = nullptr;
207 bool create_gpu_output_surface =
208 ShouldCreateGpuOutputSurface(compositor.get());
209 if (create_gpu_output_surface) {
210 CauseForGpuLaunch cause =
211 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
212 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
213 cause, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel,
214 callback_factory_.GetWeakPtr(), compositor,
215 create_gpu_output_surface, 0));
216 } else {
217 EstablishedGpuChannel(compositor, create_gpu_output_surface, 0);
221 void GpuProcessTransportFactory::EstablishedGpuChannel(
222 base::WeakPtr<ui::Compositor> compositor,
223 bool create_gpu_output_surface,
224 int num_attempts) {
225 if (!compositor)
226 return;
227 PerCompositorData* data = per_compositor_data_[compositor.get()];
228 DCHECK(data);
230 if (num_attempts > kNumRetriesBeforeSoftwareFallback) {
231 #if defined(OS_CHROMEOS)
232 LOG(FATAL) << "Unable to create a UI graphics context, and cannot use "
233 << "software compositing on ChromeOS.";
234 #endif
235 create_gpu_output_surface = false;
238 scoped_refptr<ContextProviderCommandBuffer> context_provider;
239 if (create_gpu_output_surface) {
240 scoped_refptr<GpuChannelHost> gpu_channel_host =
241 BrowserGpuChannelHostFactory::instance()->GetGpuChannel();
242 if (gpu_channel_host.get()) {
243 context_provider = ContextProviderCommandBuffer::Create(
244 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host,
245 data->surface_id),
246 BROWSER_COMPOSITOR_ONSCREEN_CONTEXT);
247 if (context_provider && !context_provider->BindToCurrentThread())
248 context_provider = nullptr;
251 UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
252 !!context_provider.get());
254 if (!context_provider) {
255 // Try again.
256 CauseForGpuLaunch cause =
257 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE;
258 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
259 cause, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel,
260 callback_factory_.GetWeakPtr(), compositor,
261 create_gpu_output_surface, num_attempts + 1));
262 return;
266 scoped_ptr<BrowserCompositorOutputSurface> surface;
267 if (!create_gpu_output_surface) {
268 surface = make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface(
269 CreateSoftwareOutputDevice(compositor.get()),
270 compositor->vsync_manager()));
271 } else {
272 DCHECK(context_provider);
273 ContextProvider::Capabilities capabilities =
274 context_provider->ContextCapabilities();
275 if (!data->surface_id) {
276 surface = make_scoped_ptr(new OffscreenBrowserCompositorOutputSurface(
277 context_provider, compositor->vsync_manager(),
278 scoped_ptr<BrowserCompositorOverlayCandidateValidator>()));
279 } else if (capabilities.gpu.surfaceless) {
280 GLenum target = GL_TEXTURE_2D;
281 GLenum format = GL_RGB;
282 #if defined(OS_MACOSX)
283 target = GL_TEXTURE_RECTANGLE_ARB;
284 format = GL_BGRA_EXT;
285 #endif
286 surface =
287 make_scoped_ptr(new GpuSurfacelessBrowserCompositorOutputSurface(
288 context_provider, data->surface_id, compositor->vsync_manager(),
289 CreateOverlayCandidateValidator(compositor->widget()), target,
290 format, BrowserGpuMemoryBufferManager::current()));
291 } else {
292 if (!surface) {
293 surface = make_scoped_ptr(new GpuBrowserCompositorOutputSurface(
294 context_provider, compositor->vsync_manager(),
295 CreateOverlayCandidateValidator(compositor->widget())));
300 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
301 // output_surface_map_ here.
302 output_surface_map_.AddWithID(surface.get(), data->surface_id);
303 data->surface = surface.get();
304 if (data->reflector)
305 data->reflector->OnSourceSurfaceReady(data->surface);
307 if (!UseSurfacesEnabled()) {
308 compositor->SetOutputSurface(surface.Pass());
309 return;
312 // This gets a bit confusing. Here we have a ContextProvider in the |surface|
313 // configured to render directly to this widget. We need to make an
314 // OnscreenDisplayClient associated with that context, then return a
315 // SurfaceDisplayOutputSurface set up to draw to the display's surface.
316 cc::SurfaceManager* manager = surface_manager_.get();
317 scoped_ptr<cc::OnscreenDisplayClient> display_client(
318 new cc::OnscreenDisplayClient(
319 surface.Pass(), manager, HostSharedBitmapManager::current(),
320 BrowserGpuMemoryBufferManager::current(),
321 compositor->GetRendererSettings(), compositor->task_runner()));
323 scoped_ptr<cc::SurfaceDisplayOutputSurface> output_surface(
324 new cc::SurfaceDisplayOutputSurface(
325 manager, compositor->surface_id_allocator(), context_provider));
326 display_client->set_surface_output_surface(output_surface.get());
327 output_surface->set_display_client(display_client.get());
328 display_client->display()->Resize(compositor->size());
329 data->display_client = display_client.Pass();
330 compositor->SetOutputSurface(output_surface.Pass());
333 scoped_ptr<ui::Reflector> GpuProcessTransportFactory::CreateReflector(
334 ui::Compositor* source_compositor,
335 ui::Layer* target_layer) {
336 PerCompositorData* source_data = per_compositor_data_[source_compositor];
337 DCHECK(source_data);
339 scoped_ptr<ReflectorImpl> reflector(
340 new ReflectorImpl(source_compositor, target_layer));
341 source_data->reflector = reflector.get();
342 if (BrowserCompositorOutputSurface* source_surface = source_data->surface)
343 reflector->OnSourceSurfaceReady(source_surface);
344 return reflector.Pass();
347 void GpuProcessTransportFactory::RemoveReflector(ui::Reflector* reflector) {
348 ReflectorImpl* reflector_impl = static_cast<ReflectorImpl*>(reflector);
349 PerCompositorData* data =
350 per_compositor_data_[reflector_impl->mirrored_compositor()];
351 DCHECK(data);
352 data->reflector->Shutdown();
353 data->reflector = nullptr;
356 void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor* compositor) {
357 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
358 if (it == per_compositor_data_.end())
359 return;
360 PerCompositorData* data = it->second;
361 DCHECK(data);
362 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
363 // output_surface_map_ here.
364 if (data->surface)
365 output_surface_map_.Remove(data->surface_id);
366 if (data->surface_id)
367 GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id);
368 delete data;
369 per_compositor_data_.erase(it);
370 if (per_compositor_data_.empty()) {
371 // Destroying the GLHelper may cause some async actions to be cancelled,
372 // causing things to request a new GLHelper. Due to crbug.com/176091 the
373 // GLHelper created in this case would be lost/leaked if we just reset()
374 // on the |gl_helper_| variable directly. So instead we call reset() on a
375 // local scoped_ptr.
376 scoped_ptr<GLHelper> helper = gl_helper_.Pass();
378 // If there are any observer left at this point, make sure they clean up
379 // before we destroy the GLHelper.
380 FOR_EACH_OBSERVER(
381 ImageTransportFactoryObserver, observer_list_, OnLostResources());
383 helper.reset();
384 DCHECK(!gl_helper_) << "Destroying the GLHelper should not cause a new "
385 "GLHelper to be created.";
389 bool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; }
391 uint32 GpuProcessTransportFactory::GetImageTextureTarget(
392 gfx::GpuMemoryBuffer::Format format,
393 gfx::GpuMemoryBuffer::Usage usage) {
394 return BrowserGpuMemoryBufferManager::GetImageTextureTarget(format, usage);
397 cc::SharedBitmapManager* GpuProcessTransportFactory::GetSharedBitmapManager() {
398 return HostSharedBitmapManager::current();
401 gpu::GpuMemoryBufferManager*
402 GpuProcessTransportFactory::GetGpuMemoryBufferManager() {
403 return BrowserGpuMemoryBufferManager::current();
406 cc::TaskGraphRunner* GpuProcessTransportFactory::GetTaskGraphRunner() {
407 return task_graph_runner_.get();
410 ui::ContextFactory* GpuProcessTransportFactory::GetContextFactory() {
411 return this;
414 gfx::GLSurfaceHandle GpuProcessTransportFactory::GetSharedSurfaceHandle() {
415 gfx::GLSurfaceHandle handle = gfx::GLSurfaceHandle(
416 gfx::kNullPluginWindow, gfx::NULL_TRANSPORT);
417 handle.parent_client_id =
418 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
419 return handle;
422 scoped_ptr<cc::SurfaceIdAllocator>
423 GpuProcessTransportFactory::CreateSurfaceIdAllocator() {
424 scoped_ptr<cc::SurfaceIdAllocator> allocator =
425 make_scoped_ptr(new cc::SurfaceIdAllocator(next_surface_id_namespace_++));
426 if (GetSurfaceManager())
427 allocator->RegisterSurfaceIdNamespace(GetSurfaceManager());
428 return allocator;
431 void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor* compositor,
432 const gfx::Size& size) {
433 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
434 if (it == per_compositor_data_.end())
435 return;
436 PerCompositorData* data = it->second;
437 DCHECK(data);
438 if (data->display_client)
439 data->display_client->display()->Resize(size);
442 cc::SurfaceManager* GpuProcessTransportFactory::GetSurfaceManager() {
443 return surface_manager_.get();
446 GLHelper* GpuProcessTransportFactory::GetGLHelper() {
447 if (!gl_helper_ && !per_compositor_data_.empty()) {
448 scoped_refptr<cc::ContextProvider> provider =
449 SharedMainThreadContextProvider();
450 if (provider.get())
451 gl_helper_.reset(new GLHelper(provider->ContextGL(),
452 provider->ContextSupport()));
454 return gl_helper_.get();
457 void GpuProcessTransportFactory::AddObserver(
458 ImageTransportFactoryObserver* observer) {
459 observer_list_.AddObserver(observer);
462 void GpuProcessTransportFactory::RemoveObserver(
463 ImageTransportFactoryObserver* observer) {
464 observer_list_.RemoveObserver(observer);
467 #if defined(OS_MACOSX)
468 void GpuProcessTransportFactory::OnSurfaceDisplayed(int surface_id) {
469 BrowserCompositorOutputSurface* surface = output_surface_map_.Lookup(
470 surface_id);
471 if (surface)
472 surface->OnSurfaceDisplayed();
475 void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
476 ui::Compositor* compositor,
477 bool suspended) {
478 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
479 if (it == per_compositor_data_.end())
480 return;
481 PerCompositorData* data = it->second;
482 DCHECK(data);
483 BrowserCompositorOutputSurface* surface =
484 output_surface_map_.Lookup(data->surface_id);
485 if (surface)
486 surface->SetSurfaceSuspendedForRecycle(suspended);
489 bool GpuProcessTransportFactory::
490 SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id) const {
491 BrowserCompositorOutputSurface* surface =
492 output_surface_map_.Lookup(surface_id);
493 if (surface)
494 return surface->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
495 return false;
497 #endif
499 scoped_refptr<cc::ContextProvider>
500 GpuProcessTransportFactory::SharedMainThreadContextProvider() {
501 if (shared_main_thread_contexts_.get())
502 return shared_main_thread_contexts_;
504 // In threaded compositing mode, we have to create our own context for the
505 // main thread since the compositor's context will be bound to the
506 // compositor thread. When not in threaded mode, we still need a separate
507 // context so that skia and gl_helper don't step on each other.
508 shared_main_thread_contexts_ = ContextProviderCommandBuffer::Create(
509 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(),
510 BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT);
512 if (shared_main_thread_contexts_.get()) {
513 shared_main_thread_contexts_->SetLostContextCallback(
514 base::Bind(&GpuProcessTransportFactory::
515 OnLostMainThreadSharedContextInsideCallback,
516 callback_factory_.GetWeakPtr()));
517 if (!shared_main_thread_contexts_->BindToCurrentThread())
518 shared_main_thread_contexts_ = NULL;
520 return shared_main_thread_contexts_;
523 GpuProcessTransportFactory::PerCompositorData*
524 GpuProcessTransportFactory::CreatePerCompositorData(
525 ui::Compositor* compositor) {
526 DCHECK(!per_compositor_data_[compositor]);
528 gfx::AcceleratedWidget widget = compositor->widget();
529 GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get();
531 PerCompositorData* data = new PerCompositorData;
532 if (compositor->widget() == gfx::kNullAcceleratedWidget) {
533 data->surface_id = 0;
534 } else {
535 data->surface_id = tracker->AddSurfaceForNativeWidget(widget);
536 tracker->SetSurfaceHandle(data->surface_id,
537 gfx::GLSurfaceHandle(widget, gfx::NATIVE_DIRECT));
540 per_compositor_data_[compositor] = data;
542 return data;
545 scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
546 GpuProcessTransportFactory::CreateContextCommon(
547 scoped_refptr<GpuChannelHost> gpu_channel_host,
548 int surface_id) {
549 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
550 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
551 blink::WebGraphicsContext3D::Attributes attrs;
552 attrs.shareResources = true;
553 attrs.depth = false;
554 attrs.stencil = false;
555 attrs.antialias = false;
556 attrs.noAutomaticFlushes = true;
557 bool lose_context_when_out_of_memory = true;
558 if (!gpu_channel_host.get()) {
559 LOG(ERROR) << "Failed to establish GPU channel.";
560 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
562 GURL url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
563 scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
564 new WebGraphicsContext3DCommandBufferImpl(
565 surface_id,
566 url,
567 gpu_channel_host.get(),
568 attrs,
569 lose_context_when_out_of_memory,
570 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
571 NULL));
572 return context.Pass();
575 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
576 base::ThreadTaskRunnerHandle::Get()->PostTask(
577 FROM_HERE,
578 base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext,
579 callback_factory_.GetWeakPtr()));
582 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
583 LOG(ERROR) << "Lost UI shared context.";
585 // Keep old resources around while we call the observers, but ensure that
586 // new resources are created if needed.
587 // Kill shared contexts for both threads in tandem so they are always in
588 // the same share group.
589 scoped_refptr<cc::ContextProvider> lost_shared_main_thread_contexts =
590 shared_main_thread_contexts_;
591 shared_main_thread_contexts_ = NULL;
593 scoped_ptr<GLHelper> lost_gl_helper = gl_helper_.Pass();
595 FOR_EACH_OBSERVER(ImageTransportFactoryObserver,
596 observer_list_,
597 OnLostResources());
599 // Kill things that use the shared context before killing the shared context.
600 lost_gl_helper.reset();
601 lost_shared_main_thread_contexts = NULL;
604 } // namespace content