Index: content/common/gpu/gpu_command_buffer_stub.cc |
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc |
index 6f49445d95eabd77f1ae882aea5ab9675fcca75d..381f354a9446a4759775e4cd9e579f48edb4e3bf 100644 |
--- a/content/common/gpu/gpu_command_buffer_stub.cc |
+++ b/content/common/gpu/gpu_command_buffer_stub.cc |
@@ -536,11 +536,9 @@ void GpuCommandBufferStub::OnInitialize( |
scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), |
decoder_.get(), |
decoder_.get())); |
- sync_point_client_ = |
- sync_point_manager->CreateSyncPointClient( |
- channel_->GetSyncPointClientState(), |
- gpu::CommandBufferNamespace::GPU_IO, |
- command_buffer_id_); |
+ sync_point_client_ = sync_point_manager->CreateSyncPointClient( |
+ channel_->GetSyncPointOrderData(), gpu::CommandBufferNamespace::GPU_IO, |
+ command_buffer_id_); |
if (preemption_flag_.get()) |
scheduler_->SetPreemptByFlag(preemption_flag_); |
@@ -645,6 +643,10 @@ void GpuCommandBufferStub::OnInitialize( |
decoder_->SetWaitSyncPointCallback( |
base::Bind(&GpuCommandBufferStub::OnWaitSyncPoint, |
base::Unretained(this))); |
+ decoder_->SetFenceSyncReleaseCallback(base::Bind( |
+ &GpuCommandBufferStub::OnFenceSyncRelease, base::Unretained(this))); |
+ decoder_->SetWaitFenceSyncCallback(base::Bind( |
+ &GpuCommandBufferStub::OnWaitFenceSync, base::Unretained(this))); |
command_buffer_->SetPutOffsetChangeCallback( |
base::Bind(&GpuCommandBufferStub::PutChanged, base::Unretained(this))); |
@@ -933,8 +935,15 @@ void GpuCommandBufferStub::OnRetireSyncPoint(uint32 sync_point) { |
gpu::gles2::MailboxManager* mailbox_manager = |
context_group_->mailbox_manager(); |
- if (mailbox_manager->UsesSync() && MakeCurrent()) |
- mailbox_manager->PushTextureUpdates(sync_point); |
+ if (mailbox_manager->UsesSync() && MakeCurrent()) { |
+ // Old sync points are global and do not have a command buffer ID, |
+ // We can simply use the global sync point number as the release count with |
+ // 0 for the command buffer ID (under normal circumstances 0 is invalid so |
+ // will not be used) until the old sync points are replaced. |
+ gpu::gles2::SyncToken sync_token = {gpu::CommandBufferNamespace::GPU_IO, 0, |
+ sync_point}; |
+ mailbox_manager->PushTextureUpdates(sync_token); |
+ } |
GpuChannelManager* manager = channel_->gpu_channel_manager(); |
manager->sync_point_manager()->RetireSyncPoint(sync_point); |
@@ -947,7 +956,11 @@ bool GpuCommandBufferStub::OnWaitSyncPoint(uint32 sync_point) { |
return true; |
GpuChannelManager* manager = channel_->gpu_channel_manager(); |
if (manager->sync_point_manager()->IsSyncPointRetired(sync_point)) { |
- PullTextureUpdates(sync_point); |
+ // Old sync points are global and do not have a command buffer ID, |
+ // We can simply use the global sync point number as the release count with |
+ // 0 for the command buffer ID (under normal circumstances 0 is invalid so |
+ // will not be used) until the old sync points are replaced. |
+ PullTextureUpdates(gpu::CommandBufferNamespace::GPU_IO, 0, sync_point); |
return true; |
} |
@@ -969,16 +982,26 @@ void GpuCommandBufferStub::OnWaitSyncPointCompleted(uint32 sync_point) { |
DCHECK(!scheduler_->scheduled()); |
TRACE_EVENT_ASYNC_END1("gpu", "WaitSyncPoint", this, "GpuCommandBufferStub", |
this); |
- PullTextureUpdates(sync_point); |
+ // Old sync points are global and do not have a command buffer ID, |
+ // We can simply use the global sync point number as the release count with |
+ // 0 for the command buffer ID (under normal circumstances 0 is invalid so |
+ // will not be used) until the old sync points are replaced. |
+ PullTextureUpdates(gpu::CommandBufferNamespace::GPU_IO, 0, sync_point); |
waiting_for_sync_point_ = false; |
scheduler_->SetScheduled(true); |
} |
-void GpuCommandBufferStub::PullTextureUpdates(uint32 sync_point) { |
+void GpuCommandBufferStub::PullTextureUpdates( |
+ gpu::CommandBufferNamespace namespace_id, |
+ uint64_t command_buffer_id, |
+ uint32_t release) { |
gpu::gles2::MailboxManager* mailbox_manager = |
context_group_->mailbox_manager(); |
- if (mailbox_manager->UsesSync() && MakeCurrent()) |
- mailbox_manager->PullTextureUpdates(sync_point); |
+ if (mailbox_manager->UsesSync() && MakeCurrent()) { |
+ gpu::gles2::SyncToken sync_token = {namespace_id, command_buffer_id, |
+ release}; |
+ mailbox_manager->PullTextureUpdates(sync_token); |
+ } |
} |
void GpuCommandBufferStub::OnSignalSyncPoint(uint32 sync_point, uint32 id) { |
@@ -1013,6 +1036,73 @@ void GpuCommandBufferStub::OnSignalQuery(uint32 query_id, uint32 id) { |
OnSignalSyncPointAck(id); |
} |
+void GpuCommandBufferStub::OnFenceSyncRelease(uint64_t release) { |
+ if (sync_point_client_->client_state()->IsFenceSyncReleased(release)) { |
+ DLOG(ERROR) << "Fence Sync has already been released."; |
+ return; |
+ } |
+ |
+ gpu::gles2::MailboxManager* mailbox_manager = |
+ context_group_->mailbox_manager(); |
+ if (mailbox_manager->UsesSync() && MakeCurrent()) { |
+ gpu::gles2::SyncToken sync_token = {gpu::CommandBufferNamespace::GPU_IO, |
+ command_buffer_id_, release}; |
+ mailbox_manager->PushTextureUpdates(sync_token); |
+ } |
+ |
+ sync_point_client_->ReleaseFenceSync(release); |
+} |
+ |
+bool GpuCommandBufferStub::OnWaitFenceSync( |
+ gpu::CommandBufferNamespace namespace_id, |
+ uint64_t command_buffer_id, |
+ uint64_t release) { |
+ DCHECK(!waiting_for_sync_point_); |
+ DCHECK(scheduler_->scheduled()); |
+ |
+ GpuChannelManager* manager = channel_->gpu_channel_manager(); |
+ DCHECK(manager); |
+ |
+ gpu::SyncPointManager* sync_point_manager = manager->sync_point_manager(); |
+ DCHECK(sync_point_manager); |
+ |
+ scoped_refptr<gpu::SyncPointClientState> release_state = |
+ sync_point_manager->GetSyncPointClientState(namespace_id, |
+ command_buffer_id); |
+ |
+ if (!release_state) |
+ return true; |
+ |
+ if (release_state->IsFenceSyncReleased(release)) { |
+ PullTextureUpdates(namespace_id, command_buffer_id, release); |
+ return true; |
+ } |
+ |
+ TRACE_EVENT_ASYNC_BEGIN1("gpu", "WaitFenceSync", this, "GpuCommandBufferStub", |
+ this); |
+ scheduler_->SetScheduled(false); |
+ waiting_for_sync_point_ = true; |
+ sync_point_client_->WaitNonThreadSafe( |
+ release_state.get(), release, task_runner_, |
+ base::Bind(&GpuCommandBufferStub::OnWaitFenceSyncCompleted, |
+ this->AsWeakPtr(), namespace_id, command_buffer_id, release)); |
+ |
+ return scheduler_->scheduled(); |
+} |
+ |
+void GpuCommandBufferStub::OnWaitFenceSyncCompleted( |
+ gpu::CommandBufferNamespace namespace_id, |
+ uint64_t command_buffer_id, |
+ uint64_t release) { |
+ DCHECK(waiting_for_sync_point_); |
+ DCHECK(!scheduler_->scheduled()); |
+ TRACE_EVENT_ASYNC_END1("gpu", "WaitFenceSync", this, "GpuCommandBufferStub", |
+ this); |
+ PullTextureUpdates(namespace_id, command_buffer_id, release); |
+ waiting_for_sync_point_ = false; |
+ scheduler_->SetScheduled(true); |
+} |
+ |
void GpuCommandBufferStub::OnCreateImage(int32 id, |
gfx::GpuMemoryBufferHandle handle, |
gfx::Size size, |