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

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

Issue 12213073: Re-land: Mark async texture uploads as completed from the upload thread. (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
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/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "gpu/command_buffer/common/gles2_cmd_format.h" 10 #include "gpu/command_buffer/common/gles2_cmd_format.h"
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 , public base::SupportsWeakPtr<AsyncPixelTransfersCompletedQuery> { 169 , public base::SupportsWeakPtr<AsyncPixelTransfersCompletedQuery> {
170 public: 170 public:
171 AsyncPixelTransfersCompletedQuery( 171 AsyncPixelTransfersCompletedQuery(
172 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); 172 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
173 173
174 virtual bool Begin() OVERRIDE; 174 virtual bool Begin() OVERRIDE;
175 virtual bool End(uint32 submit_count) OVERRIDE; 175 virtual bool End(uint32 submit_count) OVERRIDE;
176 virtual bool Process() OVERRIDE; 176 virtual bool Process() OVERRIDE;
177 virtual void Destroy(bool have_context) OVERRIDE; 177 virtual void Destroy(bool have_context) OVERRIDE;
178 178
179 void MarkAsCompletedCallback() { MarkAsCompleted(1); }
180
181 protected: 179 protected:
182 virtual ~AsyncPixelTransfersCompletedQuery(); 180 virtual ~AsyncPixelTransfersCompletedQuery();
183 }; 181 };
184 182
185 AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery( 183 AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery(
186 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) 184 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
187 : Query(manager, target, shm_id, shm_offset) { 185 : Query(manager, target, shm_id, shm_offset) {
188 } 186 }
189 187
190 bool AsyncPixelTransfersCompletedQuery::Begin() { 188 bool AsyncPixelTransfersCompletedQuery::Begin() {
191 return true; 189 return true;
192 } 190 }
193 191
194 bool AsyncPixelTransfersCompletedQuery::End(uint32 submit_count) { 192 bool AsyncPixelTransfersCompletedQuery::End(uint32 submit_count) {
195 MarkAsPending(submit_count); 193 gfx::AsyncMemoryParams mem_params;
194 // Get the real shared memory since it might need to be duped to prevent
195 // use-after-free of the memory.
196 Buffer buffer = manager()->decoder()->GetSharedMemoryBuffer(shm_id());
197 mem_params.shared_memory = buffer.shared_memory;
198 mem_params.shm_size = buffer.size;
199 mem_params.shm_data_offset = shm_offset();
200 mem_params.shm_data_size = sizeof(QuerySync);
epenner 2013/02/07 20:22:56 I was in debate of whether we needed to do this in
reveman 2013/02/07 21:30:52 I think the safe way to do this for now is duplica
196 201
197 // This will call MarkAsCompleted(1) as a reply to a task on 202 // This tells AsyncPixelTransferDelegate to mark QuerySync as completed
198 // the async upload thread, such that it occurs after all previous 203 // after all previous async transfers are done.
199 // async transfers have completed.
200 manager()->decoder()->GetAsyncPixelTransferDelegate()->AsyncNotifyCompletion( 204 manager()->decoder()->GetAsyncPixelTransferDelegate()->AsyncNotifyCompletion(
epenner 2013/02/07 20:22:56 I think to avoid the layering violation, we could
reveman 2013/02/07 21:30:52 yea, sounds like that might be a pretty clean solu
201 base::Bind( 205 mem_params, submit_count);
202 &AsyncPixelTransfersCompletedQuery::MarkAsCompletedCallback,
203 AsWeakPtr()));
204 206
205 // TODO(epenner): The async task occurs outside the normal 207 return AddToPendingTransferQueue(submit_count);
206 // flow, via a callback on this thread. Is there anything 208 }
207 // missing or wrong with that?
208 209
209 // TODO(epenner): Could we possibly trigger the completion on 210 bool AsyncPixelTransfersCompletedQuery::Process() {
210 // the upload thread by writing to the query shared memory 211 QuerySync* sync = manager()->decoder()->GetSharedMemoryAs<QuerySync*>(
211 // directly? 212 shm_id(), shm_offset(), sizeof(*sync));
213 if (!sync)
214 return false;
215
216 // Check if AsyncPixelTransferDelegate has marked QuerySync as completed.
217 if (sync->process_count != submit_count())
epenner 2013/02/07 20:22:56 Is this thread safe? Given it's simplicity maybe i
reveman 2013/02/07 21:30:52 this is consistent with the code in the client sid
218 return true;
219
220 UnmarkAsPending();
212 return true; 221 return true;
213 } 222 }
214 223
215 bool AsyncPixelTransfersCompletedQuery::Process() {
216 NOTREACHED();
217 return true;
218 }
219
220 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) { 224 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) {
221 if (!IsDeleted()) { 225 if (!IsDeleted()) {
222 MarkAsDeleted(); 226 MarkAsDeleted();
223 } 227 }
224 } 228 }
225 229
226 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() { 230 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() {
227 } 231 }
228 232
229 class GetErrorQuery : public QueryManager::Query { 233 class GetErrorQuery : public QueryManager::Query {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 return true; 432 return true;
429 } 433 }
430 434
431 bool QueryManager::ProcessPendingQueries() { 435 bool QueryManager::ProcessPendingQueries() {
432 while (!pending_queries_.empty()) { 436 while (!pending_queries_.empty()) {
433 Query* query = pending_queries_.front().get(); 437 Query* query = pending_queries_.front().get();
434 if (!query->Process()) { 438 if (!query->Process()) {
435 return false; 439 return false;
436 } 440 }
437 if (query->pending()) { 441 if (query->pending()) {
438 return true; 442 break;
439 } 443 }
440 pending_queries_.pop_front(); 444 pending_queries_.pop_front();
441 } 445 }
446 while (!pending_transfer_queries_.empty()) {
447 Query* query = pending_transfer_queries_.front().get();
448 if (!query->Process()) {
449 return false;
450 }
451 if (query->pending()) {
452 break;
453 }
454 pending_transfer_queries_.pop_front();
455 }
442 456
443 return true; 457 return true;
444 } 458 }
445 459
446 bool QueryManager::HavePendingQueries() { 460 bool QueryManager::HavePendingQueries() {
447 return !pending_queries_.empty(); 461 return !pending_queries_.empty() || !pending_transfer_queries_.empty();
448 } 462 }
449 463
450 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) { 464 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
451 DCHECK(query); 465 DCHECK(query);
452 DCHECK(!query->IsDeleted()); 466 DCHECK(!query->IsDeleted());
453 if (!RemovePendingQuery(query)) { 467 if (!RemovePendingQuery(query)) {
454 return false; 468 return false;
455 } 469 }
456 query->MarkAsPending(submit_count); 470 query->MarkAsPending(submit_count);
457 pending_queries_.push_back(query); 471 pending_queries_.push_back(query);
458 return true; 472 return true;
459 } 473 }
460 474
475 bool QueryManager::AddPendingTransferQuery(Query* query, uint32 submit_count) {
476 DCHECK(query);
477 DCHECK(!query->IsDeleted());
478 if (!RemovePendingQuery(query)) {
479 return false;
480 }
481 query->MarkAsPending(submit_count);
482 pending_transfer_queries_.push_back(query);
483 return true;
484 }
485
461 bool QueryManager::RemovePendingQuery(Query* query) { 486 bool QueryManager::RemovePendingQuery(Query* query) {
462 DCHECK(query); 487 DCHECK(query);
463 if (query->pending()) { 488 if (query->pending()) {
464 // TODO(gman): Speed this up if this is a common operation. This would only 489 // TODO(gman): Speed this up if this is a common operation. This would only
465 // happen if you do being/end begin/end on the same query without waiting 490 // happen if you do being/end begin/end on the same query without waiting
466 // for the first one to finish. 491 // for the first one to finish.
467 for (QueryQueue::iterator it = pending_queries_.begin(); 492 for (QueryQueue::iterator it = pending_queries_.begin();
468 it != pending_queries_.end(); ++it) { 493 it != pending_queries_.end(); ++it) {
469 if (it->get() == query) { 494 if (it->get() == query) {
470 pending_queries_.erase(it); 495 pending_queries_.erase(it);
471 break; 496 break;
472 } 497 }
473 } 498 }
499 for (QueryQueue::iterator it = pending_transfer_queries_.begin();
500 it != pending_transfer_queries_.end(); ++it) {
501 if (it->get() == query) {
502 pending_transfer_queries_.erase(it);
503 break;
504 }
505 }
474 if (!query->MarkAsCompleted(0)) { 506 if (!query->MarkAsCompleted(0)) {
475 return false; 507 return false;
476 } 508 }
477 } 509 }
478 return true; 510 return true;
479 } 511 }
480 512
481 bool QueryManager::BeginQuery(Query* query) { 513 bool QueryManager::BeginQuery(Query* query) {
482 DCHECK(query); 514 DCHECK(query);
483 if (!RemovePendingQuery(query)) { 515 if (!RemovePendingQuery(query)) {
484 return false; 516 return false;
485 } 517 }
486 return query->Begin(); 518 return query->Begin();
487 } 519 }
488 520
489 bool QueryManager::EndQuery(Query* query, uint32 submit_count) { 521 bool QueryManager::EndQuery(Query* query, uint32 submit_count) {
490 DCHECK(query); 522 DCHECK(query);
491 if (!RemovePendingQuery(query)) { 523 if (!RemovePendingQuery(query)) {
492 return false; 524 return false;
493 } 525 }
494 return query->End(submit_count); 526 return query->End(submit_count);
495 } 527 }
496 528
497 } // namespace gles2 529 } // namespace gles2
498 } // namespace gpu 530 } // namespace gpu
499 531
500 532
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698