diff options
author | kaanb@chromium.org <kaanb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-19 23:25:54 +0000 |
---|---|---|
committer | kaanb@chromium.org <kaanb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-19 23:25:54 +0000 |
commit | 3110b12ee2f239e0f0fb02f1255d1cfb31c8d9ef (patch) | |
tree | 41858a54fe5c59926c06ad279ad41427cd1fb337 /gpu | |
parent | 009fcb260f64800b183ecb2796baaa1e918bc572 (diff) | |
download | chromium_src-3110b12ee2f239e0f0fb02f1255d1cfb31c8d9ef.zip chromium_src-3110b12ee2f239e0f0fb02f1255d1cfb31c8d9ef.tar.gz chromium_src-3110b12ee2f239e0f0fb02f1255d1cfb31c8d9ef.tar.bz2 |
Revert 235428 "Revert 234915 "Revert 234758 "gpu: Remove redunda..."
> Revert 234915 "Revert 234758 "gpu: Remove redundant calls from C..."
>
> > Revert 234758 "gpu: Remove redundant calls from CommandBufferHel..."
> >
> > > gpu: Remove redundant calls from CommandBufferHelper::GetSpace() and optimize it.
> > >
> > > GetSpace() was calling AllocateRingBuffer() followed by WaitForAvailableEntries(). However, WaitForAvailable() was also calling AllocateRingBuffer() which ended up being redundant. We remove the redundant AllocateRingBuffer() call from GetSpace() in this patch.
> > >
> > > Also, we add a "fast-path" to return memory as soon as possible without issuing any GL commands if a suitably allocated buffer is already present and can satisfy the request immediately.
> > >
> > > BUG=181711
> > >
> > > Review URL: https://codereview.chromium.org/63513002
> >
> > TBR=kaanb@chromium.org
> >
> > Review URL: https://codereview.chromium.org/64833010
>
> TBR=kaanb@chromium.org
>
> Review URL: https://codereview.chromium.org/74123003
TBR=kaanb@chromium.org
Review URL: https://codereview.chromium.org/59153014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@236069 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/client/cmd_buffer_helper.cc | 58 | ||||
-rw-r--r-- | gpu/command_buffer/client/cmd_buffer_helper.h | 41 | ||||
-rw-r--r-- | gpu/command_buffer/client/cmd_buffer_helper_test.cc | 4 |
3 files changed, 46 insertions, 57 deletions
diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc index 3b9599e..11219ed 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper.cc @@ -12,6 +12,12 @@ namespace gpu { +const int kCommandsPerFlushCheck = 100; + +#if !defined(OS_ANDROID) +const double kFlushDelay = 1.0 / (5.0 * 60.0); +#endif + CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) : command_buffer_(command_buffer), ring_buffer_id_(-1), @@ -190,7 +196,12 @@ void CommandBufferHelper::WaitForToken(int32 token) { // around, adding a noops. Thus this function may change the value of put_. The // function will return early if an error occurs, in which case the available // space may not be available. -bool CommandBufferHelper::WaitForAvailableEntries(int32 count) { +void CommandBufferHelper::WaitForAvailableEntries(int32 count) { + AllocateRingBuffer(); + if (!usable()) { + return; + } + DCHECK(HaveRingBuffer()); DCHECK(count < total_entry_count_); if (put_ + count > total_entry_count_) { // There's not enough room between the current put and the end of the @@ -204,7 +215,7 @@ bool CommandBufferHelper::WaitForAvailableEntries(int32 count) { // Do not loop forever if the flush fails, meaning the command buffer // reader has shutdown. if (!FlushSync()) - return false; + return; } } // Insert Noops to fill out the buffer. @@ -223,29 +234,46 @@ bool CommandBufferHelper::WaitForAvailableEntries(int32 count) { // Do not loop forever if the flush fails, meaning the command buffer // reader has shutdown. if (!FlushSync()) - return false; + return; } } - FlushIfNeeded(); - return true; + // Force a flush if the buffer is getting half full, or even earlier if the + // reader is known to be idle. + int32 pending = + (put_ + total_entry_count_ - last_put_sent_) % total_entry_count_; + int32 limit = total_entry_count_ / + ((get_offset() == last_put_sent_) ? 16 : 2); + if (pending > limit) { + Flush(); + } else if (flush_automatically_ && + (commands_issued_ % kCommandsPerFlushCheck == 0)) { +#if !defined(OS_ANDROID) + // Allow this command buffer to be pre-empted by another if a "reasonable" + // amount of work has been done. On highend machines, this reduces the + // latency of GPU commands. However, on Android, this can cause the + // kernel to thrash between generating GPU commands and executing them. + clock_t current_time = clock(); + if (current_time - last_flush_time_ > kFlushDelay * CLOCKS_PER_SEC) + Flush(); +#endif + } } CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { - ++commands_issued_; - if (HaveRingBuffer() && usable() && entries <= SpaceAvailableImmediately()) { - FlushIfNeeded(); - return GetSpaceForEntries(entries); - } - AllocateRingBuffer(); if (!usable()) { return NULL; } DCHECK(HaveRingBuffer()); - if (!WaitForAvailableEntries(entries)) - return NULL; - - return GetSpaceForEntries(entries); + ++commands_issued_; + WaitForAvailableEntries(entries); + CommandBufferEntry* space = &entries_[put_]; + put_ += entries; + DCHECK_LE(put_, total_entry_count_); + if (put_ == total_entry_count_) { + put_ = 0; + } + return space; } } // namespace gpu diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h index 4d334e9..a50dc7b 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper.h +++ b/gpu/command_buffer/client/cmd_buffer_helper.h @@ -72,9 +72,7 @@ class GPU_EXPORT CommandBufferHelper { // Parameters: // count: number of entries needed. This value must be at most // the size of the buffer minus one. - // Returns: - // true on success, false on failure. - bool WaitForAvailableEntries(int32 count); + void WaitForAvailableEntries(int32 count); // Inserts a new token into the command buffer. This token either has a value // different from previously inserted tokens, or ensures that previously @@ -245,43 +243,6 @@ class GPU_EXPORT CommandBufferHelper { bool AllocateRingBuffer(); void FreeResources(); - CommandBufferEntry* GetSpaceForEntries(uint32 entries) { - CommandBufferEntry* space = &entries_[put_]; - put_ += entries; - DCHECK_LE(put_, total_entry_count_); - if (put_ == total_entry_count_) { - put_ = 0; - } - return space; - } - - uint32 SpaceAvailableImmediately() { - return get_offset() > put_ ? get_offset() - put_ - : total_entry_count_ - put_; - } - - void FlushIfNeeded() { - const int kCommandsPerFlushCheck = 100; - const double kFlushDelay = 1.0 / (5.0 * 60.0); - - // Force a flush if the buffer is getting half full, or even earlier if the - // reader is known to be idle. - int32 pending = - (put_ + total_entry_count_ - last_put_sent_) % total_entry_count_; - int32 limit = total_entry_count_ / - ((get_offset() == last_put_sent_) ? 16 : 2); - if (pending > limit) { - Flush(); - } else if (flush_automatically_ && - (commands_issued_ % kCommandsPerFlushCheck == 0)) { - // Allow this command buffer to be pre-empted by another if a "reasonable" - // amount of work has been done. On highend machines, this reduces the - // latency of GPU commands. - clock_t current_time = clock(); - if (current_time - last_flush_time_ > kFlushDelay * CLOCKS_PER_SEC) - Flush(); - } - } CommandBuffer* command_buffer_; int32 ring_buffer_id_; diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc index d92a033..bd0e86e 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc @@ -240,7 +240,7 @@ TEST_F(CommandBufferHelperTest, TestAvailableEntries) { AddCommandWithExpect(error::kNoError, kUnusedCommandId + 4, 2, args); // Ask for 5 entries. - EXPECT_TRUE(helper_->WaitForAvailableEntries(5)); + helper_->WaitForAvailableEntries(5); CommandBufferOffset put = get_helper_put(); CheckFreeSpace(put, 5); @@ -248,7 +248,7 @@ TEST_F(CommandBufferHelperTest, TestAvailableEntries) { // Add more commands. AddCommandWithExpect(error::kNoError, kUnusedCommandId + 5, 2, args); - // Wait until everything is done. + // Wait until everything is done done. helper_->Finish(); // Check that the commands did happen. |