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

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

Issue 12211144: Revert 181883 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 10 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
« no previous file with comments | « gpu/command_buffer/service/query_manager.h ('k') | ui/gl/async_pixel_transfer_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
7 #include "base/atomicops.h" 6 #include "base/atomicops.h"
8 #include "base/bind.h" 7 #include "base/bind.h"
9 #include "base/logging.h" 8 #include "base/logging.h"
10 #include "base/shared_memory.h"
11 #include "base/time.h" 9 #include "base/time.h"
12 #include "gpu/command_buffer/common/gles2_cmd_format.h" 10 #include "gpu/command_buffer/common/gles2_cmd_format.h"
11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
13 #include "gpu/command_buffer/service/feature_info.h" 12 #include "gpu/command_buffer/service/feature_info.h"
14 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
15 #include "ui/gl/async_pixel_transfer_delegate.h" 13 #include "ui/gl/async_pixel_transfer_delegate.h"
16 14
17 namespace gpu { 15 namespace gpu {
18 namespace gles2 { 16 namespace gles2 {
19 17
20 class AllSamplesPassedQuery : public QueryManager::Query { 18 class AllSamplesPassedQuery : public QueryManager::Query {
21 public: 19 public:
22 AllSamplesPassedQuery( 20 AllSamplesPassedQuery(
23 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset, 21 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
24 GLuint service_id); 22 GLuint service_id);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 , public base::SupportsWeakPtr<AsyncPixelTransfersCompletedQuery> { 169 , public base::SupportsWeakPtr<AsyncPixelTransfersCompletedQuery> {
172 public: 170 public:
173 AsyncPixelTransfersCompletedQuery( 171 AsyncPixelTransfersCompletedQuery(
174 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); 172 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
175 173
176 virtual bool Begin() OVERRIDE; 174 virtual bool Begin() OVERRIDE;
177 virtual bool End(uint32 submit_count) OVERRIDE; 175 virtual bool End(uint32 submit_count) OVERRIDE;
178 virtual bool Process() OVERRIDE; 176 virtual bool Process() OVERRIDE;
179 virtual void Destroy(bool have_context) OVERRIDE; 177 virtual void Destroy(bool have_context) OVERRIDE;
180 178
179 void MarkAsCompletedCallback() { MarkAsCompleted(1); }
180
181 protected: 181 protected:
182 virtual ~AsyncPixelTransfersCompletedQuery(); 182 virtual ~AsyncPixelTransfersCompletedQuery();
183
184 static void MarkAsCompletedThreadSafe(
185 uint32 submit_count, const gfx::AsyncMemoryParams& mem_params) {
186 DCHECK(mem_params.shared_memory);
187 DCHECK(mem_params.shared_memory->memory());
188 void *data = static_cast<int8*>(mem_params.shared_memory->memory()) +
189 mem_params.shm_data_offset;
190 QuerySync* sync = static_cast<QuerySync*>(data);
191
192 // No need for a MemoryBarrier here as sync->result is not written.
193 sync->process_count = submit_count;
194 }
195 }; 183 };
196 184
197 AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery( 185 AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery(
198 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) 186 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
199 : Query(manager, target, shm_id, shm_offset) { 187 : Query(manager, target, shm_id, shm_offset) {
200 } 188 }
201 189
202 bool AsyncPixelTransfersCompletedQuery::Begin() { 190 bool AsyncPixelTransfersCompletedQuery::Begin() {
203 return true; 191 return true;
204 } 192 }
205 193
206 bool AsyncPixelTransfersCompletedQuery::End(uint32 submit_count) { 194 bool AsyncPixelTransfersCompletedQuery::End(uint32 submit_count) {
207 gfx::AsyncMemoryParams mem_params; 195 MarkAsPending(submit_count);
208 // Get the real shared memory since it might need to be duped to prevent
209 // use-after-free of the memory.
210 Buffer buffer = manager()->decoder()->GetSharedMemoryBuffer(shm_id());
211 if (!buffer.shared_memory)
212 return false;
213 mem_params.shared_memory = buffer.shared_memory;
214 mem_params.shm_size = buffer.size;
215 mem_params.shm_data_offset = shm_offset();
216 mem_params.shm_data_size = sizeof(QuerySync);
217 196
218 // Ask AsyncPixelTransferDelegate to run completion callback after all 197 // This will call MarkAsCompleted(1) as a reply to a task on
219 // previous async transfers are done. No guarantee that callback is run 198 // the async upload thread, such that it occurs after all previous
220 // on the current thread. 199 // async transfers have completed.
221 manager()->decoder()->GetAsyncPixelTransferDelegate()->AsyncNotifyCompletion( 200 manager()->decoder()->GetAsyncPixelTransferDelegate()->AsyncNotifyCompletion(
222 mem_params, 201 base::Bind(
223 base::Bind(AsyncPixelTransfersCompletedQuery::MarkAsCompletedThreadSafe, 202 &AsyncPixelTransfersCompletedQuery::MarkAsCompletedCallback,
224 submit_count)); 203 AsWeakPtr()));
225 204
226 return AddToPendingTransferQueue(submit_count); 205 // TODO(epenner): The async task occurs outside the normal
206 // flow, via a callback on this thread. Is there anything
207 // missing or wrong with that?
208
209 // TODO(epenner): Could we possibly trigger the completion on
210 // the upload thread by writing to the query shared memory
211 // directly?
212 return true;
227 } 213 }
228 214
229 bool AsyncPixelTransfersCompletedQuery::Process() { 215 bool AsyncPixelTransfersCompletedQuery::Process() {
230 QuerySync* sync = manager()->decoder()->GetSharedMemoryAs<QuerySync*>( 216 NOTREACHED();
231 shm_id(), shm_offset(), sizeof(*sync));
232 if (!sync)
233 return false;
234
235 // Check if completion callback has been run. sync->process_count atomicity
236 // is guaranteed as this is already used to notify client of a completed
237 // query.
238 if (sync->process_count != submit_count())
239 return true;
240
241 UnmarkAsPending();
242 return true; 217 return true;
243 } 218 }
244 219
245 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) { 220 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) {
246 if (!IsDeleted()) { 221 if (!IsDeleted()) {
247 MarkAsDeleted(); 222 MarkAsDeleted();
248 } 223 }
249 } 224 }
250 225
251 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() { 226 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 return true; 428 return true;
454 } 429 }
455 430
456 bool QueryManager::ProcessPendingQueries() { 431 bool QueryManager::ProcessPendingQueries() {
457 while (!pending_queries_.empty()) { 432 while (!pending_queries_.empty()) {
458 Query* query = pending_queries_.front().get(); 433 Query* query = pending_queries_.front().get();
459 if (!query->Process()) { 434 if (!query->Process()) {
460 return false; 435 return false;
461 } 436 }
462 if (query->pending()) { 437 if (query->pending()) {
463 break; 438 return true;
464 } 439 }
465 pending_queries_.pop_front(); 440 pending_queries_.pop_front();
466 } 441 }
467 442
468 return true; 443 return true;
469 } 444 }
470 445
471 bool QueryManager::HavePendingQueries() { 446 bool QueryManager::HavePendingQueries() {
472 return !pending_queries_.empty(); 447 return !pending_queries_.empty();
473 } 448 }
474 449
475 bool QueryManager::ProcessPendingTransferQueries() {
476 while (!pending_transfer_queries_.empty()) {
477 Query* query = pending_transfer_queries_.front().get();
478 if (!query->Process()) {
479 return false;
480 }
481 if (query->pending()) {
482 break;
483 }
484 pending_transfer_queries_.pop_front();
485 }
486
487 return true;
488 }
489
490 bool QueryManager::HavePendingTransferQueries() {
491 return !pending_transfer_queries_.empty();
492 }
493
494 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) { 450 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
495 DCHECK(query); 451 DCHECK(query);
496 DCHECK(!query->IsDeleted()); 452 DCHECK(!query->IsDeleted());
497 if (!RemovePendingQuery(query)) { 453 if (!RemovePendingQuery(query)) {
498 return false; 454 return false;
499 } 455 }
500 query->MarkAsPending(submit_count); 456 query->MarkAsPending(submit_count);
501 pending_queries_.push_back(query); 457 pending_queries_.push_back(query);
502 return true; 458 return true;
503 } 459 }
504 460
505 bool QueryManager::AddPendingTransferQuery(Query* query, uint32 submit_count) {
506 DCHECK(query);
507 DCHECK(!query->IsDeleted());
508 if (!RemovePendingQuery(query)) {
509 return false;
510 }
511 query->MarkAsPending(submit_count);
512 pending_transfer_queries_.push_back(query);
513 return true;
514 }
515
516 bool QueryManager::RemovePendingQuery(Query* query) { 461 bool QueryManager::RemovePendingQuery(Query* query) {
517 DCHECK(query); 462 DCHECK(query);
518 if (query->pending()) { 463 if (query->pending()) {
519 // TODO(gman): Speed this up if this is a common operation. This would only 464 // TODO(gman): Speed this up if this is a common operation. This would only
520 // happen if you do being/end begin/end on the same query without waiting 465 // happen if you do being/end begin/end on the same query without waiting
521 // for the first one to finish. 466 // for the first one to finish.
522 for (QueryQueue::iterator it = pending_queries_.begin(); 467 for (QueryQueue::iterator it = pending_queries_.begin();
523 it != pending_queries_.end(); ++it) { 468 it != pending_queries_.end(); ++it) {
524 if (it->get() == query) { 469 if (it->get() == query) {
525 pending_queries_.erase(it); 470 pending_queries_.erase(it);
526 break; 471 break;
527 } 472 }
528 } 473 }
529 for (QueryQueue::iterator it = pending_transfer_queries_.begin();
530 it != pending_transfer_queries_.end(); ++it) {
531 if (it->get() == query) {
532 pending_transfer_queries_.erase(it);
533 break;
534 }
535 }
536 if (!query->MarkAsCompleted(0)) { 474 if (!query->MarkAsCompleted(0)) {
537 return false; 475 return false;
538 } 476 }
539 } 477 }
540 return true; 478 return true;
541 } 479 }
542 480
543 bool QueryManager::BeginQuery(Query* query) { 481 bool QueryManager::BeginQuery(Query* query) {
544 DCHECK(query); 482 DCHECK(query);
545 if (!RemovePendingQuery(query)) { 483 if (!RemovePendingQuery(query)) {
546 return false; 484 return false;
547 } 485 }
548 return query->Begin(); 486 return query->Begin();
549 } 487 }
550 488
551 bool QueryManager::EndQuery(Query* query, uint32 submit_count) { 489 bool QueryManager::EndQuery(Query* query, uint32 submit_count) {
552 DCHECK(query); 490 DCHECK(query);
553 if (!RemovePendingQuery(query)) { 491 if (!RemovePendingQuery(query)) {
554 return false; 492 return false;
555 } 493 }
556 return query->End(submit_count); 494 return query->End(submit_count);
557 } 495 }
558 496
559 } // namespace gles2 497 } // namespace gles2
560 } // namespace gpu 498 } // namespace gpu
561 499
562 500
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/query_manager.h ('k') | ui/gl/async_pixel_transfer_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698