OLD | NEW |
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 |
7 #include "base/atomicops.h" | 7 #include "base/atomicops.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
11 #include "base/numerics/safe_math.h" | 11 #include "base/numerics/safe_math.h" |
12 #include "base/synchronization/lock.h" | 12 #include "base/synchronization/lock.h" |
13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
14 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 14 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
15 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" | |
16 #include "gpu/command_buffer/service/error_state.h" | 15 #include "gpu/command_buffer/service/error_state.h" |
17 #include "gpu/command_buffer/service/feature_info.h" | 16 #include "gpu/command_buffer/service/feature_info.h" |
18 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 17 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 18 #include "ui/gl/gl_bindings.h" |
19 #include "ui/gl/gl_context.h" | 19 #include "ui/gl/gl_context.h" |
20 #include "ui/gl/gl_fence.h" | 20 #include "ui/gl/gl_fence.h" |
21 #include "ui/gl/gpu_timing.h" | 21 #include "ui/gl/gpu_timing.h" |
22 | 22 |
23 namespace gpu { | 23 namespace gpu { |
24 namespace gles2 { | 24 namespace gles2 { |
25 | 25 |
26 namespace { | |
27 | |
28 class AsyncPixelTransferCompletionObserverImpl | |
29 : public AsyncPixelTransferCompletionObserver { | |
30 public: | |
31 AsyncPixelTransferCompletionObserverImpl(base::subtle::Atomic32 submit_count) | |
32 : submit_count_(submit_count), cancelled_(false) {} | |
33 | |
34 void Cancel() { | |
35 base::AutoLock locked(lock_); | |
36 cancelled_ = true; | |
37 } | |
38 | |
39 void DidComplete(const AsyncMemoryParams& mem_params) override { | |
40 base::AutoLock locked(lock_); | |
41 if (!cancelled_) { | |
42 DCHECK(mem_params.buffer().get()); | |
43 void* data = mem_params.GetDataAddress(); | |
44 QuerySync* sync = static_cast<QuerySync*>(data); | |
45 base::subtle::Release_Store(&sync->process_count, submit_count_); | |
46 } | |
47 } | |
48 | |
49 private: | |
50 ~AsyncPixelTransferCompletionObserverImpl() override {} | |
51 | |
52 base::subtle::Atomic32 submit_count_; | |
53 | |
54 base::Lock lock_; | |
55 bool cancelled_; | |
56 | |
57 DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferCompletionObserverImpl); | |
58 }; | |
59 | |
60 class AsyncPixelTransfersCompletedQuery | |
61 : public QueryManager::Query, | |
62 public base::SupportsWeakPtr<AsyncPixelTransfersCompletedQuery> { | |
63 public: | |
64 AsyncPixelTransfersCompletedQuery( | |
65 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); | |
66 | |
67 bool Begin() override; | |
68 bool End(base::subtle::Atomic32 submit_count) override; | |
69 bool QueryCounter(base::subtle::Atomic32 submit_count) override; | |
70 void Pause() override; | |
71 void Resume() override; | |
72 bool Process(bool did_finish) override; | |
73 void Destroy(bool have_context) override; | |
74 | |
75 protected: | |
76 ~AsyncPixelTransfersCompletedQuery() override; | |
77 | |
78 scoped_refptr<AsyncPixelTransferCompletionObserverImpl> observer_; | |
79 }; | |
80 | |
81 AsyncPixelTransfersCompletedQuery::AsyncPixelTransfersCompletedQuery( | |
82 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset) | |
83 : Query(manager, target, shm_id, shm_offset) { | |
84 } | |
85 | |
86 bool AsyncPixelTransfersCompletedQuery::Begin() { | |
87 MarkAsActive(); | |
88 return true; | |
89 } | |
90 | |
91 void AsyncPixelTransfersCompletedQuery::Pause() { | |
92 MarkAsPaused(); | |
93 } | |
94 | |
95 void AsyncPixelTransfersCompletedQuery::Resume() { | |
96 MarkAsActive(); | |
97 } | |
98 | |
99 bool AsyncPixelTransfersCompletedQuery::End( | |
100 base::subtle::Atomic32 submit_count) { | |
101 // Get the real shared memory since it might need to be duped to prevent | |
102 // use-after-free of the memory. | |
103 scoped_refptr<Buffer> buffer = | |
104 manager()->decoder()->GetSharedMemoryBuffer(shm_id()); | |
105 if (!buffer.get()) | |
106 return false; | |
107 AsyncMemoryParams mem_params(buffer, shm_offset(), sizeof(QuerySync)); | |
108 if (!mem_params.GetDataAddress()) | |
109 return false; | |
110 | |
111 observer_ = new AsyncPixelTransferCompletionObserverImpl(submit_count); | |
112 | |
113 // Ask AsyncPixelTransferDelegate to run completion callback after all | |
114 // previous async transfers are done. No guarantee that callback is run | |
115 // on the current thread. | |
116 manager()->decoder()->GetAsyncPixelTransferManager()->AsyncNotifyCompletion( | |
117 mem_params, observer_.get()); | |
118 | |
119 return AddToPendingTransferQueue(submit_count); | |
120 } | |
121 | |
122 bool AsyncPixelTransfersCompletedQuery::QueryCounter( | |
123 base::subtle::Atomic32 submit_count) { | |
124 NOTREACHED(); | |
125 return false; | |
126 } | |
127 | |
128 bool AsyncPixelTransfersCompletedQuery::Process(bool did_finish) { | |
129 QuerySync* sync = manager()->decoder()->GetSharedMemoryAs<QuerySync*>( | |
130 shm_id(), shm_offset(), sizeof(*sync)); | |
131 if (!sync) | |
132 return false; | |
133 | |
134 // Check if completion callback has been run. sync->process_count atomicity | |
135 // is guaranteed as this is already used to notify client of a completed | |
136 // query. | |
137 if (base::subtle::Acquire_Load(&sync->process_count) != submit_count()) | |
138 return true; | |
139 | |
140 UnmarkAsPending(); | |
141 return true; | |
142 } | |
143 | |
144 void AsyncPixelTransfersCompletedQuery::Destroy(bool /* have_context */) { | |
145 if (!IsDeleted()) { | |
146 MarkAsDeleted(); | |
147 } | |
148 } | |
149 | |
150 AsyncPixelTransfersCompletedQuery::~AsyncPixelTransfersCompletedQuery() { | |
151 if (observer_.get()) | |
152 observer_->Cancel(); | |
153 } | |
154 | |
155 } // namespace | |
156 | |
157 class AllSamplesPassedQuery : public QueryManager::Query { | 26 class AllSamplesPassedQuery : public QueryManager::Query { |
158 public: | 27 public: |
159 AllSamplesPassedQuery( | 28 AllSamplesPassedQuery( |
160 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); | 29 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset); |
161 bool Begin() override; | 30 bool Begin() override; |
162 bool End(base::subtle::Atomic32 submit_count) override; | 31 bool End(base::subtle::Atomic32 submit_count) override; |
163 bool QueryCounter(base::subtle::Atomic32 submit_count) override; | 32 bool QueryCounter(base::subtle::Atomic32 submit_count) override; |
164 void Pause() override; | 33 void Pause() override; |
165 void Resume() override; | 34 void Resume() override; |
166 bool Process(bool did_finish) override; | 35 bool Process(bool did_finish) override; |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 QueryManager::Query* QueryManager::CreateQuery( | 682 QueryManager::Query* QueryManager::CreateQuery( |
814 GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset) { | 683 GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset) { |
815 scoped_refptr<Query> query; | 684 scoped_refptr<Query> query; |
816 switch (target) { | 685 switch (target) { |
817 case GL_COMMANDS_ISSUED_CHROMIUM: | 686 case GL_COMMANDS_ISSUED_CHROMIUM: |
818 query = new CommandsIssuedQuery(this, target, shm_id, shm_offset); | 687 query = new CommandsIssuedQuery(this, target, shm_id, shm_offset); |
819 break; | 688 break; |
820 case GL_LATENCY_QUERY_CHROMIUM: | 689 case GL_LATENCY_QUERY_CHROMIUM: |
821 query = new CommandLatencyQuery(this, target, shm_id, shm_offset); | 690 query = new CommandLatencyQuery(this, target, shm_id, shm_offset); |
822 break; | 691 break; |
823 case GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM: | |
824 // Currently async pixel transfer delegates only support uploads. | |
825 query = new AsyncPixelTransfersCompletedQuery( | |
826 this, target, shm_id, shm_offset); | |
827 break; | |
828 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM: | 692 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM: |
829 query = new AsyncReadPixelsCompletedQuery( | 693 query = new AsyncReadPixelsCompletedQuery( |
830 this, target, shm_id, shm_offset); | 694 this, target, shm_id, shm_offset); |
831 break; | 695 break; |
832 case GL_GET_ERROR_QUERY_CHROMIUM: | 696 case GL_GET_ERROR_QUERY_CHROMIUM: |
833 query = new GetErrorQuery(this, target, shm_id, shm_offset); | 697 query = new GetErrorQuery(this, target, shm_id, shm_offset); |
834 break; | 698 break; |
835 case GL_COMMANDS_COMPLETED_CHROMIUM: | 699 case GL_COMMANDS_COMPLETED_CHROMIUM: |
836 query = new CommandsCompletedQuery(this, target, shm_id, shm_offset); | 700 query = new CommandsCompletedQuery(this, target, shm_id, shm_offset); |
837 break; | 701 break; |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1169 for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) { | 1033 for (std::pair<const GLenum, scoped_refptr<Query> >& it : active_queries_) { |
1170 if (it.second->IsPaused()) { | 1034 if (it.second->IsPaused()) { |
1171 it.second->Resume(); | 1035 it.second->Resume(); |
1172 DCHECK(it.second->IsActive()); | 1036 DCHECK(it.second->IsActive()); |
1173 } | 1037 } |
1174 } | 1038 } |
1175 } | 1039 } |
1176 | 1040 |
1177 } // namespace gles2 | 1041 } // namespace gles2 |
1178 } // namespace gpu | 1042 } // namespace gpu |
OLD | NEW |