Make USB permissions work in the new permission message system
[chromium-blink-merge.git] / content / browser / compositor / gpu_process_transport_factory.cc
blob4c0b3630df7eaa3c2565da02b28c9161b2467e5a
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/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"
54 #if defined(OS_WIN)
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"
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 raster_thread_.reset(new RasterThread(task_graph_runner_.get()));
114 raster_thread_->Start();
115 #if defined(OS_WIN)
116 software_backing_.reset(new OutputDeviceBacking);
117 #endif
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();
127 if (raster_thread_)
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) {
143 #if defined(OS_WIN)
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(
148 compositor));
149 #elif defined(USE_X11)
150 return scoped_ptr<cc::SoftwareOutputDevice>(new SoftwareOutputDeviceX11(
151 compositor));
152 #elif defined(OS_MACOSX)
153 return scoped_ptr<cc::SoftwareOutputDevice>(
154 new SoftwareOutputDeviceMac(compositor));
155 #else
156 NOTREACHED();
157 return scoped_ptr<cc::SoftwareOutputDevice>();
158 #endif
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));
179 #endif
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.
186 return true;
187 #endif
189 #if defined(OS_WIN)
190 if (::GetProp(compositor->widget(), kForceSoftwareCompositor) &&
191 ::RemoveProp(compositor->widget(), kForceSoftwareCompositor))
192 return false;
193 #endif
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()];
202 if (!data) {
203 data = CreatePerCompositorData(compositor.get());
204 } else {
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));
220 } else {
221 EstablishedGpuChannel(compositor, create_gpu_output_surface, 0);
225 void GpuProcessTransportFactory::EstablishedGpuChannel(
226 base::WeakPtr<ui::Compositor> compositor,
227 bool create_gpu_output_surface,
228 int num_attempts) {
229 if (!compositor)
230 return;
231 PerCompositorData* data = per_compositor_data_[compositor.get()];
232 DCHECK(data);
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.";
238 #endif
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,
256 data->surface_id),
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) {
278 // Try again.
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));
285 return;
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()));
294 } else {
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;
309 #endif
310 surface =
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()));
316 } else {
317 if (!surface) {
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();
330 if (data->reflector)
331 data->reflector->OnSourceSurfaceReady(data->surface);
333 if (!UseSurfacesEnabled()) {
334 compositor->SetOutputSurface(surface.Pass());
335 return;
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];
364 DCHECK(source_data);
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()];
378 DCHECK(data);
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())
386 return;
387 PerCompositorData* data = it->second;
388 DCHECK(data);
389 // TODO(piman): Use GpuSurfaceTracker to map ids to surfaces instead of an
390 // output_surface_map_ here.
391 if (data->surface)
392 output_surface_map_.Remove(data->surface_id);
393 if (data->surface_id)
394 GpuSurfaceTracker::Get()->RemoveSurface(data->surface_id);
395 delete data;
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
402 // local scoped_ptr.
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.
407 FOR_EACH_OBSERVER(
408 ImageTransportFactoryObserver, observer_list_, OnLostResources());
410 helper.reset();
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() {
438 return this;
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();
446 return handle;
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());
455 return allocator;
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())
462 return;
463 PerCompositorData* data = it->second;
464 DCHECK(data);
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();
477 if (provider.get())
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(
497 surface_id);
498 if (surface)
499 surface->OnSurfaceDisplayed();
502 void GpuProcessTransportFactory::SetCompositorSuspendedForRecycle(
503 ui::Compositor* compositor,
504 bool suspended) {
505 PerCompositorDataMap::iterator it = per_compositor_data_.find(compositor);
506 if (it == per_compositor_data_.end())
507 return;
508 PerCompositorData* data = it->second;
509 DCHECK(data);
510 BrowserCompositorOutputSurface* surface =
511 output_surface_map_.Lookup(data->surface_id);
512 if (surface)
513 surface->SetSurfaceSuspendedForRecycle(suspended);
516 bool GpuProcessTransportFactory::
517 SurfaceShouldNotShowFramesAfterSuspendForRecycle(int surface_id) const {
518 BrowserCompositorOutputSurface* surface =
519 output_surface_map_.Lookup(surface_id);
520 if (surface)
521 return surface->SurfaceShouldNotShowFramesAfterSuspendForRecycle();
522 return false;
524 #endif
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;
561 } else {
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;
569 return data;
572 scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
573 GpuProcessTransportFactory::CreateContextCommon(
574 scoped_refptr<GpuChannelHost> gpu_channel_host,
575 int surface_id) {
576 if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor())
577 return scoped_ptr<WebGraphicsContext3DCommandBufferImpl>();
578 blink::WebGraphicsContext3D::Attributes attrs;
579 attrs.shareResources = true;
580 attrs.depth = false;
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(
592 surface_id,
593 url,
594 gpu_channel_host.get(),
595 attrs,
596 lose_context_when_out_of_memory,
597 WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
598 NULL));
599 return context.Pass();
602 void GpuProcessTransportFactory::OnLostMainThreadSharedContextInsideCallback() {
603 base::ThreadTaskRunnerHandle::Get()->PostTask(
604 FROM_HERE,
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,
623 observer_list_,
624 OnLostResources());
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