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/profiler/scoped_tracker.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/thread_task_runner_handle.h"
16 #include "base/threading/simple_thread.h"
17 #include "base/threading/thread.h"
18 #include "cc/output/compositor_frame.h"
19 #include "cc/output/output_surface.h"
20 #include "cc/raster/task_graph_runner.h"
21 #include "cc/surfaces/onscreen_display_client.h"
22 #include "cc/surfaces/surface_display_output_surface.h"
23 #include "cc/surfaces/surface_manager.h"
24 #include "content/browser/compositor/browser_compositor_output_surface.h"
25 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator.h"
26 #include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
27 #include "content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h"
28 #include "content/browser/compositor/offscreen_browser_compositor_output_surface.h"
29 #include "content/browser/compositor/reflector_impl.h"
30 #include "content/browser/compositor/software_browser_compositor_output_surface.h"
31 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
32 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
33 #include "content/browser/gpu/compositor_util.h"
34 #include "content/browser/gpu/gpu_data_manager_impl.h"
35 #include "content/browser/gpu/gpu_surface_tracker.h"
36 #include "content/browser/renderer_host/render_widget_host_impl.h"
37 #include "content/common/gpu/client/context_provider_command_buffer.h"
38 #include "content/common/gpu/client/gl_helper.h"
39 #include "content/common/gpu/client/gpu_channel_host.h"
40 #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
41 #include "content/common/gpu/gpu_process_launch_causes.h"
42 #include "content/common/host_shared_bitmap_manager.h"
43 #include "content/public/common/content_switches.h"
44 #include "gpu/GLES2/gl2extchromium.h"
45 #include "gpu/command_buffer/client/gles2_interface.h"
46 #include "gpu/command_buffer/common/mailbox.h"
47 #include "third_party/khronos/GLES2/gl2.h"
48 #include "ui/compositor/compositor.h"
49 #include "ui/compositor/compositor_constants.h"
50 #include "ui/compositor/compositor_switches.h"
51 #include "ui/compositor/layer.h"
52 #include "ui/gfx/geometry/size.h"
53 #include "ui/gfx/native_widget_types.h"
56 #include "content/browser/compositor/software_output_device_win.h"
57 #elif defined(USE_OZONE)
58 #include "content/browser/compositor/browser_compositor_overlay_candidate_validator_ozone.h"
59 #include "content/browser/compositor/software_output_device_ozone.h"
60 #include "ui/ozone/public/overlay_candidates_ozone.h"
61 #include "ui/ozone/public/overlay_manager_ozone.h"
62 #include "ui/ozone/public/ozone_platform.h"
63 #include "ui/ozone/public/ozone_switches.h"
64 #elif defined(USE_X11)
65 #include "content/browser/compositor/software_output_device_x11.h"
66 #elif defined(OS_MACOSX)
67 #include "content/browser/compositor/software_output_device_mac.h"
70 using cc::ContextProvider
;
71 using gpu::gles2::GLES2Interface
;
73 static const int kNumRetriesBeforeSoftwareFallback
= 4;
78 class RasterThread
: public base::SimpleThread
{
80 RasterThread(cc::TaskGraphRunner
* task_graph_runner
)
81 : base::SimpleThread("CompositorTileWorker1"),
82 task_graph_runner_(task_graph_runner
) {}
84 // Overridden from base::SimpleThread:
85 void Run() override
{ task_graph_runner_
->Run(); }
88 cc::TaskGraphRunner
* task_graph_runner_
;
90 DISALLOW_COPY_AND_ASSIGN(RasterThread
);
95 struct GpuProcessTransportFactory::PerCompositorData
{
97 BrowserCompositorOutputSurface
* surface
;
98 ReflectorImpl
* reflector
;
99 scoped_ptr
<cc::OnscreenDisplayClient
> display_client
;
101 PerCompositorData() : surface_id(0), surface(nullptr), reflector(nullptr) {}
104 GpuProcessTransportFactory::GpuProcessTransportFactory()
105 : next_surface_id_namespace_(1u),
106 task_graph_runner_(new cc::TaskGraphRunner
),
107 callback_factory_(this) {
108 ui::Layer::InitializeUILayerSettings();
110 if (UseSurfacesEnabled())
111 surface_manager_
= make_scoped_ptr(new cc::SurfaceManager
);
113 if (ui::IsUIImplSidePaintingEnabled()) {
114 raster_thread_
.reset(new RasterThread(task_graph_runner_
.get()));
115 raster_thread_
->Start();
118 software_backing_
.reset(new OutputDeviceBacking
);
122 GpuProcessTransportFactory::~GpuProcessTransportFactory() {
123 DCHECK(per_compositor_data_
.empty());
125 // Make sure the lost context callback doesn't try to run during destruction.
126 callback_factory_
.InvalidateWeakPtrs();
128 task_graph_runner_
->Shutdown();
130 raster_thread_
->Join();
133 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
134 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() {
135 CauseForGpuLaunch cause
=
136 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
137 scoped_refptr
<GpuChannelHost
> gpu_channel_host(
138 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause
));
139 return CreateContextCommon(gpu_channel_host
, 0);
142 scoped_ptr
<cc::SoftwareOutputDevice
>
143 GpuProcessTransportFactory::CreateSoftwareOutputDevice(
144 ui::Compositor
* compositor
) {
146 return scoped_ptr
<cc::SoftwareOutputDevice
>(
147 new SoftwareOutputDeviceWin(software_backing_
.get(), compositor
));
148 #elif defined(USE_OZONE)
149 return scoped_ptr
<cc::SoftwareOutputDevice
>(new SoftwareOutputDeviceOzone(
151 #elif defined(USE_X11)
152 return scoped_ptr
<cc::SoftwareOutputDevice
>(new SoftwareOutputDeviceX11(
154 #elif defined(OS_MACOSX)
155 return scoped_ptr
<cc::SoftwareOutputDevice
>(
156 new SoftwareOutputDeviceMac(compositor
));
159 return scoped_ptr
<cc::SoftwareOutputDevice
>();
163 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>
164 CreateOverlayCandidateValidator(gfx::AcceleratedWidget widget
) {
165 #if defined(USE_OZONE)
166 scoped_ptr
<ui::OverlayCandidatesOzone
> overlay_candidates
=
167 ui::OzonePlatform::GetInstance()
168 ->GetOverlayManager()
169 ->CreateOverlayCandidates(widget
);
170 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
171 if (overlay_candidates
&&
172 (command_line
->HasSwitch(switches::kEnableHardwareOverlays
) ||
173 command_line
->HasSwitch(switches::kOzoneTestSingleOverlaySupport
))) {
174 return scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>(
175 new BrowserCompositorOverlayCandidateValidatorOzone(
176 widget
, overlay_candidates
.Pass()));
179 return scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>();
182 static bool ShouldCreateGpuOutputSurface(ui::Compositor
* compositor
) {
183 #if defined(OS_CHROMEOS)
184 // Software fallback does not happen on Chrome OS.
189 if (::GetProp(compositor
->widget(), kForceSoftwareCompositor
) &&
190 ::RemoveProp(compositor
->widget(), kForceSoftwareCompositor
))
194 return GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor();
197 void GpuProcessTransportFactory::CreateOutputSurface(
198 base::WeakPtr
<ui::Compositor
> compositor
) {
199 DCHECK(!!compositor
);
200 PerCompositorData
* data
= per_compositor_data_
[compositor
.get()];
202 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
204 tracked_objects::ScopedTracker
tracking_profile1(
205 FROM_HERE_WITH_EXPLICIT_FUNCTION(
206 "466870 GpuProcessTransportFactory::CreateOutputSurface1"));
207 data
= CreatePerCompositorData(compositor
.get());
209 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
210 // output_surface_map_ here.
211 output_surface_map_
.Remove(data
->surface_id
);
212 data
->surface
= nullptr;
215 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
217 tracked_objects::ScopedTracker
tracking_profile2(
218 FROM_HERE_WITH_EXPLICIT_FUNCTION(
219 "466870 GpuProcessTransportFactory::CreateOutputSurface2"));
221 bool create_gpu_output_surface
=
222 ShouldCreateGpuOutputSurface(compositor
.get());
223 if (create_gpu_output_surface
) {
224 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
226 tracked_objects::ScopedTracker
tracking_profile3(
227 FROM_HERE_WITH_EXPLICIT_FUNCTION(
228 "466870 GpuProcessTransportFactory::CreateOutputSurface3"));
230 CauseForGpuLaunch cause
=
231 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
232 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
233 cause
, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel
,
234 callback_factory_
.GetWeakPtr(), compositor
,
235 create_gpu_output_surface
, 0));
237 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
239 tracked_objects::ScopedTracker
tracking_profile4(
240 FROM_HERE_WITH_EXPLICIT_FUNCTION(
241 "466870 GpuProcessTransportFactory::CreateOutputSurface4"));
243 EstablishedGpuChannel(compositor
, create_gpu_output_surface
, 0);
247 void GpuProcessTransportFactory::EstablishedGpuChannel(
248 base::WeakPtr
<ui::Compositor
> compositor
,
249 bool create_gpu_output_surface
,
253 PerCompositorData
* data
= per_compositor_data_
[compositor
.get()];
256 if (num_attempts
> kNumRetriesBeforeSoftwareFallback
) {
257 #if defined(OS_CHROMEOS)
258 LOG(FATAL
) << "Unable to create a UI graphics context, and cannot use "
259 << "software compositing on ChromeOS.";
261 create_gpu_output_surface
= false;
264 scoped_refptr
<ContextProviderCommandBuffer
> context_provider
;
265 if (create_gpu_output_surface
) {
266 scoped_refptr
<GpuChannelHost
> gpu_channel_host
=
267 BrowserGpuChannelHostFactory::instance()->GetGpuChannel();
268 if (gpu_channel_host
.get()) {
269 context_provider
= ContextProviderCommandBuffer::Create(
270 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host
,
272 BROWSER_COMPOSITOR_ONSCREEN_CONTEXT
);
273 if (context_provider
&& !context_provider
->BindToCurrentThread())
274 context_provider
= nullptr;
277 UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
278 !!context_provider
.get());
280 if (!context_provider
) {
282 CauseForGpuLaunch cause
=
283 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
284 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
285 cause
, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel
,
286 callback_factory_
.GetWeakPtr(), compositor
,
287 create_gpu_output_surface
, num_attempts
+ 1));
292 scoped_ptr
<BrowserCompositorOutputSurface
> surface
;
293 if (!create_gpu_output_surface
) {
294 surface
= make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface(
295 CreateSoftwareOutputDevice(compositor
.get()),
296 compositor
->vsync_manager()));
298 DCHECK(context_provider
);
299 if (!data
->surface_id
) {
300 surface
= make_scoped_ptr(new OffscreenBrowserCompositorOutputSurface(
301 context_provider
, compositor
->vsync_manager(),
302 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>()));
304 #if defined(USE_OZONE)
305 if (ui::OzonePlatform::GetInstance()
306 ->GetOverlayManager()
307 ->CanShowPrimaryPlaneAsOverlay()) {
309 make_scoped_ptr(new GpuSurfacelessBrowserCompositorOutputSurface(
310 context_provider
, data
->surface_id
, compositor
->vsync_manager(),
311 CreateOverlayCandidateValidator(compositor
->widget()), GL_RGB
,
312 BrowserGpuMemoryBufferManager::current()));
316 surface
= make_scoped_ptr(new GpuBrowserCompositorOutputSurface(
317 context_provider
, compositor
->vsync_manager(),
318 CreateOverlayCandidateValidator(compositor
->widget())));
322 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
323 // output_surface_map_ here.
324 output_surface_map_
.AddWithID(surface
.get(), data
->surface_id
);
325 data
->surface
= surface
.get();
327 data
->reflector
->OnSourceSurfaceReady(data
->surface
);
329 if (!UseSurfacesEnabled()) {
330 compositor
->SetOutputSurface(surface
.Pass());
334 // This gets a bit confusing. Here we have a ContextProvider in the |surface|
335 // configured to render directly to this widget. We need to make an
336 // OnscreenDisplayClient associated with that context, then return a
337 // SurfaceDisplayOutputSurface set up to draw to the display's surface.
338 cc::SurfaceManager
* manager
= surface_manager_
.get();
339 scoped_ptr
<cc::OnscreenDisplayClient
> display_client(
340 new cc::OnscreenDisplayClient(
341 surface
.Pass(), manager
, HostSharedBitmapManager::current(),
342 BrowserGpuMemoryBufferManager::current(),
343 compositor
->GetRendererSettings(), compositor
->task_runner()));
345 scoped_ptr
<cc::SurfaceDisplayOutputSurface
> output_surface(
346 new cc::SurfaceDisplayOutputSurface(
347 manager
, compositor
->surface_id_allocator(), context_provider
));
348 display_client
->set_surface_output_surface(output_surface
.get());
349 output_surface
->set_display_client(display_client
.get());
350 display_client
->display()->Resize(compositor
->size());
351 data
->display_client
= display_client
.Pass();
352 compositor
->SetOutputSurface(output_surface
.Pass());
355 scoped_ptr
<ui::Reflector
> GpuProcessTransportFactory::CreateReflector(
356 ui::Compositor
* source_compositor
,
357 ui::Layer
* target_layer
) {
358 PerCompositorData
* source_data
= per_compositor_data_
[source_compositor
];
361 scoped_ptr
<ReflectorImpl
> reflector(
362 new ReflectorImpl(source_compositor
, target_layer
));
363 source_data
->reflector
= reflector
.get();
364 if (BrowserCompositorOutputSurface
* source_surface
= source_data
->surface
)
365 reflector
->OnSourceSurfaceReady(source_surface
);
366 return reflector
.Pass();
369 void GpuProcessTransportFactory::RemoveReflector(ui::Reflector
* reflector
) {
370 ReflectorImpl
* reflector_impl
= static_cast<ReflectorImpl
*>(reflector
);
371 PerCompositorData
* data
=
372 per_compositor_data_
[reflector_impl
->mirrored_compositor()];
374 data
->reflector
->Shutdown();
375 data
->reflector
= nullptr;
378 void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor
* compositor
) {
379 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
380 if (it
== per_compositor_data_
.end())
382 PerCompositorData
* data
= it
->second
;
384 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
385 // output_surface_map_ here.
387 output_surface_map_
.Remove(data
->surface_id
);
388 if (data
->surface_id
)
389 GpuSurfaceTracker::Get()->RemoveSurface(data
->surface_id
);
391 per_compositor_data_
.erase(it
);
392 if (per_compositor_data_
.empty()) {
393 // Destroying the GLHelper may cause some async actions to be cancelled,
394 // causing things to request a new GLHelper. Due to crbug.com/176091 the
395 // GLHelper created in this case would be lost/leaked if we just reset()
396 // on the |gl_helper_| variable directly. So instead we call reset() on a
398 scoped_ptr
<GLHelper
> helper
= gl_helper_
.Pass();
400 // If there are any observer left at this point, make sure they clean up
401 // before we destroy the GLHelper.
403 ImageTransportFactoryObserver
, observer_list_
, OnLostResources());
406 DCHECK(!gl_helper_
) << "Destroying the GLHelper should not cause a new "
407 "GLHelper to be created.";
411 bool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; }
413 uint32
GpuProcessTransportFactory::GetImageTextureTarget(
414 gfx::GpuMemoryBuffer::Format format
,
415 gfx::GpuMemoryBuffer::Usage usage
) {
416 return BrowserGpuChannelHostFactory::GetImageTextureTarget(format
, usage
);
419 cc::SharedBitmapManager
* GpuProcessTransportFactory::GetSharedBitmapManager() {
420 return HostSharedBitmapManager::current();
423 gpu::GpuMemoryBufferManager
*
424 GpuProcessTransportFactory::GetGpuMemoryBufferManager() {
425 return BrowserGpuMemoryBufferManager::current();
428 cc::TaskGraphRunner
* GpuProcessTransportFactory::GetTaskGraphRunner() {
429 return task_graph_runner_
.get();
432 ui::ContextFactory
* GpuProcessTransportFactory::GetContextFactory() {
436 gfx::GLSurfaceHandle
GpuProcessTransportFactory::GetSharedSurfaceHandle() {
437 gfx::GLSurfaceHandle handle
= gfx::GLSurfaceHandle(
438 gfx::kNullPluginWindow
, gfx::NULL_TRANSPORT
);
439 handle
.parent_client_id
=
440 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
444 scoped_ptr
<cc::SurfaceIdAllocator
>
445 GpuProcessTransportFactory::CreateSurfaceIdAllocator() {
446 scoped_ptr
<cc::SurfaceIdAllocator
> allocator
=
447 make_scoped_ptr(new cc::SurfaceIdAllocator(next_surface_id_namespace_
++));
448 if (GetSurfaceManager())
449 allocator
->RegisterSurfaceIdNamespace(GetSurfaceManager());
453 void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor
* compositor
,
454 const gfx::Size
& size
) {
455 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
456 if (it
== per_compositor_data_
.end())
458 PerCompositorData
* data
= it
->second
;
460 if (data
->display_client
)
461 data
->display_client
->display()->Resize(size
);
464 cc::SurfaceManager
* GpuProcessTransportFactory::GetSurfaceManager() {
465 return surface_manager_
.get();
468 GLHelper
* GpuProcessTransportFactory::GetGLHelper() {
469 if (!gl_helper_
&& !per_compositor_data_
.empty()) {
470 scoped_refptr
<cc::ContextProvider
> provider
=
471 SharedMainThreadContextProvider();
473 gl_helper_
.reset(new GLHelper(provider
->ContextGL(),
474 provider
->ContextSupport()));
476 return gl_helper_
.get();
479 void GpuProcessTransportFactory::AddObserver(
480 ImageTransportFactoryObserver
* observer
) {
481 observer_list_
.AddObserver(observer
);
484 void GpuProcessTransportFactory::RemoveObserver(
485 ImageTransportFactoryObserver
* observer
) {
486 observer_list_
.RemoveObserver(observer
);
489 #if defined(OS_MACOSX)
490 void GpuProcessTransportFactory::OnSurfaceDisplayed(int surface_id
) {
491 BrowserCompositorOutputSurface
* surface
= output_surface_map_
.Lookup(
494 surface
->OnSurfaceDisplayed();
497 void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
498 ui::Compositor
* compositor
,
500 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
501 if (it
== per_compositor_data_
.end())
503 PerCompositorData
* data
= it
->second
;
505 BrowserCompositorOutputSurface
* surface
=
506 output_surface_map_
.Lookup(data
->surface_id
);
508 surface
->SetSurfaceSuspendedForRecycle(suspended
);
511 bool GpuProcessTransportFactory::
512 SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id
) const {
513 BrowserCompositorOutputSurface
* surface
=
514 output_surface_map_
.Lookup(surface_id
);
516 return surface
->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
521 scoped_refptr
<cc::ContextProvider
>
522 GpuProcessTransportFactory::SharedMainThreadContextProvider() {
523 if (shared_main_thread_contexts_
.get())
524 return shared_main_thread_contexts_
;
526 // In threaded compositing mode, we have to create our own context for the
527 // main thread since the compositor's context will be bound to the
528 // compositor thread. When not in threaded mode, we still need a separate
529 // context so that skia and gl_helper don't step on each other.
530 shared_main_thread_contexts_
= ContextProviderCommandBuffer::Create(
531 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(),
532 BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT
);
534 if (shared_main_thread_contexts_
.get()) {
535 shared_main_thread_contexts_
->SetLostContextCallback(
536 base::Bind(&GpuProcessTransportFactory::
537 OnLostMainThreadSharedContextInsideCallback
,
538 callback_factory_
.GetWeakPtr()));
539 if (!shared_main_thread_contexts_
->BindToCurrentThread())
540 shared_main_thread_contexts_
= NULL
;
542 return shared_main_thread_contexts_
;
545 GpuProcessTransportFactory::PerCompositorData
*
546 GpuProcessTransportFactory::CreatePerCompositorData(
547 ui::Compositor
* compositor
) {
548 DCHECK(!per_compositor_data_
[compositor
]);
550 gfx::AcceleratedWidget widget
= compositor
->widget();
551 GpuSurfaceTracker
* tracker
= GpuSurfaceTracker::Get();
553 PerCompositorData
* data
= new PerCompositorData
;
554 if (compositor
->widget() == gfx::kNullAcceleratedWidget
) {
555 data
->surface_id
= 0;
557 data
->surface_id
= tracker
->AddSurfaceForNativeWidget(widget
);
558 tracker
->SetSurfaceHandle(data
->surface_id
,
559 gfx::GLSurfaceHandle(widget
, gfx::NATIVE_DIRECT
));
562 per_compositor_data_
[compositor
] = data
;
567 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
568 GpuProcessTransportFactory::CreateContextCommon(
569 scoped_refptr
<GpuChannelHost
> gpu_channel_host
,
571 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
572 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
573 blink::WebGraphicsContext3D::Attributes attrs
;
574 attrs
.shareResources
= true;
576 attrs
.stencil
= false;
577 attrs
.antialias
= false;
578 attrs
.noAutomaticFlushes
= true;
579 bool lose_context_when_out_of_memory
= true;
580 if (!gpu_channel_host
.get()) {
581 LOG(ERROR
) << "Failed to establish GPU channel.";
582 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
584 GURL
url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
585 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context(
586 new WebGraphicsContext3DCommandBufferImpl(
589 gpu_channel_host
.get(),
591 lose_context_when_out_of_memory
,
592 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
594 return context
.Pass();
597 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
598 base::ThreadTaskRunnerHandle::Get()->PostTask(
600 base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext
,
601 callback_factory_
.GetWeakPtr()));
604 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
605 LOG(ERROR
) << "Lost UI shared context.";
607 // Keep old resources around while we call the observers, but ensure that
608 // new resources are created if needed.
609 // Kill shared contexts for both threads in tandem so they are always in
610 // the same share group.
611 scoped_refptr
<cc::ContextProvider
> lost_shared_main_thread_contexts
=
612 shared_main_thread_contexts_
;
613 shared_main_thread_contexts_
= NULL
;
615 scoped_ptr
<GLHelper
> lost_gl_helper
= gl_helper_
.Pass();
617 FOR_EACH_OBSERVER(ImageTransportFactoryObserver
,
621 // Kill things that use the shared context before killing the shared context.
622 lost_gl_helper
.reset();
623 lost_shared_main_thread_contexts
= NULL
;
626 } // namespace content