chrome/browser/extensions: Remove use of MessageLoopProxy and deprecated MessageLoop...
[chromium-blink-merge.git] / content / browser / compositor / gpu_process_transport_factory.cc
blobe1b4cfa4a4b9015b940e4a41b1db39cc81ff926c
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"
7 #include <string>
9 #include "base/bind.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"
55 #if defined(OS_WIN)
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"
68 #endif
70 using cc::ContextProvider;
71 using gpu::gles2::GLES2Interface;
73 static const int kNumRetriesBeforeSoftwareFallback = 4;
75 namespace content {
76 namespace {
78 class RasterThread : public base::SimpleThread {
79 public:
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(); }
87 private:
88 cc::TaskGraphRunner* task_graph_runner_;
90 DISALLOW_COPY_AND_ASSIGN(RasterThread);
93 } // namespace
95 struct GpuProcessTransportFactory::PerCompositorData {
96 int surface_id;
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();
117 #if defined(OS_WIN)
118 software_backing_.reset(new OutputDeviceBacking);
119 #endif
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();
129 if (raster_thread_)
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) {
145 #if defined(OS_WIN)
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(
150 compositor));
151 #elif defined(USE_X11)
152 return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceX11(
153 compositor));
154 #elif defined(OS_MACOSX)
155 return scoped_ptr<cc::SoftwareOutputDevice>(
156 new SoftwareOutputDeviceMac(compositor));
157 #else
158 NOTREACHED();
159 return scoped_ptr<cc::SoftwareOutputDevice>();
160 #endif
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 #endif
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.
185 return true;
186 #endif
188 #if defined(OS_WIN)
189 if (::GetProp(compositor->widget(), kForceSoftwareCompositor) &&
190 ::RemoveProp(compositor->widget(), kForceSoftwareCompositor))
191 return false;
192 #endif
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()];
201 if (!data) {
202 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
203 // is fixed.
204 tracked_objects::ScopedTracker tracking_profile1(
205 FROM_HERE_WITH_EXPLICIT_FUNCTION(
206 "466870 GpuProcessTransportFactory::CreateOutputSurface1"));
207 data = CreatePerCompositorData(compositor.get());
208 } else {
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
216 // is fixed.
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
225 // is fixed.
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));
236 } else {
237 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466870
238 // is fixed.
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,
250 int num_attempts) {
251 if (!compositor)
252 return;
253 PerCompositorData* data = per_compositor_data_[compositor.get()];
254 DCHECK(data);
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.";
260 #endif
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,
271 data->surface_id),
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) {
281 // Try again.
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));
288 return;
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()));
297 } else {
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>()));
303 } else
304 #if defined(USE_OZONE)
305 if (ui::OzonePlatform::GetInstance()
306 ->GetOverlayManager()
307 ->CanShowPrimaryPlaneAsOverlay()) {
308 surface =
309 make_scoped_ptr(new GpuSurfacelessBrowserCompositorOutputSurface(
310 context_provider, data->surface_id, compositor->vsync_manager(),
311 CreateOverlayCandidateValidator(compositor->widget()), GL_RGB,
312 BrowserGpuMemoryBufferManager::current()));
313 } else
314 #endif
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();
326 if (data->reflector)
327 data->reflector->OnSourceSurfaceReady(data->surface);
329 if (!UseSurfacesEnabled()) {
330 compositor->SetOutputSurface(surface.Pass());
331 return;
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];
359 DCHECK(source_data);
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()];
373 DCHECK(data);
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())
381 return;
382 PerCompositorData* data = it->second;
383 DCHECK(data);
384 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
385 // output_surface_map_ here.
386 if (data->surface)
387 output_surface_map_.Remove(data->surface_id);
388 if (data->surface_id)
389 GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id);
390 delete data;
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
397 // local scoped_ptr.
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.
402 FOR_EACH_OBSERVER(
403 ImageTransportFactoryObserver, observer_list_, OnLostResources());
405 helper.reset();
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() {
433 return this;
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();
441 return handle;
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());
450 return allocator;
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())
457 return;
458 PerCompositorData* data = it->second;
459 DCHECK(data);
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();
472 if (provider.get())
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(
492 surface_id);
493 if (surface)
494 surface->OnSurfaceDisplayed();
497 void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
498 ui::Compositor* compositor,
499 bool suspended) {
500 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
501 if (it == per_compositor_data_.end())
502 return;
503 PerCompositorData* data = it->second;
504 DCHECK(data);
505 BrowserCompositorOutputSurface* surface =
506 output_surface_map_.Lookup(data->surface_id);
507 if (surface)
508 surface->SetSurfaceSuspendedForRecycle(suspended);
511 bool GpuProcessTransportFactory::
512 SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id) const {
513 BrowserCompositorOutputSurface* surface =
514 output_surface_map_.Lookup(surface_id);
515 if (surface)
516 return surface->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
517 return false;
519 #endif
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;
556 } else {
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;
564 return data;
567 scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
568 GpuProcessTransportFactory::CreateContextCommon(
569 scoped_refptr<GpuChannelHost> gpu_channel_host,
570 int surface_id) {
571 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
572 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
573 blink::WebGraphicsContext3D::Attributes attrs;
574 attrs.shareResources = true;
575 attrs.depth = false;
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(
587 surface_id,
588 url,
589 gpu_channel_host.get(),
590 attrs,
591 lose_context_when_out_of_memory,
592 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
593 NULL));
594 return context.Pass();
597 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
598 base::ThreadTaskRunnerHandle::Get()->PostTask(
599 FROM_HERE,
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,
618 observer_list_,
619 OnLostResources());
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