summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service
diff options
context:
space:
mode:
authorjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-09 07:56:25 +0000
committerjamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-09 07:56:25 +0000
commit3f0855c057b90feb3f77176d67d990d9e8d1097c (patch)
treea4b1bfca1cab915ab98c6e07702e809bed12e638 /gpu/command_buffer/service
parente65e0b769b533835228a15cc9f2e7bd989f22908 (diff)
downloadchromium_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')
-rw-r--r--gpu/command_buffer/service/gpu_control_service.cc16
-rw-r--r--gpu/command_buffer/service/gpu_control_service.h5
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.cc65
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.h11
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);
};