Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Unified Diff: cc/raster/staging_buffer_pool.cc

Issue 2446523002: cc: Use CHROMIUM_copy_image for one-copy tile updates.
Patch Set: rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/raster/staging_buffer_pool.cc
diff --git a/cc/raster/staging_buffer_pool.cc b/cc/raster/staging_buffer_pool.cc
index 0e2a88a14a7f84fa26e17b42c8e320c702438eca..7453d4f9a1882cf39de7a97221367124a480b3fb 100644
--- a/cc/raster/staging_buffer_pool.cc
+++ b/cc/raster/staging_buffer_pool.cc
@@ -15,76 +15,51 @@
#include "cc/debug/traced_value.h"
#include "cc/resources/scoped_resource.h"
#include "gpu/command_buffer/client/gles2_interface.h"
+#include "ui/gfx/gpu_fence.h"
#include "ui/gfx/gpu_memory_buffer_tracing.h"
namespace cc {
namespace {
-// Delay between checking for query result to be available.
-const int kCheckForQueryResultAvailableTickRateMs = 1;
-
-// Number of attempts to allow before we perform a check that will wait for
-// query to complete.
-const int kMaxCheckForQueryResultAvailableAttempts = 256;
+// Maximum amount of time to wait for fence before we call glFinish().
+const int kWaitForFenceMaxTimeMs = 256;
// Delay before a staging buffer might be released.
const int kStagingBufferExpirationDelayMs = 1000;
-bool CheckForQueryResult(gpu::gles2::GLES2Interface* gl, unsigned query_id) {
- unsigned complete = 1;
- gl->GetQueryObjectuivEXT(query_id, GL_QUERY_RESULT_AVAILABLE_EXT, &complete);
- return !!complete;
-}
-
-void WaitForQueryResult(gpu::gles2::GLES2Interface* gl, unsigned query_id) {
- TRACE_EVENT0("cc", "WaitForQueryResult");
-
- int attempts_left = kMaxCheckForQueryResultAvailableAttempts;
- while (attempts_left--) {
- if (CheckForQueryResult(gl, query_id))
- break;
-
- // We have to flush the context to be guaranteed that a query result will
- // be available in a finite amount of time.
- gl->ShallowFlushCHROMIUM();
+bool WaitForGpuFence(gfx::GpuFence* gpu_fence) {
+ TRACE_EVENT0("cc", "WaitForGpuFence");
- base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(
- kCheckForQueryResultAvailableTickRateMs));
+ base::TimeTicks now = base::TimeTicks::Now();
+ base::TimeTicks end =
+ now + base::TimeDelta::FromMilliseconds(kWaitForFenceMaxTimeMs);
+ while (now < end) {
+ if (gpu_fence->Wait(end - now))
ericrk 2017/01/10 03:50:31 nit: I understand that things like this sometimes
reveman 2017/01/10 19:37:55 That was my initial approach but I decided it was
+ return true;
+ now = base::TimeTicks::Now();
}
-
- unsigned result = 0;
- gl->GetQueryObjectuivEXT(query_id, GL_QUERY_RESULT_EXT, &result);
+ return false;
}
} // namespace
StagingBuffer::StagingBuffer(const gfx::Size& size, ResourceFormat format)
- : size(size),
- format(format),
- texture_id(0),
- image_id(0),
- query_id(0),
- content_id(0) {}
+ : size(size), format(format), image_id(0), fence_id(0), content_id(0) {}
StagingBuffer::~StagingBuffer() {
- DCHECK_EQ(texture_id, 0u);
DCHECK_EQ(image_id, 0u);
- DCHECK_EQ(query_id, 0u);
+ DCHECK_EQ(fence_id, 0u);
}
void StagingBuffer::DestroyGLResources(gpu::gles2::GLES2Interface* gl) {
- if (query_id) {
- gl->DeleteQueriesEXT(1, &query_id);
- query_id = 0;
+ if (fence_id) {
+ gl->DestroyFenceCHROMIUM(fence_id);
+ fence_id = 0;
}
if (image_id) {
gl->DestroyImageCHROMIUM(image_id);
image_id = 0;
}
- if (texture_id) {
- gl->DeleteTextures(1, &texture_id);
- texture_id = 0;
- }
}
void StagingBuffer::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
@@ -249,22 +224,18 @@ std::unique_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer(
std::unique_ptr<StagingBuffer> staging_buffer;
- ContextProvider::ScopedContextLock scoped_context(worker_context_provider_);
-
- gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL();
- DCHECK(gl);
-
// Check if any busy buffers have become available.
- if (resource_provider_->use_sync_query()) {
- while (!busy_buffers_.empty()) {
- if (!CheckForQueryResult(gl, busy_buffers_.front()->query_id))
- break;
+ while (!busy_buffers_.empty()) {
+ if (!busy_buffers_.front()->gpu_fence->IsSignaled())
+ break;
- MarkStagingBufferAsFree(busy_buffers_.front().get());
- free_buffers_.push_back(PopFront(&busy_buffers_));
- }
+ busy_buffers_.front()->gpu_fence->Reset();
+ MarkStagingBufferAsFree(busy_buffers_.front().get());
+ free_buffers_.push_back(PopFront(&busy_buffers_));
}
+ bool flushed = false;
+
// Wait for memory usage of non-free buffers to become less than the limit.
while (
(staging_buffer_usage_in_bytes_ - free_staging_buffer_usage_in_bytes_) >=
@@ -273,14 +244,33 @@ std::unique_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer(
if (busy_buffers_.empty())
break;
- if (resource_provider_->use_sync_query()) {
- WaitForQueryResult(gl, busy_buffers_.front()->query_id);
+ if (!flushed) {
+ ContextProvider::ScopedContextLock scoped_context(
+ worker_context_provider_);
+ gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL();
+ DCHECK(gl);
+
+ // We have to flush the context to be guaranteed that fence will signel in
+ // a finite amount of time.
+ gl->ShallowFlushCHROMIUM();
+ flushed = true;
+ }
+
+ if (WaitForGpuFence(busy_buffers_.front()->gpu_fence.get())) {
+ busy_buffers_.front()->gpu_fence->Reset();
MarkStagingBufferAsFree(busy_buffers_.front().get());
free_buffers_.push_back(PopFront(&busy_buffers_));
} else {
- // Fall-back to glFinish if CHROMIUM_sync_query is not available.
+ ContextProvider::ScopedContextLock scoped_context(
+ worker_context_provider_);
+ gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL();
+ DCHECK(gl);
+
+ // glFinish() should result in the fence signaling or the context is lost
+ // and fence will never signal.
gl->Finish();
while (!busy_buffers_.empty()) {
+ busy_buffers_.front()->gpu_fence->Reset();
MarkStagingBufferAsFree(busy_buffers_.front().get());
free_buffers_.push_back(PopFront(&busy_buffers_));
}
@@ -329,7 +319,15 @@ std::unique_ptr<StagingBuffer> StagingBufferPool::AcquireStagingBuffer(
if (free_buffers_.empty())
break;
- free_buffers_.front()->DestroyGLResources(gl);
+ {
+ ContextProvider::ScopedContextLock scoped_context(
ericrk 2017/01/10 03:50:31 not sure what the overhead of locking/re-locking,
reveman 2017/01/10 19:37:55 Makes sense. I'll address this as I rebase this pa
+ worker_context_provider_);
+ gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL();
+ DCHECK(gl);
+
+ free_buffers_.front()->DestroyGLResources(gl);
+ }
+
MarkStagingBufferAsBusy(free_buffers_.front().get());
RemoveStagingBuffer(free_buffers_.front().get());
free_buffers_.pop_front();

Powered by Google App Engine
This is Rietveld 408576698