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

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: Fix shutdown issue 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
6 #include "base/atomicops.h" 7 #include "base/atomicops.h"
7 #include "base/bind.h" 8 #include "base/bind.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/shared_memory.h"
9 #include "base/time.h" 11 #include "base/time.h"
10 #include "gpu/command_buffer/common/gles2_cmd_format.h" 12 #include "gpu/command_buffer/common/gles2_cmd_format.h"
13 #include "gpu/command_buffer/service/feature_info.h"
11 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 14 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
12 #include "gpu/command_buffer/service/feature_info.h"
13 #include "ui/gl/async_pixel_transfer_delegate.h" 15 #include "ui/gl/async_pixel_transfer_delegate.h"
14 16
15 namespace gpu { 17 namespace gpu {
16 namespace gles2 { 18 namespace gles2 {
17 19
18 class AllSamplesPassedQuery : public QueryManager::Query { 20 class AllSamplesPassedQuery : public QueryManager::Query {
19 public: 21 public:
20 AllSamplesPassedQuery( 22 AllSamplesPassedQuery(
21 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset, 23 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset,
22 GLuint service_id); 24 GLuint service_id);
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 , public base::SupportsWeakPtr<AsyncPixelTransfersCompletedQuery> { 171 , public base::SupportsWeakPtr<AsyncPixelTransfersCompletedQuery> {
170 public: 172 public:
171 AsyncPixelTransfersCompletedQuery( 173 AsyncPixelTransfersCompletedQuery(
172 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); 174 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
173 175
174 virtual bool Begin() OVERRIDE; 176 virtual bool Begin() OVERRIDE;
175 virtual bool End(uint32 submit_count) OVERRIDE; 177 virtual bool End(uint32 submit_count) OVERRIDE;
176 virtual bool Process() OVERRIDE; 178 virtual bool Process() OVERRIDE;
177 virtual void Destroy(bool have_context) OVERRIDE; 179 virtual void Destroy(bool have_context) OVERRIDE;
178 180
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 }
183 }; 195 };
184 196
185 AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery( 197 AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery(
186 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) 198 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset)
187 : Query(manager, target, shm_id, shm_offset) { 199 : Query(manager, target, shm_id, shm_offset) {
188 } 200 }
189 201
190 bool AsyncPixelTransfersCompletedQuery::Begin() { 202 bool AsyncPixelTransfersCompletedQuery::Begin() {
191 return true; 203 return true;
192 } 204 }
193 205
194 bool AsyncPixelTransfersCompletedQuery::End(uint32 submit_count) { 206 bool AsyncPixelTransfersCompletedQuery::End(uint32 submit_count) {
195 MarkAsPending(submit_count); 207 gfx::AsyncMemoryParams mem_params;
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);
196 217
197 // This will call MarkAsCompleted(1) as a reply to a task on 218 // Ask AsyncPixelTransferDelegate to run completion callback after all
198 // the async upload thread, such that it occurs after all previous 219 // previous async transfers are done. No guarantee that callback is run
199 // async transfers have completed. 220 // on the current thread.
200 manager()->decoder()->GetAsyncPixelTransferDelegate()->AsyncNotifyCompletion( 221 manager()->decoder()->GetAsyncPixelTransferDelegate()->AsyncNotifyCompletion(
201 base::Bind( 222 mem_params,
202 &AsyncPixelTransfersCompletedQuery::MarkAsCompletedCallback, 223 base::Bind(AsyncPixelTransfersCompletedQuery::MarkAsCompletedThreadSafe,
203 AsWeakPtr())); 224 submit_count));
204 225
205 // TODO(epenner): The async task occurs outside the normal 226 return AddToPendingTransferQueue(submit_count);
206 // flow, via a callback on this thread. Is there anything 227 }
207 // missing or wrong with that?
208 228
209 // TODO(epenner): Could we possibly trigger the completion on 229 bool AsyncPixelTransfersCompletedQuery::Process() {
210 // the upload thread by writing to the query shared memory 230 QuerySync* sync = manager()->decoder()->GetSharedMemoryAs<QuerySync*>(
211 // directly? 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();
212 return true; 242 return true;
213 } 243 }
214 244
215 bool AsyncPixelTransfersCompletedQuery::Process() {
216 NOTREACHED();
217 return true;
218 }
219
220 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) { 245 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) {
221 if (!IsDeleted()) { 246 if (!IsDeleted()) {
222 MarkAsDeleted(); 247 MarkAsDeleted();
223 } 248 }
224 } 249 }
225 250
226 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() { 251 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() {
227 } 252 }
228 253
229 class GetErrorQuery : public QueryManager::Query { 254 class GetErrorQuery : public QueryManager::Query {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 return true; 453 return true;
429 } 454 }
430 455
431 bool QueryManager::ProcessPendingQueries() { 456 bool QueryManager::ProcessPendingQueries() {
432 while (!pending_queries_.empty()) { 457 while (!pending_queries_.empty()) {
433 Query* query = pending_queries_.front().get(); 458 Query* query = pending_queries_.front().get();
434 if (!query->Process()) { 459 if (!query->Process()) {
435 return false; 460 return false;
436 } 461 }
437 if (query->pending()) { 462 if (query->pending()) {
438 return true; 463 break;
439 } 464 }
440 pending_queries_.pop_front(); 465 pending_queries_.pop_front();
441 } 466 }
442 467
443 return true; 468 return true;
444 } 469 }
445 470
446 bool QueryManager::HavePendingQueries() { 471 bool QueryManager::HavePendingQueries() {
447 return !pending_queries_.empty(); 472 return !pending_queries_.empty();
448 } 473 }
449 474
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
450 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) { 494 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
451 DCHECK(query); 495 DCHECK(query);
452 DCHECK(!query->IsDeleted()); 496 DCHECK(!query->IsDeleted());
453 if (!RemovePendingQuery(query)) { 497 if (!RemovePendingQuery(query)) {
454 return false; 498 return false;
455 } 499 }
456 query->MarkAsPending(submit_count); 500 query->MarkAsPending(submit_count);
457 pending_queries_.push_back(query); 501 pending_queries_.push_back(query);
458 return true; 502 return true;
459 } 503 }
460 504
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
461 bool QueryManager::RemovePendingQuery(Query* query) { 516 bool QueryManager::RemovePendingQuery(Query* query) {
462 DCHECK(query); 517 DCHECK(query);
463 if (query->pending()) { 518 if (query->pending()) {
464 // TODO(gman): Speed this up if this is a common operation. This would only 519 // 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 520 // happen if you do being/end begin/end on the same query without waiting
466 // for the first one to finish. 521 // for the first one to finish.
467 for (QueryQueue::iterator it = pending_queries_.begin(); 522 for (QueryQueue::iterator it = pending_queries_.begin();
468 it != pending_queries_.end(); ++it) { 523 it != pending_queries_.end(); ++it) {
469 if (it->get() == query) { 524 if (it->get() == query) {
470 pending_queries_.erase(it); 525 pending_queries_.erase(it);
471 break; 526 break;
472 } 527 }
473 } 528 }
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 }
474 if (!query->MarkAsCompleted(0)) { 536 if (!query->MarkAsCompleted(0)) {
475 return false; 537 return false;
476 } 538 }
477 } 539 }
478 return true; 540 return true;
479 } 541 }
480 542
481 bool QueryManager::BeginQuery(Query* query) { 543 bool QueryManager::BeginQuery(Query* query) {
482 DCHECK(query); 544 DCHECK(query);
483 if (!RemovePendingQuery(query)) { 545 if (!RemovePendingQuery(query)) {
484 return false; 546 return false;
485 } 547 }
486 return query->Begin(); 548 return query->Begin();
487 } 549 }
488 550
489 bool QueryManager::EndQuery(Query* query, uint32 submit_count) { 551 bool QueryManager::EndQuery(Query* query, uint32 submit_count) {
490 DCHECK(query); 552 DCHECK(query);
491 if (!RemovePendingQuery(query)) { 553 if (!RemovePendingQuery(query)) {
492 return false; 554 return false;
493 } 555 }
494 return query->End(submit_count); 556 return query->End(submit_count);
495 } 557 }
496 558
497 } // namespace gles2 559 } // namespace gles2
498 } // namespace gpu 560 } // namespace gpu
499 561
500 562
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698