Index: gpu/command_buffer/client/gles2_implementation.cc |
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc |
index 2d02579b116672e26da92edc5e66c7dcc6ae56b8..80e9ee00072df743d0bab3660e5fe96c8c492876 100644 |
--- a/gpu/command_buffer/client/gles2_implementation.cc |
+++ b/gpu/command_buffer/client/gles2_implementation.cc |
@@ -1378,11 +1378,8 @@ void GLES2Implementation::BufferDataHelper( |
BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
if (buffer) { |
- // Free buffer memory, pending the passage of a token. |
- buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
- |
- // Remove old buffer. |
- buffer_tracker_->RemoveBuffer(buffer_id); |
+ FreeTransferBuffer(buffer); |
piman
2014/01/16 21:22:50
How does synchronization work wrt asynchronous Rea
jadahl
2014/01/17 08:50:25
Hmm. Good point. Reading how readpixels is impleme
|
+ buffer_tracker_->RemoveBuffer(buffer->id()); |
} |
// Create new buffer. |
@@ -1511,6 +1508,24 @@ void GLES2Implementation::BufferSubData( |
CheckGLError(); |
} |
+void GLES2Implementation::FreeTransferBuffer(BufferTracker::Buffer* buffer) { |
+ int32 token = buffer->last_usage_token(); |
+ |
+ if (buffer->async_query_id()) { |
+ QueryTracker::Query* query = |
+ query_tracker_->GetQuery(buffer->async_query_id()); |
+ if (!query->CheckResultsAvailable(helper_)) |
+ buffer_tracker_->FreePendingSerial(buffer, query->serial()); |
+ else |
+ buffer_tracker_->Free(buffer); |
+ } else if (token) { |
+ if (helper_->HasTokenPassed(token)) |
+ buffer_tracker_->Free(buffer); |
+ else |
+ buffer_tracker_->FreePendingToken(buffer, token); |
+ } |
+} |
+ |
bool GLES2Implementation::GetBoundPixelTransferBuffer( |
GLenum target, |
const char* function_name, |
@@ -1586,7 +1601,7 @@ void GLES2Implementation::CompressedTexImage2D( |
helper_->CompressedTexImage2D( |
target, level, internalformat, width, height, border, image_size, |
buffer->shm_id(), buffer->shm_offset() + offset); |
- buffer->set_transfer_ready_token(helper_->InsertToken()); |
+ MarkPixelTransferBufferLastUsage(buffer); |
} |
return; |
} |
@@ -1627,7 +1642,7 @@ void GLES2Implementation::CompressedTexSubImage2D( |
helper_->CompressedTexSubImage2D( |
target, level, xoffset, yoffset, width, height, format, image_size, |
buffer->shm_id(), buffer->shm_offset() + offset); |
- buffer->set_transfer_ready_token(helper_->InsertToken()); |
+ MarkPixelTransferBufferLastUsage(buffer); |
CheckGLError(); |
} |
return; |
@@ -1714,7 +1729,7 @@ void GLES2Implementation::TexImage2D( |
helper_->TexImage2D( |
target, level, internalformat, width, height, border, format, type, |
buffer->shm_id(), buffer->shm_offset() + offset); |
- buffer->set_transfer_ready_token(helper_->InsertToken()); |
+ MarkPixelTransferBufferLastUsage(buffer); |
CheckGLError(); |
} |
return; |
@@ -1820,7 +1835,7 @@ void GLES2Implementation::TexSubImage2D( |
helper_->TexSubImage2D( |
target, level, xoffset, yoffset, width, height, format, type, |
buffer->shm_id(), buffer->shm_offset() + offset, false); |
- buffer->set_transfer_ready_token(helper_->InsertToken()); |
+ MarkPixelTransferBufferLastUsage(buffer); |
CheckGLError(); |
} |
return; |
@@ -2403,24 +2418,24 @@ void GLES2Implementation::GenQueriesEXTHelper( |
// deleted the resource. |
bool GLES2Implementation::BindBufferHelper( |
- GLenum target, GLuint buffer) { |
+ GLenum target, GLuint buffer_id) { |
// TODO(gman): See note #1 above. |
bool changed = false; |
switch (target) { |
case GL_ARRAY_BUFFER: |
- if (bound_array_buffer_id_ != buffer) { |
- bound_array_buffer_id_ = buffer; |
+ if (bound_array_buffer_id_ != buffer_id) { |
+ bound_array_buffer_id_ = buffer_id; |
changed = true; |
} |
break; |
case GL_ELEMENT_ARRAY_BUFFER: |
- changed = vertex_array_object_manager_->BindElementArray(buffer); |
+ changed = vertex_array_object_manager_->BindElementArray(buffer_id); |
break; |
case GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM: |
- bound_pixel_pack_transfer_buffer_id_ = buffer; |
+ bound_pixel_pack_transfer_buffer_id_ = buffer_id; |
break; |
case GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM: |
- bound_pixel_unpack_transfer_buffer_id_ = buffer; |
+ bound_pixel_unpack_transfer_buffer_id_ = buffer_id; |
break; |
default: |
changed = true; |
@@ -2428,7 +2443,7 @@ bool GLES2Implementation::BindBufferHelper( |
} |
// TODO(gman): There's a bug here. If the target is invalid the ID will not be |
// used even though it's marked it as used here. |
- GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer); |
+ GetIdHandler(id_namespaces::kBuffers)->MarkAsUsedForBind(buffer_id); |
return changed; |
} |
@@ -2562,13 +2577,13 @@ void GLES2Implementation::DeleteBuffersHelper( |
bound_array_buffer_id_ = 0; |
} |
vertex_array_object_manager_->UnbindBuffer(buffers[ii]); |
+ |
BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffers[ii]); |
if (buffer) { |
- // Free buffer memory, pending the passage of a token. |
- buffer_tracker_->FreePendingToken(buffer, helper_->InsertToken()); |
- // Remove buffer. |
- buffer_tracker_->RemoveBuffer(buffers[ii]); |
+ FreeTransferBuffer(buffer); |
+ buffer_tracker_->RemoveBuffer(buffer->id()); |
} |
+ |
if (buffers[ii] == bound_pixel_unpack_transfer_buffer_id_) { |
bound_pixel_unpack_transfer_buffer_id_ = 0; |
} |
@@ -3288,8 +3303,10 @@ void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) { |
<< GLES2Util::GetStringQueryTarget(target) |
<< ", " << id << ")"); |
+ QueryKey key = std::make_pair(target, false); |
+ |
// if any outstanding queries INV_OP |
- QueryMap::iterator it = current_queries_.find(target); |
+ QueryMap::iterator it = current_queries_.find(key); |
if (it != current_queries_.end()) { |
SetGLError( |
GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); |
@@ -3318,7 +3335,7 @@ void GLES2Implementation::BeginQueryEXT(GLenum target, GLuint id) { |
return; |
} |
- current_queries_[target] = query; |
+ current_queries_[key] = query; |
query->Begin(this); |
CheckGLError(); |
@@ -3333,7 +3350,8 @@ void GLES2Implementation::EndQueryEXT(GLenum target) { |
return; |
} |
- QueryMap::iterator it = current_queries_.find(target); |
+ QueryKey key = std::make_pair(target, false); |
+ QueryMap::iterator it = current_queries_.find(key); |
if (it == current_queries_.end()) { |
SetGLError(GL_INVALID_OPERATION, "glEndQueryEXT", "no active query"); |
return; |
@@ -3357,7 +3375,8 @@ void GLES2Implementation::GetQueryivEXT( |
SetGLErrorInvalidEnum("glGetQueryivEXT", pname, "pname"); |
return; |
} |
- QueryMap::iterator it = current_queries_.find(target); |
+ QueryKey key = std::make_pair(target, false); |
+ QueryMap::iterator it = current_queries_.find(key); |
if (it != current_queries_.end()) { |
QueryTracker::Query* query = it->second; |
*params = query->id(); |
@@ -3381,7 +3400,8 @@ void GLES2Implementation::GetQueryObjectuivEXT( |
return; |
} |
- QueryMap::iterator it = current_queries_.find(query->target()); |
+ QueryKey key = std::make_pair(query->target(), false); |
+ QueryMap::iterator it = current_queries_.find(key); |
if (it != current_queries_.end()) { |
SetGLError( |
GL_INVALID_OPERATION, |
@@ -3611,9 +3631,9 @@ void* GLES2Implementation::MapBufferCHROMIUM(GLuint target, GLenum access) { |
// with this method of synchronization. Until this is fixed, |
// MapBufferCHROMIUM will not block even if the transfer is not ready |
// for these calls. |
- if (buffer->transfer_ready_token()) { |
- helper_->WaitForToken(buffer->transfer_ready_token()); |
- buffer->set_transfer_ready_token(0); |
+ if (buffer->last_usage_token()) { |
+ helper_->WaitForToken(buffer->last_usage_token()); |
+ buffer->set_last_usage_token(0); |
} |
buffer->set_mapped(true); |
@@ -3647,6 +3667,45 @@ GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { |
return true; |
} |
+void GLES2Implementation::BeginInternalQueryAsyncPixelUnpackCompleted( |
+ BufferTracker::Buffer *buffer) { |
+ QueryKey key = std::make_pair(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, true); |
+ |
+ DCHECK(current_queries_.find(key) == current_queries_.end()); |
+ |
+ GLuint id; |
+ GetIdHandler(id_namespaces::kQueries)->MakeIds(this, 0, 1, &id); |
+ QueryTracker::Query* query = query_tracker_->CreateInternalQuery( |
+ id, GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM); |
+ if (!query) { |
+ MustBeContextLost(); |
+ return; |
+ } |
+ |
+ buffer->set_async_query_id(id); |
+ query->Begin(this); |
+ CheckGLError(); |
+ |
+ current_queries_[key] = query; |
+} |
+ |
+void GLES2Implementation::EndInternalQueryAsyncPixelUnpackCompleted() { |
+ QueryKey key = std::make_pair(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, true); |
+ |
+ DCHECK(current_queries_.find(key) != current_queries_.end()); |
+ |
+ QueryMap::iterator it = current_queries_.find(key); |
+ QueryTracker::Query* query = it->second; |
+ query->End(this); |
+ current_queries_.erase(it); |
+ CheckGLError(); |
+} |
+ |
+void GLES2Implementation::MarkPixelTransferBufferLastUsage( |
+ BufferTracker::Buffer* buffer) { |
+ buffer->set_last_usage_token(helper_->InsertToken()); |
+} |
+ |
void GLES2Implementation::AsyncTexImage2DCHROMIUM( |
GLenum target, GLint level, GLint internalformat, GLsizei width, |
GLsizei height, GLint border, GLenum format, GLenum type, |
@@ -3691,9 +3750,11 @@ void GLES2Implementation::AsyncTexImage2DCHROMIUM( |
bound_pixel_unpack_transfer_buffer_id_, |
"glAsyncTexImage2DCHROMIUM", offset, size); |
if (buffer && buffer->shm_id() != -1) { |
+ BeginInternalQueryAsyncPixelUnpackCompleted(buffer); |
helper_->AsyncTexImage2DCHROMIUM( |
target, level, internalformat, width, height, border, format, type, |
buffer->shm_id(), buffer->shm_offset() + offset); |
+ EndInternalQueryAsyncPixelUnpackCompleted(); |
} |
} |
@@ -3735,9 +3796,11 @@ void GLES2Implementation::AsyncTexSubImage2DCHROMIUM( |
bound_pixel_unpack_transfer_buffer_id_, |
"glAsyncTexSubImage2DCHROMIUM", offset, size); |
if (buffer && buffer->shm_id() != -1) { |
+ BeginInternalQueryAsyncPixelUnpackCompleted(buffer); |
helper_->AsyncTexSubImage2DCHROMIUM( |
target, level, xoffset, yoffset, width, height, format, type, |
buffer->shm_id(), buffer->shm_offset() + offset); |
+ EndInternalQueryAsyncPixelUnpackCompleted(); |
} |
} |