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"
10 #include "base/command_line.h"
11 #include "base/location.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/metrics/histogram.h"
14 #include "base/profiler/scoped_tracker.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/resources/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/gfx/geometry/size.h"
51 #include "ui/gfx/native_widget_types.h"
54 #include "content/browser/compositor/software_output_device_win.h"
55 #elif defined(USE_OZONE)
56 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h"
57 #include "content/browser/compositor/software_output_device_ozone.h"
58 #include "ui/ozone/public/ozone_switches.h"
59 #include "ui/ozone/public/surface_factory_ozone.h"
60 #elif defined(USE_X11)
61 #include "content/browser/compositor/software_output_device_x11.h"
62 #elif defined(OS_MACOSX)
63 #include "content/browser/compositor/software_output_device_mac.h"
66 using cc::ContextProvider
;
67 using gpu::gles2::GLES2Interface
;
69 static const int kNumRetriesBeforeSoftwareFallback
= 4;
74 class RasterThread
: public base::SimpleThread
{
76 RasterThread(cc::TaskGraphRunner
* task_graph_runner
)
77 : base::SimpleThread("CompositorTileWorker1"),
78 task_graph_runner_(task_graph_runner
) {}
80 // Overridden from base::SimpleThread:
81 void Run() override
{ task_graph_runner_
->Run(); }
84 cc::TaskGraphRunner
* task_graph_runner_
;
86 DISALLOW_COPY_AND_ASSIGN(RasterThread
);
91 struct GpuProcessTransportFactory::PerCompositorData
{
93 BrowserCompositorOutputSurface
* surface
;
94 ReflectorImpl
* reflector
;
95 scoped_ptr
<cc::OnscreenDisplayClient
> display_client
;
97 PerCompositorData() : surface_id(0), surface(nullptr), reflector(nullptr) {}
100 GpuProcessTransportFactory::GpuProcessTransportFactory()
101 : next_surface_id_namespace_(1u),
102 task_graph_runner_(new cc::TaskGraphRunner
),
103 callback_factory_(this) {
104 if (UseSurfacesEnabled())
105 surface_manager_
= make_scoped_ptr(new cc::SurfaceManager
);
107 if (ui::IsUIImplSidePaintingEnabled()) {
108 raster_thread_
.reset(new RasterThread(task_graph_runner_
.get()));
109 raster_thread_
->Start();
112 software_backing_
.reset(new OutputDeviceBacking
);
116 GpuProcessTransportFactory::~GpuProcessTransportFactory() {
117 DCHECK(per_compositor_data_
.empty());
119 // Make sure the lost context callback doesn't try to run during destruction.
120 callback_factory_
.InvalidateWeakPtrs();
122 task_graph_runner_
->Shutdown();
124 raster_thread_
->Join();
127 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
128 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() {
129 CauseForGpuLaunch cause
=
130 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
131 scoped_refptr
<GpuChannelHost
> gpu_channel_host(
132 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause
));
133 return CreateContextCommon(gpu_channel_host
, 0);
136 scoped_ptr
<cc::SoftwareOutputDevice
>
137 GpuProcessTransportFactory::CreateSoftwareOutputDevice(
138 ui::Compositor
* compositor
) {
140 return scoped_ptr
<cc::SoftwareOutputDevice
>(
141 new SoftwareOutputDeviceWin(software_backing_
.get(), compositor
));
142 #elif defined(USE_OZONE)
143 return scoped_ptr
<cc::SoftwareOutputDevice
>(new SoftwareOutputDeviceOzone(
145 #elif defined(USE_X11)
146 return scoped_ptr
<cc::SoftwareOutputDevice
>(new SoftwareOutputDeviceX11(
148 #elif defined(OS_MACOSX)
149 return scoped_ptr
<cc::SoftwareOutputDevice
>(
150 new SoftwareOutputDeviceMac(compositor
));
153 return scoped_ptr
<cc::SoftwareOutputDevice
>();
157 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>
158 CreateOverlayCandidateValidator(gfx::AcceleratedWidget widget
) {
159 #if defined(USE_OZONE)
160 ui::OverlayCandidatesOzone
* overlay_candidates
=
161 ui::SurfaceFactoryOzone::GetInstance()->GetOverlayCandidates(widget
);
162 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
163 if (overlay_candidates
&&
164 (command_line
->HasSwitch(switches::kEnableHardwareOverlays
) ||
165 command_line
->HasSwitch(switches::kOzoneTestSingleOverlaySupport
))) {
166 return scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>(
167 new BrowserCompositorOverlayCandidateValidatorOzone(
168 widget
, overlay_candidates
));
171 return scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>();
174 static bool ShouldCreateGpuOutputSurface(ui::Compositor
* compositor
) {
175 #if defined(OS_CHROMEOS)
176 // Software fallback does not happen on Chrome OS.
181 if (::GetProp(compositor
->widget(), kForceSoftwareCompositor
) &&
182 ::RemoveProp(compositor
->widget(), kForceSoftwareCompositor
))
186 return GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor();
189 void GpuProcessTransportFactory::CreateOutputSurface(
190 base::WeakPtr
<ui::Compositor
> compositor
) {
191 DCHECK(!!compositor
);
192 PerCompositorData
* data
= per_compositor_data_
[compositor
.get()];
194 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
196 tracked_objects::ScopedTracker
tracking_profile1(
197 FROM_HERE_WITH_EXPLICIT_FUNCTION(
198 "466870 GpuProcessTransportFactory::CreateOutputSurface1"));
199 data
= CreatePerCompositorData(compositor
.get());
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 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
209 tracked_objects::ScopedTracker
tracking_profile2(
210 FROM_HERE_WITH_EXPLICIT_FUNCTION(
211 "466870 GpuProcessTransportFactory::CreateOutputSurface2"));
213 bool create_gpu_output_surface
=
214 ShouldCreateGpuOutputSurface(compositor
.get());
215 if (create_gpu_output_surface
) {
216 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
218 tracked_objects::ScopedTracker
tracking_profile3(
219 FROM_HERE_WITH_EXPLICIT_FUNCTION(
220 "466870 GpuProcessTransportFactory::CreateOutputSurface3"));
222 CauseForGpuLaunch cause
=
223 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
224 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
225 cause
, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel
,
226 callback_factory_
.GetWeakPtr(), compositor
,
227 create_gpu_output_surface
, 0));
229 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
231 tracked_objects::ScopedTracker
tracking_profile4(
232 FROM_HERE_WITH_EXPLICIT_FUNCTION(
233 "466870 GpuProcessTransportFactory::CreateOutputSurface4"));
235 EstablishedGpuChannel(compositor
, create_gpu_output_surface
, 0);
239 void GpuProcessTransportFactory::EstablishedGpuChannel(
240 base::WeakPtr
<ui::Compositor
> compositor
,
241 bool create_gpu_output_surface
,
245 PerCompositorData
* data
= per_compositor_data_
[compositor
.get()];
248 if (num_attempts
> kNumRetriesBeforeSoftwareFallback
) {
249 #if defined(OS_CHROMEOS)
250 LOG(FATAL
) << "Unable to create a UI graphics context, and cannot use "
251 << "software compositing on ChromeOS.";
253 create_gpu_output_surface
= false;
256 scoped_refptr
<ContextProviderCommandBuffer
> context_provider
;
257 if (create_gpu_output_surface
) {
258 scoped_refptr
<GpuChannelHost
> gpu_channel_host
=
259 BrowserGpuChannelHostFactory::instance()->GetGpuChannel();
260 if (gpu_channel_host
.get()) {
261 context_provider
= ContextProviderCommandBuffer::Create(
262 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host
,
264 BROWSER_COMPOSITOR_ONSCREEN_CONTEXT
);
265 if (context_provider
&& !context_provider
->BindToCurrentThread())
266 context_provider
= nullptr;
269 UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
270 !!context_provider
.get());
272 if (!context_provider
) {
274 CauseForGpuLaunch cause
=
275 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
276 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
277 cause
, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel
,
278 callback_factory_
.GetWeakPtr(), compositor
,
279 create_gpu_output_surface
, num_attempts
+ 1));
284 scoped_ptr
<BrowserCompositorOutputSurface
> surface
;
285 if (!create_gpu_output_surface
) {
286 surface
= make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface(
287 CreateSoftwareOutputDevice(compositor
.get()),
288 compositor
->vsync_manager()));
290 DCHECK(context_provider
);
291 if (!data
->surface_id
) {
292 surface
= make_scoped_ptr(new OffscreenBrowserCompositorOutputSurface(
293 context_provider
, compositor
->vsync_manager(),
294 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>()));
296 #if defined(USE_OZONE)
297 if (ui::SurfaceFactoryOzone::GetInstance()
298 ->CanShowPrimaryPlaneAsOverlay()) {
300 make_scoped_ptr(new GpuSurfacelessBrowserCompositorOutputSurface(
301 context_provider
, data
->surface_id
, compositor
->vsync_manager(),
302 CreateOverlayCandidateValidator(compositor
->widget()), GL_RGB
,
303 BrowserGpuMemoryBufferManager::current()));
307 surface
= make_scoped_ptr(new GpuBrowserCompositorOutputSurface(
308 context_provider
, compositor
->vsync_manager(),
309 CreateOverlayCandidateValidator(compositor
->widget())));
313 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
314 // output_surface_map_ here.
315 output_surface_map_
.AddWithID(surface
.get(), data
->surface_id
);
316 data
->surface
= surface
.get();
318 data
->reflector
->OnSourceSurfaceReady(data
->surface
);
320 if (!UseSurfacesEnabled()) {
321 compositor
->SetOutputSurface(surface
.Pass());
325 // This gets a bit confusing. Here we have a ContextProvider in the |surface|
326 // configured to render directly to this widget. We need to make an
327 // OnscreenDisplayClient associated with that context, then return a
328 // SurfaceDisplayOutputSurface set up to draw to the display's surface.
329 cc::SurfaceManager
* manager
= surface_manager_
.get();
330 scoped_ptr
<cc::OnscreenDisplayClient
> display_client(
331 new cc::OnscreenDisplayClient(
332 surface
.Pass(), manager
, HostSharedBitmapManager::current(),
333 BrowserGpuMemoryBufferManager::current(),
334 compositor
->GetRendererSettings(), compositor
->task_runner()));
336 scoped_ptr
<cc::SurfaceDisplayOutputSurface
> output_surface(
337 new cc::SurfaceDisplayOutputSurface(
338 manager
, compositor
->surface_id_allocator(), context_provider
));
339 display_client
->set_surface_output_surface(output_surface
.get());
340 output_surface
->set_display_client(display_client
.get());
341 display_client
->display()->Resize(compositor
->size());
342 data
->display_client
= display_client
.Pass();
343 compositor
->SetOutputSurface(output_surface
.Pass());
346 scoped_ptr
<ui::Reflector
> GpuProcessTransportFactory::CreateReflector(
347 ui::Compositor
* source_compositor
,
348 ui::Layer
* target_layer
) {
349 PerCompositorData
* source_data
= per_compositor_data_
[source_compositor
];
352 scoped_ptr
<ReflectorImpl
> reflector(
353 new ReflectorImpl(source_compositor
, target_layer
));
354 source_data
->reflector
= reflector
.get();
355 if (BrowserCompositorOutputSurface
* source_surface
= source_data
->surface
)
356 reflector
->OnSourceSurfaceReady(source_surface
);
357 return reflector
.Pass();
360 void GpuProcessTransportFactory::RemoveReflector(ui::Reflector
* reflector
) {
361 ReflectorImpl
* reflector_impl
= static_cast<ReflectorImpl
*>(reflector
);
362 PerCompositorData
* data
=
363 per_compositor_data_
[reflector_impl
->mirrored_compositor()];
365 data
->reflector
->Shutdown();
366 data
->reflector
= nullptr;
369 void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor
* compositor
) {
370 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
371 if (it
== per_compositor_data_
.end())
373 PerCompositorData
* data
= it
->second
;
375 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
376 // output_surface_map_ here.
378 output_surface_map_
.Remove(data
->surface_id
);
379 if (data
->surface_id
)
380 GpuSurfaceTracker::Get()->RemoveSurface(data
->surface_id
);
382 per_compositor_data_
.erase(it
);
383 if (per_compositor_data_
.empty()) {
384 // Destroying the GLHelper may cause some async actions to be cancelled,
385 // causing things to request a new GLHelper. Due to crbug.com/176091 the
386 // GLHelper created in this case would be lost/leaked if we just reset()
387 // on the |gl_helper_| variable directly. So instead we call reset() on a
389 scoped_ptr
<GLHelper
> helper
= gl_helper_
.Pass();
391 // If there are any observer left at this point, make sure they clean up
392 // before we destroy the GLHelper.
394 ImageTransportFactoryObserver
, observer_list_
, OnLostResources());
397 DCHECK(!gl_helper_
) << "Destroying the GLHelper should not cause a new "
398 "GLHelper to be created.";
402 bool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; }
404 uint32
GpuProcessTransportFactory::GetImageTextureTarget() {
405 return BrowserGpuChannelHostFactory::GetImageTextureTarget();
408 cc::SharedBitmapManager
* GpuProcessTransportFactory::GetSharedBitmapManager() {
409 return HostSharedBitmapManager::current();
412 gpu::GpuMemoryBufferManager
*
413 GpuProcessTransportFactory::GetGpuMemoryBufferManager() {
414 return BrowserGpuMemoryBufferManager::current();
417 cc::TaskGraphRunner
* GpuProcessTransportFactory::GetTaskGraphRunner() {
418 return task_graph_runner_
.get();
421 ui::ContextFactory
* GpuProcessTransportFactory::GetContextFactory() {
425 gfx::GLSurfaceHandle
GpuProcessTransportFactory::GetSharedSurfaceHandle() {
426 gfx::GLSurfaceHandle handle
= gfx::GLSurfaceHandle(
427 gfx::kNullPluginWindow
, gfx::NULL_TRANSPORT
);
428 handle
.parent_client_id
=
429 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
433 scoped_ptr
<cc::SurfaceIdAllocator
>
434 GpuProcessTransportFactory::CreateSurfaceIdAllocator() {
435 return make_scoped_ptr(
436 new cc::SurfaceIdAllocator(next_surface_id_namespace_
++));
439 void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor
* compositor
,
440 const gfx::Size
& size
) {
441 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
442 if (it
== per_compositor_data_
.end())
444 PerCompositorData
* data
= it
->second
;
446 if (data
->display_client
)
447 data
->display_client
->display()->Resize(size
);
450 cc::SurfaceManager
* GpuProcessTransportFactory::GetSurfaceManager() {
451 return surface_manager_
.get();
454 GLHelper
* GpuProcessTransportFactory::GetGLHelper() {
455 if (!gl_helper_
&& !per_compositor_data_
.empty()) {
456 scoped_refptr
<cc::ContextProvider
> provider
=
457 SharedMainThreadContextProvider();
459 gl_helper_
.reset(new GLHelper(provider
->ContextGL(),
460 provider
->ContextSupport()));
462 return gl_helper_
.get();
465 void GpuProcessTransportFactory::AddObserver(
466 ImageTransportFactoryObserver
* observer
) {
467 observer_list_
.AddObserver(observer
);
470 void GpuProcessTransportFactory::RemoveObserver(
471 ImageTransportFactoryObserver
* observer
) {
472 observer_list_
.RemoveObserver(observer
);
475 #if defined(OS_MACOSX)
476 void GpuProcessTransportFactory::OnSurfaceDisplayed(int surface_id
) {
477 BrowserCompositorOutputSurface
* surface
= output_surface_map_
.Lookup(
480 surface
->OnSurfaceDisplayed();
483 void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
484 ui::Compositor
* compositor
,
486 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
487 if (it
== per_compositor_data_
.end())
489 PerCompositorData
* data
= it
->second
;
491 BrowserCompositorOutputSurface
* surface
=
492 output_surface_map_
.Lookup(data
->surface_id
);
494 surface
->SetSurfaceSuspendedForRecycle(suspended
);
497 bool GpuProcessTransportFactory::
498 SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id
) const {
499 BrowserCompositorOutputSurface
* surface
=
500 output_surface_map_
.Lookup(surface_id
);
502 return surface
->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
507 scoped_refptr
<cc::ContextProvider
>
508 GpuProcessTransportFactory::SharedMainThreadContextProvider() {
509 if (shared_main_thread_contexts_
.get())
510 return shared_main_thread_contexts_
;
512 // In threaded compositing mode, we have to create our own context for the
513 // main thread since the compositor's context will be bound to the
514 // compositor thread. When not in threaded mode, we still need a separate
515 // context so that skia and gl_helper don't step on each other.
516 shared_main_thread_contexts_
= ContextProviderCommandBuffer::Create(
517 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(),
518 BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT
);
520 if (shared_main_thread_contexts_
.get()) {
521 shared_main_thread_contexts_
->SetLostContextCallback(
522 base::Bind(&GpuProcessTransportFactory::
523 OnLostMainThreadSharedContextInsideCallback
,
524 callback_factory_
.GetWeakPtr()));
525 if (!shared_main_thread_contexts_
->BindToCurrentThread())
526 shared_main_thread_contexts_
= NULL
;
528 return shared_main_thread_contexts_
;
531 GpuProcessTransportFactory::PerCompositorData
*
532 GpuProcessTransportFactory::CreatePerCompositorData(
533 ui::Compositor
* compositor
) {
534 DCHECK(!per_compositor_data_
[compositor
]);
536 gfx::AcceleratedWidget widget
= compositor
->widget();
537 GpuSurfaceTracker
* tracker
= GpuSurfaceTracker::Get();
539 PerCompositorData
* data
= new PerCompositorData
;
540 if (compositor
->widget() == gfx::kNullAcceleratedWidget
) {
541 data
->surface_id
= 0;
543 data
->surface_id
= tracker
->AddSurfaceForNativeWidget(widget
);
544 tracker
->SetSurfaceHandle(data
->surface_id
,
545 gfx::GLSurfaceHandle(widget
, gfx::NATIVE_DIRECT
));
548 per_compositor_data_
[compositor
] = data
;
553 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
554 GpuProcessTransportFactory::CreateContextCommon(
555 scoped_refptr
<GpuChannelHost
> gpu_channel_host
,
557 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
558 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
559 blink::WebGraphicsContext3D::Attributes attrs
;
560 attrs
.shareResources
= true;
562 attrs
.stencil
= false;
563 attrs
.antialias
= false;
564 attrs
.noAutomaticFlushes
= true;
565 bool lose_context_when_out_of_memory
= true;
566 if (!gpu_channel_host
.get()) {
567 LOG(ERROR
) << "Failed to establish GPU channel.";
568 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
570 GURL
url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
571 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context(
572 new WebGraphicsContext3DCommandBufferImpl(
575 gpu_channel_host
.get(),
577 lose_context_when_out_of_memory
,
578 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
580 return context
.Pass();
583 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
584 base::MessageLoop::current()->PostTask(
586 base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext
,
587 callback_factory_
.GetWeakPtr()));
590 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
591 LOG(ERROR
) << "Lost UI shared context.";
593 // Keep old resources around while we call the observers, but ensure that
594 // new resources are created if needed.
595 // Kill shared contexts for both threads in tandem so they are always in
596 // the same share group.
597 scoped_refptr
<cc::ContextProvider
> lost_shared_main_thread_contexts
=
598 shared_main_thread_contexts_
;
599 shared_main_thread_contexts_
= NULL
;
601 scoped_ptr
<GLHelper
> lost_gl_helper
= gl_helper_
.Pass();
603 FOR_EACH_OBSERVER(ImageTransportFactoryObserver
,
607 // Kill things that use the shared context before killing the shared context.
608 lost_gl_helper
.reset();
609 lost_shared_main_thread_contexts
= NULL
;
612 } // namespace content