Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/synchronization/waitable_event.h" | 9 #include "base/synchronization/waitable_event.h" |
| 10 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 CreateRequest() | 29 CreateRequest() |
| 30 : event(true, false), gpu_host_id(0), route_id(MSG_ROUTING_NONE), | 30 : event(true, false), gpu_host_id(0), route_id(MSG_ROUTING_NONE), |
| 31 result(CREATE_COMMAND_BUFFER_FAILED) {} | 31 result(CREATE_COMMAND_BUFFER_FAILED) {} |
| 32 ~CreateRequest() {} | 32 ~CreateRequest() {} |
| 33 base::WaitableEvent event; | 33 base::WaitableEvent event; |
| 34 int gpu_host_id; | 34 int gpu_host_id; |
| 35 int32 route_id; | 35 int32 route_id; |
| 36 CreateCommandBufferResult result; | 36 CreateCommandBufferResult result; |
| 37 }; | 37 }; |
| 38 | 38 |
| 39 struct BrowserGpuChannelHostFactory::AllocateGpuMemoryBufferRequest { | |
| 40 AllocateGpuMemoryBufferRequest() | |
| 41 : event(true, false), width(0), height(0), internalformat(0), usage(0) {} | |
|
piman
2014/09/05 22:30:37
nit: might as well providing instead a constructor
reveman
2014/09/05 23:58:43
Did it this way to be consistent with CreateReques
| |
| 42 ~AllocateGpuMemoryBufferRequest() {} | |
| 43 base::WaitableEvent event; | |
| 44 size_t width; | |
| 45 size_t height; | |
| 46 unsigned internalformat; | |
| 47 unsigned usage; | |
| 48 scoped_ptr<gfx::GpuMemoryBuffer> result; | |
| 49 }; | |
| 50 | |
| 39 class BrowserGpuChannelHostFactory::EstablishRequest | 51 class BrowserGpuChannelHostFactory::EstablishRequest |
| 40 : public base::RefCountedThreadSafe<EstablishRequest> { | 52 : public base::RefCountedThreadSafe<EstablishRequest> { |
| 41 public: | 53 public: |
| 42 static scoped_refptr<EstablishRequest> Create(CauseForGpuLaunch cause, | 54 static scoped_refptr<EstablishRequest> Create(CauseForGpuLaunch cause, |
| 43 int gpu_client_id, | 55 int gpu_client_id, |
| 44 int gpu_host_id); | 56 int gpu_host_id); |
| 45 void Wait(); | 57 void Wait(); |
| 46 void Cancel(); | 58 void Cancel(); |
| 47 | 59 |
| 48 int gpu_host_id() { return gpu_host_id_; } | 60 int gpu_host_id() { return gpu_host_id_; } |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 established_callbacks_[n].Run(); | 368 established_callbacks_[n].Run(); |
| 357 | 369 |
| 358 established_callbacks_.clear(); | 370 established_callbacks_.clear(); |
| 359 } | 371 } |
| 360 | 372 |
| 361 scoped_ptr<gfx::GpuMemoryBuffer> | 373 scoped_ptr<gfx::GpuMemoryBuffer> |
| 362 BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer(size_t width, | 374 BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer(size_t width, |
| 363 size_t height, | 375 size_t height, |
| 364 unsigned internalformat, | 376 unsigned internalformat, |
| 365 unsigned usage) { | 377 unsigned usage) { |
| 366 if (!GpuMemoryBufferImpl::IsFormatValid(internalformat) || | 378 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
|
piman
2014/09/05 22:30:37
Couldn't this be called on the compositor thread?
reveman
2014/09/05 23:58:43
I didn't think of that. Changed DCHECKs as suggest
| |
| 367 !GpuMemoryBufferImpl::IsUsageValid(usage)) | |
| 368 return scoped_ptr<gfx::GpuMemoryBuffer>(); | |
| 369 | 379 |
| 370 return GpuMemoryBufferImpl::Create(gfx::Size(width, height), | 380 AllocateGpuMemoryBufferRequest request; |
| 371 internalformat, | 381 request.width = width; |
| 372 usage).PassAs<gfx::GpuMemoryBuffer>(); | 382 request.height = height; |
| 383 request.internalformat = internalformat; | |
| 384 request.usage = usage; | |
| 385 | |
| 386 GetIOLoopProxy()->PostTask( | |
| 387 FROM_HERE, | |
| 388 base::Bind(&BrowserGpuChannelHostFactory::AllocateGpuMemoryBufferOnIO, | |
| 389 base::Unretained(&request))); | |
| 390 | |
| 391 // We're blocking the UI thread, which is generally undesirable. | |
| 392 TRACE_EVENT0("browser", | |
| 393 "BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer"); | |
| 394 base::ThreadRestrictions::ScopedAllowWait allow_wait; | |
| 395 request.event.Wait(); | |
| 396 return request.result.Pass(); | |
| 397 } | |
| 398 | |
| 399 void BrowserGpuChannelHostFactory::DeleteGpuMemoryBuffer( | |
| 400 scoped_ptr<gfx::GpuMemoryBuffer> buffer) { | |
| 401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 402 | |
| 403 GetIOLoopProxy()->PostTask( | |
| 404 FROM_HERE, | |
| 405 base::Bind(&BrowserGpuChannelHostFactory::DeleteGpuMemoryBufferOnIO, | |
| 406 base::Passed(&buffer))); | |
| 407 } | |
| 408 | |
| 409 void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( | |
| 410 const gfx::GpuMemoryBufferHandle& handle, | |
| 411 const gfx::Size& size, | |
| 412 unsigned internalformat, | |
| 413 unsigned usage, | |
| 414 const CreateGpuMemoryBufferCallback& callback) { | |
| 415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 416 | |
| 417 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | |
| 418 if (!host) { | |
| 419 callback.Run(gfx::GpuMemoryBufferHandle()); | |
| 420 return; | |
| 421 } | |
| 422 | |
| 423 uint32 request_id = next_create_gpu_memory_buffer_request_id_++; | |
| 424 create_gpu_memory_buffer_requests_[request_id] = callback; | |
| 425 | |
| 426 host->CreateGpuMemoryBuffer( | |
| 427 handle, | |
| 428 size, | |
| 429 internalformat, | |
| 430 usage, | |
| 431 base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated, | |
| 432 base::Unretained(this), | |
| 433 request_id)); | |
| 434 } | |
| 435 | |
| 436 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer( | |
| 437 const gfx::GpuMemoryBufferHandle& handle, | |
| 438 int32 sync_point) { | |
| 439 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 440 | |
| 441 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | |
| 442 if (!host) | |
| 443 return; | |
| 444 | |
| 445 host->DestroyGpuMemoryBuffer(handle, sync_point); | |
| 373 } | 446 } |
| 374 | 447 |
| 375 // static | 448 // static |
| 376 void BrowserGpuChannelHostFactory::AddFilterOnIO( | 449 void BrowserGpuChannelHostFactory::AddFilterOnIO( |
| 377 int host_id, | 450 int host_id, |
| 378 scoped_refptr<IPC::MessageFilter> filter) { | 451 scoped_refptr<IPC::MessageFilter> filter) { |
| 379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 452 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 380 | 453 |
| 381 GpuProcessHost* host = GpuProcessHost::FromID(host_id); | 454 GpuProcessHost* host = GpuProcessHost::FromID(host_id); |
| 382 if (host) | 455 if (host) |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 399 target_task_runner); | 472 target_task_runner); |
| 400 filter->AddRoute(MSG_ROUTING_CONTROL, handler); | 473 filter->AddRoute(MSG_ROUTING_CONTROL, handler); |
| 401 | 474 |
| 402 GetIOLoopProxy()->PostTask( | 475 GetIOLoopProxy()->PostTask( |
| 403 FROM_HERE, | 476 FROM_HERE, |
| 404 base::Bind(&BrowserGpuChannelHostFactory::AddFilterOnIO, | 477 base::Bind(&BrowserGpuChannelHostFactory::AddFilterOnIO, |
| 405 gpu_host_id_, | 478 gpu_host_id_, |
| 406 filter)); | 479 filter)); |
| 407 } | 480 } |
| 408 | 481 |
| 409 void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( | 482 // static |
| 410 const gfx::GpuMemoryBufferHandle& handle, | 483 void BrowserGpuChannelHostFactory::AllocateGpuMemoryBufferOnIO( |
| 411 const gfx::Size& size, | 484 AllocateGpuMemoryBufferRequest* request) { |
| 412 unsigned internalformat, | 485 if (!GpuMemoryBufferImpl::IsFormatValid(request->internalformat) || |
| 413 unsigned usage, | 486 !GpuMemoryBufferImpl::IsUsageValid(request->usage)) { |
| 414 const CreateGpuMemoryBufferCallback& callback) { | 487 request->result = scoped_ptr<gfx::GpuMemoryBuffer>(); |
| 415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 488 request->event.Signal(); |
|
piman
2014/09/05 22:30:37
To confirm, if the GPU process dies while a reques
reveman
2014/09/05 23:58:43
No, unless I misunderstood your question. This cod
piman
2014/09/06 00:28:23
Then I'm confused... Shouldn't we signal the event
reveman
2014/09/06 20:30:49
If the format or usage is an invalid value that ca
piman
2014/09/08 18:33:57
ACK about early reject, but what about the general
reveman
2014/09/08 19:58:57
So this patch doesn't actually make it possible to
| |
| 416 uint32 request_id = next_create_gpu_memory_buffer_request_id_++; | |
| 417 create_gpu_memory_buffer_requests_[request_id] = callback; | |
| 418 GetIOLoopProxy()->PostTask( | |
| 419 FROM_HERE, | |
| 420 base::Bind(&BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO, | |
| 421 base::Unretained(this), | |
| 422 handle, | |
| 423 size, | |
| 424 internalformat, | |
| 425 usage, | |
| 426 request_id)); | |
| 427 } | |
| 428 | |
| 429 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer( | |
| 430 const gfx::GpuMemoryBufferHandle& handle, | |
| 431 int32 sync_point) { | |
| 432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 433 GetIOLoopProxy()->PostTask( | |
| 434 FROM_HERE, | |
| 435 base::Bind(&BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO, | |
| 436 base::Unretained(this), | |
| 437 handle, | |
| 438 sync_point)); | |
| 439 } | |
| 440 | |
| 441 void BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO( | |
| 442 const gfx::GpuMemoryBufferHandle& handle, | |
| 443 const gfx::Size& size, | |
| 444 unsigned internalformat, | |
| 445 unsigned usage, | |
| 446 uint32 request_id) { | |
| 447 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | |
| 448 if (!host) { | |
| 449 GpuMemoryBufferCreatedOnIO(request_id, gfx::GpuMemoryBufferHandle()); | |
| 450 return; | 489 return; |
| 451 } | 490 } |
| 452 | 491 |
| 453 host->CreateGpuMemoryBuffer( | 492 request->result = GpuMemoryBufferImpl::Create( |
| 454 handle, | 493 gfx::Size(request->width, request->height), |
|
piman
2014/09/05 22:30:37
nit: indent looks weird
reveman
2014/09/05 23:58:43
I agree but this seems to be the way cl format lik
| |
| 455 size, | 494 request->internalformat, |
| 456 internalformat, | 495 request->usage).PassAs<gfx::GpuMemoryBuffer>(); |
| 457 usage, | 496 request->event.Signal(); |
| 458 base::Bind(&BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO, | |
| 459 base::Unretained(this), | |
| 460 request_id)); | |
| 461 } | 497 } |
| 462 | 498 |
| 463 void BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO( | 499 // static |
| 464 uint32 request_id, | 500 void BrowserGpuChannelHostFactory::DeleteGpuMemoryBufferOnIO( |
| 465 const gfx::GpuMemoryBufferHandle& handle) { | 501 scoped_ptr<gfx::GpuMemoryBuffer> buffer) { |
| 466 BrowserThread::PostTask( | |
| 467 BrowserThread::UI, | |
| 468 FROM_HERE, | |
| 469 base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated, | |
| 470 base::Unretained(this), | |
| 471 request_id, | |
| 472 handle)); | |
| 473 } | 502 } |
| 474 | 503 |
| 475 void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated( | 504 void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated( |
| 476 uint32 request_id, | 505 uint32 request_id, |
| 477 const gfx::GpuMemoryBufferHandle& handle) { | 506 const gfx::GpuMemoryBufferHandle& handle) { |
| 507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 508 | |
| 478 CreateGpuMemoryBufferCallbackMap::iterator iter = | 509 CreateGpuMemoryBufferCallbackMap::iterator iter = |
| 479 create_gpu_memory_buffer_requests_.find(request_id); | 510 create_gpu_memory_buffer_requests_.find(request_id); |
| 480 DCHECK(iter != create_gpu_memory_buffer_requests_.end()); | 511 DCHECK(iter != create_gpu_memory_buffer_requests_.end()); |
| 481 iter->second.Run(handle); | 512 iter->second.Run(handle); |
| 482 create_gpu_memory_buffer_requests_.erase(iter); | 513 create_gpu_memory_buffer_requests_.erase(iter); |
| 483 } | 514 } |
| 484 | 515 |
| 485 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO( | |
| 486 const gfx::GpuMemoryBufferHandle& handle, | |
| 487 int32 sync_point) { | |
| 488 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | |
| 489 if (!host) | |
| 490 return; | |
| 491 | |
| 492 host->DestroyGpuMemoryBuffer(handle, sync_point); | |
| 493 } | |
| 494 | |
| 495 } // namespace content | 516 } // namespace content |
| OLD | NEW |