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

Side by Side Diff: gpu/command_buffer/service/query_manager.cc

Issue 9694025: Add support for GL_COMMANDS_ISSUED_CHROMIUM fence like query. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/query_manager.h" 5 #include "gpu/command_buffer/service/query_manager.h"
6 #include "base/atomicops.h" 6 #include "base/atomicops.h"
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "gpu/command_buffer/common/gles2_cmd_format.h" 8 #include "gpu/command_buffer/common/gles2_cmd_format.h"
9 #include "gpu/command_buffer/service/common_decoder.h" 9 #include "gpu/command_buffer/service/common_decoder.h"
10 10
11 namespace gpu { 11 namespace gpu {
12 namespace gles2 { 12 namespace gles2 {
13 13
14 QueryManager::QueryManager() 14 class AllSamplesPassedQuery : public QueryManager::Query {
15 : query_count_(0) { 15 public:
16 AllSamplesPassedQuery(
17 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
18 GLuint service_id);
19 virtual ~AllSamplesPassedQuery();
20 virtual bool Begin() OVERRIDE;
21 virtual bool End(uint32 submit_count) OVERRIDE;
22 virtual bool Process() OVERRIDE;
23 virtual void Destroy(bool have_context) OVERRIDE;
24
25 // Service side query id.
26 GLuint service_id_;
27 };
28
29 AllSamplesPassedQuery::AllSamplesPassedQuery(
30 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
31 GLuint service_id)
32 : Query(manager, target, shm_id, shm_offset),
33 service_id_(service_id) {
34 }
35
36 AllSamplesPassedQuery::~AllSamplesPassedQuery() {
37 }
38
39 void AllSamplesPassedQuery::Destroy(bool have_context) {
40 if (have_context && !IsDeleted()) {
41 glDeleteQueriesARB(1, &service_id_);
42 MarkAsDeleted();
43 }
44 }
45
46 bool AllSamplesPassedQuery::Begin() {
47 glBeginQueryARB(target(), service_id_);
48 return true;
49 }
50
51 bool AllSamplesPassedQuery::End(uint32 submit_count) {
52 glEndQueryARB(target());
53 return AddToPendingQueue(submit_count);
54 }
55
56 bool AllSamplesPassedQuery::Process() {
57 GLuint available = 0;
58 glGetQueryObjectuivARB(
59 service_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
60 if (!available) {
61 return true;
62 }
63 GLuint result = 0;
64 glGetQueryObjectuivARB(
65 service_id_, GL_QUERY_RESULT_EXT, &result);
66
67 return MarkAsCompleted(result);
68 }
69
70 class CommandsIssuedQuery : public QueryManager::Query {
71 public:
72 CommandsIssuedQuery(
73 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
74 virtual ~CommandsIssuedQuery();
75
76 virtual bool Begin() OVERRIDE;
77 virtual bool End(uint32 submit_count) OVERRIDE;
78 virtual bool Process() OVERRIDE;
79 virtual void Destroy(bool have_context) OVERRIDE;
80 };
81
82 CommandsIssuedQuery::CommandsIssuedQuery(
83 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
84 : Query(manager, target, shm_id, shm_offset) {
85 }
86
87 CommandsIssuedQuery::~CommandsIssuedQuery() {
88 }
89
90 bool CommandsIssuedQuery::Process() {
91 NOTREACHED();
92 return true;
93 }
94
95 bool CommandsIssuedQuery::Begin() {
96 return true;
97 }
98
99 bool CommandsIssuedQuery::End(uint32 submit_count) {
100 MarkAsPending(submit_count);
101 return MarkAsCompleted(1);
102 }
103
104 void CommandsIssuedQuery::Destroy(bool /* have_context */) {
105 if (!IsDeleted()) {
106 MarkAsDeleted();
107 }
108 }
109
110 QueryManager::QueryManager(CommonDecoder* decoder)
111 : decoder_(decoder),
112 query_count_(0) {
16 } 113 }
17 114
18 QueryManager::~QueryManager() { 115 QueryManager::~QueryManager() {
19 DCHECK(queries_.empty()); 116 DCHECK(queries_.empty());
20 117
21 // If this triggers, that means something is keeping a reference to 118 // If this triggers, that means something is keeping a reference to
22 // a Query belonging to this. 119 // a Query belonging to this.
23 CHECK_EQ(query_count_, 0u); 120 CHECK_EQ(query_count_, 0u);
24 } 121 }
25 122
26 void QueryManager::Destroy(bool have_context) { 123 void QueryManager::Destroy(bool have_context) {
27 pending_queries_.clear(); 124 pending_queries_.clear();
28 while (!queries_.empty()) { 125 while (!queries_.empty()) {
29 Query* query = queries_.begin()->second; 126 Query* query = queries_.begin()->second;
30 if (have_context) { 127 query->Destroy(have_context);
31 if (!query->IsDeleted()) {
32 GLuint service_id = query->service_id();
33 glDeleteQueriesARB(1, &service_id);
34 query->MarkAsDeleted();
35 }
36 }
37 queries_.erase(queries_.begin()); 128 queries_.erase(queries_.begin());
38 } 129 }
39 } 130 }
40 131
41 QueryManager::Query* QueryManager::CreateQuery( 132 QueryManager::Query* QueryManager::CreateQuery(
42 GLuint client_id, 133 GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset) {
43 GLuint service_id) { 134 Query::Ref query;
44 Query::Ref query(new Query(this, service_id)); 135 switch (target) {
136 case GL_COMMANDS_ISSUED_CHROMIUM:
137 query = new CommandsIssuedQuery(this, target, shm_id, shm_offset);
138 break;
139 default: {
140 GLuint service_id = 0;
141 glGenQueriesARB(1, &service_id);
142 DCHECK_NE(0u, service_id);
143 query = new AllSamplesPassedQuery(
144 this, target, shm_id, shm_offset, service_id);
145 break;
146 }
147 }
45 std::pair<QueryMap::iterator, bool> result = 148 std::pair<QueryMap::iterator, bool> result =
46 queries_.insert(std::make_pair(client_id, query)); 149 queries_.insert(std::make_pair(client_id, query));
47 DCHECK(result.second); 150 DCHECK(result.second);
48 return query.get(); 151 return query.get();
49 } 152 }
50 153
51 QueryManager::Query* QueryManager::GetQuery( 154 QueryManager::Query* QueryManager::GetQuery(
52 GLuint client_id) { 155 GLuint client_id) {
53 QueryMap::iterator it = queries_.find(client_id); 156 QueryMap::iterator it = queries_.find(client_id);
54 return it != queries_.end() ? it->second : NULL; 157 return it != queries_.end() ? it->second : NULL;
(...skipping 11 matching lines...) Expand all
66 169
67 void QueryManager::StartTracking(QueryManager::Query* /* query */) { 170 void QueryManager::StartTracking(QueryManager::Query* /* query */) {
68 ++query_count_; 171 ++query_count_;
69 } 172 }
70 173
71 void QueryManager::StopTracking(QueryManager::Query* /* query */) { 174 void QueryManager::StopTracking(QueryManager::Query* /* query */) {
72 --query_count_; 175 --query_count_;
73 } 176 }
74 177
75 QueryManager::Query::Query( 178 QueryManager::Query::Query(
76 QueryManager* manager, 179 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
77 GLuint service_id)
78 : manager_(manager), 180 : manager_(manager),
79 service_id_(service_id), 181 target_(target),
80 target_(0), 182 shm_id_(shm_id),
81 shm_id_(0), 183 shm_offset_(shm_offset),
82 shm_offset_(0), 184 pending_(false),
83 pending_(false) { 185 deleted_(false) {
84 DCHECK(manager); 186 DCHECK(manager);
85 manager_->StartTracking(this); 187 manager_->StartTracking(this);
86 } 188 }
87 189
88 QueryManager::Query::~Query() { 190 QueryManager::Query::~Query() {
89 if (manager_) { 191 if (manager_) {
90 manager_->StopTracking(this); 192 manager_->StopTracking(this);
91 manager_ = NULL; 193 manager_ = NULL;
92 } 194 }
93 } 195 }
94 196
95 void QueryManager::Query::Initialize( 197 bool QueryManager::Query::MarkAsCompleted(GLuint result) {
96 GLenum target, int32 shm_id, uint32 shm_offset) { 198 DCHECK(pending_);
97 DCHECK(!IsInitialized()); 199 QuerySync* sync = manager_->decoder_->GetSharedMemoryAs<QuerySync*>(
98 target_ = target; 200 shm_id_, shm_offset_, sizeof(*sync));
99 shm_id_ = shm_id; 201 if (!sync) {
100 shm_offset_ = shm_offset; 202 return false;
203 }
204
205 pending_ = false;
206 sync->result = result;
207 // Need a MemoryBarrier here so that sync->result is written before
208 // sync->process_count.
209 base::subtle::MemoryBarrier();
210 sync->process_count = submit_count_;
211
212 return true;
101 } 213 }
102 214
103 bool QueryManager::GetClientId(GLuint service_id, GLuint* client_id) const { 215 bool QueryManager::ProcessPendingQueries() {
104 DCHECK(client_id); 216 while (!pending_queries_.empty()) {
105 // This doesn't need to be fast. It's only used during slow queries. 217 Query* query = pending_queries_.front().get();
106 for (QueryMap::const_iterator it = queries_.begin(); 218 if (!query->Process()) {
107 it != queries_.end(); ++it) { 219 return false;
108 if (it->second->service_id() == service_id) { 220 }
109 *client_id = it->first; 221 if (query->pending()) {
110 return true; 222 return true;
111 } 223 }
112 }
113 return false;
114 }
115
116 bool QueryManager::ProcessPendingQueries(CommonDecoder* decoder) {
117 DCHECK(decoder);
118 while (!pending_queries_.empty()) {
119 Query* query = pending_queries_.front().get();
120 GLuint available = 0;
121 glGetQueryObjectuivARB(
122 query->service_id(), GL_QUERY_RESULT_AVAILABLE_EXT, &available);
123 if (!available) {
124 return true;
125 }
126 GLuint result = 0;
127 glGetQueryObjectuivARB(
128 query->service_id(), GL_QUERY_RESULT_EXT, &result);
129 QuerySync* sync = decoder->GetSharedMemoryAs<QuerySync*>(
130 query->shm_id(), query->shm_offset(), sizeof(*sync));
131 if (!sync) {
132 return false;
133 }
134
135 sync->result = result;
136 // Need a MemoryBarrier here so that sync->result is written before
137 // sync->process_count.
138 base::subtle::MemoryBarrier();
139 sync->process_count = query->submit_count();
140
141 query->MarkAsCompleted();
142 pending_queries_.pop_front(); 224 pending_queries_.pop_front();
143 } 225 }
144 226
145 return true; 227 return true;
146 } 228 }
147 229
148 void QueryManager::AddPendingQuery(Query* query, uint32 submit_count) { 230 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
149 DCHECK(query); 231 DCHECK(query);
150 DCHECK(query->IsInitialized());
151 DCHECK(!query->IsDeleted()); 232 DCHECK(!query->IsDeleted());
152 RemovePendingQuery(query); 233 if (!RemovePendingQuery(query)) {
234 return false;
235 }
153 query->MarkAsPending(submit_count); 236 query->MarkAsPending(submit_count);
154 pending_queries_.push_back(query); 237 pending_queries_.push_back(query);
238 return true;
155 } 239 }
156 240
157 void QueryManager::RemovePendingQuery(Query* query) { 241 bool QueryManager::RemovePendingQuery(Query* query) {
158 DCHECK(query); 242 DCHECK(query);
159 if (query->pending()) { 243 if (query->pending()) {
160 // TODO(gman): Speed this up if this is a common operation. This would only 244 // TODO(gman): Speed this up if this is a common operation. This would only
161 // happen if you do being/end begin/end on the same query without waiting 245 // happen if you do being/end begin/end on the same query without waiting
162 // for the first one to finish. 246 // for the first one to finish.
163 for (QueryQueue::iterator it = pending_queries_.begin(); 247 for (QueryQueue::iterator it = pending_queries_.begin();
164 it != pending_queries_.end(); ++it) { 248 it != pending_queries_.end(); ++it) {
165 if (it->get() == query) { 249 if (it->get() == query) {
166 pending_queries_.erase(it); 250 pending_queries_.erase(it);
167 break; 251 break;
168 } 252 }
169 } 253 }
170 query->MarkAsCompleted(); 254 if (!query->MarkAsCompleted(0)) {
255 return false;
256 }
171 } 257 }
258 return true;
259 }
260
261 bool QueryManager::BeginQuery(Query* query) {
262 DCHECK(query);
263 if (!RemovePendingQuery(query)) {
264 return false;
265 }
266 return query->Begin();
267 }
268
269 bool QueryManager::EndQuery(Query* query, uint32 submit_count) {
270 DCHECK(query);
271 if (!RemovePendingQuery(query)) {
272 return false;
273 }
274 return query->End(submit_count);
172 } 275 }
173 276
174 } // namespace gles2 277 } // namespace gles2
175 } // namespace gpu 278 } // namespace gpu
176 279
177 280
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698