Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / gpu / command_buffer / service / query_manager.h
blob7e8ba49e97352b1360489594462f20ca8484b581
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
3 // found in the LICENSE file.
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_
8 #include <deque>
9 #include <vector>
10 #include "base/atomicops.h"
11 #include "base/basictypes.h"
12 #include "base/containers/hash_tables.h"
13 #include "base/logging.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "gpu/command_buffer/service/feature_info.h"
17 #include "gpu/gpu_export.h"
19 namespace gfx {
20 class GPUTimer;
21 class GPUTimingClient;
24 namespace gpu {
26 class GLES2Decoder;
28 namespace gles2 {
30 class FeatureInfo;
32 // This class keeps track of the queries and their state
33 // As Queries are not shared there is one QueryManager per context.
34 class GPU_EXPORT QueryManager {
35 public:
36 class GPU_EXPORT Query : public base::RefCounted<Query> {
37 public:
38 Query(
39 QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
41 GLenum target() const {
42 return target_;
45 bool IsDeleted() const {
46 return deleted_;
49 bool IsValid() const {
50 return target() && !IsDeleted();
53 bool IsActive() const {
54 return query_state_ == kQueryState_Active;
57 bool IsPaused() const {
58 return query_state_ == kQueryState_Paused;
61 bool IsPending() const {
62 return query_state_ == kQueryState_Pending;
65 bool IsFinished() const {
66 return query_state_ == kQueryState_Finished;
69 int32 shm_id() const {
70 return shm_id_;
73 uint32 shm_offset() const {
74 return shm_offset_;
77 // Returns false if shared memory for sync is invalid.
78 virtual bool Begin() = 0;
80 // Returns false if shared memory for sync is invalid.
81 virtual bool End(base::subtle::Atomic32 submit_count) = 0;
83 // Returns false if shared memory for sync is invalid.
84 virtual bool QueryCounter(base::subtle::Atomic32 submit_count) = 0;
86 // Returns false if shared memory for sync is invalid.
87 virtual bool Process(bool did_finish) = 0;
89 // Pauses active query to be resumed later.
90 virtual void Pause() = 0;
92 // Resume from a paused active query.
93 virtual void Resume() = 0;
95 virtual void Destroy(bool have_context) = 0;
97 void AddCallback(base::Closure callback);
99 protected:
100 virtual ~Query();
102 QueryManager* manager() const {
103 return manager_;
106 void MarkAsDeleted() {
107 deleted_ = true;
110 void MarkAsActive() {
111 DCHECK(query_state_ == kQueryState_Initialize ||
112 query_state_ == kQueryState_Paused ||
113 query_state_ == kQueryState_Finished);
114 query_state_ = kQueryState_Active;
117 void MarkAsPaused() {
118 DCHECK(query_state_ == kQueryState_Active);
119 query_state_ = kQueryState_Paused;
122 void MarkAsPending(base::subtle::Atomic32 submit_count) {
123 DCHECK(query_state_ == kQueryState_Active);
124 query_state_ = kQueryState_Pending;
125 submit_count_ = submit_count;
128 // Returns false if shared memory for sync is invalid.
129 bool MarkAsCompleted(uint64 result);
131 void UnmarkAsPending() {
132 DCHECK(query_state_ == kQueryState_Pending);
133 query_state_ = kQueryState_Finished;
136 // Returns false if shared memory for sync is invalid.
137 bool AddToPendingQueue(base::subtle::Atomic32 submit_count) {
138 return manager_->AddPendingQuery(this, submit_count);
141 // Returns false if shared memory for sync is invalid.
142 bool AddToPendingTransferQueue(base::subtle::Atomic32 submit_count) {
143 return manager_->AddPendingTransferQuery(this, submit_count);
146 void BeginQueryHelper(GLenum target, GLuint id) {
147 manager_->BeginQueryHelper(target, id);
150 void EndQueryHelper(GLenum target) {
151 manager_->EndQueryHelper(target);
154 base::subtle::Atomic32 submit_count() const { return submit_count_; }
156 private:
157 friend class QueryManager;
158 friend class QueryManagerTest;
159 friend class base::RefCounted<Query>;
161 void RunCallbacks();
163 // The manager that owns this Query.
164 QueryManager* manager_;
166 // The type of query.
167 GLenum target_;
169 // The shared memory used with this Query.
170 int32 shm_id_;
171 uint32 shm_offset_;
173 // Count to set process count do when completed.
174 base::subtle::Atomic32 submit_count_;
176 // Current state of the query.
177 enum QueryState {
178 kQueryState_Initialize, // Has not been queried yet.
179 kQueryState_Active, // Query began but has not ended.
180 kQueryState_Paused, // Query was active but is now paused.
181 kQueryState_Pending, // Query ended, waiting for result.
182 kQueryState_Finished, // Query received result.
183 } query_state_;
185 // True if deleted.
186 bool deleted_;
188 // List of callbacks to run when result is available.
189 std::vector<base::Closure> callbacks_;
192 QueryManager(
193 GLES2Decoder* decoder,
194 FeatureInfo* feature_info);
195 ~QueryManager();
197 // Must call before destruction.
198 void Destroy(bool have_context);
200 // Creates a Query for the given query.
201 Query* CreateQuery(
202 GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset);
204 // Gets the query info for the given query.
205 Query* GetQuery(GLuint client_id);
207 // Gets the currently active query for a target.
208 Query* GetActiveQuery(GLenum target);
210 // Removes a query info for the given query.
211 void RemoveQuery(GLuint client_id);
213 // Returns false if any query is pointing to invalid shared memory.
214 bool BeginQuery(Query* query);
216 // Returns false if any query is pointing to invalid shared memory.
217 bool EndQuery(Query* query, base::subtle::Atomic32 submit_count);
219 // Returns false if any query is pointing to invalid shared memory.
220 bool QueryCounter(Query* query, base::subtle::Atomic32 submit_count);
222 void PauseQueries();
223 void ResumeQueries();
225 // Processes pending queries. Returns false if any queries are pointing
226 // to invalid shared memory. |did_finish| is true if this is called as
227 // a result of calling glFinish().
228 bool ProcessPendingQueries(bool did_finish);
230 // True if there are pending queries.
231 bool HavePendingQueries();
233 // Processes pending transfer queries. Returns false if any queries are
234 // pointing to invalid shared memory.
235 bool ProcessPendingTransferQueries();
237 // True if there are pending transfer queries.
238 bool HavePendingTransferQueries();
240 GLES2Decoder* decoder() const {
241 return decoder_;
244 scoped_ptr<gfx::GPUTimer> CreateGPUTimer(bool elapsed_time);
245 bool GPUTimingAvailable();
247 void GenQueries(GLsizei n, const GLuint* queries);
248 bool IsValidQuery(GLuint id);
250 private:
251 void StartTracking(Query* query);
252 void StopTracking(Query* query);
254 // Wrappers for BeginQueryARB and EndQueryARB to hide differences between
255 // ARB_occlusion_query2 and EXT_occlusion_query_boolean.
256 void BeginQueryHelper(GLenum target, GLuint id);
257 void EndQueryHelper(GLenum target);
259 // Adds to queue of queries waiting for completion.
260 // Returns false if any query is pointing to invalid shared memory.
261 bool AddPendingQuery(Query* query, base::subtle::Atomic32 submit_count);
263 // Adds to queue of transfer queries waiting for completion.
264 // Returns false if any query is pointing to invalid shared memory.
265 bool AddPendingTransferQuery(Query* query,
266 base::subtle::Atomic32 submit_count);
268 // Removes a query from the queue of pending queries.
269 // Returns false if any query is pointing to invalid shared memory.
270 bool RemovePendingQuery(Query* query);
272 // Returns a target used for the underlying GL extension
273 // used to emulate a query.
274 GLenum AdjustTargetForEmulation(GLenum target);
276 // Used to validate shared memory and get GL errors.
277 GLES2Decoder* decoder_;
279 bool use_arb_occlusion_query2_for_occlusion_query_boolean_;
280 bool use_arb_occlusion_query_for_occlusion_query_boolean_;
282 // Counts the number of Queries allocated with 'this' as their manager.
283 // Allows checking no Query will outlive this.
284 unsigned query_count_;
286 // Info for each query in the system.
287 typedef base::hash_map<GLuint, scoped_refptr<Query> > QueryMap;
288 QueryMap queries_;
290 typedef base::hash_set<GLuint> GeneratedQueryIds;
291 GeneratedQueryIds generated_query_ids_;
293 // A map of targets -> Query for current active queries.
294 typedef std::map<GLenum, scoped_refptr<Query> > ActiveQueryMap;
295 ActiveQueryMap active_queries_;
297 // Queries waiting for completion.
298 typedef std::deque<scoped_refptr<Query> > QueryQueue;
299 QueryQueue pending_queries_;
301 // Async pixel transfer queries waiting for completion.
302 QueryQueue pending_transfer_queries_;
304 scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_;
306 DISALLOW_COPY_AND_ASSIGN(QueryManager);
309 } // namespace gles2
310 } // namespace gpu
312 #endif // GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_