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/browser_compositor_overlay_candidate_validator_mac.h"
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 raster_thread_
.reset(new RasterThread(task_graph_runner_
.get()));
114 raster_thread_
->Start();
116 software_backing_
.reset(new OutputDeviceBacking
);
120 GpuProcessTransportFactory::~GpuProcessTransportFactory() {
121 DCHECK(per_compositor_data_
.empty());
123 // Make sure the lost context callback doesn't try to run during destruction.
124 callback_factory_
.InvalidateWeakPtrs();
126 task_graph_runner_
->Shutdown();
128 raster_thread_
->Join();
131 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
132 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext() {
133 CauseForGpuLaunch cause
=
134 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
135 scoped_refptr
<GpuChannelHost
> gpu_channel_host(
136 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannelSync(cause
));
137 return CreateContextCommon(gpu_channel_host
, 0);
140 scoped_ptr
<cc::SoftwareOutputDevice
>
141 GpuProcessTransportFactory::CreateSoftwareOutputDevice(
142 ui::Compositor
* compositor
) {
144 return scoped_ptr
<cc::SoftwareOutputDevice
>(
145 new SoftwareOutputDeviceWin(software_backing_
.get(), compositor
));
146 #elif defined(USE_OZONE)
147 return scoped_ptr
<cc::SoftwareOutputDevice
>(new SoftwareOutputDeviceOzone(
149 #elif defined(USE_X11)
150 return scoped_ptr
<cc::SoftwareOutputDevice
>(new SoftwareOutputDeviceX11(
152 #elif defined(OS_MACOSX)
153 return scoped_ptr
<cc::SoftwareOutputDevice
>(
154 new SoftwareOutputDeviceMac(compositor
));
157 return scoped_ptr
<cc::SoftwareOutputDevice
>();
161 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>
162 CreateOverlayCandidateValidator(gfx::AcceleratedWidget widget
) {
163 #if defined(USE_OZONE)
164 scoped_ptr
<ui::OverlayCandidatesOzone
> overlay_candidates
=
165 ui::OzonePlatform::GetInstance()
166 ->GetOverlayManager()
167 ->CreateOverlayCandidates(widget
);
168 base::CommandLine
* command_line
= base::CommandLine::ForCurrentProcess();
169 if (overlay_candidates
&&
170 (command_line
->HasSwitch(switches::kEnableHardwareOverlays
) ||
171 command_line
->HasSwitch(switches::kOzoneTestSingleOverlaySupport
))) {
172 return scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>(
173 new BrowserCompositorOverlayCandidateValidatorOzone(
174 widget
, overlay_candidates
.Pass()));
176 #elif defined(OS_MACOSX)
177 return make_scoped_ptr(
178 new BrowserCompositorOverlayCandidateValidatorMac(widget
));
180 return scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>();
183 static bool ShouldCreateGpuOutputSurface(ui::Compositor
* compositor
) {
184 #if defined(OS_CHROMEOS)
185 // Software fallback does not happen on Chrome OS.
190 if (::GetProp(compositor
->widget(), kForceSoftwareCompositor
) &&
191 ::RemoveProp(compositor
->widget(), kForceSoftwareCompositor
))
195 return GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor();
198 void GpuProcessTransportFactory::CreateOutputSurface(
199 base::WeakPtr
<ui::Compositor
> compositor
) {
200 DCHECK(!!compositor
);
201 PerCompositorData
* data
= per_compositor_data_
[compositor
.get()];
203 data
= CreatePerCompositorData(compositor
.get());
205 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
206 // output_surface_map_ here.
207 output_surface_map_
.Remove(data
->surface_id
);
208 data
->surface
= nullptr;
211 bool create_gpu_output_surface
=
212 ShouldCreateGpuOutputSurface(compositor
.get());
213 if (create_gpu_output_surface
) {
214 CauseForGpuLaunch cause
=
215 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
216 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
217 cause
, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel
,
218 callback_factory_
.GetWeakPtr(), compositor
,
219 create_gpu_output_surface
, 0));
221 EstablishedGpuChannel(compositor
, create_gpu_output_surface
, 0);
225 void GpuProcessTransportFactory::EstablishedGpuChannel(
226 base::WeakPtr
<ui::Compositor
> compositor
,
227 bool create_gpu_output_surface
,
231 PerCompositorData
* data
= per_compositor_data_
[compositor
.get()];
234 if (num_attempts
> kNumRetriesBeforeSoftwareFallback
) {
235 #if defined(OS_CHROMEOS)
236 LOG(FATAL
) << "Unable to create a UI graphics context, and cannot use "
237 << "software compositing on ChromeOS.";
239 create_gpu_output_surface
= false;
242 scoped_refptr
<ContextProviderCommandBuffer
> context_provider
;
243 if (create_gpu_output_surface
) {
244 // Try to reuse existing worker context provider.
245 if (shared_worker_context_provider_
) {
246 base::AutoLock
lock(*shared_worker_context_provider_
->GetLock());
247 if (shared_worker_context_provider_
->ContextGL()
248 ->GetGraphicsResetStatusKHR() != GL_NO_ERROR
)
249 shared_worker_context_provider_
= nullptr;
251 scoped_refptr
<GpuChannelHost
> gpu_channel_host
=
252 BrowserGpuChannelHostFactory::instance()->GetGpuChannel();
253 if (gpu_channel_host
.get()) {
254 context_provider
= ContextProviderCommandBuffer::Create(
255 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host
,
257 BROWSER_COMPOSITOR_ONSCREEN_CONTEXT
);
258 if (context_provider
&& !context_provider
->BindToCurrentThread())
259 context_provider
= nullptr;
260 if (!shared_worker_context_provider_
) {
261 shared_worker_context_provider_
= ContextProviderCommandBuffer::Create(
262 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host
,
264 BROWSER_WORKER_CONTEXT
);
265 if (shared_worker_context_provider_
&&
266 !shared_worker_context_provider_
->BindToCurrentThread())
267 shared_worker_context_provider_
= nullptr;
271 bool created_gpu_browser_compositor
=
272 !!context_provider
&& !!shared_worker_context_provider_
;
274 UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
275 created_gpu_browser_compositor
);
277 if (!created_gpu_browser_compositor
) {
279 CauseForGpuLaunch cause
=
280 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
281 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
282 cause
, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel
,
283 callback_factory_
.GetWeakPtr(), compositor
,
284 create_gpu_output_surface
, num_attempts
+ 1));
289 scoped_ptr
<BrowserCompositorOutputSurface
> surface
;
290 if (!create_gpu_output_surface
) {
291 surface
= make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface(
292 CreateSoftwareOutputDevice(compositor
.get()),
293 compositor
->vsync_manager()));
295 DCHECK(context_provider
);
296 ContextProvider::Capabilities capabilities
=
297 context_provider
->ContextCapabilities();
298 if (!data
->surface_id
) {
299 surface
= make_scoped_ptr(new OffscreenBrowserCompositorOutputSurface(
300 context_provider
, shared_worker_context_provider_
,
301 compositor
->vsync_manager(),
302 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>()));
303 } else if (capabilities
.gpu
.surfaceless
) {
304 GLenum target
= GL_TEXTURE_2D
;
305 GLenum format
= GL_RGB
;
306 #if defined(OS_MACOSX)
307 target
= GL_TEXTURE_RECTANGLE_ARB
;
308 format
= GL_BGRA_EXT
;
311 make_scoped_ptr(new GpuSurfacelessBrowserCompositorOutputSurface(
312 context_provider
, shared_worker_context_provider_
,
313 data
->surface_id
, compositor
->vsync_manager(),
314 CreateOverlayCandidateValidator(compositor
->widget()), target
,
315 format
, BrowserGpuMemoryBufferManager::current()));
318 surface
= make_scoped_ptr(new GpuBrowserCompositorOutputSurface(
319 context_provider
, shared_worker_context_provider_
,
320 compositor
->vsync_manager(),
321 CreateOverlayCandidateValidator(compositor
->widget())));
326 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
327 // output_surface_map_ here.
328 output_surface_map_
.AddWithID(surface
.get(), data
->surface_id
);
329 data
->surface
= surface
.get();
331 data
->reflector
->OnSourceSurfaceReady(data
->surface
);
333 if (!UseSurfacesEnabled()) {
334 compositor
->SetOutputSurface(surface
.Pass());
338 // This gets a bit confusing. Here we have a ContextProvider in the |surface|
339 // configured to render directly to this widget. We need to make an
340 // OnscreenDisplayClient associated with that context, then return a
341 // SurfaceDisplayOutputSurface set up to draw to the display's surface.
342 cc::SurfaceManager
* manager
= surface_manager_
.get();
343 scoped_ptr
<cc::OnscreenDisplayClient
> display_client(
344 new cc::OnscreenDisplayClient(
345 surface
.Pass(), manager
, HostSharedBitmapManager::current(),
346 BrowserGpuMemoryBufferManager::current(),
347 compositor
->GetRendererSettings(), compositor
->task_runner()));
349 scoped_ptr
<cc::SurfaceDisplayOutputSurface
> output_surface(
350 new cc::SurfaceDisplayOutputSurface(
351 manager
, compositor
->surface_id_allocator(), context_provider
,
352 shared_worker_context_provider_
));
353 display_client
->set_surface_output_surface(output_surface
.get());
354 output_surface
->set_display_client(display_client
.get());
355 display_client
->display()->Resize(compositor
->size());
356 data
->display_client
= display_client
.Pass();
357 compositor
->SetOutputSurface(output_surface
.Pass());
360 scoped_ptr
<ui::Reflector
> GpuProcessTransportFactory::CreateReflector(
361 ui::Compositor
* source_compositor
,
362 ui::Layer
* target_layer
) {
363 PerCompositorData
* source_data
= per_compositor_data_
[source_compositor
];
366 scoped_ptr
<ReflectorImpl
> reflector(
367 new ReflectorImpl(source_compositor
, target_layer
));
368 source_data
->reflector
= reflector
.get();
369 if (BrowserCompositorOutputSurface
* source_surface
= source_data
->surface
)
370 reflector
->OnSourceSurfaceReady(source_surface
);
371 return reflector
.Pass();
374 void GpuProcessTransportFactory::RemoveReflector(ui::Reflector
* reflector
) {
375 ReflectorImpl
* reflector_impl
= static_cast<ReflectorImpl
*>(reflector
);
376 PerCompositorData
* data
=
377 per_compositor_data_
[reflector_impl
->mirrored_compositor()];
379 data
->reflector
->Shutdown();
380 data
->reflector
= nullptr;
383 void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor
* compositor
) {
384 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
385 if (it
== per_compositor_data_
.end())
387 PerCompositorData
* data
= it
->second
;
389 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
390 // output_surface_map_ here.
392 output_surface_map_
.Remove(data
->surface_id
);
393 if (data
->surface_id
)
394 GpuSurfaceTracker::Get()->RemoveSurface(data
->surface_id
);
396 per_compositor_data_
.erase(it
);
397 if (per_compositor_data_
.empty()) {
398 // Destroying the GLHelper may cause some async actions to be cancelled,
399 // causing things to request a new GLHelper. Due to crbug.com/176091 the
400 // GLHelper created in this case would be lost/leaked if we just reset()
401 // on the |gl_helper_| variable directly. So instead we call reset() on a
403 scoped_ptr
<GLHelper
> helper
= gl_helper_
.Pass();
405 // If there are any observer left at this point, make sure they clean up
406 // before we destroy the GLHelper.
408 ImageTransportFactoryObserver
, observer_list_
, OnLostResources());
411 DCHECK(!gl_helper_
) << "Destroying the GLHelper should not cause a new "
412 "GLHelper to be created.";
416 bool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; }
418 uint32
GpuProcessTransportFactory::GetImageTextureTarget(
419 gfx::BufferFormat format
,
420 gfx::BufferUsage usage
) {
421 return BrowserGpuMemoryBufferManager::GetImageTextureTarget(format
, usage
);
424 cc::SharedBitmapManager
* GpuProcessTransportFactory::GetSharedBitmapManager() {
425 return HostSharedBitmapManager::current();
428 gpu::GpuMemoryBufferManager
*
429 GpuProcessTransportFactory::GetGpuMemoryBufferManager() {
430 return BrowserGpuMemoryBufferManager::current();
433 cc::TaskGraphRunner
* GpuProcessTransportFactory::GetTaskGraphRunner() {
434 return task_graph_runner_
.get();
437 ui::ContextFactory
* GpuProcessTransportFactory::GetContextFactory() {
441 gfx::GLSurfaceHandle
GpuProcessTransportFactory::GetSharedSurfaceHandle() {
442 gfx::GLSurfaceHandle handle
= gfx::GLSurfaceHandle(
443 gfx::kNullPluginWindow
, gfx::NULL_TRANSPORT
);
444 handle
.parent_client_id
=
445 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
449 scoped_ptr
<cc::SurfaceIdAllocator
>
450 GpuProcessTransportFactory::CreateSurfaceIdAllocator() {
451 scoped_ptr
<cc::SurfaceIdAllocator
> allocator
=
452 make_scoped_ptr(new cc::SurfaceIdAllocator(next_surface_id_namespace_
++));
453 if (GetSurfaceManager())
454 allocator
->RegisterSurfaceIdNamespace(GetSurfaceManager());
458 void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor
* compositor
,
459 const gfx::Size
& size
) {
460 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
461 if (it
== per_compositor_data_
.end())
463 PerCompositorData
* data
= it
->second
;
465 if (data
->display_client
)
466 data
->display_client
->display()->Resize(size
);
469 cc::SurfaceManager
* GpuProcessTransportFactory::GetSurfaceManager() {
470 return surface_manager_
.get();
473 GLHelper
* GpuProcessTransportFactory::GetGLHelper() {
474 if (!gl_helper_
&& !per_compositor_data_
.empty()) {
475 scoped_refptr
<cc::ContextProvider
> provider
=
476 SharedMainThreadContextProvider();
478 gl_helper_
.reset(new GLHelper(provider
->ContextGL(),
479 provider
->ContextSupport()));
481 return gl_helper_
.get();
484 void GpuProcessTransportFactory::AddObserver(
485 ImageTransportFactoryObserver
* observer
) {
486 observer_list_
.AddObserver(observer
);
489 void GpuProcessTransportFactory::RemoveObserver(
490 ImageTransportFactoryObserver
* observer
) {
491 observer_list_
.RemoveObserver(observer
);
494 #if defined(OS_MACOSX)
495 void GpuProcessTransportFactory::OnSurfaceDisplayed(int surface_id
) {
496 BrowserCompositorOutputSurface
* surface
= output_surface_map_
.Lookup(
499 surface
->OnSurfaceDisplayed();
502 void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
503 ui::Compositor
* compositor
,
505 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
506 if (it
== per_compositor_data_
.end())
508 PerCompositorData
* data
= it
->second
;
510 BrowserCompositorOutputSurface
* surface
=
511 output_surface_map_
.Lookup(data
->surface_id
);
513 surface
->SetSurfaceSuspendedForRecycle(suspended
);
516 bool GpuProcessTransportFactory::
517 SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id
) const {
518 BrowserCompositorOutputSurface
* surface
=
519 output_surface_map_
.Lookup(surface_id
);
521 return surface
->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
526 scoped_refptr
<cc::ContextProvider
>
527 GpuProcessTransportFactory::SharedMainThreadContextProvider() {
528 if (shared_main_thread_contexts_
.get())
529 return shared_main_thread_contexts_
;
531 // In threaded compositing mode, we have to create our own context for the
532 // main thread since the compositor's context will be bound to the
533 // compositor thread. When not in threaded mode, we still need a separate
534 // context so that skia and gl_helper don't step on each other.
535 shared_main_thread_contexts_
= ContextProviderCommandBuffer::Create(
536 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(),
537 BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT
);
539 if (shared_main_thread_contexts_
.get()) {
540 shared_main_thread_contexts_
->SetLostContextCallback(
541 base::Bind(&GpuProcessTransportFactory::
542 OnLostMainThreadSharedContextInsideCallback
,
543 callback_factory_
.GetWeakPtr()));
544 if (!shared_main_thread_contexts_
->BindToCurrentThread())
545 shared_main_thread_contexts_
= NULL
;
547 return shared_main_thread_contexts_
;
550 GpuProcessTransportFactory::PerCompositorData
*
551 GpuProcessTransportFactory::CreatePerCompositorData(
552 ui::Compositor
* compositor
) {
553 DCHECK(!per_compositor_data_
[compositor
]);
555 gfx::AcceleratedWidget widget
= compositor
->widget();
556 GpuSurfaceTracker
* tracker
= GpuSurfaceTracker::Get();
558 PerCompositorData
* data
= new PerCompositorData
;
559 if (compositor
->widget() == gfx::kNullAcceleratedWidget
) {
560 data
->surface_id
= 0;
562 data
->surface_id
= tracker
->AddSurfaceForNativeWidget(widget
);
563 tracker
->SetSurfaceHandle(data
->surface_id
,
564 gfx::GLSurfaceHandle(widget
, gfx::NATIVE_DIRECT
));
567 per_compositor_data_
[compositor
] = data
;
572 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
573 GpuProcessTransportFactory::CreateContextCommon(
574 scoped_refptr
<GpuChannelHost
> gpu_channel_host
,
576 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
577 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
578 blink::WebGraphicsContext3D::Attributes attrs
;
579 attrs
.shareResources
= true;
581 attrs
.stencil
= false;
582 attrs
.antialias
= false;
583 attrs
.noAutomaticFlushes
= true;
584 bool lose_context_when_out_of_memory
= true;
585 if (!gpu_channel_host
.get()) {
586 LOG(ERROR
) << "Failed to establish GPU channel.";
587 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
589 GURL
url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
590 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context(
591 new WebGraphicsContext3DCommandBufferImpl(
594 gpu_channel_host
.get(),
596 lose_context_when_out_of_memory
,
597 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
599 return context
.Pass();
602 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
603 base::ThreadTaskRunnerHandle::Get()->PostTask(
605 base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext
,
606 callback_factory_
.GetWeakPtr()));
609 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
610 LOG(ERROR
) << "Lost UI shared context.";
612 // Keep old resources around while we call the observers, but ensure that
613 // new resources are created if needed.
614 // Kill shared contexts for both threads in tandem so they are always in
615 // the same share group.
616 scoped_refptr
<cc::ContextProvider
> lost_shared_main_thread_contexts
=
617 shared_main_thread_contexts_
;
618 shared_main_thread_contexts_
= NULL
;
620 scoped_ptr
<GLHelper
> lost_gl_helper
= gl_helper_
.Pass();
622 FOR_EACH_OBSERVER(ImageTransportFactoryObserver
,
626 // Kill things that use the shared context before killing the shared context.
627 lost_gl_helper
.reset();
628 lost_shared_main_thread_contexts
= NULL
;
631 } // namespace content