| Index: content/common/gpu/client/command_buffer_proxy_impl.cc
|
| diff --git a/content/common/gpu/client/command_buffer_proxy_impl.cc b/content/common/gpu/client/command_buffer_proxy_impl.cc
|
| index fc0cb83a2d75b6a090abcfaca63392033f7048d2..cb509a83413881c8738d6d84bb691531e55774ea 100644
|
| --- a/content/common/gpu/client/command_buffer_proxy_impl.cc
|
| +++ b/content/common/gpu/client/command_buffer_proxy_impl.cc
|
| @@ -46,6 +46,9 @@ CommandBufferProxyImpl::CommandBufferProxyImpl(GpuChannelHost* channel,
|
| flush_count_(0),
|
| last_put_offset_(-1),
|
| last_barrier_put_offset_(-1),
|
| + next_fence_sync_release_(1),
|
| + flushed_fence_sync_release_(0),
|
| + verified_fence_sync_release_(0),
|
| next_signal_id_(0) {
|
| DCHECK(channel);
|
| }
|
| @@ -212,8 +215,18 @@ void CommandBufferProxyImpl::Flush(int32 put_offset) {
|
| last_barrier_put_offset_ = put_offset;
|
|
|
| if (channel_) {
|
| - channel_->OrderingBarrier(route_id_, stream_id_, put_offset, ++flush_count_,
|
| - latency_info_, put_offset_changed, true);
|
| + const uint32_t flush_id = channel_->OrderingBarrier(
|
| + route_id_, stream_id_, put_offset, ++flush_count_, latency_info_,
|
| + put_offset_changed, true);
|
| + if (put_offset_changed) {
|
| + DCHECK(flush_id);
|
| + const uint64_t fence_sync_release = next_fence_sync_release_ - 1;
|
| + if (fence_sync_release > flushed_fence_sync_release_) {
|
| + flushed_fence_sync_release_ = fence_sync_release;
|
| + flushed_release_flush_id_.push(
|
| + std::make_pair(fence_sync_release, flush_id));
|
| + }
|
| + }
|
| }
|
|
|
| if (put_offset_changed)
|
| @@ -231,8 +244,18 @@ void CommandBufferProxyImpl::OrderingBarrier(int32 put_offset) {
|
| last_barrier_put_offset_ = put_offset;
|
|
|
| if (channel_) {
|
| - channel_->OrderingBarrier(route_id_, stream_id_, put_offset, ++flush_count_,
|
| - latency_info_, put_offset_changed, false);
|
| + const uint32_t flush_id = channel_->OrderingBarrier(
|
| + route_id_, stream_id_, put_offset, ++flush_count_, latency_info_,
|
| + put_offset_changed, false);
|
| + if (put_offset_changed) {
|
| + DCHECK(flush_id);
|
| + const uint64_t fence_sync_release = next_fence_sync_release_ - 1;
|
| + if (fence_sync_release > flushed_fence_sync_release_) {
|
| + flushed_fence_sync_release_ = fence_sync_release;
|
| + flushed_release_flush_id_.push(
|
| + std::make_pair(fence_sync_release, flush_id));
|
| + }
|
| + }
|
| }
|
|
|
| if (put_offset_changed)
|
| @@ -473,6 +496,38 @@ uint64_t CommandBufferProxyImpl::GetCommandBufferID() const {
|
| return command_buffer_id_;
|
| }
|
|
|
| +uint64_t CommandBufferProxyImpl::GenerateFenceSyncRelease() {
|
| + return next_fence_sync_release_++;
|
| +}
|
| +
|
| +bool CommandBufferProxyImpl::IsFenceSyncRelease(uint64_t release) {
|
| + return release != 0 && release < next_fence_sync_release_;
|
| +}
|
| +
|
| +bool CommandBufferProxyImpl::IsFenceSyncFlushed(uint64_t release) {
|
| + CheckLock();
|
| + if (last_state_.error != gpu::error::kNoError)
|
| + return false;
|
| +
|
| + if (release <= verified_fence_sync_release_)
|
| + return true;
|
| +
|
| + // Check if we have actually flushed the fence sync release.
|
| + if (release <= flushed_fence_sync_release_) {
|
| + DCHECK(!flushed_release_flush_id_.empty());
|
| + // Check if it has already been validated by another context.
|
| + UpdateVerifiedReleases(channel_->GetHighestValidatedFlushID(stream_id_));
|
| + if (release <= verified_fence_sync_release_)
|
| + return true;
|
| +
|
| + // Has not been validated, validate it now.
|
| + UpdateVerifiedReleases(channel_->ValidateFlushIDReachedServer(stream_id_));
|
| + return release <= verified_fence_sync_release_;
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| uint32 CommandBufferProxyImpl::InsertSyncPoint() {
|
| CheckLock();
|
| if (last_state_.error != gpu::error::kNoError)
|
| @@ -619,6 +674,17 @@ void CommandBufferProxyImpl::TryUpdateState() {
|
| shared_state()->Read(&last_state_);
|
| }
|
|
|
| +void CommandBufferProxyImpl::UpdateVerifiedReleases(uint32_t verified_flush) {
|
| + while (!flushed_release_flush_id_.empty()) {
|
| + const std::pair<uint64_t, uint32_t>& front_item =
|
| + flushed_release_flush_id_.front();
|
| + if (front_item.second > verified_flush)
|
| + break;
|
| + verified_fence_sync_release_ = front_item.first;
|
| + flushed_release_flush_id_.pop();
|
| + }
|
| +}
|
| +
|
| gpu::CommandBufferSharedState* CommandBufferProxyImpl::shared_state() const {
|
| return reinterpret_cast<gpu::CommandBufferSharedState*>(
|
| shared_state_shm_->memory());
|
|
|