Index: gpu/command_buffer/client/gl_in_process_context.cc |
diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc |
index 7e17929ab8fd431f2e5b6b281cb531fb67a5644e..f465915d21a76cc0d30ac650e13d5e739571938b 100644 |
--- a/gpu/command_buffer/client/gl_in_process_context.cc |
+++ b/gpu/command_buffer/client/gl_in_process_context.cc |
@@ -4,6 +4,7 @@ |
#include "gpu/command_buffer/client/gl_in_process_context.h" |
+#include <deque> |
#include <utility> |
#include <vector> |
@@ -123,7 +124,6 @@ class GLInProcessContextImpl |
void Destroy(); |
bool IsCommandBufferContextLost(); |
void PollQueryCallbacks(); |
- void CallQueryCallback(size_t index); |
gles2::ImageManager* GetImageManager(); |
@@ -143,7 +143,7 @@ class GLInProcessContextImpl |
bool context_lost_; |
typedef std::pair<unsigned, base::Closure> QueryCallback; |
- std::vector<QueryCallback> query_callbacks_; |
+ std::deque<QueryCallback> query_callbacks_; |
DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl); |
}; |
@@ -504,9 +504,12 @@ bool GLInProcessContextImpl::Initialize( |
void GLInProcessContextImpl::Destroy() { |
while (!query_callbacks_.empty()) { |
- CallQueryCallback(0); |
+ base::Closure query_callback = query_callbacks_.back().second; |
+ query_callbacks_.pop_back(); |
+ query_callback.Run(); |
} |
+ |
bool context_lost = IsCommandBufferContextLost(); |
if (gles2_implementation_) { |
@@ -547,16 +550,19 @@ void GLInProcessContextImpl::OnContextLost() { |
} |
} |
-void GLInProcessContextImpl::CallQueryCallback(size_t index) { |
- DCHECK_LT(index, query_callbacks_.size()); |
- QueryCallback query_callback = query_callbacks_[index]; |
- query_callbacks_[index] = query_callbacks_.back(); |
- query_callbacks_.pop_back(); |
- query_callback.second.Run(); |
-} |
- |
void GLInProcessContextImpl::PollQueryCallbacks() { |
- for (size_t i = 0; i < query_callbacks_.size();) { |
+ // Queries are put on to to the query_callback_ deque from the FRONT. |
+ // This means that if there are several queries of the same type in |
+ // the queue, and we find that one of them has finished, the rest |
+ // of them should be finished too. We want to make sure that |
piman
2013/06/28 23:35:46
That's not true though.
An async texture upload do
hubbe
2013/06/29 00:13:56
Async readpixels (and maybe other queries) *do* fi
|
+ // a) Query callbacks are called in the right order |
+ // b) query_callbacks_ is in a good state when we call the callbacks |
+ // To do that we pul out the queries that have completed and put them |
+ // in a separate container in reversed order, then we compress |
+ // query_callbacks_ and before invoking the callbacks. |
+ std::deque<QueryCallback> to_call; |
+ size_t queries_left = 0; |
+ for (size_t i = 0; i < query_callbacks_.size(); i++) { |
unsigned query = query_callbacks_[i].first; |
GLuint param = 0; |
gles2::GLES2Implementation* gl = GetImplementation(); |
@@ -566,11 +572,16 @@ void GLInProcessContextImpl::PollQueryCallbacks() { |
param = 1; |
} |
if (param) { |
- CallQueryCallback(i); |
+ to_call.push_front(query_callbacks_[i]); |
} else { |
- i++; |
+ query_callbacks_[queries_left++] = query_callbacks_[i]; |
} |
} |
+ query_callbacks_.resize(queries_left); |
+ for (size_t i = 0; i < to_call.size(); i++) { |
+ to_call[i].second.Run(); |
+ } |
+ |
if (!query_callbacks_.empty()) { |
base::MessageLoop::current()->PostDelayedTask( |
FROM_HERE, |
@@ -583,7 +594,7 @@ void GLInProcessContextImpl::PollQueryCallbacks() { |
void GLInProcessContextImpl::SignalQuery( |
unsigned query, |
const base::Closure& callback) { |
- query_callbacks_.push_back(std::make_pair(query, callback)); |
+ query_callbacks_.push_front(std::make_pair(query, callback)); |
// If size > 1, there is already a poll callback pending. |
if (query_callbacks_.size() == 1) { |
PollQueryCallbacks(); |