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

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: Keep replies. 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
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());
greggman 2013/02/11 17:34:09 Is there any chance this will fail?
reveman 2013/02/11 23:27:13 Good point. Added a check for this.
211 mem_params.shared_memory = buffer.shared_memory;
212 mem_params.shm_size = buffer.size;
213 mem_params.shm_data_offset = shm_offset();
214 mem_params.shm_data_size = sizeof(QuerySync);
196 215
197 // This will call MarkAsCompleted(1) as a reply to a task on 216 // Ask AsyncPixelTransferDelegate to run completion callback after all
198 // the async upload thread, such that it occurs after all previous 217 // previous async transfers are done. No guarantee that callback is run
199 // async transfers have completed. 218 // on the current thread.
200 manager()->decoder()->GetAsyncPixelTransferDelegate()->AsyncNotifyCompletion( 219 manager()->decoder()->GetAsyncPixelTransferDelegate()->AsyncNotifyCompletion(
201 base::Bind( 220 mem_params,
202 &AsyncPixelTransfersCompletedQuery::MarkAsCompletedCallback, 221 base::Bind(AsyncPixelTransfersCompletedQuery::MarkAsCompletedThreadSafe,
203 AsWeakPtr())); 222 submit_count));
204 223
205 // TODO(epenner): The async task occurs outside the normal 224 return AddToPendingTransferQueue(submit_count);
206 // flow, via a callback on this thread. Is there anything 225 }
207 // missing or wrong with that?
208 226
209 // TODO(epenner): Could we possibly trigger the completion on 227 bool AsyncPixelTransfersCompletedQuery::Process() {
210 // the upload thread by writing to the query shared memory 228 QuerySync* sync = manager()->decoder()->GetSharedMemoryAs<QuerySync*>(
211 // directly? 229 shm_id(), shm_offset(), sizeof(*sync));
230 if (!sync)
231 return false;
232
233 // Check if completion callback has been run. sync->process_count atomicity
234 // is guaranteed as this is already used to notify client of a completed
235 // query.
236 if (sync->process_count != submit_count())
237 return true;
238
239 UnmarkAsPending();
212 return true; 240 return true;
213 } 241 }
214 242
215 bool AsyncPixelTransfersCompletedQuery::Process() {
216 NOTREACHED();
217 return true;
218 }
219
220 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) { 243 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) {
221 if (!IsDeleted()) { 244 if (!IsDeleted()) {
222 MarkAsDeleted(); 245 MarkAsDeleted();
223 } 246 }
224 } 247 }
225 248
226 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() { 249 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() {
227 } 250 }
228 251
229 class GetErrorQuery : public QueryManager::Query { 252 class GetErrorQuery : public QueryManager::Query {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 return true; 451 return true;
429 } 452 }
430 453
431 bool QueryManager::ProcessPendingQueries() { 454 bool QueryManager::ProcessPendingQueries() {
432 while (!pending_queries_.empty()) { 455 while (!pending_queries_.empty()) {
433 Query* query = pending_queries_.front().get(); 456 Query* query = pending_queries_.front().get();
434 if (!query->Process()) { 457 if (!query->Process()) {
435 return false; 458 return false;
436 } 459 }
437 if (query->pending()) { 460 if (query->pending()) {
438 return true; 461 break;
439 } 462 }
440 pending_queries_.pop_front(); 463 pending_queries_.pop_front();
441 } 464 }
465 while (!pending_transfer_queries_.empty()) {
466 Query* query = pending_transfer_queries_.front().get();
467 if (!query->Process()) {
468 return false;
469 }
470 if (query->pending()) {
471 break;
472 }
473 pending_transfer_queries_.pop_front();
474 }
442 475
443 return true; 476 return true;
444 } 477 }
445 478
446 bool QueryManager::HavePendingQueries() { 479 bool QueryManager::HavePendingQueries() {
447 return !pending_queries_.empty(); 480 return !pending_queries_.empty() || !pending_transfer_queries_.empty();
448 } 481 }
449 482
450 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) { 483 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
451 DCHECK(query); 484 DCHECK(query);
452 DCHECK(!query->IsDeleted()); 485 DCHECK(!query->IsDeleted());
453 if (!RemovePendingQuery(query)) { 486 if (!RemovePendingQuery(query)) {
454 return false; 487 return false;
455 } 488 }
456 query->MarkAsPending(submit_count); 489 query->MarkAsPending(submit_count);
457 pending_queries_.push_back(query); 490 pending_queries_.push_back(query);
458 return true; 491 return true;
459 } 492 }
460 493
494 bool QueryManager::AddPendingTransferQuery(Query* query, uint32 submit_count) {
495 DCHECK(query);
496 DCHECK(!query->IsDeleted());
497 if (!RemovePendingQuery(query)) {
498 return false;
499 }
500 query->MarkAsPending(submit_count);
501 pending_transfer_queries_.push_back(query);
502 return true;
503 }
504
461 bool QueryManager::RemovePendingQuery(Query* query) { 505 bool QueryManager::RemovePendingQuery(Query* query) {
462 DCHECK(query); 506 DCHECK(query);
463 if (query->pending()) { 507 if (query->pending()) {
464 // TODO(gman): Speed this up if this is a common operation. This would only 508 // 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 509 // happen if you do being/end begin/end on the same query without waiting
466 // for the first one to finish. 510 // for the first one to finish.
467 for (QueryQueue::iterator it = pending_queries_.begin(); 511 for (QueryQueue::iterator it = pending_queries_.begin();
468 it != pending_queries_.end(); ++it) { 512 it != pending_queries_.end(); ++it) {
469 if (it->get() == query) { 513 if (it->get() == query) {
470 pending_queries_.erase(it); 514 pending_queries_.erase(it);
471 break; 515 break;
472 } 516 }
473 } 517 }
518 for (QueryQueue::iterator it = pending_transfer_queries_.begin();
519 it != pending_transfer_queries_.end(); ++it) {
520 if (it->get() == query) {
521 pending_transfer_queries_.erase(it);
522 break;
523 }
524 }
474 if (!query->MarkAsCompleted(0)) { 525 if (!query->MarkAsCompleted(0)) {
475 return false; 526 return false;
476 } 527 }
477 } 528 }
478 return true; 529 return true;
479 } 530 }
480 531
481 bool QueryManager::BeginQuery(Query* query) { 532 bool QueryManager::BeginQuery(Query* query) {
482 DCHECK(query); 533 DCHECK(query);
483 if (!RemovePendingQuery(query)) { 534 if (!RemovePendingQuery(query)) {
484 return false; 535 return false;
485 } 536 }
486 return query->Begin(); 537 return query->Begin();
487 } 538 }
488 539
489 bool QueryManager::EndQuery(Query* query, uint32 submit_count) { 540 bool QueryManager::EndQuery(Query* query, uint32 submit_count) {
490 DCHECK(query); 541 DCHECK(query);
491 if (!RemovePendingQuery(query)) { 542 if (!RemovePendingQuery(query)) {
492 return false; 543 return false;
493 } 544 }
494 return query->End(submit_count); 545 return query->End(submit_count);
495 } 546 }
496 547
497 } // namespace gles2 548 } // namespace gles2
498 } // namespace gpu 549 } // namespace gpu
499 550
500 551
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