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 // Try to reuse existing worker context provider.
241 if (shared_worker_context_provider_
) {
242 base::AutoLock
lock(*shared_worker_context_provider_
->GetLock());
243 if (shared_worker_context_provider_
->ContextGL()
244 ->GetGraphicsResetStatusKHR() != GL_NO_ERROR
)
245 shared_worker_context_provider_
= nullptr;
247 scoped_refptr
<GpuChannelHost
> gpu_channel_host
=
248 BrowserGpuChannelHostFactory::instance()->GetGpuChannel();
249 if (gpu_channel_host
.get()) {
250 context_provider
= ContextProviderCommandBuffer::Create(
251 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host
,
253 BROWSER_COMPOSITOR_ONSCREEN_CONTEXT
);
254 if (context_provider
&& !context_provider
->BindToCurrentThread())
255 context_provider
= nullptr;
256 if (!shared_worker_context_provider_
) {
257 shared_worker_context_provider_
= ContextProviderCommandBuffer::Create(
258 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host
,
260 BROWSER_WORKER_CONTEXT
);
261 if (shared_worker_context_provider_
&&
262 !shared_worker_context_provider_
->BindToCurrentThread())
263 shared_worker_context_provider_
= nullptr;
267 bool created_gpu_browser_compositor
=
268 !!context_provider
&& !!shared_worker_context_provider_
;
270 UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
271 created_gpu_browser_compositor
);
273 if (!created_gpu_browser_compositor
) {
275 CauseForGpuLaunch cause
=
276 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
277 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
278 cause
, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel
,
279 callback_factory_
.GetWeakPtr(), compositor
,
280 create_gpu_output_surface
, num_attempts
+ 1));
285 scoped_ptr
<BrowserCompositorOutputSurface
> surface
;
286 if (!create_gpu_output_surface
) {
287 surface
= make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface(
288 CreateSoftwareOutputDevice(compositor
.get()),
289 compositor
->vsync_manager()));
291 DCHECK(context_provider
);
292 ContextProvider::Capabilities capabilities
=
293 context_provider
->ContextCapabilities();
294 if (!data
->surface_id
) {
295 surface
= make_scoped_ptr(new OffscreenBrowserCompositorOutputSurface(
296 context_provider
, shared_worker_context_provider_
,
297 compositor
->vsync_manager(),
298 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>()));
299 } else if (capabilities
.gpu
.surfaceless
) {
300 GLenum target
= GL_TEXTURE_2D
;
301 GLenum format
= GL_RGB
;
302 #if defined(OS_MACOSX)
303 target
= GL_TEXTURE_RECTANGLE_ARB
;
304 format
= GL_BGRA_EXT
;
307 make_scoped_ptr(new GpuSurfacelessBrowserCompositorOutputSurface(
308 context_provider
, shared_worker_context_provider_
,
309 data
->surface_id
, compositor
->vsync_manager(),
310 CreateOverlayCandidateValidator(compositor
->widget()), target
,
311 format
, BrowserGpuMemoryBufferManager::current()));
314 surface
= make_scoped_ptr(new GpuBrowserCompositorOutputSurface(
315 context_provider
, shared_worker_context_provider_
,
316 compositor
->vsync_manager(),
317 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 shared_worker_context_provider_
));
349 display_client
->set_surface_output_surface(output_surface
.get());
350 output_surface
->set_display_client(display_client
.get());
351 display_client
->display()->Resize(compositor
->size());
352 data
->display_client
= display_client
.Pass();
353 compositor
->SetOutputSurface(output_surface
.Pass());
356 scoped_ptr
<ui::Reflector
> GpuProcessTransportFactory::CreateReflector(
357 ui::Compositor
* source_compositor
,
358 ui::Layer
* target_layer
) {
359 PerCompositorData
* source_data
= per_compositor_data_
[source_compositor
];
362 scoped_ptr
<ReflectorImpl
> reflector(
363 new ReflectorImpl(source_compositor
, target_layer
));
364 source_data
->reflector
= reflector
.get();
365 if (BrowserCompositorOutputSurface
* source_surface
= source_data
->surface
)
366 reflector
->OnSourceSurfaceReady(source_surface
);
367 return reflector
.Pass();
370 void GpuProcessTransportFactory::RemoveReflector(ui::Reflector
* reflector
) {
371 ReflectorImpl
* reflector_impl
= static_cast<ReflectorImpl
*>(reflector
);
372 PerCompositorData
* data
=
373 per_compositor_data_
[reflector_impl
->mirrored_compositor()];
375 data
->reflector
->Shutdown();
376 data
->reflector
= nullptr;
379 void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor
* compositor
) {
380 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
381 if (it
== per_compositor_data_
.end())
383 PerCompositorData
* data
= it
->second
;
385 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
386 // output_surface_map_ here.
388 output_surface_map_
.Remove(data
->surface_id
);
389 if (data
->surface_id
)
390 GpuSurfaceTracker::Get()->RemoveSurface(data
->surface_id
);
392 per_compositor_data_
.erase(it
);
393 if (per_compositor_data_
.empty()) {
394 // Destroying the GLHelper may cause some async actions to be cancelled,
395 // causing things to request a new GLHelper. Due to crbug.com/176091 the
396 // GLHelper created in this case would be lost/leaked if we just reset()
397 // on the |gl_helper_| variable directly. So instead we call reset() on a
399 scoped_ptr
<GLHelper
> helper
= gl_helper_
.Pass();
401 // If there are any observer left at this point, make sure they clean up
402 // before we destroy the GLHelper.
404 ImageTransportFactoryObserver
, observer_list_
, OnLostResources());
407 DCHECK(!gl_helper_
) << "Destroying the GLHelper should not cause a new "
408 "GLHelper to be created.";
412 bool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; }
414 uint32
GpuProcessTransportFactory::GetImageTextureTarget(
415 gfx::BufferFormat format
,
416 gfx::BufferUsage usage
) {
417 return BrowserGpuMemoryBufferManager::GetImageTextureTarget(format
, usage
);
420 cc::SharedBitmapManager
* GpuProcessTransportFactory::GetSharedBitmapManager() {
421 return HostSharedBitmapManager::current();
424 gpu::GpuMemoryBufferManager
*
425 GpuProcessTransportFactory::GetGpuMemoryBufferManager() {
426 return BrowserGpuMemoryBufferManager::current();
429 cc::TaskGraphRunner
* GpuProcessTransportFactory::GetTaskGraphRunner() {
430 return task_graph_runner_
.get();
433 ui::ContextFactory
* GpuProcessTransportFactory::GetContextFactory() {
437 gfx::GLSurfaceHandle
GpuProcessTransportFactory::GetSharedSurfaceHandle() {
438 gfx::GLSurfaceHandle handle
= gfx::GLSurfaceHandle(
439 gfx::kNullPluginWindow
, gfx::NULL_TRANSPORT
);
440 handle
.parent_client_id
=
441 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
445 scoped_ptr
<cc::SurfaceIdAllocator
>
446 GpuProcessTransportFactory::CreateSurfaceIdAllocator() {
447 scoped_ptr
<cc::SurfaceIdAllocator
> allocator
=
448 make_scoped_ptr(new cc::SurfaceIdAllocator(next_surface_id_namespace_
++));
449 if (GetSurfaceManager())
450 allocator
->RegisterSurfaceIdNamespace(GetSurfaceManager());
454 void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor
* compositor
,
455 const gfx::Size
& size
) {
456 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
457 if (it
== per_compositor_data_
.end())
459 PerCompositorData
* data
= it
->second
;
461 if (data
->display_client
)
462 data
->display_client
->display()->Resize(size
);
465 cc::SurfaceManager
* GpuProcessTransportFactory::GetSurfaceManager() {
466 return surface_manager_
.get();
469 GLHelper
* GpuProcessTransportFactory::GetGLHelper() {
470 if (!gl_helper_
&& !per_compositor_data_
.empty()) {
471 scoped_refptr
<cc::ContextProvider
> provider
=
472 SharedMainThreadContextProvider();
474 gl_helper_
.reset(new GLHelper(provider
->ContextGL(),
475 provider
->ContextSupport()));
477 return gl_helper_
.get();
480 void GpuProcessTransportFactory::AddObserver(
481 ImageTransportFactoryObserver
* observer
) {
482 observer_list_
.AddObserver(observer
);
485 void GpuProcessTransportFactory::RemoveObserver(
486 ImageTransportFactoryObserver
* observer
) {
487 observer_list_
.RemoveObserver(observer
);
490 #if defined(OS_MACOSX)
491 void GpuProcessTransportFactory::OnSurfaceDisplayed(int surface_id
) {
492 BrowserCompositorOutputSurface
* surface
= output_surface_map_
.Lookup(
495 surface
->OnSurfaceDisplayed();
498 void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
499 ui::Compositor
* compositor
,
501 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
502 if (it
== per_compositor_data_
.end())
504 PerCompositorData
* data
= it
->second
;
506 BrowserCompositorOutputSurface
* surface
=
507 output_surface_map_
.Lookup(data
->surface_id
);
509 surface
->SetSurfaceSuspendedForRecycle(suspended
);
512 bool GpuProcessTransportFactory::
513 SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id
) const {
514 BrowserCompositorOutputSurface
* surface
=
515 output_surface_map_
.Lookup(surface_id
);
517 return surface
->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
522 scoped_refptr
<cc::ContextProvider
>
523 GpuProcessTransportFactory::SharedMainThreadContextProvider() {
524 if (shared_main_thread_contexts_
.get())
525 return shared_main_thread_contexts_
;
527 // In threaded compositing mode, we have to create our own context for the
528 // main thread since the compositor's context will be bound to the
529 // compositor thread. When not in threaded mode, we still need a separate
530 // context so that skia and gl_helper don't step on each other.
531 shared_main_thread_contexts_
= ContextProviderCommandBuffer::Create(
532 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(),
533 BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT
);
535 if (shared_main_thread_contexts_
.get()) {
536 shared_main_thread_contexts_
->SetLostContextCallback(
537 base::Bind(&GpuProcessTransportFactory::
538 OnLostMainThreadSharedContextInsideCallback
,
539 callback_factory_
.GetWeakPtr()));
540 if (!shared_main_thread_contexts_
->BindToCurrentThread())
541 shared_main_thread_contexts_
= NULL
;
543 return shared_main_thread_contexts_
;
546 GpuProcessTransportFactory::PerCompositorData
*
547 GpuProcessTransportFactory::CreatePerCompositorData(
548 ui::Compositor
* compositor
) {
549 DCHECK(!per_compositor_data_
[compositor
]);
551 gfx::AcceleratedWidget widget
= compositor
->widget();
552 GpuSurfaceTracker
* tracker
= GpuSurfaceTracker::Get();
554 PerCompositorData
* data
= new PerCompositorData
;
555 if (compositor
->widget() == gfx::kNullAcceleratedWidget
) {
556 data
->surface_id
= 0;
558 data
->surface_id
= tracker
->AddSurfaceForNativeWidget(widget
);
559 tracker
->SetSurfaceHandle(data
->surface_id
,
560 gfx::GLSurfaceHandle(widget
, gfx::NATIVE_DIRECT
));
563 per_compositor_data_
[compositor
] = data
;
568 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
569 GpuProcessTransportFactory::CreateContextCommon(
570 scoped_refptr
<GpuChannelHost
> gpu_channel_host
,
572 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
573 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
574 blink::WebGraphicsContext3D::Attributes attrs
;
575 attrs
.shareResources
= true;
577 attrs
.stencil
= false;
578 attrs
.antialias
= false;
579 attrs
.noAutomaticFlushes
= true;
580 bool lose_context_when_out_of_memory
= true;
581 if (!gpu_channel_host
.get()) {
582 LOG(ERROR
) << "Failed to establish GPU channel.";
583 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
585 GURL
url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
586 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context(
587 new WebGraphicsContext3DCommandBufferImpl(
590 gpu_channel_host
.get(),
592 lose_context_when_out_of_memory
,
593 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
595 return context
.Pass();
598 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
599 base::ThreadTaskRunnerHandle::Get()->PostTask(
601 base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext
,
602 callback_factory_
.GetWeakPtr()));
605 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
606 LOG(ERROR
) << "Lost UI shared context.";
608 // Keep old resources around while we call the observers, but ensure that
609 // new resources are created if needed.
610 // Kill shared contexts for both threads in tandem so they are always in
611 // the same share group.
612 scoped_refptr
<cc::ContextProvider
> lost_shared_main_thread_contexts
=
613 shared_main_thread_contexts_
;
614 shared_main_thread_contexts_
= NULL
;
616 scoped_ptr
<GLHelper
> lost_gl_helper
= gl_helper_
.Pass();
618 FOR_EACH_OBSERVER(ImageTransportFactoryObserver
,
622 // Kill things that use the shared context before killing the shared context.
623 lost_gl_helper
.reset();
624 lost_shared_main_thread_contexts
= NULL
;
627 } // namespace content