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

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: remove "tracing" from name 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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration)) 135 if (IsGpuMemoryBufferFactoryConfigurationSupported(type, configuration))
135 configurations.push_back(configuration); 136 configurations.push_back(configuration);
136 } 137 }
137 #endif 138 #endif
138 139
139 return configurations; 140 return configurations;
140 } 141 }
141 142
142 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr; 143 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr;
143 144
144 // Global atomic to generate gpu memory buffer unique IDs.
145 base::StaticAtomicSequenceNumber g_next_gpu_memory_buffer_id;
146
147 } // namespace 145 } // namespace
148 146
149 struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest { 147 struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest {
150 AllocateGpuMemoryBufferRequest(const gfx::Size& size, 148 AllocateGpuMemoryBufferRequest(const gfx::Size& size,
151 gfx::BufferFormat format, 149 gfx::BufferFormat format,
152 gfx::BufferUsage usage, 150 gfx::BufferUsage usage,
153 int client_id, 151 int client_id,
154 int surface_id) 152 int surface_id)
155 : event(true, false), 153 : event(true, false),
156 size(size), 154 size(size),
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForScanout( 225 BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForScanout(
228 const gfx::Size& size, 226 const gfx::Size& size,
229 gfx::BufferFormat format, 227 gfx::BufferFormat format,
230 int32 surface_id) { 228 int32 surface_id) {
231 DCHECK_GT(surface_id, 0); 229 DCHECK_GT(surface_id, 0);
232 return AllocateGpuMemoryBufferForSurface( 230 return AllocateGpuMemoryBufferForSurface(
233 size, format, gfx::BufferUsage::SCANOUT, surface_id); 231 size, format, gfx::BufferUsage::SCANOUT, surface_id);
234 } 232 }
235 233
236 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess( 234 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForChildProcess(
235 gfx::GpuMemoryBufferId id,
237 const gfx::Size& size, 236 const gfx::Size& size,
238 gfx::BufferFormat format, 237 gfx::BufferFormat format,
239 gfx::BufferUsage usage, 238 gfx::BufferUsage usage,
240 base::ProcessHandle child_process_handle, 239 base::ProcessHandle child_process_handle,
241 int child_client_id, 240 int child_client_id,
242 const AllocationCallback& callback) { 241 const AllocationCallback& callback) {
243 DCHECK_CURRENTLY_ON(BrowserThread::IO); 242 DCHECK_CURRENTLY_ON(BrowserThread::IO);
244 243
245 gfx::GpuMemoryBufferId new_id = g_next_gpu_memory_buffer_id.GetNext();
246
247 // Use service side allocation if this is a supported configuration. 244 // Use service side allocation if this is a supported configuration.
248 if (IsGpuMemoryBufferConfigurationSupported(format, usage)) { 245 if (IsGpuMemoryBufferConfigurationSupported(format, usage)) {
249 AllocateGpuMemoryBufferOnIO(new_id, size, format, usage, child_client_id, 0, 246 AllocateGpuMemoryBufferOnIO(id, size, format, usage, child_client_id, 0,
250 false, callback); 247 false, callback);
251 return; 248 return;
252 } 249 }
253 250
254 // Early out if we cannot fallback to shared memory buffer. 251 // Early out if we cannot fallback to shared memory buffer.
255 if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) || 252 if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) ||
256 !GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) || 253 !GpuMemoryBufferImplSharedMemory::IsUsageSupported(usage) ||
257 !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format)) { 254 !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format)) {
258 callback.Run(gfx::GpuMemoryBufferHandle()); 255 callback.Run(gfx::GpuMemoryBufferHandle());
259 return; 256 return;
260 } 257 }
261 258
262 BufferMap& buffers = clients_[child_client_id]; 259 BufferMap& buffers = clients_[child_client_id];
263 DCHECK(buffers.find(new_id) == buffers.end());
264 260
265 // Allocate shared memory buffer as fallback. 261 // Allocate shared memory buffer as fallback.
266 buffers[new_id] = 262 auto insert_result = buffers.insert(std::make_pair(
267 BufferInfo(size, gfx::SHARED_MEMORY_BUFFER, format, usage, 0); 263 id, BufferInfo(size, gfx::SHARED_MEMORY_BUFFER, format, usage, 0)));
264 if (!insert_result.second) {
265 DLOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with "
266 "an existing ID.";
267 callback.Run(gfx::GpuMemoryBufferHandle());
268 return;
269 }
270
268 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess( 271 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
269 new_id, size, format, child_process_handle)); 272 id, size, format, child_process_handle));
270 } 273 }
271 274
272 gfx::GpuMemoryBuffer* 275 gfx::GpuMemoryBuffer*
273 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( 276 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
274 ClientBuffer buffer) { 277 ClientBuffer buffer) {
275 return GpuMemoryBufferImpl::FromClientBuffer(buffer); 278 return GpuMemoryBufferImpl::FromClientBuffer(buffer);
276 } 279 }
277 280
278 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint( 281 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint(
279 gfx::GpuMemoryBuffer* buffer, 282 gfx::GpuMemoryBuffer* buffer,
(...skipping 10 matching lines...) Expand all
290 for (const auto& client : clients_) { 293 for (const auto& client : clients_) {
291 int client_id = client.first; 294 int client_id = client.first;
292 295
293 for (const auto& buffer : client.second) { 296 for (const auto& buffer : client.second) {
294 if (buffer.second.type == gfx::EMPTY_BUFFER) 297 if (buffer.second.type == gfx::EMPTY_BUFFER)
295 continue; 298 continue;
296 299
297 gfx::GpuMemoryBufferId buffer_id = buffer.first; 300 gfx::GpuMemoryBufferId buffer_id = buffer.first;
298 base::trace_event::MemoryAllocatorDump* dump = 301 base::trace_event::MemoryAllocatorDump* dump =
299 pmd->CreateAllocatorDump(base::StringPrintf( 302 pmd->CreateAllocatorDump(base::StringPrintf(
300 "gpumemorybuffer/client_%d/buffer_%d", client_id, buffer_id)); 303 "gpumemorybuffer/client_%d/buffer_%d", client_id, buffer_id.id));
301 if (!dump) 304 if (!dump)
302 return false; 305 return false;
303 306
304 size_t buffer_size_in_bytes = 0; 307 size_t buffer_size_in_bytes = 0;
305 // Note: BufferSizeInBytes returns an approximated size for the buffer 308 // Note: BufferSizeInBytes returns an approximated size for the buffer
306 // but the factory can be made to return the exact size if this 309 // but the factory can be made to return the exact size if this
307 // approximation is not good enough. 310 // approximation is not good enough.
308 bool valid_size = GpuMemoryBufferImpl::BufferSizeInBytes( 311 bool valid_size = GpuMemoryBufferImpl::BufferSizeInBytes(
309 buffer.second.size, buffer.second.format, &buffer_size_in_bytes); 312 buffer.second.size, buffer.second.format, &buffer_size_in_bytes);
310 DCHECK(valid_size); 313 DCHECK(valid_size);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 if (configuration.format == format && configuration.usage == usage) 400 if (configuration.format == format && configuration.usage == usage)
398 return true; 401 return true;
399 } 402 }
400 return false; 403 return false;
401 } 404 }
402 405
403 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO( 406 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO(
404 AllocateGpuMemoryBufferRequest* request) { 407 AllocateGpuMemoryBufferRequest* request) {
405 DCHECK_CURRENTLY_ON(BrowserThread::IO); 408 DCHECK_CURRENTLY_ON(BrowserThread::IO);
406 409
407 gfx::GpuMemoryBufferId new_id = g_next_gpu_memory_buffer_id.GetNext(); 410 gfx::GpuMemoryBufferId new_id = content::GetNextGenericSharedMemoryId();
408 411
409 // Use service side allocation if this is a supported configuration. 412 // Use service side allocation if this is a supported configuration.
410 if (IsGpuMemoryBufferConfigurationSupported(request->format, 413 if (IsGpuMemoryBufferConfigurationSupported(request->format,
411 request->usage)) { 414 request->usage)) {
412 // Note: Unretained is safe as this is only used for synchronous allocation 415 // Note: Unretained is safe as this is only used for synchronous allocation
413 // from a non-IO thread. 416 // from a non-IO thread.
414 AllocateGpuMemoryBufferOnIO( 417 AllocateGpuMemoryBufferOnIO(
415 new_id, request->size, request->format, request->usage, 418 new_id, request->size, request->format, request->usage,
416 request->client_id, request->surface_id, false, 419 request->client_id, request->surface_id, false,
417 base::Bind(&BrowserGpuMemoryBufferManager:: 420 base::Bind(&BrowserGpuMemoryBufferManager::
418 GpuMemoryBufferAllocatedForSurfaceOnIO, 421 GpuMemoryBufferAllocatedForSurfaceOnIO,
419 base::Unretained(this), base::Unretained(request))); 422 base::Unretained(this), base::Unretained(request)));
420 return; 423 return;
421 } 424 }
422 425
423 DCHECK(GpuMemoryBufferImplSharedMemory::IsFormatSupported(request->format)) 426 DCHECK(GpuMemoryBufferImplSharedMemory::IsFormatSupported(request->format))
424 << static_cast<int>(request->format); 427 << static_cast<int>(request->format);
425 DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage)) 428 DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage))
426 << static_cast<int>(request->usage); 429 << static_cast<int>(request->usage);
427 430
428 BufferMap& buffers = clients_[request->client_id]; 431 BufferMap& buffers = clients_[request->client_id];
429 DCHECK(buffers.find(new_id) == buffers.end());
430 432
431 // Allocate shared memory buffer as fallback. 433 // Allocate shared memory buffer as fallback.
432 buffers[new_id] = BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER, 434 auto insert_result = buffers.insert(std::make_pair(
433 request->format, request->usage, 0); 435 new_id, BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER,
436 request->format, request->usage, 0)));
437 DCHECK(insert_result.second);
438
434 // Note: Unretained is safe as IO thread is stopped before manager is 439 // Note: Unretained is safe as IO thread is stopped before manager is
435 // destroyed. 440 // destroyed.
436 request->result = GpuMemoryBufferImplSharedMemory::Create( 441 request->result = GpuMemoryBufferImplSharedMemory::Create(
437 new_id, request->size, request->format, 442 new_id, request->size, request->format,
438 base::Bind( 443 base::Bind(
439 &GpuMemoryBufferDeleted, 444 &GpuMemoryBufferDeleted,
440 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 445 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
441 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, 446 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO,
442 base::Unretained(this), new_id, request->client_id))); 447 base::Unretained(this), new_id, request->client_id)));
443 request->event.Signal(); 448 request->event.Signal();
(...skipping 26 matching lines...) Expand all
470 gfx::GpuMemoryBufferId id, 475 gfx::GpuMemoryBufferId id,
471 const gfx::Size& size, 476 const gfx::Size& size,
472 gfx::BufferFormat format, 477 gfx::BufferFormat format,
473 gfx::BufferUsage usage, 478 gfx::BufferUsage usage,
474 int client_id, 479 int client_id,
475 int surface_id, 480 int surface_id,
476 bool reused_gpu_process, 481 bool reused_gpu_process,
477 const AllocationCallback& callback) { 482 const AllocationCallback& callback) {
478 DCHECK_CURRENTLY_ON(BrowserThread::IO); 483 DCHECK_CURRENTLY_ON(BrowserThread::IO);
479 484
480 BufferMap& buffers = clients_[client_id];
481 DCHECK(buffers.find(id) == buffers.end());
482
483 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); 485 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
484 if (!host) { 486 if (!host) {
485 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 487 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
486 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE); 488 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE);
487 if (!host) { 489 if (!host) {
488 LOG(ERROR) << "Failed to launch GPU process."; 490 LOG(ERROR) << "Failed to launch GPU process.";
489 callback.Run(gfx::GpuMemoryBufferHandle()); 491 callback.Run(gfx::GpuMemoryBufferHandle());
490 return; 492 return;
491 } 493 }
492 gpu_host_id_ = host->host_id(); 494 gpu_host_id_ = host->host_id();
493 reused_gpu_process = false; 495 reused_gpu_process = false;
494 } else { 496 } else {
495 if (reused_gpu_process) { 497 if (reused_gpu_process) {
496 // We come here if we retried to allocate the buffer because of a 498 // We come here if we retried to allocate the buffer because of a
497 // failure in GpuMemoryBufferAllocatedOnIO, but we ended up with the 499 // failure in GpuMemoryBufferAllocatedOnIO, but we ended up with the
498 // same process ID, meaning the failure was not because of a channel 500 // same process ID, meaning the failure was not because of a channel
499 // error, but another reason. So fail now. 501 // error, but another reason. So fail now.
500 LOG(ERROR) << "Failed to allocate GpuMemoryBuffer."; 502 LOG(ERROR) << "Failed to allocate GpuMemoryBuffer.";
501 callback.Run(gfx::GpuMemoryBufferHandle()); 503 callback.Run(gfx::GpuMemoryBufferHandle());
502 return; 504 return;
503 } 505 }
504 reused_gpu_process = true; 506 reused_gpu_process = true;
505 } 507 }
506 508
509 BufferMap& buffers = clients_[client_id];
510
507 // Note: Handling of cases where the client is removed before the allocation 511 // Note: Handling of cases where the client is removed before the allocation
508 // completes is less subtle if we set the buffer type to EMPTY_BUFFER here 512 // completes is less subtle if we set the buffer type to EMPTY_BUFFER here
509 // and verify that this has not changed when allocation completes. 513 // and verify that this has not changed when allocation completes.
510 buffers[id] = BufferInfo(size, gfx::EMPTY_BUFFER, format, usage, 0); 514 auto insert_result = buffers.insert(std::make_pair(
515 id, BufferInfo(size, gfx::EMPTY_BUFFER, format, usage, 0)));
516 if (!insert_result.second) {
517 DLOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with "
518 "an existing ID.";
519 callback.Run(gfx::GpuMemoryBufferHandle());
520 return;
521 }
511 522
512 // Note: Unretained is safe as IO thread is stopped before manager is 523 // Note: Unretained is safe as IO thread is stopped before manager is
513 // destroyed. 524 // destroyed.
514 host->CreateGpuMemoryBuffer( 525 host->CreateGpuMemoryBuffer(
515 id, size, format, usage, client_id, surface_id, 526 id, size, format, usage, client_id, surface_id,
516 base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO, 527 base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO,
517 base::Unretained(this), id, client_id, surface_id, 528 base::Unretained(this), id, client_id, surface_id,
518 gpu_host_id_, reused_gpu_process, callback)); 529 gpu_host_id_, reused_gpu_process, callback));
519 } 530 }
520 531
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 return gpu_client_tracing_id_; 631 return gpu_client_tracing_id_;
621 } 632 }
622 633
623 // In normal cases, |client_id| is a child process id, so we can perform 634 // In normal cases, |client_id| is a child process id, so we can perform
624 // the standard conversion. 635 // the standard conversion.
625 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId( 636 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
626 client_id); 637 client_id);
627 } 638 }
628 639
629 } // namespace content 640 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698