Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: content/browser/gpu/browser_gpu_channel_host_factory.cc

Issue 1189943002: content: Fix lost context handling when using native GpuMemoryBuffers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: retry logic and remove singleton Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/gpu/browser_gpu_channel_host_factory.h" 5 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
6 6
7 #include <set>
8
9 #include "base/bind.h" 7 #include "base/bind.h"
10 #include "base/location.h" 8 #include "base/location.h"
11 #include "base/profiler/scoped_tracker.h" 9 #include "base/profiler/scoped_tracker.h"
12 #include "base/single_thread_task_runner.h" 10 #include "base/single_thread_task_runner.h"
13 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
14 #include "base/thread_task_runner_handle.h" 12 #include "base/thread_task_runner_handle.h"
15 #include "base/threading/thread_restrictions.h" 13 #include "base/threading/thread_restrictions.h"
16 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
17 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" 15 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
18 #include "content/browser/gpu/gpu_data_manager_impl.h" 16 #include "content/browser/gpu/gpu_data_manager_impl.h"
19 #include "content/browser/gpu/gpu_process_host.h" 17 #include "content/browser/gpu/gpu_process_host.h"
20 #include "content/browser/gpu/gpu_surface_tracker.h" 18 #include "content/browser/gpu/gpu_surface_tracker.h"
21 #include "content/common/child_process_host_impl.h" 19 #include "content/common/child_process_host_impl.h"
22 #include "content/common/gpu/gpu_memory_buffer_factory.h"
23 #include "content/common/gpu/gpu_messages.h" 20 #include "content/common/gpu/gpu_messages.h"
24 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/gpu_data_manager.h" 22 #include "content/public/browser/gpu_data_manager.h"
26 #include "content/public/common/content_client.h" 23 #include "content/public/common/content_client.h"
27 #include "gpu/GLES2/gl2extchromium.h"
28 #include "ipc/ipc_channel_handle.h" 24 #include "ipc/ipc_channel_handle.h"
29 #include "ipc/ipc_forwarding_message_filter.h" 25 #include "ipc/ipc_forwarding_message_filter.h"
30 #include "ipc/message_filter.h" 26 #include "ipc/message_filter.h"
31 27
32 #if defined(OS_MACOSX)
33 #include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h"
34 #endif
35
36 #if defined(OS_ANDROID)
37 #include "content/common/gpu/gpu_memory_buffer_factory_surface_texture.h"
38 #endif
39
40 #if defined(USE_OZONE)
41 #include "content/common/gpu/gpu_memory_buffer_factory_ozone_native_buffer.h"
42 #endif
43
44 namespace content { 28 namespace content {
45 namespace {
46
47 base::LazyInstance<std::set<gfx::GpuMemoryBuffer::Usage>>
48 g_enabled_gpu_memory_buffer_usages;
49
50 bool IsGpuMemoryBufferFactoryConfigurationSupported(
51 gfx::GpuMemoryBuffer::Format format,
52 gfx::GpuMemoryBuffer::Usage usage,
53 gfx::GpuMemoryBufferType type) {
54 switch (type) {
55 case gfx::SHARED_MEMORY_BUFFER:
56 // Shared memory buffers must be created in-process.
57 return false;
58 #if defined(OS_MACOSX)
59 case gfx::IO_SURFACE_BUFFER:
60 return GpuMemoryBufferFactoryIOSurface::
61 IsGpuMemoryBufferConfigurationSupported(format, usage);
62 #endif
63 #if defined(OS_ANDROID)
64 case gfx::SURFACE_TEXTURE_BUFFER:
65 return GpuMemoryBufferFactorySurfaceTexture::
66 IsGpuMemoryBufferConfigurationSupported(format, usage);
67 #endif
68 #if defined(USE_OZONE)
69 case gfx::OZONE_NATIVE_BUFFER:
70 return GpuMemoryBufferFactoryOzoneNativeBuffer::
71 IsGpuMemoryBufferConfigurationSupported(format, usage);
72 #endif
73 default:
74 NOTREACHED();
75 return false;
76 }
77 }
78
79 } // namespace
80 29
81 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; 30 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL;
82 31
83 struct BrowserGpuChannelHostFactory::CreateRequest { 32 struct BrowserGpuChannelHostFactory::CreateRequest {
84 CreateRequest(int32 route_id) 33 CreateRequest(int32 route_id)
85 : event(true, false), 34 : event(true, false),
86 gpu_host_id(0), 35 gpu_host_id(0),
87 route_id(route_id), 36 route_id(route_id),
88 result(CREATE_COMMAND_BUFFER_FAILED) {} 37 result(CREATE_COMMAND_BUFFER_FAILED) {}
89 ~CreateRequest() {} 38 ~CreateRequest() {}
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 base::Closure()); 216 base::Closure());
268 } 217 }
269 } 218 }
270 219
271 void BrowserGpuChannelHostFactory::Terminate() { 220 void BrowserGpuChannelHostFactory::Terminate() {
272 DCHECK(instance_); 221 DCHECK(instance_);
273 delete instance_; 222 delete instance_;
274 instance_ = NULL; 223 instance_ = NULL;
275 } 224 }
276 225
277 // static
278 void BrowserGpuChannelHostFactory::EnableGpuMemoryBufferFactoryUsage(
279 gfx::GpuMemoryBuffer::Usage usage) {
280 g_enabled_gpu_memory_buffer_usages.Get().insert(usage);
281 }
282
283 // static
284 bool BrowserGpuChannelHostFactory::IsGpuMemoryBufferFactoryUsageEnabled(
285 gfx::GpuMemoryBuffer::Usage usage) {
286 return g_enabled_gpu_memory_buffer_usages.Get().count(usage) != 0;
287 }
288
289 // static
290 uint32 BrowserGpuChannelHostFactory::GetImageTextureTarget(
291 gfx::GpuMemoryBuffer::Format format,
292 gfx::GpuMemoryBuffer::Usage usage) {
293 if (!IsGpuMemoryBufferFactoryUsageEnabled(usage))
294 return GL_TEXTURE_2D;
295
296 std::vector<gfx::GpuMemoryBufferType> supported_types;
297 GpuMemoryBufferFactory::GetSupportedTypes(&supported_types);
298 DCHECK(!supported_types.empty());
299
300 // The GPU service will always use the preferred type, if the |format| and
301 // |usage| allows.
302 gfx::GpuMemoryBufferType type = supported_types[0];
303
304 if (!IsGpuMemoryBufferFactoryConfigurationSupported(format, usage, type))
305 return GL_TEXTURE_2D;
306
307 switch (type) {
308 case gfx::SURFACE_TEXTURE_BUFFER:
309 case gfx::OZONE_NATIVE_BUFFER:
310 // GPU memory buffers that are shared with the GL using EGLImages require
311 // TEXTURE_EXTERNAL_OES.
312 return GL_TEXTURE_EXTERNAL_OES;
313 case gfx::IO_SURFACE_BUFFER:
314 // IOSurface backed images require GL_TEXTURE_RECTANGLE_ARB.
315 return GL_TEXTURE_RECTANGLE_ARB;
316 default:
317 return GL_TEXTURE_2D;
318 }
319 }
320
321 BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory() 226 BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
322 : gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), 227 : gpu_client_id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
323 shutdown_event_(new base::WaitableEvent(true, false)), 228 shutdown_event_(new base::WaitableEvent(true, false)),
324 gpu_memory_buffer_manager_( 229 gpu_memory_buffer_manager_(
325 new BrowserGpuMemoryBufferManager(this, gpu_client_id_)), 230 new BrowserGpuMemoryBufferManager(gpu_client_id_)),
326 gpu_host_id_(0), 231 gpu_host_id_(0) {
327 next_create_gpu_memory_buffer_request_id_(0) {
328 } 232 }
329 233
330 BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() { 234 BrowserGpuChannelHostFactory::~BrowserGpuChannelHostFactory() {
331 DCHECK(IsMainThread()); 235 DCHECK(IsMainThread());
332 if (pending_request_.get()) 236 if (pending_request_.get())
333 pending_request_->Cancel(); 237 pending_request_->Cancel();
334 for (size_t n = 0; n < established_callbacks_.size(); n++) 238 for (size_t n = 0; n < established_callbacks_.size(); n++)
335 established_callbacks_[n].Run(); 239 established_callbacks_[n].Run();
336 shutdown_event_->Signal(); 240 shutdown_event_->Signal();
337 if (gpu_channel_) { 241 if (gpu_channel_) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 DCHECK(pending_request_.get()); 371 DCHECK(pending_request_.get());
468 if (pending_request_->channel_handle().name.empty()) { 372 if (pending_request_->channel_handle().name.empty()) {
469 DCHECK(!gpu_channel_.get()); 373 DCHECK(!gpu_channel_.get());
470 } else { 374 } else {
471 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866 375 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866
472 // is fixed. 376 // is fixed.
473 tracked_objects::ScopedTracker tracking_profile1( 377 tracked_objects::ScopedTracker tracking_profile1(
474 FROM_HERE_WITH_EXPLICIT_FUNCTION( 378 FROM_HERE_WITH_EXPLICIT_FUNCTION(
475 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished1")); 379 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished1"));
476 GetContentClient()->SetGpuInfo(pending_request_->gpu_info()); 380 GetContentClient()->SetGpuInfo(pending_request_->gpu_info());
477 gpu_channel_ = 381 gpu_channel_ = GpuChannelHost::Create(
478 GpuChannelHost::Create(this, 382 this, pending_request_->gpu_info(), pending_request_->channel_handle(),
479 pending_request_->gpu_info(), 383 shutdown_event_.get(), gpu_memory_buffer_manager_.get());
480 pending_request_->channel_handle(),
481 shutdown_event_.get(),
482 BrowserGpuMemoryBufferManager::current());
483 } 384 }
484 gpu_host_id_ = pending_request_->gpu_host_id(); 385 gpu_host_id_ = pending_request_->gpu_host_id();
485 pending_request_ = NULL; 386 pending_request_ = NULL;
486 387
487 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866 is 388 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/466866 is
488 // fixed. 389 // fixed.
489 tracked_objects::ScopedTracker tracking_profile2( 390 tracked_objects::ScopedTracker tracking_profile2(
490 FROM_HERE_WITH_EXPLICIT_FUNCTION( 391 FROM_HERE_WITH_EXPLICIT_FUNCTION(
491 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished2")); 392 "466866 BrowserGpuChannelHostFactory::GpuChannelEstablished2"));
492 393
493 for (size_t n = 0; n < established_callbacks_.size(); n++) 394 for (size_t n = 0; n < established_callbacks_.size(); n++)
494 established_callbacks_[n].Run(); 395 established_callbacks_[n].Run();
495 396
496 established_callbacks_.clear(); 397 established_callbacks_.clear();
497 } 398 }
498 399
499 // static 400 // static
500 void BrowserGpuChannelHostFactory::AddFilterOnIO( 401 void BrowserGpuChannelHostFactory::AddFilterOnIO(
501 int host_id, 402 int host_id,
502 scoped_refptr<IPC::MessageFilter> filter) { 403 scoped_refptr<IPC::MessageFilter> filter) {
503 DCHECK_CURRENTLY_ON(BrowserThread::IO); 404 DCHECK_CURRENTLY_ON(BrowserThread::IO);
504 405
505 GpuProcessHost* host = GpuProcessHost::FromID(host_id); 406 GpuProcessHost* host = GpuProcessHost::FromID(host_id);
506 if (host) 407 if (host)
507 host->AddFilter(filter.get()); 408 host->AddFilter(filter.get());
508 } 409 }
509 410
510 bool BrowserGpuChannelHostFactory::IsGpuMemoryBufferConfigurationSupported(
511 gfx::GpuMemoryBuffer::Format format,
512 gfx::GpuMemoryBuffer::Usage usage) {
513 // Return early if usage is not enabled.
514 if (!IsGpuMemoryBufferFactoryUsageEnabled(usage))
515 return false;
516
517 std::vector<gfx::GpuMemoryBufferType> supported_types;
518 GpuMemoryBufferFactory::GetSupportedTypes(&supported_types);
519 DCHECK(!supported_types.empty());
520
521 // The GPU service will always use the preferred type, if the |format| and
522 // |usage| allows.
523 gfx::GpuMemoryBufferType type = supported_types[0];
524
525 return IsGpuMemoryBufferFactoryConfigurationSupported(format, usage, type);
526 }
527
528 void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer(
529 gfx::GpuMemoryBufferId id,
530 const gfx::Size& size,
531 gfx::GpuMemoryBuffer::Format format,
532 gfx::GpuMemoryBuffer::Usage usage,
533 int client_id,
534 int32 surface_id,
535 const CreateGpuMemoryBufferCallback& callback) {
536 DCHECK_CURRENTLY_ON(BrowserThread::IO);
537
538 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
539 if (!host) {
540 callback.Run(gfx::GpuMemoryBufferHandle());
541 return;
542 }
543
544 uint32 request_id = next_create_gpu_memory_buffer_request_id_++;
545 create_gpu_memory_buffer_requests_[request_id] = callback;
546
547 host->CreateGpuMemoryBuffer(
548 id, size, format, usage, client_id, surface_id,
549 base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated,
550 base::Unretained(this), request_id));
551 }
552
553 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer(
554 gfx::GpuMemoryBufferId id,
555 int client_id,
556 int32 sync_point) {
557 BrowserThread::PostTask(
558 BrowserThread::IO,
559 FROM_HERE,
560 base::Bind(&BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO,
561 base::Unretained(this),
562 id,
563 client_id,
564 sync_point));
565 }
566
567 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO(
568 gfx::GpuMemoryBufferId id,
569 int client_id,
570 int32 sync_point) {
571 DCHECK_CURRENTLY_ON(BrowserThread::IO);
572
573 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
574 if (!host)
575 return;
576
577 host->DestroyGpuMemoryBuffer(id, client_id, sync_point);
578 }
579
580 void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated(
581 uint32 request_id,
582 const gfx::GpuMemoryBufferHandle& handle) {
583 DCHECK_CURRENTLY_ON(BrowserThread::IO);
584
585 CreateGpuMemoryBufferCallbackMap::iterator iter =
586 create_gpu_memory_buffer_requests_.find(request_id);
587 DCHECK(iter != create_gpu_memory_buffer_requests_.end());
588 iter->second.Run(handle);
589 create_gpu_memory_buffer_requests_.erase(iter);
590 }
591
592 } // namespace content 411 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gpu/browser_gpu_channel_host_factory.h ('k') | content/browser/gpu/browser_gpu_memory_buffer_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698