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/base/histograms.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/browser_compositor_overlay_candidate_validator_mac.h"
68 #include "content/browser/compositor/software_output_device_mac.h"
71 using cc::ContextProvider
;
72 using gpu::gles2::GLES2Interface
;
74 static const int kNumRetriesBeforeSoftwareFallback
= 4;
79 class RasterThread
: public base::SimpleThread
{
81 RasterThread(cc::TaskGraphRunner
* task_graph_runner
)
82 : base::SimpleThread("CompositorTileWorker1"),
83 task_graph_runner_(task_graph_runner
) {}
85 // Overridden from base::SimpleThread:
86 void Run() override
{ task_graph_runner_
->Run(); }
89 cc::TaskGraphRunner
* task_graph_runner_
;
91 DISALLOW_COPY_AND_ASSIGN(RasterThread
);
96 struct GpuProcessTransportFactory::PerCompositorData
{
98 BrowserCompositorOutputSurface
* surface
;
99 ReflectorImpl
* reflector
;
100 scoped_ptr
<cc::OnscreenDisplayClient
> display_client
;
102 PerCompositorData() : surface_id(0), surface(nullptr), reflector(nullptr) {}
105 GpuProcessTransportFactory::GpuProcessTransportFactory()
106 : next_surface_id_namespace_(1u),
107 task_graph_runner_(new cc::TaskGraphRunner
),
108 callback_factory_(this) {
109 ui::Layer::InitializeUILayerSettings();
110 cc::SetClientNameForMetrics("Browser");
112 if (UseSurfacesEnabled())
113 surface_manager_
= make_scoped_ptr(new cc::SurfaceManager
);
115 raster_thread_
.reset(new RasterThread(task_graph_runner_
.get()));
116 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()));
178 #elif defined(OS_MACOSX)
179 return make_scoped_ptr(
180 new BrowserCompositorOverlayCandidateValidatorMac(widget
));
182 return scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>();
185 static bool ShouldCreateGpuOutputSurface(ui::Compositor
* compositor
) {
186 #if defined(OS_CHROMEOS)
187 // Software fallback does not happen on Chrome OS.
192 if (::GetProp(compositor
->widget(), kForceSoftwareCompositor
) &&
193 ::RemoveProp(compositor
->widget(), kForceSoftwareCompositor
))
197 return GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor();
200 void GpuProcessTransportFactory::CreateOutputSurface(
201 base::WeakPtr
<ui::Compositor
> compositor
) {
202 DCHECK(!!compositor
);
203 PerCompositorData
* data
= per_compositor_data_
[compositor
.get()];
205 data
= CreatePerCompositorData(compositor
.get());
207 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
208 // output_surface_map_ here.
209 output_surface_map_
.Remove(data
->surface_id
);
210 data
->surface
= nullptr;
213 bool create_gpu_output_surface
=
214 ShouldCreateGpuOutputSurface(compositor
.get());
215 if (create_gpu_output_surface
) {
216 CauseForGpuLaunch cause
=
217 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
218 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
219 cause
, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel
,
220 callback_factory_
.GetWeakPtr(), compositor
,
221 create_gpu_output_surface
, 0));
223 EstablishedGpuChannel(compositor
, create_gpu_output_surface
, 0);
227 void GpuProcessTransportFactory::EstablishedGpuChannel(
228 base::WeakPtr
<ui::Compositor
> compositor
,
229 bool create_gpu_output_surface
,
233 PerCompositorData
* data
= per_compositor_data_
[compositor
.get()];
236 if (num_attempts
> kNumRetriesBeforeSoftwareFallback
) {
237 #if defined(OS_CHROMEOS)
238 LOG(FATAL
) << "Unable to create a UI graphics context, and cannot use "
239 << "software compositing on ChromeOS.";
241 create_gpu_output_surface
= false;
244 scoped_refptr
<ContextProviderCommandBuffer
> context_provider
;
245 if (create_gpu_output_surface
) {
246 // Try to reuse existing worker context provider.
247 if (shared_worker_context_provider_
) {
248 base::AutoLock
lock(*shared_worker_context_provider_
->GetLock());
249 if (shared_worker_context_provider_
->ContextGL()
250 ->GetGraphicsResetStatusKHR() != GL_NO_ERROR
)
251 shared_worker_context_provider_
= nullptr;
253 scoped_refptr
<GpuChannelHost
> gpu_channel_host
=
254 BrowserGpuChannelHostFactory::instance()->GetGpuChannel();
255 if (gpu_channel_host
.get()) {
256 context_provider
= ContextProviderCommandBuffer::Create(
257 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host
,
259 BROWSER_COMPOSITOR_ONSCREEN_CONTEXT
);
260 if (context_provider
&& !context_provider
->BindToCurrentThread())
261 context_provider
= nullptr;
262 if (!shared_worker_context_provider_
) {
263 shared_worker_context_provider_
= ContextProviderCommandBuffer::Create(
264 GpuProcessTransportFactory::CreateContextCommon(gpu_channel_host
,
266 BROWSER_WORKER_CONTEXT
);
267 if (shared_worker_context_provider_
&&
268 !shared_worker_context_provider_
->BindToCurrentThread())
269 shared_worker_context_provider_
= nullptr;
273 bool created_gpu_browser_compositor
=
274 !!context_provider
&& !!shared_worker_context_provider_
;
276 UMA_HISTOGRAM_BOOLEAN("Aura.CreatedGpuBrowserCompositor",
277 created_gpu_browser_compositor
);
279 if (!created_gpu_browser_compositor
) {
281 CauseForGpuLaunch cause
=
282 CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE
;
283 BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel(
284 cause
, base::Bind(&GpuProcessTransportFactory::EstablishedGpuChannel
,
285 callback_factory_
.GetWeakPtr(), compositor
,
286 create_gpu_output_surface
, num_attempts
+ 1));
291 scoped_ptr
<BrowserCompositorOutputSurface
> surface
;
292 if (!create_gpu_output_surface
) {
293 surface
= make_scoped_ptr(new SoftwareBrowserCompositorOutputSurface(
294 CreateSoftwareOutputDevice(compositor
.get()),
295 compositor
->vsync_manager()));
297 DCHECK(context_provider
);
298 ContextProvider::Capabilities capabilities
=
299 context_provider
->ContextCapabilities();
300 if (!data
->surface_id
) {
301 surface
= make_scoped_ptr(new OffscreenBrowserCompositorOutputSurface(
302 context_provider
, shared_worker_context_provider_
,
303 compositor
->vsync_manager(),
304 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
>()));
305 } else if (capabilities
.gpu
.surfaceless
) {
306 GLenum target
= GL_TEXTURE_2D
;
307 GLenum format
= GL_RGB
;
308 #if defined(OS_MACOSX)
309 target
= GL_TEXTURE_RECTANGLE_ARB
;
310 format
= GL_BGRA_EXT
;
313 make_scoped_ptr(new GpuSurfacelessBrowserCompositorOutputSurface(
314 context_provider
, shared_worker_context_provider_
,
315 data
->surface_id
, compositor
->vsync_manager(),
316 CreateOverlayCandidateValidator(compositor
->widget()), target
,
317 format
, BrowserGpuMemoryBufferManager::current()));
319 scoped_ptr
<BrowserCompositorOverlayCandidateValidator
> validator
;
320 #if !defined(OS_MACOSX)
321 // Overlays are only supported on surfaceless output surfaces on Mac.
322 validator
= CreateOverlayCandidateValidator(compositor
->widget());
324 surface
= make_scoped_ptr(new GpuBrowserCompositorOutputSurface(
325 context_provider
, shared_worker_context_provider_
,
326 compositor
->vsync_manager(), validator
.Pass()));
330 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
331 // output_surface_map_ here.
332 output_surface_map_
.AddWithID(surface
.get(), data
->surface_id
);
333 data
->surface
= surface
.get();
335 data
->reflector
->OnSourceSurfaceReady(data
->surface
);
337 if (!UseSurfacesEnabled()) {
338 compositor
->SetOutputSurface(surface
.Pass());
342 // This gets a bit confusing. Here we have a ContextProvider in the |surface|
343 // configured to render directly to this widget. We need to make an
344 // OnscreenDisplayClient associated with that context, then return a
345 // SurfaceDisplayOutputSurface set up to draw to the display's surface.
346 cc::SurfaceManager
* manager
= surface_manager_
.get();
347 scoped_ptr
<cc::OnscreenDisplayClient
> display_client(
348 new cc::OnscreenDisplayClient(
349 surface
.Pass(), manager
, HostSharedBitmapManager::current(),
350 BrowserGpuMemoryBufferManager::current(),
351 compositor
->GetRendererSettings(), compositor
->task_runner()));
353 scoped_ptr
<cc::SurfaceDisplayOutputSurface
> output_surface(
354 new cc::SurfaceDisplayOutputSurface(
355 manager
, compositor
->surface_id_allocator(), context_provider
,
356 shared_worker_context_provider_
));
357 display_client
->set_surface_output_surface(output_surface
.get());
358 output_surface
->set_display_client(display_client
.get());
359 display_client
->display()->Resize(compositor
->size());
360 data
->display_client
= display_client
.Pass();
361 compositor
->SetOutputSurface(output_surface
.Pass());
364 scoped_ptr
<ui::Reflector
> GpuProcessTransportFactory::CreateReflector(
365 ui::Compositor
* source_compositor
,
366 ui::Layer
* target_layer
) {
367 PerCompositorData
* source_data
= per_compositor_data_
[source_compositor
];
370 scoped_ptr
<ReflectorImpl
> reflector(
371 new ReflectorImpl(source_compositor
, target_layer
));
372 source_data
->reflector
= reflector
.get();
373 if (BrowserCompositorOutputSurface
* source_surface
= source_data
->surface
)
374 reflector
->OnSourceSurfaceReady(source_surface
);
375 return reflector
.Pass();
378 void GpuProcessTransportFactory::RemoveReflector(ui::Reflector
* reflector
) {
379 ReflectorImpl
* reflector_impl
= static_cast<ReflectorImpl
*>(reflector
);
380 PerCompositorData
* data
=
381 per_compositor_data_
[reflector_impl
->mirrored_compositor()];
383 data
->reflector
->Shutdown();
384 data
->reflector
= nullptr;
387 void GpuProcessTransportFactory::RemoveCompositor(ui::Compositor
* compositor
) {
388 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
389 if (it
== per_compositor_data_
.end())
391 PerCompositorData
* data
= it
->second
;
393 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
394 // output_surface_map_ here.
396 output_surface_map_
.Remove(data
->surface_id
);
397 if (data
->surface_id
)
398 GpuSurfaceTracker::Get()->RemoveSurface(data
->surface_id
);
400 per_compositor_data_
.erase(it
);
401 if (per_compositor_data_
.empty()) {
402 // Destroying the GLHelper may cause some async actions to be cancelled,
403 // causing things to request a new GLHelper. Due to crbug.com/176091 the
404 // GLHelper created in this case would be lost/leaked if we just reset()
405 // on the |gl_helper_| variable directly. So instead we call reset() on a
407 scoped_ptr
<GLHelper
> helper
= gl_helper_
.Pass();
409 // If there are any observer left at this point, make sure they clean up
410 // before we destroy the GLHelper.
412 ImageTransportFactoryObserver
, observer_list_
, OnLostResources());
415 DCHECK(!gl_helper_
) << "Destroying the GLHelper should not cause a new "
416 "GLHelper to be created.";
420 bool GpuProcessTransportFactory::DoesCreateTestContexts() { return false; }
422 uint32
GpuProcessTransportFactory::GetImageTextureTarget(
423 gfx::BufferFormat format
,
424 gfx::BufferUsage usage
) {
425 return BrowserGpuMemoryBufferManager::GetImageTextureTarget(format
, usage
);
428 cc::SharedBitmapManager
* GpuProcessTransportFactory::GetSharedBitmapManager() {
429 return HostSharedBitmapManager::current();
432 gpu::GpuMemoryBufferManager
*
433 GpuProcessTransportFactory::GetGpuMemoryBufferManager() {
434 return BrowserGpuMemoryBufferManager::current();
437 cc::TaskGraphRunner
* GpuProcessTransportFactory::GetTaskGraphRunner() {
438 return task_graph_runner_
.get();
441 ui::ContextFactory
* GpuProcessTransportFactory::GetContextFactory() {
445 gfx::GLSurfaceHandle
GpuProcessTransportFactory::GetSharedSurfaceHandle() {
446 gfx::GLSurfaceHandle handle
= gfx::GLSurfaceHandle(
447 gfx::kNullPluginWindow
, gfx::NULL_TRANSPORT
);
448 handle
.parent_client_id
=
449 BrowserGpuChannelHostFactory::instance()->GetGpuChannelId();
453 scoped_ptr
<cc::SurfaceIdAllocator
>
454 GpuProcessTransportFactory::CreateSurfaceIdAllocator() {
455 scoped_ptr
<cc::SurfaceIdAllocator
> allocator
=
456 make_scoped_ptr(new cc::SurfaceIdAllocator(next_surface_id_namespace_
++));
457 if (GetSurfaceManager())
458 allocator
->RegisterSurfaceIdNamespace(GetSurfaceManager());
462 void GpuProcessTransportFactory::ResizeDisplay(ui::Compositor
* compositor
,
463 const gfx::Size
& size
) {
464 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
465 if (it
== per_compositor_data_
.end())
467 PerCompositorData
* data
= it
->second
;
469 if (data
->display_client
)
470 data
->display_client
->display()->Resize(size
);
473 cc::SurfaceManager
* GpuProcessTransportFactory::GetSurfaceManager() {
474 return surface_manager_
.get();
477 GLHelper
* GpuProcessTransportFactory::GetGLHelper() {
478 if (!gl_helper_
&& !per_compositor_data_
.empty()) {
479 scoped_refptr
<cc::ContextProvider
> provider
=
480 SharedMainThreadContextProvider();
482 gl_helper_
.reset(new GLHelper(provider
->ContextGL(),
483 provider
->ContextSupport()));
485 return gl_helper_
.get();
488 void GpuProcessTransportFactory::AddObserver(
489 ImageTransportFactoryObserver
* observer
) {
490 observer_list_
.AddObserver(observer
);
493 void GpuProcessTransportFactory::RemoveObserver(
494 ImageTransportFactoryObserver
* observer
) {
495 observer_list_
.RemoveObserver(observer
);
498 #if defined(OS_MACOSX)
499 void GpuProcessTransportFactory::OnSurfaceDisplayed(int surface_id
) {
500 BrowserCompositorOutputSurface
* surface
= output_surface_map_
.Lookup(
503 surface
->OnSurfaceDisplayed();
506 void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
507 ui::Compositor
* compositor
,
509 PerCompositorDataMap::iterator it
= per_compositor_data_
.find(compositor
);
510 if (it
== per_compositor_data_
.end())
512 PerCompositorData
* data
= it
->second
;
514 BrowserCompositorOutputSurface
* surface
=
515 output_surface_map_
.Lookup(data
->surface_id
);
517 surface
->SetSurfaceSuspendedForRecycle(suspended
);
520 bool GpuProcessTransportFactory::
521 SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id
) const {
522 BrowserCompositorOutputSurface
* surface
=
523 output_surface_map_
.Lookup(surface_id
);
525 return surface
->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
530 scoped_refptr
<cc::ContextProvider
>
531 GpuProcessTransportFactory::SharedMainThreadContextProvider() {
532 if (shared_main_thread_contexts_
.get())
533 return shared_main_thread_contexts_
;
535 // In threaded compositing mode, we have to create our own context for the
536 // main thread since the compositor's context will be bound to the
537 // compositor thread. When not in threaded mode, we still need a separate
538 // context so that skia and gl_helper don't step on each other.
539 shared_main_thread_contexts_
= ContextProviderCommandBuffer::Create(
540 GpuProcessTransportFactory::CreateOffscreenCommandBufferContext(),
541 BROWSER_OFFSCREEN_MAINTHREAD_CONTEXT
);
543 if (shared_main_thread_contexts_
.get()) {
544 shared_main_thread_contexts_
->SetLostContextCallback(
545 base::Bind(&GpuProcessTransportFactory::
546 OnLostMainThreadSharedContextInsideCallback
,
547 callback_factory_
.GetWeakPtr()));
548 if (!shared_main_thread_contexts_
->BindToCurrentThread())
549 shared_main_thread_contexts_
= NULL
;
551 return shared_main_thread_contexts_
;
554 GpuProcessTransportFactory::PerCompositorData
*
555 GpuProcessTransportFactory::CreatePerCompositorData(
556 ui::Compositor
* compositor
) {
557 DCHECK(!per_compositor_data_
[compositor
]);
559 gfx::AcceleratedWidget widget
= compositor
->widget();
560 GpuSurfaceTracker
* tracker
= GpuSurfaceTracker::Get();
562 PerCompositorData
* data
= new PerCompositorData
;
563 if (compositor
->widget() == gfx::kNullAcceleratedWidget
) {
564 data
->surface_id
= 0;
566 data
->surface_id
= tracker
->AddSurfaceForNativeWidget(widget
);
567 tracker
->SetSurfaceHandle(data
->surface_id
,
568 gfx::GLSurfaceHandle(widget
, gfx::NATIVE_DIRECT
));
571 per_compositor_data_
[compositor
] = data
;
576 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>
577 GpuProcessTransportFactory::CreateContextCommon(
578 scoped_refptr
<GpuChannelHost
> gpu_channel_host
,
580 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
581 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
582 blink::WebGraphicsContext3D::Attributes attrs
;
583 attrs
.shareResources
= true;
585 attrs
.stencil
= false;
586 attrs
.antialias
= false;
587 attrs
.noAutomaticFlushes
= true;
588 bool lose_context_when_out_of_memory
= true;
589 if (!gpu_channel_host
.get()) {
590 LOG(ERROR
) << "Failed to establish GPU channel.";
591 return scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
>();
593 GURL
url("chrome://gpu/GpuProcessTransportFactory::CreateContextCommon");
594 scoped_ptr
<WebGraphicsContext3DCommandBufferImpl
> context(
595 new WebGraphicsContext3DCommandBufferImpl(
598 gpu_channel_host
.get(),
600 lose_context_when_out_of_memory
,
601 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
603 return context
.Pass();
606 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
607 base::ThreadTaskRunnerHandle::Get()->PostTask(
609 base::Bind(&GpuProcessTransportFactory::OnLostMainThreadSharedContext
,
610 callback_factory_
.GetWeakPtr()));
613 void GpuProcessTransportFactory::OnLostMainThreadSharedContext() {
614 LOG(ERROR
) << "Lost UI shared context.";
616 // Keep old resources around while we call the observers, but ensure that
617 // new resources are created if needed.
618 // Kill shared contexts for both threads in tandem so they are always in
619 // the same share group.
620 scoped_refptr
<cc::ContextProvider
> lost_shared_main_thread_contexts
=
621 shared_main_thread_contexts_
;
622 shared_main_thread_contexts_
= NULL
;
624 scoped_ptr
<GLHelper
> lost_gl_helper
= gl_helper_
.Pass();
626 FOR_EACH_OBSERVER(ImageTransportFactoryObserver
,
630 // Kill things that use the shared context before killing the shared context.
631 lost_gl_helper
.reset();
632 lost_shared_main_thread_contexts
= NULL
;
635 } // namespace content