| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "gpu/command_buffer/service/in_process_command_buffer.h" | 5 #include "gpu/command_buffer/service/in_process_command_buffer.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/memory/weak_ptr.h" | 16 #include "base/memory/weak_ptr.h" |
| 17 #include "base/message_loop/message_loop_proxy.h" | 17 #include "base/message_loop/message_loop_proxy.h" |
| 18 #include "base/sequence_checker.h" | 18 #include "base/sequence_checker.h" |
| 19 #include "base/synchronization/condition_variable.h" | 19 #include "base/synchronization/condition_variable.h" |
| 20 #include "base/threading/thread.h" | 20 #include "base/threading/thread.h" |
| 21 #include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" |
| 21 #include "gpu/command_buffer/service/command_buffer_service.h" | 22 #include "gpu/command_buffer/service/command_buffer_service.h" |
| 22 #include "gpu/command_buffer/service/context_group.h" | 23 #include "gpu/command_buffer/service/context_group.h" |
| 23 #include "gpu/command_buffer/service/gl_context_virtual.h" | 24 #include "gpu/command_buffer/service/gl_context_virtual.h" |
| 24 #include "gpu/command_buffer/service/gpu_scheduler.h" | 25 #include "gpu/command_buffer/service/gpu_scheduler.h" |
| 25 #include "gpu/command_buffer/service/gpu_switches.h" | 26 #include "gpu/command_buffer/service/gpu_switches.h" |
| 27 #include "gpu/command_buffer/service/image_factory.h" |
| 26 #include "gpu/command_buffer/service/image_manager.h" | 28 #include "gpu/command_buffer/service/image_manager.h" |
| 27 #include "gpu/command_buffer/service/mailbox_manager_impl.h" | 29 #include "gpu/command_buffer/service/mailbox_manager_impl.h" |
| 28 #include "gpu/command_buffer/service/mailbox_manager_sync.h" | 30 #include "gpu/command_buffer/service/mailbox_manager_sync.h" |
| 29 #include "gpu/command_buffer/service/memory_tracking.h" | 31 #include "gpu/command_buffer/service/memory_tracking.h" |
| 30 #include "gpu/command_buffer/service/query_manager.h" | 32 #include "gpu/command_buffer/service/query_manager.h" |
| 31 #include "gpu/command_buffer/service/transfer_buffer_manager.h" | 33 #include "gpu/command_buffer/service/transfer_buffer_manager.h" |
| 32 #include "ui/gfx/size.h" | 34 #include "ui/gfx/size.h" |
| 33 #include "ui/gl/gl_context.h" | 35 #include "ui/gl/gl_context.h" |
| 34 #include "ui/gl/gl_image.h" | 36 #include "ui/gl/gl_image.h" |
| 35 #include "ui/gl/gl_share_group.h" | 37 #include "ui/gl/gl_share_group.h" |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 } else { | 205 } else { |
| 204 service = new GpuInProcessThread; | 206 service = new GpuInProcessThread; |
| 205 } | 207 } |
| 206 return service; | 208 return service; |
| 207 } | 209 } |
| 208 | 210 |
| 209 InProcessCommandBuffer::InProcessCommandBuffer( | 211 InProcessCommandBuffer::InProcessCommandBuffer( |
| 210 const scoped_refptr<Service>& service) | 212 const scoped_refptr<Service>& service) |
| 211 : context_lost_(false), | 213 : context_lost_(false), |
| 212 idle_work_pending_(false), | 214 idle_work_pending_(false), |
| 215 image_factory_(nullptr), |
| 213 last_put_offset_(-1), | 216 last_put_offset_(-1), |
| 217 gpu_memory_buffer_manager_(nullptr), |
| 214 flush_event_(false, false), | 218 flush_event_(false, false), |
| 215 service_(service.get() ? service : GetDefaultService()), | 219 service_(service.get() ? service : GetDefaultService()), |
| 216 gpu_thread_weak_ptr_factory_(this) { | 220 gpu_thread_weak_ptr_factory_(this) { |
| 217 if (!service.get()) { | 221 if (!service.get()) { |
| 218 base::AutoLock lock(default_thread_clients_lock_.Get()); | 222 base::AutoLock lock(default_thread_clients_lock_.Get()); |
| 219 default_thread_clients_.Get().insert(this); | 223 default_thread_clients_.Get().insert(this); |
| 220 } | 224 } |
| 225 next_image_id_.GetNext(); |
| 221 } | 226 } |
| 222 | 227 |
| 223 InProcessCommandBuffer::~InProcessCommandBuffer() { | 228 InProcessCommandBuffer::~InProcessCommandBuffer() { |
| 224 Destroy(); | 229 Destroy(); |
| 225 base::AutoLock lock(default_thread_clients_lock_.Get()); | 230 base::AutoLock lock(default_thread_clients_lock_.Get()); |
| 226 default_thread_clients_.Get().erase(this); | 231 default_thread_clients_.Get().erase(this); |
| 227 } | 232 } |
| 228 | 233 |
| 229 void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) { | 234 void InProcessCommandBuffer::OnResizeView(gfx::Size size, float scale_factor) { |
| 230 CheckSequencedThread(); | 235 CheckSequencedThread(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 } | 267 } |
| 263 | 268 |
| 264 bool InProcessCommandBuffer::Initialize( | 269 bool InProcessCommandBuffer::Initialize( |
| 265 scoped_refptr<gfx::GLSurface> surface, | 270 scoped_refptr<gfx::GLSurface> surface, |
| 266 bool is_offscreen, | 271 bool is_offscreen, |
| 267 gfx::AcceleratedWidget window, | 272 gfx::AcceleratedWidget window, |
| 268 const gfx::Size& size, | 273 const gfx::Size& size, |
| 269 const std::vector<int32>& attribs, | 274 const std::vector<int32>& attribs, |
| 270 gfx::GpuPreference gpu_preference, | 275 gfx::GpuPreference gpu_preference, |
| 271 const base::Closure& context_lost_callback, | 276 const base::Closure& context_lost_callback, |
| 272 InProcessCommandBuffer* share_group) { | 277 InProcessCommandBuffer* share_group, |
| 278 GpuMemoryBufferManager* gpu_memory_buffer_manager, |
| 279 ImageFactory* image_factory) { |
| 273 DCHECK(!share_group || service_.get() == share_group->service_.get()); | 280 DCHECK(!share_group || service_.get() == share_group->service_.get()); |
| 274 context_lost_callback_ = WrapCallback(context_lost_callback); | 281 context_lost_callback_ = WrapCallback(context_lost_callback); |
| 275 | 282 |
| 276 if (surface.get()) { | 283 if (surface.get()) { |
| 277 // GPU thread must be the same as client thread due to GLSurface not being | 284 // GPU thread must be the same as client thread due to GLSurface not being |
| 278 // thread safe. | 285 // thread safe. |
| 279 sequence_checker_.reset(new base::SequenceChecker); | 286 sequence_checker_.reset(new base::SequenceChecker); |
| 280 surface_ = surface; | 287 surface_ = surface; |
| 281 } | 288 } |
| 282 | 289 |
| 283 gpu::Capabilities capabilities; | 290 gpu::Capabilities capabilities; |
| 284 InitializeOnGpuThreadParams params(is_offscreen, | 291 InitializeOnGpuThreadParams params(is_offscreen, |
| 285 window, | 292 window, |
| 286 size, | 293 size, |
| 287 attribs, | 294 attribs, |
| 288 gpu_preference, | 295 gpu_preference, |
| 289 &capabilities, | 296 &capabilities, |
| 290 share_group); | 297 share_group, |
| 298 image_factory); |
| 291 | 299 |
| 292 base::Callback<bool(void)> init_task = | 300 base::Callback<bool(void)> init_task = |
| 293 base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread, | 301 base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread, |
| 294 base::Unretained(this), | 302 base::Unretained(this), |
| 295 params); | 303 params); |
| 296 | 304 |
| 297 base::WaitableEvent completion(true, false); | 305 base::WaitableEvent completion(true, false); |
| 298 bool result = false; | 306 bool result = false; |
| 299 QueueTask( | 307 QueueTask( |
| 300 base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion)); | 308 base::Bind(&RunTaskWithResult<bool>, init_task, &result, &completion)); |
| 301 completion.Wait(); | 309 completion.Wait(); |
| 302 | 310 |
| 303 if (result) | 311 gpu_memory_buffer_manager_ = gpu_memory_buffer_manager; |
| 312 |
| 313 if (result) { |
| 304 capabilities_ = capabilities; | 314 capabilities_ = capabilities; |
| 315 capabilities_.image = capabilities_.image && gpu_memory_buffer_manager_; |
| 316 } |
| 305 | 317 |
| 306 return result; | 318 return result; |
| 307 } | 319 } |
| 308 | 320 |
| 309 bool InProcessCommandBuffer::InitializeOnGpuThread( | 321 bool InProcessCommandBuffer::InitializeOnGpuThread( |
| 310 const InitializeOnGpuThreadParams& params) { | 322 const InitializeOnGpuThreadParams& params) { |
| 311 CheckSequencedThread(); | 323 CheckSequencedThread(); |
| 312 gpu_thread_weak_ptr_ = gpu_thread_weak_ptr_factory_.GetWeakPtr(); | 324 gpu_thread_weak_ptr_ = gpu_thread_weak_ptr_factory_.GetWeakPtr(); |
| 313 | 325 |
| 314 DCHECK(params.size.width() >= 0 && params.size.height() >= 0); | 326 DCHECK(params.size.width() >= 0 && params.size.height() >= 0); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 *params.capabilities = decoder_->GetCapabilities(); | 428 *params.capabilities = decoder_->GetCapabilities(); |
| 417 | 429 |
| 418 if (!params.is_offscreen) { | 430 if (!params.is_offscreen) { |
| 419 decoder_->SetResizeCallback(base::Bind( | 431 decoder_->SetResizeCallback(base::Bind( |
| 420 &InProcessCommandBuffer::OnResizeView, gpu_thread_weak_ptr_)); | 432 &InProcessCommandBuffer::OnResizeView, gpu_thread_weak_ptr_)); |
| 421 } | 433 } |
| 422 decoder_->SetWaitSyncPointCallback( | 434 decoder_->SetWaitSyncPointCallback( |
| 423 base::Bind(&InProcessCommandBuffer::WaitSyncPointOnGpuThread, | 435 base::Bind(&InProcessCommandBuffer::WaitSyncPointOnGpuThread, |
| 424 base::Unretained(this))); | 436 base::Unretained(this))); |
| 425 | 437 |
| 438 image_factory_ = params.image_factory; |
| 439 params.capabilities->image = params.capabilities->image && image_factory_; |
| 440 |
| 426 return true; | 441 return true; |
| 427 } | 442 } |
| 428 | 443 |
| 429 void InProcessCommandBuffer::Destroy() { | 444 void InProcessCommandBuffer::Destroy() { |
| 430 CheckSequencedThread(); | 445 CheckSequencedThread(); |
| 431 | 446 |
| 432 base::WaitableEvent completion(true, false); | 447 base::WaitableEvent completion(true, false); |
| 433 bool result = false; | 448 bool result = false; |
| 434 base::Callback<bool(void)> destroy_task = base::Bind( | 449 base::Callback<bool(void)> destroy_task = base::Bind( |
| 435 &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this)); | 450 &InProcessCommandBuffer::DestroyOnGpuThread, base::Unretained(this)); |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 } | 620 } |
| 606 | 621 |
| 607 gpu::Capabilities InProcessCommandBuffer::GetCapabilities() { | 622 gpu::Capabilities InProcessCommandBuffer::GetCapabilities() { |
| 608 return capabilities_; | 623 return capabilities_; |
| 609 } | 624 } |
| 610 | 625 |
| 611 int32 InProcessCommandBuffer::CreateImage(ClientBuffer buffer, | 626 int32 InProcessCommandBuffer::CreateImage(ClientBuffer buffer, |
| 612 size_t width, | 627 size_t width, |
| 613 size_t height, | 628 size_t height, |
| 614 unsigned internalformat) { | 629 unsigned internalformat) { |
| 615 NOTREACHED(); | 630 CheckSequencedThread(); |
| 616 return -1; | 631 |
| 632 DCHECK(gpu_memory_buffer_manager_); |
| 633 gfx::GpuMemoryBuffer* gpu_memory_buffer = |
| 634 gpu_memory_buffer_manager_->GpuMemoryBufferFromClientBuffer(buffer); |
| 635 DCHECK(gpu_memory_buffer); |
| 636 |
| 637 int32 new_id = next_image_id_.GetNext(); |
| 638 |
| 639 DCHECK(gpu::ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat( |
| 640 internalformat, gpu_memory_buffer->GetFormat())); |
| 641 QueueTask(base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread, |
| 642 base::Unretained(this), |
| 643 new_id, |
| 644 gpu_memory_buffer->GetHandle(), |
| 645 gfx::Size(width, height), |
| 646 gpu_memory_buffer->GetFormat(), |
| 647 internalformat)); |
| 648 return new_id; |
| 649 } |
| 650 |
| 651 void InProcessCommandBuffer::CreateImageOnGpuThread( |
| 652 int32 id, |
| 653 const gfx::GpuMemoryBufferHandle& handle, |
| 654 const gfx::Size& size, |
| 655 gfx::GpuMemoryBuffer::Format format, |
| 656 uint32 internalformat) { |
| 657 if (!decoder_) |
| 658 return; |
| 659 |
| 660 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); |
| 661 DCHECK(image_manager); |
| 662 if (image_manager->LookupImage(id)) { |
| 663 LOG(ERROR) << "Image already exists with same ID."; |
| 664 return; |
| 665 } |
| 666 |
| 667 // Note: this assumes that client ID is always 0. |
| 668 const int kClientId = 0; |
| 669 |
| 670 DCHECK(image_factory_); |
| 671 scoped_refptr<gfx::GLImage> image = |
| 672 image_factory_->CreateImageForGpuMemoryBuffer( |
| 673 handle, size, format, internalformat, kClientId); |
| 674 if (!image.get()) |
| 675 return; |
| 676 |
| 677 image_manager->AddImage(image.get(), id); |
| 617 } | 678 } |
| 618 | 679 |
| 619 void InProcessCommandBuffer::DestroyImage(int32 id) { | 680 void InProcessCommandBuffer::DestroyImage(int32 id) { |
| 620 NOTREACHED(); | 681 CheckSequencedThread(); |
| 682 |
| 683 QueueTask(base::Bind(&InProcessCommandBuffer::DestroyImageOnGpuThread, |
| 684 base::Unretained(this), |
| 685 id)); |
| 686 } |
| 687 |
| 688 void InProcessCommandBuffer::DestroyImageOnGpuThread(int32 id) { |
| 689 if (!decoder_) |
| 690 return; |
| 691 |
| 692 gpu::gles2::ImageManager* image_manager = decoder_->GetImageManager(); |
| 693 DCHECK(image_manager); |
| 694 if (!image_manager->LookupImage(id)) { |
| 695 LOG(ERROR) << "Image with ID doesn't exist."; |
| 696 return; |
| 697 } |
| 698 |
| 699 image_manager->RemoveImage(id); |
| 621 } | 700 } |
| 622 | 701 |
| 623 int32 InProcessCommandBuffer::CreateGpuMemoryBufferImage( | 702 int32 InProcessCommandBuffer::CreateGpuMemoryBufferImage( |
| 624 size_t width, | 703 size_t width, |
| 625 size_t height, | 704 size_t height, |
| 626 unsigned internalformat, | 705 unsigned internalformat, |
| 627 unsigned usage) { | 706 unsigned usage) { |
| 628 NOTREACHED(); | 707 CheckSequencedThread(); |
| 629 return -1; | 708 |
| 709 DCHECK(gpu_memory_buffer_manager_); |
| 710 scoped_ptr<gfx::GpuMemoryBuffer> buffer( |
| 711 gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer( |
| 712 gfx::Size(width, height), |
| 713 gpu::ImageFactory::ImageFormatToGpuMemoryBufferFormat(internalformat), |
| 714 gpu::ImageFactory::ImageUsageToGpuMemoryBufferUsage(usage))); |
| 715 if (!buffer) |
| 716 return -1; |
| 717 |
| 718 return CreateImage(buffer->AsClientBuffer(), width, height, internalformat); |
| 630 } | 719 } |
| 631 | 720 |
| 632 uint32 InProcessCommandBuffer::InsertSyncPoint() { | 721 uint32 InProcessCommandBuffer::InsertSyncPoint() { |
| 633 uint32 sync_point = g_sync_point_manager.Get().GenerateSyncPoint(); | 722 uint32 sync_point = g_sync_point_manager.Get().GenerateSyncPoint(); |
| 634 QueueTask(base::Bind(&InProcessCommandBuffer::RetireSyncPointOnGpuThread, | 723 QueueTask(base::Bind(&InProcessCommandBuffer::RetireSyncPointOnGpuThread, |
| 635 base::Unretained(this), | 724 base::Unretained(this), |
| 636 sync_point)); | 725 sync_point)); |
| 637 return sync_point; | 726 return sync_point; |
| 638 } | 727 } |
| 639 | 728 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 | 874 |
| 786 #if defined(OS_ANDROID) | 875 #if defined(OS_ANDROID) |
| 787 scoped_refptr<gfx::SurfaceTexture> | 876 scoped_refptr<gfx::SurfaceTexture> |
| 788 InProcessCommandBuffer::GetSurfaceTexture(uint32 stream_id) { | 877 InProcessCommandBuffer::GetSurfaceTexture(uint32 stream_id) { |
| 789 DCHECK(stream_texture_manager_); | 878 DCHECK(stream_texture_manager_); |
| 790 return stream_texture_manager_->GetSurfaceTexture(stream_id); | 879 return stream_texture_manager_->GetSurfaceTexture(stream_id); |
| 791 } | 880 } |
| 792 #endif | 881 #endif |
| 793 | 882 |
| 794 } // namespace gpu | 883 } // namespace gpu |
| OLD | NEW |