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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 event_.Wait(); | 181 event_.Wait(); |
182 } | 182 } |
183 FinishOnMain(); | 183 FinishOnMain(); |
184 } | 184 } |
185 | 185 |
186 void BrowserGpuChannelHostFactory::EstablishRequest::Cancel() { | 186 void BrowserGpuChannelHostFactory::EstablishRequest::Cancel() { |
187 DCHECK(main_loop_->BelongsToCurrentThread()); | 187 DCHECK(main_loop_->BelongsToCurrentThread()); |
188 finished_ = true; | 188 finished_ = true; |
189 } | 189 } |
190 | 190 |
| 191 class BrowserGpuChannelHostFactory::CreateGpuMemoryBufferRequest |
| 192 : public base::RefCountedThreadSafe<CreateGpuMemoryBufferRequest> { |
| 193 public: |
| 194 enum RequestType { |
| 195 SYNC, |
| 196 CALLBACK, |
| 197 }; |
| 198 static scoped_refptr<CreateGpuMemoryBufferRequest> CreateSync(); |
| 199 static scoped_refptr<CreateGpuMemoryBufferRequest> CreateForCallback( |
| 200 uint32 request_id); |
| 201 |
| 202 void Wait(); |
| 203 void Signal(); |
| 204 |
| 205 void set_result(const gfx::GpuMemoryBufferHandle& handle) { |
| 206 handle_ = handle; |
| 207 } |
| 208 gfx::GpuMemoryBufferHandle result() { return handle_; } |
| 209 uint32 request_id() { return request_id_; } |
| 210 RequestType request_type() { return request_type_; } |
| 211 |
| 212 private: |
| 213 friend class base::RefCountedThreadSafe<CreateGpuMemoryBufferRequest>; |
| 214 CreateGpuMemoryBufferRequest(scoped_ptr<base::WaitableEvent> event, |
| 215 uint32 request_id, |
| 216 RequestType request_type); |
| 217 ~CreateGpuMemoryBufferRequest() {} |
| 218 |
| 219 scoped_ptr<base::WaitableEvent> event_; |
| 220 gfx::GpuMemoryBufferHandle handle_; |
| 221 uint32 request_id_; |
| 222 RequestType request_type_; |
| 223 }; |
| 224 |
| 225 scoped_refptr<BrowserGpuChannelHostFactory::CreateGpuMemoryBufferRequest> |
| 226 BrowserGpuChannelHostFactory::CreateGpuMemoryBufferRequest::CreateSync() { |
| 227 scoped_ptr<base::WaitableEvent> event(new base::WaitableEvent(true, false)); |
| 228 scoped_refptr<CreateGpuMemoryBufferRequest> request = |
| 229 new CreateGpuMemoryBufferRequest(event.Pass(), 0, SYNC); |
| 230 return request; |
| 231 } |
| 232 |
| 233 scoped_refptr<BrowserGpuChannelHostFactory::CreateGpuMemoryBufferRequest> |
| 234 BrowserGpuChannelHostFactory::CreateGpuMemoryBufferRequest::CreateForCallback( |
| 235 uint32 request_id) { |
| 236 scoped_refptr<CreateGpuMemoryBufferRequest> request = |
| 237 new CreateGpuMemoryBufferRequest( |
| 238 scoped_ptr<base::WaitableEvent>(), request_id, CALLBACK); |
| 239 return request; |
| 240 } |
| 241 |
| 242 BrowserGpuChannelHostFactory::CreateGpuMemoryBufferRequest:: |
| 243 CreateGpuMemoryBufferRequest(scoped_ptr<base::WaitableEvent> event, |
| 244 uint32 request_id, |
| 245 RequestType request_type) |
| 246 : event_(event.Pass()), |
| 247 request_id_(request_id), |
| 248 request_type_(request_type) { |
| 249 } |
| 250 |
| 251 void BrowserGpuChannelHostFactory::CreateGpuMemoryBufferRequest::Wait() { |
| 252 DCHECK(event_.get()); |
| 253 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
| 254 event_->Wait(); |
| 255 } |
| 256 |
| 257 void BrowserGpuChannelHostFactory::CreateGpuMemoryBufferRequest::Signal() { |
| 258 DCHECK(event_.get()); |
| 259 event_->Signal(); |
| 260 } |
| 261 |
191 bool BrowserGpuChannelHostFactory::CanUseForTesting() { | 262 bool BrowserGpuChannelHostFactory::CanUseForTesting() { |
192 return GpuDataManager::GetInstance()->GpuAccessAllowed(NULL); | 263 return GpuDataManager::GetInstance()->GpuAccessAllowed(NULL); |
193 } | 264 } |
194 | 265 |
195 void BrowserGpuChannelHostFactory::Initialize(bool establish_gpu_channel) { | 266 void BrowserGpuChannelHostFactory::Initialize(bool establish_gpu_channel) { |
196 DCHECK(!instance_); | 267 DCHECK(!instance_); |
197 instance_ = new BrowserGpuChannelHostFactory(); | 268 instance_ = new BrowserGpuChannelHostFactory(); |
198 if (establish_gpu_channel) { | 269 if (establish_gpu_channel) { |
199 instance_->EstablishGpuChannel(CAUSE_FOR_GPU_LAUNCH_BROWSER_STARTUP, | 270 instance_->EstablishGpuChannel(CAUSE_FOR_GPU_LAUNCH_BROWSER_STARTUP, |
200 base::Closure()); | 271 base::Closure()); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 gpu_host_id_, | 476 gpu_host_id_, |
406 filter)); | 477 filter)); |
407 } | 478 } |
408 | 479 |
409 void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( | 480 void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( |
410 const gfx::GpuMemoryBufferHandle& handle, | 481 const gfx::GpuMemoryBufferHandle& handle, |
411 const gfx::Size& size, | 482 const gfx::Size& size, |
412 unsigned internalformat, | 483 unsigned internalformat, |
413 unsigned usage, | 484 unsigned usage, |
414 const CreateGpuMemoryBufferCallback& callback) { | 485 const CreateGpuMemoryBufferCallback& callback) { |
| 486 TRACE_EVENT2("gpu", |
| 487 "BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer", |
| 488 "primary_id", |
| 489 handle.global_id.primary_id, |
| 490 "secondary_id", |
| 491 handle.global_id.secondary_id); |
415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 492 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
416 uint32 request_id = next_create_gpu_memory_buffer_request_id_++; | 493 uint32 request_id = next_create_gpu_memory_buffer_request_id_++; |
417 create_gpu_memory_buffer_requests_[request_id] = callback; | 494 create_gpu_memory_buffer_requests_[request_id] = callback; |
418 GetIOLoopProxy()->PostTask( | 495 GetIOLoopProxy()->PostTask( |
419 FROM_HERE, | 496 FROM_HERE, |
420 base::Bind(&BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO, | 497 base::Bind(&BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO, |
421 base::Unretained(this), | 498 base::Unretained(this), |
422 handle, | 499 handle, |
423 size, | 500 size, |
424 internalformat, | 501 internalformat, |
425 usage, | 502 usage, |
426 request_id)); | 503 CreateGpuMemoryBufferRequest::CreateForCallback(request_id))); |
| 504 } |
| 505 |
| 506 gfx::GpuMemoryBufferHandle |
| 507 BrowserGpuChannelHostFactory::CreateGpuMemoryBufferSync( |
| 508 const gfx::GpuMemoryBufferHandle& handle, |
| 509 const gfx::Size& size, |
| 510 unsigned internalformat, |
| 511 unsigned usage) { |
| 512 TRACE_EVENT2("gpu", |
| 513 "BrowserGpuChannelHostFactory::CreateGpuMemoryBufferSync", |
| 514 "primary_id", |
| 515 handle.global_id.primary_id, |
| 516 "secondary_id", |
| 517 handle.global_id.secondary_id); |
| 518 scoped_refptr<CreateGpuMemoryBufferRequest> request = |
| 519 CreateGpuMemoryBufferRequest::CreateSync(); |
| 520 GetIOLoopProxy()->PostTask( |
| 521 FROM_HERE, |
| 522 base::Bind(&BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO, |
| 523 base::Unretained(this), |
| 524 handle, |
| 525 size, |
| 526 internalformat, |
| 527 usage, |
| 528 request)); |
| 529 |
| 530 request->Wait(); |
| 531 |
| 532 return request->result(); |
427 } | 533 } |
428 | 534 |
429 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer( | 535 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer( |
430 const gfx::GpuMemoryBufferHandle& handle, | 536 const gfx::GpuMemoryBufferHandle& handle, |
431 int32 sync_point) { | 537 int32 sync_point) { |
432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
433 GetIOLoopProxy()->PostTask( | 539 GetIOLoopProxy()->PostTask( |
434 FROM_HERE, | 540 FROM_HERE, |
435 base::Bind(&BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO, | 541 base::Bind(&BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO, |
436 base::Unretained(this), | 542 base::Unretained(this), |
437 handle, | 543 handle, |
438 sync_point)); | 544 sync_point)); |
439 } | 545 } |
440 | 546 |
441 void BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO( | 547 void BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO( |
442 const gfx::GpuMemoryBufferHandle& handle, | 548 const gfx::GpuMemoryBufferHandle& handle, |
443 const gfx::Size& size, | 549 const gfx::Size& size, |
444 unsigned internalformat, | 550 unsigned internalformat, |
445 unsigned usage, | 551 unsigned usage, |
446 uint32 request_id) { | 552 scoped_refptr<CreateGpuMemoryBufferRequest> request) { |
| 553 TRACE_EVENT2("gpu", |
| 554 "BrowserGpuChannelHostFactory::CreateGpuMemoryBufferOnIO", |
| 555 "primary_id", |
| 556 handle.global_id.primary_id, |
| 557 "secondary_id", |
| 558 handle.global_id.secondary_id); |
447 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | 559 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); |
448 if (!host) { | 560 if (!host) { |
449 GpuMemoryBufferCreatedOnIO(request_id, gfx::GpuMemoryBufferHandle()); | 561 GpuMemoryBufferCreatedOnIO(request, gfx::GpuMemoryBufferHandle()); |
450 return; | 562 return; |
451 } | 563 } |
452 | 564 |
453 host->CreateGpuMemoryBuffer( | 565 host->CreateGpuMemoryBuffer( |
454 handle, | 566 handle, |
455 size, | 567 size, |
456 internalformat, | 568 internalformat, |
457 usage, | 569 usage, |
458 base::Bind(&BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO, | 570 base::Bind(&BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO, |
459 base::Unretained(this), | 571 base::Unretained(this), |
460 request_id)); | 572 request)); |
461 } | 573 } |
462 | 574 |
463 void BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO( | 575 void BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO( |
464 uint32 request_id, | 576 scoped_refptr<CreateGpuMemoryBufferRequest> request, |
465 const gfx::GpuMemoryBufferHandle& handle) { | 577 const gfx::GpuMemoryBufferHandle& handle) { |
466 BrowserThread::PostTask( | 578 TRACE_EVENT2("gpu", |
467 BrowserThread::UI, | 579 "BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO", |
468 FROM_HERE, | 580 "primary_id", |
469 base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated, | 581 handle.global_id.primary_id, |
470 base::Unretained(this), | 582 "secondary_id", |
471 request_id, | 583 handle.global_id.secondary_id); |
472 handle)); | 584 switch (request->request_type()) { |
| 585 case CreateGpuMemoryBufferRequest::SYNC: { |
| 586 request->set_result(handle); |
| 587 request->Signal(); |
| 588 return; |
| 589 } |
| 590 case CreateGpuMemoryBufferRequest::CALLBACK: { |
| 591 BrowserThread::PostTask( |
| 592 BrowserThread::UI, |
| 593 FROM_HERE, |
| 594 base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated, |
| 595 base::Unretained(this), |
| 596 request->request_id(), |
| 597 handle)); |
| 598 return; |
| 599 } |
| 600 } |
| 601 NOTREACHED(); |
473 } | 602 } |
474 | 603 |
475 void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated( | 604 void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated( |
476 uint32 request_id, | 605 uint32 request_id, |
477 const gfx::GpuMemoryBufferHandle& handle) { | 606 const gfx::GpuMemoryBufferHandle& handle) { |
478 CreateGpuMemoryBufferCallbackMap::iterator iter = | 607 CreateGpuMemoryBufferCallbackMap::iterator iter = |
479 create_gpu_memory_buffer_requests_.find(request_id); | 608 create_gpu_memory_buffer_requests_.find(request_id); |
480 DCHECK(iter != create_gpu_memory_buffer_requests_.end()); | 609 DCHECK(iter != create_gpu_memory_buffer_requests_.end()); |
481 iter->second.Run(handle); | 610 iter->second.Run(handle); |
482 create_gpu_memory_buffer_requests_.erase(iter); | 611 create_gpu_memory_buffer_requests_.erase(iter); |
483 } | 612 } |
484 | 613 |
485 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO( | 614 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBufferOnIO( |
486 const gfx::GpuMemoryBufferHandle& handle, | 615 const gfx::GpuMemoryBufferHandle& handle, |
487 int32 sync_point) { | 616 int32 sync_point) { |
488 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); | 617 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); |
489 if (!host) | 618 if (!host) |
490 return; | 619 return; |
491 | 620 |
492 host->DestroyGpuMemoryBuffer(handle, sync_point); | 621 host->DestroyGpuMemoryBuffer(handle, sync_point); |
493 } | 622 } |
494 | 623 |
495 } // namespace content | 624 } // namespace content |
OLD | NEW |