| 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" |
| 11 #include "content/browser/gpu/gpu_data_manager_impl.h" | 11 #include "content/browser/gpu/gpu_data_manager_impl.h" |
| 12 #include "content/browser/gpu/gpu_process_host.h" | 12 #include "content/browser/gpu/gpu_process_host.h" |
| 13 #include "content/browser/gpu/gpu_surface_tracker.h" | 13 #include "content/browser/gpu/gpu_surface_tracker.h" |
| 14 #include "content/common/child_process_host_impl.h" | 14 #include "content/common/child_process_host_impl.h" |
| 15 #include "content/common/gpu/client/gpu_memory_buffer_impl.h" | 15 #include "content/common/gpu/client/gpu_memory_buffer_impl.h" |
| 16 #include "content/common/gpu/gpu_messages.h" | 16 #include "content/common/gpu/gpu_messages.h" |
| 17 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
| 18 #include "content/public/browser/gpu_data_manager.h" | 18 #include "content/public/browser/gpu_data_manager.h" |
| 19 #include "content/public/common/content_client.h" | 19 #include "content/public/common/content_client.h" |
| 20 #include "ipc/ipc_channel_handle.h" | 20 #include "ipc/ipc_channel_handle.h" |
| 21 #include "ipc/ipc_forwarding_message_filter.h" | 21 #include "ipc/ipc_forwarding_message_filter.h" |
| 22 #include "ipc/message_filter.h" | 22 #include "ipc/message_filter.h" |
| 23 | 23 |
| 24 namespace content { | 24 namespace content { |
| 25 | 25 |
| 26 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; | 26 BrowserGpuChannelHostFactory* BrowserGpuChannelHostFactory::instance_ = NULL; |
| 27 | 27 |
| 28 struct BrowserGpuChannelHostFactory::CreateRequest { | 28 struct BrowserGpuChannelHostFactory::CreateRequest { |
| 29 CreateRequest() | 29 CreateRequest(int32 route_id) |
| 30 : event(true, false), gpu_host_id(0), route_id(MSG_ROUTING_NONE), | 30 : event(true, false), |
| 31 gpu_host_id(0), |
| 32 route_id(route_id), |
| 31 result(CREATE_COMMAND_BUFFER_FAILED) {} | 33 result(CREATE_COMMAND_BUFFER_FAILED) {} |
| 32 ~CreateRequest() {} | 34 ~CreateRequest() {} |
| 33 base::WaitableEvent event; | 35 base::WaitableEvent event; |
| 34 int gpu_host_id; | 36 int gpu_host_id; |
| 35 int32 route_id; | 37 int32 route_id; |
| 36 CreateCommandBufferResult result; | 38 CreateCommandBufferResult result; |
| 37 }; | 39 }; |
| 38 | 40 |
| 41 struct BrowserGpuChannelHostFactory::AllocateGpuMemoryBufferRequest { |
| 42 AllocateGpuMemoryBufferRequest(size_t width, |
| 43 size_t height, |
| 44 unsigned internalformat, |
| 45 unsigned usage) |
| 46 : event(true, false), |
| 47 width(width), |
| 48 height(height), |
| 49 internalformat(internalformat), |
| 50 usage(usage) {} |
| 51 ~AllocateGpuMemoryBufferRequest() {} |
| 52 base::WaitableEvent event; |
| 53 size_t width; |
| 54 size_t height; |
| 55 unsigned internalformat; |
| 56 unsigned usage; |
| 57 scoped_ptr<gfx::GpuMemoryBuffer> result; |
| 58 }; |
| 59 |
| 39 class BrowserGpuChannelHostFactory::EstablishRequest | 60 class BrowserGpuChannelHostFactory::EstablishRequest |
| 40 : public base::RefCountedThreadSafe<EstablishRequest> { | 61 : public base::RefCountedThreadSafe<EstablishRequest> { |
| 41 public: | 62 public: |
| 42 static scoped_refptr<EstablishRequest> Create(CauseForGpuLaunch cause, | 63 static scoped_refptr<EstablishRequest> Create(CauseForGpuLaunch cause, |
| 43 int gpu_client_id, | 64 int gpu_client_id, |
| 44 int gpu_host_id); | 65 int gpu_host_id); |
| 45 void Wait(); | 66 void Wait(); |
| 46 void Cancel(); | 67 void Cancel(); |
| 47 | 68 |
| 48 int gpu_host_id() { return gpu_host_id_; } | 69 int gpu_host_id() { return gpu_host_id_; } |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 void BrowserGpuChannelHostFactory::CommandBufferCreatedOnIO( | 292 void BrowserGpuChannelHostFactory::CommandBufferCreatedOnIO( |
| 272 CreateRequest* request, CreateCommandBufferResult result) { | 293 CreateRequest* request, CreateCommandBufferResult result) { |
| 273 request->result = result; | 294 request->result = result; |
| 274 request->event.Signal(); | 295 request->event.Signal(); |
| 275 } | 296 } |
| 276 | 297 |
| 277 CreateCommandBufferResult BrowserGpuChannelHostFactory::CreateViewCommandBuffer( | 298 CreateCommandBufferResult BrowserGpuChannelHostFactory::CreateViewCommandBuffer( |
| 278 int32 surface_id, | 299 int32 surface_id, |
| 279 const GPUCreateCommandBufferConfig& init_params, | 300 const GPUCreateCommandBufferConfig& init_params, |
| 280 int32 route_id) { | 301 int32 route_id) { |
| 281 CreateRequest request; | 302 CreateRequest request(route_id); |
| 282 request.route_id = route_id; | |
| 283 GetIOLoopProxy()->PostTask(FROM_HERE, base::Bind( | 303 GetIOLoopProxy()->PostTask(FROM_HERE, base::Bind( |
| 284 &BrowserGpuChannelHostFactory::CreateViewCommandBufferOnIO, | 304 &BrowserGpuChannelHostFactory::CreateViewCommandBufferOnIO, |
| 285 base::Unretained(this), | 305 base::Unretained(this), |
| 286 &request, | 306 &request, |
| 287 surface_id, | 307 surface_id, |
| 288 init_params)); | 308 init_params)); |
| 289 // We're blocking the UI thread, which is generally undesirable. | 309 // We're blocking the UI thread, which is generally undesirable. |
| 290 // In this case we need to wait for this before we can show any UI /anyway/, | 310 // In this case we need to wait for this before we can show any UI /anyway/, |
| 291 // so it won't cause additional jank. | 311 // so it won't cause additional jank. |
| 292 // TODO(piman): Make this asynchronous (http://crbug.com/125248). | 312 // TODO(piman): Make this asynchronous (http://crbug.com/125248). |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 established_callbacks_[n].Run(); | 376 established_callbacks_[n].Run(); |
| 357 | 377 |
| 358 established_callbacks_.clear(); | 378 established_callbacks_.clear(); |
| 359 } | 379 } |
| 360 | 380 |
| 361 scoped_ptr<gfx::GpuMemoryBuffer> | 381 scoped_ptr<gfx::GpuMemoryBuffer> |
| 362 BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer(size_t width, | 382 BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer(size_t width, |
| 363 size_t height, | 383 size_t height, |
| 364 unsigned internalformat, | 384 unsigned internalformat, |
| 365 unsigned usage) { | 385 unsigned usage) { |
| 366 if (!GpuMemoryBufferImpl::IsFormatValid(internalformat) || | 386 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 367 !GpuMemoryBufferImpl::IsUsageValid(usage)) | |
| 368 return scoped_ptr<gfx::GpuMemoryBuffer>(); | |
| 369 | 387 |
| 370 return GpuMemoryBufferImpl::Create(gfx::Size(width, height), | 388 AllocateGpuMemoryBufferRequest request(width, height, internalformat, usage); |
| 371 internalformat, | 389 GetIOLoopProxy()->PostTask( |
| 372 usage).PassAs<gfx::GpuMemoryBuffer>(); | 390 FROM_HERE, |
| 391 base::Bind(&BrowserGpuChannelHostFactory::AllocateGpuMemoryBufferOnIO, |
| 392 base::Unretained(&request))); |
| 393 |
| 394 // We're blocking the UI thread, which is generally undesirable. |
| 395 TRACE_EVENT0("browser", |
| 396 "BrowserGpuChannelHostFactory::AllocateGpuMemoryBuffer"); |
| 397 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
| 398 request.event.Wait(); |
| 399 return request.result.Pass(); |
| 400 } |
| 401 |
| 402 void BrowserGpuChannelHostFactory::DeleteGpuMemoryBuffer( |
| 403 scoped_ptr<gfx::GpuMemoryBuffer> buffer) { |
| 404 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 405 |
| 406 GetIOLoopProxy()->PostTask( |
| 407 FROM_HERE, |
| 408 base::Bind(&BrowserGpuChannelHostFactory::DeleteGpuMemoryBufferOnIO, |
| 409 base::Passed(&buffer))); |
| 410 } |
| 411 |
| 412 void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( |
| 413 const gfx::GpuMemoryBufferHandle& handle, |
| 414 const gfx::Size& size, |
| 415 unsigned internalformat, |
| 416 unsigned usage, |
| 417 const CreateGpuMemoryBufferCallback& callback) { |
| 418 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 419 |
| 420 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); |
| 421 if (!host) { |
| 422 callback.Run(gfx::GpuMemoryBufferHandle()); |
| 423 return; |
| 424 } |
| 425 |
| 426 uint32 request_id = next_create_gpu_memory_buffer_request_id_++; |
| 427 create_gpu_memory_buffer_requests_[request_id] = callback; |
| 428 |
| 429 host->CreateGpuMemoryBuffer( |
| 430 handle, |
| 431 size, |
| 432 internalformat, |
| 433 usage, |
| 434 base::Bind(&BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated, |
| 435 base::Unretained(this), |
| 436 request_id)); |
| 437 } |
| 438 |
| 439 void BrowserGpuChannelHostFactory::DestroyGpuMemoryBuffer( |
| 440 const gfx::GpuMemoryBufferHandle& handle, |
| 441 int32 sync_point) { |
| 442 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 443 |
| 444 GpuProcessHost* host = GpuProcessHost::FromID(gpu_host_id_); |
| 445 if (!host) |
| 446 return; |
| 447 |
| 448 host->DestroyGpuMemoryBuffer(handle, sync_point); |
| 373 } | 449 } |
| 374 | 450 |
| 375 // static | 451 // static |
| 376 void BrowserGpuChannelHostFactory::AddFilterOnIO( | 452 void BrowserGpuChannelHostFactory::AddFilterOnIO( |
| 377 int host_id, | 453 int host_id, |
| 378 scoped_refptr<IPC::MessageFilter> filter) { | 454 scoped_refptr<IPC::MessageFilter> filter) { |
| 379 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 455 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 380 | 456 |
| 381 GpuProcessHost* host = GpuProcessHost::FromID(host_id); | 457 GpuProcessHost* host = GpuProcessHost::FromID(host_id); |
| 382 if (host) | 458 if (host) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 399 target_task_runner); | 475 target_task_runner); |
| 400 filter->AddRoute(MSG_ROUTING_CONTROL, handler); | 476 filter->AddRoute(MSG_ROUTING_CONTROL, handler); |
| 401 | 477 |
| 402 GetIOLoopProxy()->PostTask( | 478 GetIOLoopProxy()->PostTask( |
| 403 FROM_HERE, | 479 FROM_HERE, |
| 404 base::Bind(&BrowserGpuChannelHostFactory::AddFilterOnIO, | 480 base::Bind(&BrowserGpuChannelHostFactory::AddFilterOnIO, |
| 405 gpu_host_id_, | 481 gpu_host_id_, |
| 406 filter)); | 482 filter)); |
| 407 } | 483 } |
| 408 | 484 |
| 409 void BrowserGpuChannelHostFactory::CreateGpuMemoryBuffer( | 485 // static |
| 410 const gfx::GpuMemoryBufferHandle& handle, | 486 void BrowserGpuChannelHostFactory::AllocateGpuMemoryBufferOnIO( |
| 411 const gfx::Size& size, | 487 AllocateGpuMemoryBufferRequest* request) { |
| 412 unsigned internalformat, | 488 if (!GpuMemoryBufferImpl::IsFormatValid(request->internalformat) || |
| 413 unsigned usage, | 489 !GpuMemoryBufferImpl::IsUsageValid(request->usage)) { |
| 414 const CreateGpuMemoryBufferCallback& callback) { | 490 request->result = scoped_ptr<gfx::GpuMemoryBuffer>(); |
| 415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 491 request->event.Signal(); |
| 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; | 492 return; |
| 451 } | 493 } |
| 452 | 494 |
| 453 host->CreateGpuMemoryBuffer( | 495 request->result = GpuMemoryBufferImpl::Create( |
| 454 handle, | 496 gfx::Size(request->width, request->height), |
| 455 size, | 497 request->internalformat, |
| 456 internalformat, | 498 request->usage).PassAs<gfx::GpuMemoryBuffer>(); |
| 457 usage, | 499 request->event.Signal(); |
| 458 base::Bind(&BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO, | |
| 459 base::Unretained(this), | |
| 460 request_id)); | |
| 461 } | 500 } |
| 462 | 501 |
| 463 void BrowserGpuChannelHostFactory::GpuMemoryBufferCreatedOnIO( | 502 // static |
| 464 uint32 request_id, | 503 void BrowserGpuChannelHostFactory::DeleteGpuMemoryBufferOnIO( |
| 465 const gfx::GpuMemoryBufferHandle& handle) { | 504 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 } | 505 } |
| 474 | 506 |
| 475 void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated( | 507 void BrowserGpuChannelHostFactory::OnGpuMemoryBufferCreated( |
| 476 uint32 request_id, | 508 uint32 request_id, |
| 477 const gfx::GpuMemoryBufferHandle& handle) { | 509 const gfx::GpuMemoryBufferHandle& handle) { |
| 510 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 511 |
| 478 CreateGpuMemoryBufferCallbackMap::iterator iter = | 512 CreateGpuMemoryBufferCallbackMap::iterator iter = |
| 479 create_gpu_memory_buffer_requests_.find(request_id); | 513 create_gpu_memory_buffer_requests_.find(request_id); |
| 480 DCHECK(iter != create_gpu_memory_buffer_requests_.end()); | 514 DCHECK(iter != create_gpu_memory_buffer_requests_.end()); |
| 481 iter->second.Run(handle); | 515 iter->second.Run(handle); |
| 482 create_gpu_memory_buffer_requests_.erase(iter); | 516 create_gpu_memory_buffer_requests_.erase(iter); |
| 483 } | 517 } |
| 484 | 518 |
| 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 | 519 } // namespace content |
| OLD | NEW |