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

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

Issue 1280513002: Add GenericSharedMemoryId and use w/ GpuMemoryBuffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@trackpools
Patch Set: Review Feedback Created 5 years, 4 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 2014 The Chromium Authors. All rights reserved. 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 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_memory_buffer_manager.h" 5 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
6 6
7 #include "base/atomic_sequence_num.h" 7 #include "base/atomic_sequence_num.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
11 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
12 #include "base/threading/thread_restrictions.h" 12 #include "base/threading/thread_restrictions.h"
13 #include "base/trace_event/process_memory_dump.h" 13 #include "base/trace_event/process_memory_dump.h"
14 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
15 #include "content/browser/gpu/gpu_process_host.h" 15 #include "content/browser/gpu/gpu_process_host.h"
16 #include "content/common/child_process_host_impl.h" 16 #include "content/common/child_process_host_impl.h"
17 #include "content/common/generic_shared_memory_id_generator.h"
17 #include "content/common/gpu/client/gpu_memory_buffer_impl.h" 18 #include "content/common/gpu/client/gpu_memory_buffer_impl.h"
18 #include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h" 19 #include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
19 #include "content/common/gpu/gpu_memory_buffer_factory_shared_memory.h" 20 #include "content/common/gpu/gpu_memory_buffer_factory_shared_memory.h"
20 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
21 #include "content/public/common/content_switches.h" 22 #include "content/public/common/content_switches.h"
22 #include "gpu/GLES2/gl2extchromium.h" 23 #include "gpu/GLES2/gl2extchromium.h"
23 #include "ui/gl/gl_switches.h" 24 #include "ui/gl/gl_switches.h"
24 25
25 #if defined(OS_MACOSX) 26 #if defined(OS_MACOSX)
26 #include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h" 27 #include "content/common/gpu/gpu_memory_buffer_factory_io_surface.h"
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration)) 130 if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration))
130 configurations.push_back(configuration); 131 configurations.push_back(configuration);
131 } 132 }
132 #endif 133 #endif
133 134
134 return configurations; 135 return configurations;
135 } 136 }
136 137
137 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr; 138 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr;
138 139
139 // Global atomic to generate gpu memory buffer unique IDs.
140 base::StaticAtomicSequenceNumber g_next_gpu_memory_buffer_id;
141
142 } // namespace 140 } // namespace
143 141
144 struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest { 142 struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest {
145 AllocateGpuMemoryBufferRequest(const gfx::Size& size, 143 AllocateGpuMemoryBufferRequest(const gfx::Size& size,
146 gfx::BufferFormat format, 144 gfx::BufferFormat format,
147 gfx::BufferUsage usage, 145 gfx::BufferUsage usage,
148 int client_id, 146 int client_id,
149 int surface_id) 147 int surface_id)
150 : event(true, false), 148 : event(true, false),
151 size(size), 149 size(size),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForScanout( 220 BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForScanout(
223 const gfx::Size& size, 221 const gfx::Size& size,
224 gfx::BufferFormat format, 222 gfx::BufferFormat format,
225 int32 surface_id) { 223 int32 surface_id) {
226 DCHECK_GT(surface_id, 0); 224 DCHECK_GT(surface_id, 0);
227 return AllocateGpuMemoryBufferForSurface( 225 return AllocateGpuMemoryBufferForSurface(
228 size, format, gfx::BufferUsage::SCANOUT, surface_id); 226 size, format, gfx::BufferUsage::SCANOUT, surface_id);
229 } 227 }
230 228
231 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess( 229 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess(
230 gfx::GpuMemoryBufferId id,
232 const gfx::Size& size, 231 const gfx::Size& size,
233 gfx::BufferFormat format, 232 gfx::BufferFormat format,
234 gfx::BufferUsage usage, 233 gfx::BufferUsage usage,
235 base::ProcessHandle child_process_handle, 234 base::ProcessHandle child_process_handle,
236 int child_client_id, 235 int child_client_id,
237 const AllocationCallback& callback) { 236 const AllocationCallback& callback) {
238 DCHECK_CURRENTLY_ON(BrowserThread::IO); 237 DCHECK_CURRENTLY_ON(BrowserThread::IO);
239 238
240 gfx::GpuMemoryBufferId new_id = g_next_gpu_memory_buffer_id.GetNext();
241
242 // Use service side allocation if this is a supported configuration. 239 // Use service side allocation if this is a supported configuration.
243 if (IsGpuMemoryBufferConfigurationSupported(format, usage)) { 240 if (IsGpuMemoryBufferConfigurationSupported(format, usage)) {
244 AllocateGpuMemoryBufferOnIO(new_id, size, format, usage, child_client_id, 0, 241 AllocateGpuMemoryBufferOnIO(id, size, format, usage, child_client_id, 0,
245 false, callback); 242 false, callback);
246 return; 243 return;
247 } 244 }
248 245
249 // Early out if we cannot fallback to shared memory buffer. 246 // Early out if we cannot fallback to shared memory buffer.
250 if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) || 247 if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) ||
251 !GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) || 248 !GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) ||
252 !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format)) { 249 !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format)) {
253 callback.Run(gfx::GpuMemoryBufferHandle()); 250 callback.Run(gfx::GpuMemoryBufferHandle());
254 return; 251 return;
255 } 252 }
256 253
257 BufferMap& buffers = clients_[child_client_id]; 254 BufferMap& buffers = clients_[child_client_id];
258 DCHECK(buffers.find(new_id) == buffers.end());
259 255
260 // Allocate shared memory buffer as fallback. 256 // Allocate shared memory buffer as fallback.
261 buffers[new_id] = 257 if (!buffers.insert(
danakj 2015/08/12 23:49:02 is is possible to split this up into multiple line
ericrk 2015/08/13 00:13:56 Done.
262 BufferInfo(size, gfx::SHARED_MEMORY_BUFFER, format, usage, 0); 258 std::make_pair(id, BufferInfo(size, gfx::SHARED_MEMORY_BUFFER,
259 format, usage, 0)))
260 .second) {
261 LOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with "
danakj 2015/08/12 23:49:02 Can we use DLOG or VLOG? (prefer former so we don'
ericrk 2015/08/13 00:13:56 Done.
262 "an existing ID.";
263 callback.Run(gfx::GpuMemoryBufferHandle());
264 return;
265 }
266
263 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess( 267 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
264 new_id, size, format, child_process_handle)); 268 id, size, format, child_process_handle));
265 } 269 }
266 270
267 gfx::GpuMemoryBuffer* 271 gfx::GpuMemoryBuffer*
268 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( 272 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
269 ClientBuffer buffer) { 273 ClientBuffer buffer) {
270 return GpuMemoryBufferImpl::FromClientBuffer(buffer); 274 return GpuMemoryBufferImpl::FromClientBuffer(buffer);
271 } 275 }
272 276
273 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint( 277 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint(
274 gfx::GpuMemoryBuffer* buffer, 278 gfx::GpuMemoryBuffer* buffer,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 if (configuration.format == format && configuration.usage == usage) 396 if (configuration.format == format && configuration.usage == usage)
393 return true; 397 return true;
394 } 398 }
395 return false; 399 return false;
396 } 400 }
397 401
398 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO( 402 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO(
399 AllocateGpuMemoryBufferRequest* request) { 403 AllocateGpuMemoryBufferRequest* request) {
400 DCHECK_CURRENTLY_ON(BrowserThread::IO); 404 DCHECK_CURRENTLY_ON(BrowserThread::IO);
401 405
402 gfx::GpuMemoryBufferId new_id = g_next_gpu_memory_buffer_id.GetNext(); 406 gfx::GpuMemoryBufferId new_id = content::GetNextGenericSharedMemoryId();
403 407
404 // Use service side allocation if this is a supported configuration. 408 // Use service side allocation if this is a supported configuration.
405 if (IsGpuMemoryBufferConfigurationSupported(request->format, 409 if (IsGpuMemoryBufferConfigurationSupported(request->format,
406 request->usage)) { 410 request->usage)) {
407 // Note: Unretained is safe as this is only used for synchronous allocation 411 // Note: Unretained is safe as this is only used for synchronous allocation
408 // from a non-IO thread. 412 // from a non-IO thread.
409 AllocateGpuMemoryBufferOnIO( 413 AllocateGpuMemoryBufferOnIO(
410 new_id, request->size, request->format, request->usage, 414 new_id, request->size, request->format, request->usage,
411 request->client_id, request->surface_id, false, 415 request->client_id, request->surface_id, false,
412 base::Bind(&BrowserGpuMemoryBufferManager:: 416 base::Bind(&BrowserGpuMemoryBufferManager::
413 GpuMemoryBufferAllocatedForSurfaceOnIO, 417 GpuMemoryBufferAllocatedForSurfaceOnIO,
414 base::Unretained(this), base::Unretained(request))); 418 base::Unretained(this), base::Unretained(request)));
415 return; 419 return;
416 } 420 }
417 421
418 DCHECK(GpuMemoryBufferImplSharedMemory::IsFormatSupported(request->format)) 422 DCHECK(GpuMemoryBufferImplSharedMemory::IsFormatSupported(request->format))
419 << static_cast<int>(request->format); 423 << static_cast<int>(request->format);
420 DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage)) 424 DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage))
421 << static_cast<int>(request->usage); 425 << static_cast<int>(request->usage);
422 426
423 BufferMap& buffers = clients_[request->client_id]; 427 BufferMap& buffers = clients_[request->client_id];
424 DCHECK(buffers.find(new_id) == buffers.end());
425 428
426 // Allocate shared memory buffer as fallback. 429 // Allocate shared memory buffer as fallback.
427 buffers[new_id] = BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER, 430 bool insert_succeeded =
danakj 2015/08/12 23:49:01 is is possible to split this up into multiple line
ericrk 2015/08/13 00:13:56 I think that after removing the .second things loo
428 request->format, request->usage, 0); 431 buffers.insert(std::make_pair(
432 new_id,
433 BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER,
434 request->format, request->usage, 0)))
435 .second;
436 DCHECK(insert_succeeded);
437
429 // Note: Unretained is safe as IO thread is stopped before manager is 438 // Note: Unretained is safe as IO thread is stopped before manager is
430 // destroyed. 439 // destroyed.
431 request->result = GpuMemoryBufferImplSharedMemory::Create( 440 request->result = GpuMemoryBufferImplSharedMemory::Create(
432 new_id, request->size, request->format, 441 new_id, request->size, request->format,
433 base::Bind( 442 base::Bind(
434 &GpuMemoryBufferDeleted, 443 &GpuMemoryBufferDeleted,
435 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 444 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
436 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, 445 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO,
437 base::Unretained(this), new_id, request->client_id))); 446 base::Unretained(this), new_id, request->client_id)));
438 request->event.Signal(); 447 request->event.Signal();
(...skipping 26 matching lines...) Expand all
465 gfx::GpuMemoryBufferId id, 474 gfx::GpuMemoryBufferId id,
466 const gfx::Size& size, 475 const gfx::Size& size,
467 gfx::BufferFormat format, 476 gfx::BufferFormat format,
468 gfx::BufferUsage usage, 477 gfx::BufferUsage usage,
469 int client_id, 478 int client_id,
470 int surface_id, 479 int surface_id,
471 bool reused_gpu_process, 480 bool reused_gpu_process,
472 const AllocationCallback& callback) { 481 const AllocationCallback& callback) {
473 DCHECK_CURRENTLY_ON(BrowserThread::IO); 482 DCHECK_CURRENTLY_ON(BrowserThread::IO);
474 483
475 BufferMap& buffers = clients_[client_id];
476 DCHECK(buffers.find(id) == buffers.end());
477
478 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); 484 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
479 if (!host) { 485 if (!host) {
480 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 486 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
481 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE); 487 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE);
482 if (!host) { 488 if (!host) {
483 LOG(ERROR) << "Failed to launch GPU process."; 489 LOG(ERROR) << "Failed to launch GPU process.";
484 callback.Run(gfx::GpuMemoryBufferHandle()); 490 callback.Run(gfx::GpuMemoryBufferHandle());
485 return; 491 return;
486 } 492 }
487 gpu_host_id_ = host->host_id(); 493 gpu_host_id_ = host->host_id();
488 reused_gpu_process = false; 494 reused_gpu_process = false;
489 } else { 495 } else {
490 if (reused_gpu_process) { 496 if (reused_gpu_process) {
491 // We come here if we retried to allocate the buffer because of a 497 // We come here if we retried to allocate the buffer because of a
492 // failure in GpuMemoryBufferAllocatedOnIO, but we ended up with the 498 // failure in GpuMemoryBufferAllocatedOnIO, but we ended up with the
493 // same process ID, meaning the failure was not because of a channel 499 // same process ID, meaning the failure was not because of a channel
494 // error, but another reason. So fail now. 500 // error, but another reason. So fail now.
495 LOG(ERROR) << "Failed to allocate GpuMemoryBuffer."; 501 LOG(ERROR) << "Failed to allocate GpuMemoryBuffer.";
496 callback.Run(gfx::GpuMemoryBufferHandle()); 502 callback.Run(gfx::GpuMemoryBufferHandle());
497 return; 503 return;
498 } 504 }
499 reused_gpu_process = true; 505 reused_gpu_process = true;
500 } 506 }
501 507
508 BufferMap& buffers = clients_[client_id];
509
502 // Note: Handling of cases where the client is removed before the allocation 510 // Note: Handling of cases where the client is removed before the allocation
503 // completes is less subtle if we set the buffer type to EMPTY_BUFFER here 511 // completes is less subtle if we set the buffer type to EMPTY_BUFFER here
504 // and verify that this has not changed when allocation completes. 512 // and verify that this has not changed when allocation completes.
505 buffers[id] = BufferInfo(size, gfx::EMPTY_BUFFER, format, usage, 0); 513 if (!buffers.insert(std::make_pair(id, BufferInfo(size, gfx::EMPTY_BUFFER,
danakj 2015/08/12 23:49:01 is is possible to split this up into multiple line
ericrk 2015/08/13 00:13:56 Done.
514 format, usage, 0)))
515 .second) {
516 LOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with "
danakj 2015/08/12 23:49:01 DLOG? VLOD?
ericrk 2015/08/13 00:13:56 Done.
517 "an existing ID.";
518 callback.Run(gfx::GpuMemoryBufferHandle());
519 return;
520 }
506 521
507 // Note: Unretained is safe as IO thread is stopped before manager is 522 // Note: Unretained is safe as IO thread is stopped before manager is
508 // destroyed. 523 // destroyed.
509 host->CreateGpuMemoryBuffer( 524 host->CreateGpuMemoryBuffer(
510 id, size, format, usage, client_id, surface_id, 525 id, size, format, usage, client_id, surface_id,
511 base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO, 526 base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO,
512 base::Unretained(this), id, client_id, surface_id, 527 base::Unretained(this), id, client_id, surface_id,
513 gpu_host_id_, reused_gpu_process, callback)); 528 gpu_host_id_, reused_gpu_process, callback));
514 } 529 }
515 530
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 return gpu_client_tracing_id_; 630 return gpu_client_tracing_id_;
616 } 631 }
617 632
618 // In normal cases, |client_id| is a child process id, so we can perform 633 // In normal cases, |client_id| is a child process id, so we can perform
619 // the standard conversion. 634 // the standard conversion.
620 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId( 635 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
621 client_id); 636 client_id);
622 } 637 }
623 638
624 } // namespace content 639 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698