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

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: 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_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 auto insert_result = buffers.insert(std::make_pair(
danakj 2015/08/13 00:25:06 Looks good.
262 BufferInfo(size, gfx::SHARED_MEMORY_BUFFER, format, usage, 0); 258 id, BufferInfo(size, gfx::SHARED_MEMORY_BUFFER, format, usage, 0)));
259 if (!insert_result.second) {
260 DLOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with "
261 "an existing ID.";
262 callback.Run(gfx::GpuMemoryBufferHandle());
263 return;
264 }
265
263 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess( 266 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
264 new_id, size, format, child_process_handle)); 267 id, size, format, child_process_handle));
265 } 268 }
266 269
267 gfx::GpuMemoryBuffer* 270 gfx::GpuMemoryBuffer*
268 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( 271 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
269 ClientBuffer buffer) { 272 ClientBuffer buffer) {
270 return GpuMemoryBufferImpl::FromClientBuffer(buffer); 273 return GpuMemoryBufferImpl::FromClientBuffer(buffer);
271 } 274 }
272 275
273 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint( 276 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint(
274 gfx::GpuMemoryBuffer* buffer, 277 gfx::GpuMemoryBuffer* buffer,
(...skipping 10 matching lines...) Expand all
285 for (const auto& client : clients_) { 288 for (const auto& client : clients_) {
286 int client_id = client.first; 289 int client_id = client.first;
287 290
288 for (const auto& buffer : client.second) { 291 for (const auto& buffer : client.second) {
289 if (buffer.second.type == gfx::EMPTY_BUFFER) 292 if (buffer.second.type == gfx::EMPTY_BUFFER)
290 continue; 293 continue;
291 294
292 gfx::GpuMemoryBufferId buffer_id = buffer.first; 295 gfx::GpuMemoryBufferId buffer_id = buffer.first;
293 base::trace_event::MemoryAllocatorDump* dump = 296 base::trace_event::MemoryAllocatorDump* dump =
294 pmd->CreateAllocatorDump(base::StringPrintf( 297 pmd->CreateAllocatorDump(base::StringPrintf(
295 "gpumemorybuffer/client_%d/buffer_%d", client_id, buffer_id)); 298 "gpumemorybuffer/client_%d/buffer_%d", client_id, buffer_id.id));
296 if (!dump) 299 if (!dump)
297 return false; 300 return false;
298 301
299 size_t buffer_size_in_bytes = 0; 302 size_t buffer_size_in_bytes = 0;
300 // Note: BufferSizeInBytes returns an approximated size for the buffer 303 // Note: BufferSizeInBytes returns an approximated size for the buffer
301 // but the factory can be made to return the exact size if this 304 // but the factory can be made to return the exact size if this
302 // approximation is not good enough. 305 // approximation is not good enough.
303 bool valid_size = GpuMemoryBufferImpl::BufferSizeInBytes( 306 bool valid_size = GpuMemoryBufferImpl::BufferSizeInBytes(
304 buffer.second.size, buffer.second.format, &buffer_size_in_bytes); 307 buffer.second.size, buffer.second.format, &buffer_size_in_bytes);
305 DCHECK(valid_size); 308 DCHECK(valid_size);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 if (configuration.format == format && configuration.usage == usage) 395 if (configuration.format == format && configuration.usage == usage)
393 return true; 396 return true;
394 } 397 }
395 return false; 398 return false;
396 } 399 }
397 400
398 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO( 401 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferForSurfaceOnIO(
399 AllocateGpuMemoryBufferRequest* request) { 402 AllocateGpuMemoryBufferRequest* request) {
400 DCHECK_CURRENTLY_ON(BrowserThread::IO); 403 DCHECK_CURRENTLY_ON(BrowserThread::IO);
401 404
402 gfx::GpuMemoryBufferId new_id = g_next_gpu_memory_buffer_id.GetNext(); 405 gfx::GpuMemoryBufferId new_id =
406 content::GetNextGenericSharedMemoryTracingId();
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 auto insert_result = buffers.insert(std::make_pair(
428 request->format, request->usage, 0); 431 new_id, BufferInfo(request->size, gfx::SHARED_MEMORY_BUFFER,
432 request->format, request->usage, 0)));
433 DCHECK(insert_result.second);
434
429 // Note: Unretained is safe as IO thread is stopped before manager is 435 // Note: Unretained is safe as IO thread is stopped before manager is
430 // destroyed. 436 // destroyed.
431 request->result = GpuMemoryBufferImplSharedMemory::Create( 437 request->result = GpuMemoryBufferImplSharedMemory::Create(
432 new_id, request->size, request->format, 438 new_id, request->size, request->format,
433 base::Bind( 439 base::Bind(
434 &GpuMemoryBufferDeleted, 440 &GpuMemoryBufferDeleted,
435 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), 441 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
436 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO, 442 base::Bind(&BrowserGpuMemoryBufferManager::DestroyGpuMemoryBufferOnIO,
437 base::Unretained(this), new_id, request->client_id))); 443 base::Unretained(this), new_id, request->client_id)));
438 request->event.Signal(); 444 request->event.Signal();
(...skipping 26 matching lines...) Expand all
465 gfx::GpuMemoryBufferId id, 471 gfx::GpuMemoryBufferId id,
466 const gfx::Size& size, 472 const gfx::Size& size,
467 gfx::BufferFormat format, 473 gfx::BufferFormat format,
468 gfx::BufferUsage usage, 474 gfx::BufferUsage usage,
469 int client_id, 475 int client_id,
470 int surface_id, 476 int surface_id,
471 bool reused_gpu_process, 477 bool reused_gpu_process,
472 const AllocationCallback& callback) { 478 const AllocationCallback& callback) {
473 DCHECK_CURRENTLY_ON(BrowserThread::IO); 479 DCHECK_CURRENTLY_ON(BrowserThread::IO);
474 480
475 BufferMap& buffers = clients_[client_id];
476 DCHECK(buffers.find(id) == buffers.end());
477
478 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); 481 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_);
479 if (!host) { 482 if (!host) {
480 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED, 483 host = GpuProcessHost::Get(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
481 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE); 484 CAUSE_FOR_GPU_LAUNCH_GPU_MEMORY_BUFFER_ALLOCATE);
482 if (!host) { 485 if (!host) {
483 LOG(ERROR) << "Failed to launch GPU process."; 486 LOG(ERROR) << "Failed to launch GPU process.";
484 callback.Run(gfx::GpuMemoryBufferHandle()); 487 callback.Run(gfx::GpuMemoryBufferHandle());
485 return; 488 return;
486 } 489 }
487 gpu_host_id_ = host->host_id(); 490 gpu_host_id_ = host->host_id();
488 reused_gpu_process = false; 491 reused_gpu_process = false;
489 } else { 492 } else {
490 if (reused_gpu_process) { 493 if (reused_gpu_process) {
491 // We come here if we retried to allocate the buffer because of a 494 // We come here if we retried to allocate the buffer because of a
492 // failure in GpuMemoryBufferAllocatedOnIO, but we ended up with the 495 // failure in GpuMemoryBufferAllocatedOnIO, but we ended up with the
493 // same process ID, meaning the failure was not because of a channel 496 // same process ID, meaning the failure was not because of a channel
494 // error, but another reason. So fail now. 497 // error, but another reason. So fail now.
495 LOG(ERROR) << "Failed to allocate GpuMemoryBuffer."; 498 LOG(ERROR) << "Failed to allocate GpuMemoryBuffer.";
496 callback.Run(gfx::GpuMemoryBufferHandle()); 499 callback.Run(gfx::GpuMemoryBufferHandle());
497 return; 500 return;
498 } 501 }
499 reused_gpu_process = true; 502 reused_gpu_process = true;
500 } 503 }
501 504
505 BufferMap& buffers = clients_[client_id];
506
502 // Note: Handling of cases where the client is removed before the allocation 507 // 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 508 // 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. 509 // and verify that this has not changed when allocation completes.
505 buffers[id] = BufferInfo(size, gfx::EMPTY_BUFFER, format, usage, 0); 510 auto insert_result = buffers.insert(std::make_pair(
511 id, BufferInfo(size, gfx::EMPTY_BUFFER, format, usage, 0)));
512 if (!insert_result.second) {
513 DLOG(ERROR) << "Child process attempted to allocate a GpuMemoryBuffer with "
reveman 2015/08/13 08:24:44 If using DLOG here then please switch to DLOG for
514 "an existing ID.";
515 callback.Run(gfx::GpuMemoryBufferHandle());
516 return;
517 }
506 518
507 // Note: Unretained is safe as IO thread is stopped before manager is 519 // Note: Unretained is safe as IO thread is stopped before manager is
508 // destroyed. 520 // destroyed.
509 host->CreateGpuMemoryBuffer( 521 host->CreateGpuMemoryBuffer(
510 id, size, format, usage, client_id, surface_id, 522 id, size, format, usage, client_id, surface_id,
511 base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO, 523 base::Bind(&BrowserGpuMemoryBufferManager::GpuMemoryBufferAllocatedOnIO,
512 base::Unretained(this), id, client_id, surface_id, 524 base::Unretained(this), id, client_id, surface_id,
513 gpu_host_id_, reused_gpu_process, callback)); 525 gpu_host_id_, reused_gpu_process, callback));
514 } 526 }
515 527
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 return gpu_client_tracing_id_; 627 return gpu_client_tracing_id_;
616 } 628 }
617 629
618 // In normal cases, |client_id| is a child process id, so we can perform 630 // In normal cases, |client_id| is a child process id, so we can perform
619 // the standard conversion. 631 // the standard conversion.
620 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId( 632 return ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
621 client_id); 633 client_id);
622 } 634 }
623 635
624 } // namespace content 636 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698