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/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"
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"
69 using cc::ContextProvider
;
70 using gpu::gles2::GLES2Interface
;
72 static const int kNumRetriesBeforeSoftwareFallback
= 4;
77 class RasterThread
: public base::SimpleThread
{
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(); }
87 cc::TaskGraphRunner
* task_graph_runner_
;
89 DISALLOW_COPY_AND_ASSIGN(RasterThread
);
94 struct GpuProcessTransportFactory::PerCompositorData
{
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();
115 software_backing_
.reset(new OutputDeviceBacking
);
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();
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
) {
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(
148 #elif defined(USE_X11)
149 return scoped_ptr
<cc::SoftwareOutputDevice
>(new SoftwareOutputDeviceX11(
151 #elif defined(OS_MACOSX)
152 return scoped_ptr
<cc::SoftwareOutputDevice
>(
153 new SoftwareOutputDeviceMac(compositor
));
156 return scoped_ptr
<cc::SoftwareOutputDevice
>();
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()));
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.
186 if (::GetProp(compositor
->widget(), kForceSoftwareCompositor
) &&
187 ::RemoveProp(compositor
->widget(), kForceSoftwareCompositor
))
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()];
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 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));
217 EstablishedGpuChannel(compositor
, create_gpu_output_surface
, 0);
221 void GpuProcessTransportFactory::EstablishedGpuChannel(
222 base::WeakPtr
<ui::Compositor
> compositor
,
223 bool create_gpu_output_surface
,
227 PerCompositorData
* data
= per_compositor_data_
[compositor
.get()];
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.";
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
,
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
) {
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));
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()));
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
;
287 make_scoped_ptr(new GpuSurfacelessBrowserCompositorOutputSurface(
288 context_provider
, data
->surface_id
, compositor
->vsync_manager(),
289 CreateOverlayCandidateValidator(compositor
->widget()), target
,
290 format
, BrowserGpuMemoryBufferManager::current()));
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();
305 data
->reflector
->OnSourceSurfaceReady(data
->surface
);
307 if (!UseSurfacesEnabled()) {
308 compositor
->SetOutputSurface(surface
.Pass());
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
];
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()];
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())
360 PerCompositorData
* data
= it
->second
;
362 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
363 // output_surface_map_ here.
365 output_surface_map_
.Remove(data
->surface_id
);
366 if (data
->surface_id
)
367 GpuSurfaceTracker::Get()->RemoveSurface(data
->surface_id
);
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
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.
381 ImageTransportFactoryObserver
, observer_list_
, OnLostResources());
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() {
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();
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());
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())
436 PerCompositorData
* data
= it
->second
;
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();
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(
472 surface
->OnSurfaceDisplayed();
475 void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
476 ui::Compositor
* compositor
,
478 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
479 if (it
== per_compositor_data_
.end())
481 PerCompositorData
* data
= it
->second
;
483 BrowserCompositorOutputSurface
* surface
=
484 output_surface_map_
.Lookup(data
->surface_id
);
486 surface
->SetSurfaceSuspendedForRecycle(suspended
);
489 bool GpuProcessTransportFactory::
490 SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id
) const {
491 BrowserCompositorOutputSurface
* surface
=
492 output_surface_map_
.Lookup(surface_id
);
494 return surface
->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
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;
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
;
545 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
546 GpuProcessTransportFactory::CreateContextCommon(
547 scoped_refptr
<GpuChannelHost
> gpu_channel_host
,
549 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
550 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
551 blink::WebGraphicsContext3D::Attributes attrs
;
552 attrs
.shareResources
= true;
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(
567 gpu_channel_host
.get(),
569 lose_context_when_out_of_memory
,
570 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
572 return context
.Pass();
575 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
576 base::ThreadTaskRunnerHandle::Get()->PostTask(
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
,
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