summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer
diff options
context:
space:
mode:
authorsievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-25 18:13:27 +0000
committersievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-25 18:13:27 +0000
commitefaff84fd25ab16edd8ac5c9e9ab3cf3b8d0c911 (patch)
treed507da03a9c35c79d10bd22607588fa88a3f0182 /gpu/command_buffer
parente332fe24f39bb8fb42024aba1d9114b618ea1936 (diff)
downloadchromium_src-efaff84fd25ab16edd8ac5c9e9ab3cf3b8d0c911.zip
chromium_src-efaff84fd25ab16edd8ac5c9e9ab3cf3b8d0c911.tar.gz
chromium_src-efaff84fd25ab16edd8ac5c9e9ab3cf3b8d0c911.tar.bz2
GLInProcessContext: Implement global sync points
Replaces the implementation that relied on flush ordering since that is not guaranteed when running different service threads. NOTRY=True BUG=332146 Review URL: https://codereview.chromium.org/168183003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253201 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer')
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.cc91
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.h2
2 files changed, 91 insertions, 2 deletions
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index 5bc7ded..b7feee9 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -5,6 +5,7 @@
#include "gpu/command_buffer/service/in_process_command_buffer.h"
#include <queue>
+#include <set>
#include <utility>
#include <GLES2/gl2.h>
@@ -21,6 +22,7 @@
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/sequence_checker.h"
+#include "base/synchronization/condition_variable.h"
#include "base/threading/thread.h"
#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/context_group.h"
@@ -109,6 +111,71 @@ class ScopedEvent {
base::WaitableEvent* event_;
};
+class SyncPointManager {
+ public:
+ SyncPointManager();
+ ~SyncPointManager();
+
+ uint32 GenerateSyncPoint();
+ void RetireSyncPoint(uint32 sync_point);
+
+ bool IsSyncPointPassed(uint32 sync_point);
+ void WaitSyncPoint(uint32 sync_point);
+
+private:
+ // This lock protects access to pending_sync_points_ and next_sync_point_ and
+ // is used with the ConditionVariable to signal when a sync point is retired.
+ base::Lock lock_;
+ std::set<uint32> pending_sync_points_;
+ uint32 next_sync_point_;
+ base::ConditionVariable cond_var_;
+};
+
+SyncPointManager::SyncPointManager() : next_sync_point_(0), cond_var_(&lock_) {}
+
+SyncPointManager::~SyncPointManager() {
+ DCHECK_EQ(pending_sync_points_.size(), 0U);
+}
+
+uint32 SyncPointManager::GenerateSyncPoint() {
+ base::AutoLock lock(lock_);
+ uint32 sync_point = next_sync_point_++;
+ DCHECK_EQ(pending_sync_points_.count(sync_point), 0U);
+ pending_sync_points_.insert(sync_point);
+ return sync_point;
+}
+
+void SyncPointManager::RetireSyncPoint(uint32 sync_point) {
+ base::AutoLock lock(lock_);
+ DCHECK(pending_sync_points_.count(sync_point));
+ pending_sync_points_.erase(sync_point);
+ cond_var_.Broadcast();
+}
+
+bool SyncPointManager::IsSyncPointPassed(uint32 sync_point) {
+ base::AutoLock lock(lock_);
+ return pending_sync_points_.count(sync_point) == 0;
+}
+
+void SyncPointManager::WaitSyncPoint(uint32 sync_point) {
+ base::AutoLock lock(lock_);
+ while (pending_sync_points_.count(sync_point)) {
+ cond_var_.Wait();
+ }
+}
+
+base::LazyInstance<SyncPointManager> g_sync_point_manager =
+ LAZY_INSTANCE_INITIALIZER;
+
+bool WaitSyncPoint(uint32 sync_point) {
+ g_sync_point_manager.Get().WaitSyncPoint(sync_point);
+ return true;
+}
+
+void RetireSyncPoint(uint32 sync_point) {
+ g_sync_point_manager.Get().RetireSyncPoint(sync_point);
+}
+
} // anonyous namespace
InProcessCommandBuffer::Service::Service() {}
@@ -347,6 +414,7 @@ bool InProcessCommandBuffer::InitializeOnGpuThread(
decoder_->SetResizeCallback(base::Bind(
&InProcessCommandBuffer::OnResizeView, gpu_thread_weak_ptr_));
}
+ decoder_->SetWaitSyncPointCallback(base::Bind(&WaitSyncPoint));
return true;
}
@@ -552,13 +620,32 @@ void InProcessCommandBuffer::DestroyGpuMemoryBuffer(int32 id) {
}
uint32 InProcessCommandBuffer::InsertSyncPoint() {
- return 0;
+ uint32 sync_point = g_sync_point_manager.Get().GenerateSyncPoint();
+ QueueTask(base::Bind(&RetireSyncPoint, sync_point));
+ return sync_point;
}
void InProcessCommandBuffer::SignalSyncPoint(unsigned sync_point,
const base::Closure& callback) {
CheckSequencedThread();
- QueueTask(WrapCallback(callback));
+ QueueTask(base::Bind(&InProcessCommandBuffer::SignalSyncPointOnGpuThread,
+ base::Unretained(this),
+ sync_point,
+ WrapCallback(callback)));
+}
+
+void InProcessCommandBuffer::SignalSyncPointOnGpuThread(
+ unsigned sync_point,
+ const base::Closure& callback) {
+ if (g_sync_point_manager.Get().IsSyncPointPassed(sync_point)) {
+ callback.Run();
+ } else {
+ service_->ScheduleIdleWork(
+ base::Bind(&InProcessCommandBuffer::SignalSyncPointOnGpuThread,
+ gpu_thread_weak_ptr_,
+ sync_point,
+ callback));
+ }
}
void InProcessCommandBuffer::SignalQuery(unsigned query,
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index 199a294..bd83502 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -174,6 +174,8 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer,
State GetStateFast();
void QueueTask(const base::Closure& task) { service_->ScheduleTask(task); }
void CheckSequencedThread();
+ void SignalSyncPointOnGpuThread(uint32 sync_point,
+ const base::Closure& callback);
// Callbacks:
void OnContextLost();