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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/query_manager.cc
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc
index 51055e2034a46fa5012ad2cc9c046903bfa24010..c25545f0f77a1cd6e82359091e3139218c8aca6e 100644
--- a/gpu/command_buffer/service/query_manager.cc
+++ b/gpu/command_buffer/service/query_manager.cc
@@ -176,8 +176,6 @@ class AsyncPixelTransfersCompletedQuery
virtual bool Process() OVERRIDE;
virtual void Destroy(bool have_context) OVERRIDE;
- void MarkAsCompletedCallback() { MarkAsCompleted(1); }
-
protected:
virtual ~AsyncPixelTransfersCompletedQuery();
};
@@ -192,28 +190,34 @@ bool AsyncPixelTransfersCompletedQuery::Begin() {
}
bool AsyncPixelTransfersCompletedQuery::End(uint32 submit_count) {
- MarkAsPending(submit_count);
-
- // This will call MarkAsCompleted(1) as a reply to a task on
- // the async upload thread, such that it occurs after all previous
- // async transfers have completed.
+ gfx::AsyncMemoryParams mem_params;
+ // Get the real shared memory since it might need to be duped to prevent
+ // use-after-free of the memory.
+ Buffer buffer = manager()->decoder()->GetSharedMemoryBuffer(shm_id());
+ mem_params.shared_memory = buffer.shared_memory;
+ mem_params.shm_size = buffer.size;
+ mem_params.shm_data_offset = shm_offset();
+ 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
+
+ // This tells AsyncPixelTransferDelegate to mark QuerySync as completed
+ // after all previous async transfers are done.
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
- base::Bind(
- &AsyncPixelTransfersCompletedQuery::MarkAsCompletedCallback,
- AsWeakPtr()));
-
- // TODO(epenner): The async task occurs outside the normal
- // flow, via a callback on this thread. Is there anything
- // missing or wrong with that?
+ mem_params, submit_count);
- // TODO(epenner): Could we possibly trigger the completion on
- // the upload thread by writing to the query shared memory
- // directly?
- return true;
+ return AddToPendingTransferQueue(submit_count);
}
bool AsyncPixelTransfersCompletedQuery::Process() {
- NOTREACHED();
+ QuerySync* sync = manager()->decoder()->GetSharedMemoryAs<QuerySync*>(
+ shm_id(), shm_offset(), sizeof(*sync));
+ if (!sync)
+ return false;
+
+ // Check if AsyncPixelTransferDelegate has marked QuerySync as completed.
+ 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
+ return true;
+
+ UnmarkAsPending();
return true;
}
@@ -435,16 +439,26 @@ bool QueryManager::ProcessPendingQueries() {
return false;
}
if (query->pending()) {
- return true;
+ break;
}
pending_queries_.pop_front();
}
+ while (!pending_transfer_queries_.empty()) {
+ Query* query = pending_transfer_queries_.front().get();
+ if (!query->Process()) {
+ return false;
+ }
+ if (query->pending()) {
+ break;
+ }
+ pending_transfer_queries_.pop_front();
+ }
return true;
}
bool QueryManager::HavePendingQueries() {
- return !pending_queries_.empty();
+ return !pending_queries_.empty() || !pending_transfer_queries_.empty();
}
bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
@@ -458,6 +472,17 @@ bool QueryManager::AddPendingQuery(Query* query, uint32 submit_count) {
return true;
}
+bool QueryManager::AddPendingTransferQuery(Query* query, uint32 submit_count) {
+ DCHECK(query);
+ DCHECK(!query->IsDeleted());
+ if (!RemovePendingQuery(query)) {
+ return false;
+ }
+ query->MarkAsPending(submit_count);
+ pending_transfer_queries_.push_back(query);
+ return true;
+}
+
bool QueryManager::RemovePendingQuery(Query* query) {
DCHECK(query);
if (query->pending()) {
@@ -471,6 +496,13 @@ bool QueryManager::RemovePendingQuery(Query* query) {
break;
}
}
+ for (QueryQueue::iterator it = pending_transfer_queries_.begin();
+ it != pending_transfer_queries_.end(); ++it) {
+ if (it->get() == query) {
+ pending_transfer_queries_.erase(it);
+ break;
+ }
+ }
if (!query->MarkAsCompleted(0)) {
return false;
}

Powered by Google App Engine
This is Rietveld 408576698