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

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: Avoid unnecessary polling by GpuCommandBufferStub. 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()) +
greggman 2013/02/11 17:34:09 how do you know this memory is still valid?
reveman 2013/02/11 23:27:13 AsyncPixelTransferDelegate is responsible for maki
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 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 }
442 465
443 return true; 466 return true;
444 } 467 }
445 468
446 bool QueryManager::HavePendingQueries() { 469 bool QueryManager::HavePendingQueries() {
447 return !pending_queries_.empty(); 470 return !pending_queries_.empty();
448 } 471 }
449 472
473 bool QueryManager::ProcessPendingTransferQueries() {
474 while (!pending_transfer_queries_.empty()) {
475 Query* query = pending_transfer_queries_.front().get();
476 if (!query->Process()) {
477 return false;
478 }
479 if (query->pending()) {
480 break;
481 }
482 pending_transfer_queries_.pop_front();
483 }
484
485 return true;
486 }
487
488 bool QueryManager::HavePendingTransferQueries() {
489 return !pending_transfer_queries_.empty();
490 }
491
450 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) { 492 bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
451 DCHECK(query); 493 DCHECK(query);
452 DCHECK(!query->IsDeleted()); 494 DCHECK(!query->IsDeleted());
453 if (!RemovePendingQuery(query)) { 495 if (!RemovePendingQuery(query)) {
454 return false; 496 return false;
455 } 497 }
456 query->MarkAsPending(submit_count); 498 query->MarkAsPending(submit_count);
457 pending_queries_.push_back(query); 499 pending_queries_.push_back(query);
458 return true; 500 return true;
459 } 501 }
460 502
503 bool QueryManager::AddPendingTransferQuery(Query* query, uint32 submit_count) {
504 DCHECK(query);
505 DCHECK(!query->IsDeleted());
506 if (!RemovePendingQuery(query)) {
507 return false;
508 }
509 query->MarkAsPending(submit_count);
510 pending_transfer_queries_.push_back(query);
511 return true;
512 }
513
461 bool QueryManager::RemovePendingQuery(Query* query) { 514 bool QueryManager::RemovePendingQuery(Query* query) {
462 DCHECK(query); 515 DCHECK(query);
463 if (query->pending()) { 516 if (query->pending()) {
464 // TODO(gman): Speed this up if this is a common operation. This would only 517 // 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 518 // happen if you do being/end begin/end on the same query without waiting
466 // for the first one to finish. 519 // for the first one to finish.
467 for (QueryQueue::iterator it = pending_queries_.begin(); 520 for (QueryQueue::iterator it = pending_queries_.begin();
468 it != pending_queries_.end(); ++it) { 521 it != pending_queries_.end(); ++it) {
469 if (it->get() == query) { 522 if (it->get() == query) {
470 pending_queries_.erase(it); 523 pending_queries_.erase(it);
471 break; 524 break;
472 } 525 }
473 } 526 }
527 for (QueryQueue::iterator it = pending_transfer_queries_.begin();
528 it != pending_transfer_queries_.end(); ++it) {
529 if (it->get() == query) {
530 pending_transfer_queries_.erase(it);
531 break;
532 }
533 }
474 if (!query->MarkAsCompleted(0)) { 534 if (!query->MarkAsCompleted(0)) {
475 return false; 535 return false;
476 } 536 }
477 } 537 }
478 return true; 538 return true;
479 } 539 }
480 540
481 bool QueryManager::BeginQuery(Query* query) { 541 bool QueryManager::BeginQuery(Query* query) {
482 DCHECK(query); 542 DCHECK(query);
483 if (!RemovePendingQuery(query)) { 543 if (!RemovePendingQuery(query)) {
484 return false; 544 return false;
485 } 545 }
486 return query->Begin(); 546 return query->Begin();
487 } 547 }
488 548
489 bool QueryManager::EndQuery(Query* query, uint32 submit_count) { 549 bool QueryManager::EndQuery(Query* query, uint32 submit_count) {
490 DCHECK(query); 550 DCHECK(query);
491 if (!RemovePendingQuery(query)) { 551 if (!RemovePendingQuery(query)) {
492 return false; 552 return false;
493 } 553 }
494 return query->End(submit_count); 554 return query->End(submit_count);
495 } 555 }
496 556
497 } // namespace gles2 557 } // namespace gles2
498 } // namespace gpu 558 } // namespace gpu
499 559
500 560
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