Make SetGetBuffer async
This removes one sync IPC at initialization time, and after we release the command buffer.
We make sure we handle the possibility of having more than one SetGetBuffer in flight by
counting them on client side and service side, making sure we only ever compare |get| values
for the same buffer.
Bug: 484375
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: Ife91dd5846e9d82f03e5bfe5d022a06284389756
Reviewed-on: https://chromium-review.googlesource.com/502016
Commit-Queue: Antoine Labour <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Bill Budge <[email protected]>
Reviewed-by: Victor Miura <[email protected]>
Cr-Commit-Position: refs/heads/master@{#472312}
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc
index 7021fa3..42cb4165 100644
--- a/gpu/command_buffer/client/cmd_buffer_helper.cc
+++ b/gpu/command_buffer/client/cmd_buffer_helper.cc
@@ -35,6 +35,8 @@
last_put_sent_(0),
cached_last_token_read_(0),
cached_get_offset_(0),
+ set_get_buffer_count_(0),
+ service_on_old_buffer_(false),
#if defined(CMD_HELPER_PERIODIC_FLUSH_CHECK)
commands_issued_(0),
#endif
@@ -117,12 +119,15 @@
ring_buffer_ = buffer;
ring_buffer_id_ = id;
command_buffer_->SetGetBuffer(id);
+ ++set_get_buffer_count_;
entries_ = static_cast<CommandBufferEntry*>(ring_buffer_->memory());
total_entry_count_ = ring_buffer_size_ / sizeof(CommandBufferEntry);
// Call to SetGetBuffer(id) above resets get and put offsets to 0.
// No need to query it through IPC.
put_ = 0;
+ last_put_sent_ = 0;
cached_get_offset_ = 0;
+ service_on_old_buffer_ = true;
CalcImmediateEntries(0);
return true;
}
@@ -153,7 +158,12 @@
}
void CommandBufferHelper::UpdateCachedState(const CommandBuffer::State& state) {
- cached_get_offset_ = state.get_offset;
+ // If the service hasn't seen the current get buffer yet (i.e. hasn't
+ // processed the latest SetGetBuffer), it's as if it hadn't processed anything
+ // in it, i.e. get == 0.
+ service_on_old_buffer_ =
+ (state.set_get_buffer_count != set_get_buffer_count_);
+ cached_get_offset_ = service_on_old_buffer_ ? 0 : state.get_offset;
cached_last_token_read_ = state.token;
context_lost_ = error::IsError(state.error);
}
@@ -164,8 +174,8 @@
if (!usable()) {
return false;
}
- CommandBuffer::State last_state =
- command_buffer_->WaitForGetOffsetInRange(start, end);
+ CommandBuffer::State last_state = command_buffer_->WaitForGetOffsetInRange(
+ set_get_buffer_count_, start, end);
UpdateCachedState(last_state);
return !context_lost_;
}
@@ -214,12 +224,13 @@
return false;
}
// If there is no work just exit.
- if (put_ == cached_get_offset_) {
+ if (put_ == cached_get_offset_ && !service_on_old_buffer_) {
return true;
}
DCHECK(HaveRingBuffer() ||
error::IsError(command_buffer_->GetLastState().error));
- Flush();
+ if (last_put_sent_ != put_)
+ Flush();
if (!WaitForGetOffsetInRange(put_, put_))
return false;
DCHECK_EQ(cached_get_offset_, put_);