diff options
author | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-09 07:56:25 +0000 |
---|---|---|
committer | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-09 07:56:25 +0000 |
commit | 3f0855c057b90feb3f77176d67d990d9e8d1097c (patch) | |
tree | a4b1bfca1cab915ab98c6e07702e809bed12e638 /gpu/command_buffer/service | |
parent | e65e0b769b533835228a15cc9f2e7bd989f22908 (diff) | |
download | chromium_src-3f0855c057b90feb3f77176d67d990d9e8d1097c.zip chromium_src-3f0855c057b90feb3f77176d67d990d9e8d1097c.tar.gz chromium_src-3f0855c057b90feb3f77176d67d990d9e8d1097c.tar.bz2 |
Move in process SignalQuery implementation to service side
R=sievers
Review URL: https://codereview.chromium.org/26091002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@227693 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer/service')
4 files changed, 80 insertions, 17 deletions
diff --git a/gpu/command_buffer/service/gpu_control_service.cc b/gpu/command_buffer/service/gpu_control_service.cc index ac08765..c6a8b8d 100644 --- a/gpu/command_buffer/service/gpu_control_service.cc +++ b/gpu/command_buffer/service/gpu_control_service.cc @@ -7,16 +7,19 @@ #include "gpu/command_buffer/client/gpu_memory_buffer_factory.h" #include "gpu/command_buffer/service/gpu_memory_buffer_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" +#include "gpu/command_buffer/service/query_manager.h" namespace gpu { GpuControlService::GpuControlService( GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager, GpuMemoryBufferFactory* gpu_memory_buffer_factory, - gles2::MailboxManager* mailbox_manager) + gles2::MailboxManager* mailbox_manager, + gles2::QueryManager* query_manager) : gpu_memory_buffer_manager_(gpu_memory_buffer_manager), gpu_memory_buffer_factory_(gpu_memory_buffer_factory), - mailbox_manager_(mailbox_manager) { + mailbox_manager_(mailbox_manager), + query_manager_(query_manager) { } GpuControlService::~GpuControlService() { @@ -75,9 +78,14 @@ void GpuControlService::SignalSyncPoint(uint32 sync_point, NOTREACHED(); } -void GpuControlService::SignalQuery(uint32 query, +void GpuControlService::SignalQuery(uint32 query_id, const base::Closure& callback) { - NOTREACHED(); + DCHECK(query_manager_); + gles2::QueryManager::Query* query = query_manager_->GetQuery(query_id); + if (!query) + callback.Run(); + else + query->AddCallback(callback); } bool GpuControlService::RegisterGpuMemoryBuffer( diff --git a/gpu/command_buffer/service/gpu_control_service.h b/gpu/command_buffer/service/gpu_control_service.h index a0ab65d..32016ba 100644 --- a/gpu/command_buffer/service/gpu_control_service.h +++ b/gpu/command_buffer/service/gpu_control_service.h @@ -17,13 +17,15 @@ class GpuMemoryBufferManagerInterface; namespace gles2 { class MailboxManager; +class QueryManager; } class GPU_EXPORT GpuControlService : public GpuControl { public: GpuControlService(GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager, GpuMemoryBufferFactory* gpu_memory_buffer_factory, - gles2::MailboxManager* mailbox_manager); + gles2::MailboxManager* mailbox_manager, + gles2::QueryManager* query_manager); virtual ~GpuControlService(); // Overridden from GpuControl: @@ -55,6 +57,7 @@ class GPU_EXPORT GpuControlService : public GpuControl { GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager_; GpuMemoryBufferFactory* gpu_memory_buffer_factory_; gles2::MailboxManager* mailbox_manager_; + gles2::QueryManager* query_manager_; typedef std::map<int32, linked_ptr<gfx::GpuMemoryBuffer> > GpuMemoryBufferMap; GpuMemoryBufferMap gpu_memory_buffers_; diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc index cdd47cd..1d48a98 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.cc +++ b/gpu/command_buffer/service/in_process_command_buffer.cc @@ -191,6 +191,7 @@ class ThreadClient : public SchedulerClientBase { public: ThreadClient(); virtual void QueueTask(const base::Closure& task) OVERRIDE; + virtual void ScheduleIdleWork(const base::Closure& callback) OVERRIDE; }; ThreadClient::ThreadClient() : SchedulerClientBase(true) { @@ -201,11 +202,17 @@ void ThreadClient::QueueTask(const base::Closure& task) { thread_->message_loop()->PostTask(FROM_HERE, task); } +void ThreadClient::ScheduleIdleWork(const base::Closure& callback) { + thread_->message_loop()->PostDelayedTask( + FROM_HERE, callback, base::TimeDelta::FromMilliseconds(5)); +} + // A client that talks to the GpuCommandQueue class QueueClient : public SchedulerClientBase { public: QueueClient(); virtual void QueueTask(const base::Closure& task) OVERRIDE; + virtual void ScheduleIdleWork(const base::Closure& callback) OVERRIDE; }; QueueClient::QueueClient() : SchedulerClientBase(false) { @@ -216,6 +223,10 @@ void QueueClient::QueueTask(const base::Closure& task) { g_gpu_queue.Get().QueueTask(task); } +void QueueClient::ScheduleIdleWork(const base::Closure& callback) { + // TODO(sievers): Should this do anything? +} + static scoped_ptr<InProcessCommandBuffer::SchedulerClient> CreateSchedulerClient() { scoped_ptr<InProcessCommandBuffer::SchedulerClient> client; @@ -244,7 +255,8 @@ InProcessCommandBuffer::InProcessCommandBuffer() last_put_offset_(-1), supports_gpu_memory_buffer_(false), flush_event_(false, false), - queue_(CreateSchedulerClient()) {} + queue_(CreateSchedulerClient()), + gpu_thread_weak_ptr_factory_(this) {} InProcessCommandBuffer::~InProcessCommandBuffer() { Destroy(); @@ -340,6 +352,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( const std::vector<int32>& attribs, gfx::GpuPreference gpu_preference) { CheckSequencedThread(); + gpu_thread_weak_ptr_ = gpu_thread_weak_ptr_factory_.GetWeakPtr(); // Use one share group for all contexts. CR_DEFINE_STATIC_LOCAL(scoped_refptr<gfx::GLShareGroup>, share_group, (new gfx::GLShareGroup)); @@ -353,9 +366,9 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( scoped_ptr<CommandBufferService> command_buffer( new CommandBufferService(transfer_buffer_manager_.get())); command_buffer->SetPutOffsetChangeCallback(base::Bind( - &InProcessCommandBuffer::PumpCommands, base::Unretained(this))); + &InProcessCommandBuffer::PumpCommands, gpu_thread_weak_ptr_)); command_buffer->SetParseErrorCallback(base::Bind( - &InProcessCommandBuffer::OnContextLost, base::Unretained(this))); + &InProcessCommandBuffer::OnContextLost, gpu_thread_weak_ptr_)); if (!command_buffer->Initialize()) { LOG(ERROR) << "Could not initialize command buffer."; @@ -404,12 +417,6 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( &GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler_.get()))); command_buffer_ = command_buffer.Pass(); - gpu_control_.reset( - new GpuControlService(decoder_->GetContextGroup()->image_manager(), - g_gpu_memory_buffer_factory, - decoder_->GetContextGroup()->mailbox_manager())); - supports_gpu_memory_buffer_ = gpu_control_->SupportsGpuMemoryBuffer(); - decoder_->set_engine(gpu_scheduler_.get()); if (!surface_) { @@ -471,9 +478,17 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( return false; } + gpu_control_.reset( + new GpuControlService(decoder_->GetContextGroup()->image_manager(), + g_gpu_memory_buffer_factory, + decoder_->GetContextGroup()->mailbox_manager(), + decoder_->GetQueryManager())); + supports_gpu_memory_buffer_ = gpu_control_->SupportsGpuMemoryBuffer(); + + if (!is_offscreen) { decoder_->SetResizeCallback(base::Bind( - &InProcessCommandBuffer::OnResizeView, base::Unretained(this))); + &InProcessCommandBuffer::OnResizeView, gpu_thread_weak_ptr_)); } if (share_resources_) { @@ -485,6 +500,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread( void InProcessCommandBuffer::Destroy() { CheckSequencedThread(); + base::WaitableEvent completion(true, false); bool result = false; base::Callback<bool(void)> destroy_task = base::Bind( @@ -496,6 +512,7 @@ void InProcessCommandBuffer::Destroy() { bool InProcessCommandBuffer::DestroyOnGpuThread() { CheckSequencedThread(); + gpu_thread_weak_ptr_factory_.InvalidateWeakPtrs(); command_buffer_.reset(); // Clean up GL resources if possible. bool have_context = context_ && context_->MakeCurrent(surface_); @@ -569,6 +586,26 @@ void InProcessCommandBuffer::FlushOnGpuThread(int32 put_offset) { } DCHECK((!error::IsError(state_after_last_flush_.error) && !context_lost_) || (error::IsError(state_after_last_flush_.error) && context_lost_)); + + // If we've processed all pending commands but still have pending queries, + // pump idle work until the query is passed. + if (put_offset == state_after_last_flush_.get_offset && + gpu_scheduler_->HasMoreWork()) { + queue_->ScheduleIdleWork( + base::Bind(&InProcessCommandBuffer::ScheduleMoreIdleWork, + gpu_thread_weak_ptr_)); + } +} + +void InProcessCommandBuffer::ScheduleMoreIdleWork() { + CheckSequencedThread(); + base::AutoLock lock(command_buffer_lock_); + if (gpu_scheduler_->HasMoreWork()) { + gpu_scheduler_->PerformIdleWork(); + queue_->ScheduleIdleWork( + base::Bind(&InProcessCommandBuffer::ScheduleMoreIdleWork, + gpu_thread_weak_ptr_)); + } } void InProcessCommandBuffer::Flush(int32 put_offset) { @@ -581,7 +618,7 @@ void InProcessCommandBuffer::Flush(int32 put_offset) { last_put_offset_ = put_offset; base::Closure task = base::Bind(&InProcessCommandBuffer::FlushOnGpuThread, - base::Unretained(this), + gpu_thread_weak_ptr_, put_offset); QueueTask(task); } @@ -686,7 +723,11 @@ void InProcessCommandBuffer::SignalSyncPoint(unsigned sync_point, void InProcessCommandBuffer::SignalQuery(unsigned query, const base::Closure& callback) { - NOTREACHED(); + CheckSequencedThread(); + QueueTask(base::Bind(&GpuControl::SignalQuery, + base::Unretained(gpu_control_.get()), + query, + WrapCallback(callback))); } gpu::error::Error InProcessCommandBuffer::GetLastError() { diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h index 2bc6e11..3fd0982 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.h +++ b/gpu/command_buffer/service/in_process_command_buffer.h @@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "gpu/command_buffer/common/command_buffer.h" @@ -126,7 +127,13 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, class SchedulerClient { public: virtual ~SchedulerClient() {} + + // Queues a task to run as soon as possible. virtual void QueueTask(const base::Closure& task) = 0; + + // Schedules |callback| to run at an appropriate time for performing idle + // work. + virtual void ScheduleIdleWork(const base::Closure& task) = 0; }; #if defined(OS_ANDROID) @@ -154,6 +161,7 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, void OnResizeView(gfx::Size size, float scale_factor); bool GetBufferChanged(int32 transfer_buffer_id); void PumpCommands(); + void ScheduleMoreIdleWork(); // Members accessed on the gpu thread (possibly with the exception of // creation): @@ -189,6 +197,9 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer, // the client thread. scoped_ptr<base::SequenceChecker> sequence_checker_; + base::WeakPtr<InProcessCommandBuffer> gpu_thread_weak_ptr_; + base::WeakPtrFactory<InProcessCommandBuffer> gpu_thread_weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(InProcessCommandBuffer); }; |