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

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: GenericSharedMemoryId > gfx::GenericSharedMemoryTracingId 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_tracing_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(
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 "
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 10 matching lines...) Expand all
285 for (const auto& client : clients_) { 289 for (const auto& client : clients_) {
286 int client_id = client.first; 290 int client_id = client.first;
287 291
288 for (const auto& buffer : client.second) { 292 for (const auto& buffer : client.second) {
289 if (buffer.second.type == gfx::EMPTY_BUFFER) 293 if (buffer.second.type == gfx::EMPTY_BUFFER)
290 continue; 294 continue;
291 295
292 gfx::GpuMemoryBufferId buffer_id = buffer.first; 296 gfx::GpuMemoryBufferId buffer_id = buffer.first;
293 base::trace_event::MemoryAllocatorDump* dump = 297 base::trace_event::MemoryAllocatorDump* dump =
294 pmd->CreateAllocatorDump(base::StringPrintf( 298 pmd->CreateAllocatorDump(base::StringPrintf(
295 "gpumemorybuffer/client_%d/buffer_%d", client_id, buffer_id)); 299 "gpumemorybuffer/client_%d/buffer_%d", client_id, buffer_id.id));
296 if (!dump) 300 if (!dump)
297 return false; 301 return false;
298 302
299 size_t buffer_size_in_bytes = 0; 303 size_t buffer_size_in_bytes = 0;
300 // Note: BufferSizeInBytes returns an approximated size for the buffer 304 // Note: BufferSizeInBytes returns an approximated size for the buffer
301 // but the factory can be made to return the exact size if this 305 // but the factory can be made to return the exact size if this
302 // approximation is not good enough. 306 // approximation is not good enough.
303 bool valid_size = GpuMemoryBufferImpl::BufferSizeInBytes( 307 bool valid_size = GpuMemoryBufferImpl::BufferSizeInBytes(
304 buffer.second.size, buffer.second.format, &buffer_size_in_bytes); 308 buffer.second.size, buffer.second.format, &buffer_size_in_bytes);
305 DCHECK(valid_size); 309 DCHECK(valid_size);
(...skipping 86 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 =
407 content::GetNextGenericSharedMemoryTracingId();
403 408
404 // Use service side allocation if this is a supported configuration. 409 // Use service side allocation if this is a supported configuration.
405 if (IsGpuMemoryBufferConfigurationSupported(request->format, 410 if (IsGpuMemoryBufferConfigurationSupported(request->format,
406 request->usage)) { 411 request->usage)) {
407 // Note: Unretained is safe as this is only used for synchronous allocation 412 // Note: Unretained is safe as this is only used for synchronous allocation
408 // from a non-IO thread. 413 // from a non-IO thread.
409 AllocateGpuMemoryBufferOnIO( 414 AllocateGpuMemoryBufferOnIO(
410 new_id, request->size, request->format, request->usage, 415 new_id, request->size, request->format, request->usage,
411 request->client_id, request->surface_id, false, 416 request->client_id, request->surface_id, false,
412 base::Bind(&BrowserGpuMemoryBufferManager:: 417 base::Bind(&BrowserGpuMemoryBufferManager::
413 GpuMemoryBufferAllocatedForSurfaceOnIO, 418 GpuMemoryBufferAllocatedForSurfaceOnIO,
414 base::Unretained(this), base::Unretained(request))); 419 base::Unretained(this), base::Unretained(request)));
415 return; 420 return;
416 } 421 }
417 422
418 DCHECK(GpuMemoryBufferImplSharedMemory::IsFormatSupported(request->format)) 423 DCHECK(GpuMemoryBufferImplSharedMemory::IsFormatSupported(request->format))
419 << static_cast<int>(request->format); 424 << static_cast<int>(request->format);
420 DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage)) 425 DCHECK(GpuMemoryBufferImplSharedMemory::IsUsageSupported(request->usage))
421 << static_cast<int>(request->usage); 426 << static_cast<int>(request->usage);
422 427
423 BufferMap& buffers = clients_[request->client_id]; 428 BufferMap& buffers = clients_[request->client_id];
424 DCHECK(buffers.find(new_id) == buffers.end());
425 429
426 // Allocate shared memory buffer as fallback. 430 // Allocate shared memory buffer as fallback.
427 buffers[new_id] = BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER, 431 bool insert_succeeded =
428 request->format, request->usage, 0); 432 buffers.insert(std::make_pair(
433 new_id,
434 BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER,
435 request->format, request->usage, 0)))
436 .second;
437 DCHECK(insert_succeeded);
438
429 // 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
430 // destroyed. 440 // destroyed.
431 request->result = GpuMemoryBufferImplSharedMemory::Create( 441 request->result = GpuMemoryBufferImplSharedMemory::Create(
432 new_id, request->size, request->format, 442 new_id, request->size, request->format,
433 base::Bind( 443 base::Bind(
434 &GpuMemoryBufferDeleted, 444 &GpuMemoryBufferDeleted,
435 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 445 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
436 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, 446 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO,
437 base::Unretained(this), new_id, request->client_id))); 447 base::Unretained(this), new_id, request->client_id)));
438 request->event.Signal(); 448 request->event.Signal();
(...skipping 26 matching lines...) Expand all
465 gfx::GpuMemoryBufferId id, 475 gfx::GpuMemoryBufferId id,
466 const gfx::Size& size, 476 const gfx::Size& size,
467 gfx::BufferFormat format, 477 gfx::BufferFormat format,
468 gfx::BufferUsage usage, 478 gfx::BufferUsage usage,
469 int client_id, 479 int client_id,
470 int surface_id, 480 int surface_id,
471 bool reused_gpu_process, 481 bool reused_gpu_process,
472 const AllocationCallback& callback) { 482 const AllocationCallback& callback) {
473 DCHECK_CURRENTLY_ON(BrowserThread::IO); 483 DCHECK_CURRENTLY_ON(BrowserThread::IO);
474 484
475 BufferMap& buffers = clients_[client_id];
476 DCHECK(buffers.find(id) == buffers.end());
477
478 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); 485 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
479 if (!host) { 486 if (!host) {
480 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 487 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
481 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE); 488 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE);
482 if (!host) { 489 if (!host) {
483 LOG(ERROR) << "Failed to launch GPU process."; 490 LOG(ERROR) << "Failed to launch GPU process.";
484 callback.Run(gfx::GpuMemoryBufferHandle()); 491 callback.Run(gfx::GpuMemoryBufferHandle());
485 return; 492 return;
486 } 493 }
487 gpu_host_id_ = host->host_id(); 494 gpu_host_id_ = host->host_id();
488 reused_gpu_process = false; 495 reused_gpu_process = false;
489 } else { 496 } else {
490 if (reused_gpu_process) { 497 if (reused_gpu_process) {
491 // 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
492 // failure in GpuMemoryBufferAllocatedOnIO, but we ended up with the 499 // failure in GpuMemoryBufferAllocatedOnIO, but we ended up with the
493 // 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
494 // error, but another reason. So fail now. 501 // error, but another reason. So fail now.
495 LOG(ERROR) << "Failed to allocate GpuMemoryBuffer."; 502 LOG(ERROR) << "Failed to allocate GpuMemoryBuffer.";
496 callback.Run(gfx::GpuMemoryBufferHandle()); 503 callback.Run(gfx::GpuMemoryBufferHandle());
497 return; 504 return;
498 } 505 }
499 reused_gpu_process = true; 506 reused_gpu_process = true;
500 } 507 }
501 508
509 BufferMap& buffers = clients_[client_id];
510
502 // 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
503 // 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
504 // and verify that this has not changed when allocation completes. 513 // and verify that this has not changed when allocation completes.
505 buffers[id] = BufferInfo(size, gfx::EMPTY_BUFFER, format, usage, 0); 514 if (!buffers.insert(std::make_pair(id, BufferInfo(size, gfx::EMPTY_BUFFER,
515 format, usage, 0)))
516 .second) {
517 LOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with "
518 "an existing ID.";
519 callback.Run(gfx::GpuMemoryBufferHandle());
520 return;
521 }
506 522
507 // 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
508 // destroyed. 524 // destroyed.
509 host->CreateGpuMemoryBuffer( 525 host->CreateGpuMemoryBuffer(
510 id, size, format, usage, client_id, surface_id, 526 id, size, format, usage, client_id, surface_id,
511 base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO, 527 base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO,
512 base::Unretained(this), id, client_id, surface_id, 528 base::Unretained(this), id, client_id, surface_id,
513 gpu_host_id_, reused_gpu_process, callback)); 529 gpu_host_id_, reused_gpu_process, callback));
514 } 530 }
515 531
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 return gpu_client_tracing_id_; 631 return gpu_client_tracing_id_;
616 } 632 }
617 633
618 // 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
619 // the standard conversion. 635 // the standard conversion.
620 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId( 636 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
621 client_id); 637 client_id);
622 } 638 }
623 639
624 } // namespace content 640 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698