Elim cr-checkbox
[chromium-blink-merge.git] / gpu / command_buffer / service / query_manager.h
blob204c100b3f1cb51141f78f62e9320ce09c7da251
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 void SafelyResetDisjointValue() {
155 manager_->SafelyResetDisjointValue();
158 void UpdateDisjointValue() {
159 manager_->UpdateDisjointValue();
162 void BeginContinualDisjointUpdate() {
163 manager_->update_disjoints_continually_ = true;
166 base::subtle::Atomic32 submit_count() const { return submit_count_; }
168 private:
169 friend class QueryManager;
170 friend class QueryManagerTest;
171 friend class base::RefCounted<Query>;
173 void RunCallbacks();
175 // The manager that owns this Query.
176 QueryManager* manager_;
178 // The type of query.
179 GLenum target_;
181 // The shared memory used with this Query.
182 int32 shm_id_;
183 uint32 shm_offset_;
185 // Count to set process count do when completed.
186 base::subtle::Atomic32 submit_count_;
188 // Current state of the query.
189 enum QueryState {
190 kQueryState_Initialize, // Has not been queried yet.
191 kQueryState_Active, // Query began but has not ended.
192 kQueryState_Paused, // Query was active but is now paused.
193 kQueryState_Pending, // Query ended, waiting for result.
194 kQueryState_Finished, // Query received result.
195 } query_state_;
197 // True if deleted.
198 bool deleted_;
200 // List of callbacks to run when result is available.
201 std::vector<base::Closure> callbacks_;
204 QueryManager(
205 GLES2Decoder* decoder,
206 FeatureInfo* feature_info);
207 ~QueryManager();
209 // Must call before destruction.
210 void Destroy(bool have_context);
212 // Sets up a location to be incremented whenever a disjoint is detected.
213 void SetDisjointSync(int32 shm_id, uint32 shm_offset);
215 // Creates a Query for the given query.
216 Query* CreateQuery(
217 GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset);
219 // Gets the query info for the given query.
220 Query* GetQuery(GLuint client_id);
222 // Gets the currently active query for a target.
223 Query* GetActiveQuery(GLenum target);
225 // Removes a query info for the given query.
226 void RemoveQuery(GLuint client_id);
228 // Returns false if any query is pointing to invalid shared memory.
229 bool BeginQuery(Query* query);
231 // Returns false if any query is pointing to invalid shared memory.
232 bool EndQuery(Query* query, base::subtle::Atomic32 submit_count);
234 // Returns false if any query is pointing to invalid shared memory.
235 bool QueryCounter(Query* query, base::subtle::Atomic32 submit_count);
237 void PauseQueries();
238 void ResumeQueries();
240 // Processes pending queries. Returns false if any queries are pointing
241 // to invalid shared memory. |did_finish| is true if this is called as
242 // a result of calling glFinish().
243 bool ProcessPendingQueries(bool did_finish);
245 // True if there are pending queries.
246 bool HavePendingQueries();
248 // Processes pending transfer queries. Returns false if any queries are
249 // pointing to invalid shared memory.
250 bool ProcessPendingTransferQueries();
252 // True if there are pending transfer queries.
253 bool HavePendingTransferQueries();
255 // Do any updates we need to do when the frame has begun.
256 void ProcessFrameBeginUpdates();
258 GLES2Decoder* decoder() const {
259 return decoder_;
262 scoped_ptr<gfx::GPUTimer> CreateGPUTimer(bool elapsed_time);
263 bool GPUTimingAvailable();
265 void GenQueries(GLsizei n, const GLuint* queries);
266 bool IsValidQuery(GLuint id);
268 private:
269 void StartTracking(Query* query);
270 void StopTracking(Query* query);
272 // Wrappers for BeginQueryARB and EndQueryARB to hide differences between
273 // ARB_occlusion_query2 and EXT_occlusion_query_boolean.
274 void BeginQueryHelper(GLenum target, GLuint id);
275 void EndQueryHelper(GLenum target);
277 // Adds to queue of queries waiting for completion.
278 // Returns false if any query is pointing to invalid shared memory.
279 bool AddPendingQuery(Query* query, base::subtle::Atomic32 submit_count);
281 // Adds to queue of transfer queries waiting for completion.
282 // Returns false if any query is pointing to invalid shared memory.
283 bool AddPendingTransferQuery(Query* query,
284 base::subtle::Atomic32 submit_count);
286 // Removes a query from the queue of pending queries.
287 // Returns false if any query is pointing to invalid shared memory.
288 bool RemovePendingQuery(Query* query);
290 // Returns a target used for the underlying GL extension
291 // used to emulate a query.
292 GLenum AdjustTargetForEmulation(GLenum target);
294 // Checks and notifies if a disjoint occurred.
295 void UpdateDisjointValue();
297 // Safely resets the disjoint value if no queries are active.
298 void SafelyResetDisjointValue();
300 // Used to validate shared memory and get GL errors.
301 GLES2Decoder* decoder_;
303 bool use_arb_occlusion_query2_for_occlusion_query_boolean_;
304 bool use_arb_occlusion_query_for_occlusion_query_boolean_;
306 // Whether we are tracking disjoint values every frame.
307 bool update_disjoints_continually_;
309 // The shared memory used for disjoint notifications.
310 int32_t disjoint_notify_shm_id_;
311 uint32_t disjoint_notify_shm_offset_;
313 // Current number of disjoints notified.
314 uint32_t disjoints_notified_;
316 // Counts the number of Queries allocated with 'this' as their manager.
317 // Allows checking no Query will outlive this.
318 unsigned query_count_;
320 // Info for each query in the system.
321 typedef base::hash_map<GLuint, scoped_refptr<Query> > QueryMap;
322 QueryMap queries_;
324 typedef base::hash_set<GLuint> GeneratedQueryIds;
325 GeneratedQueryIds generated_query_ids_;
327 // A map of targets -> Query for current active queries.
328 typedef std::map<GLenum, scoped_refptr<Query> > ActiveQueryMap;
329 ActiveQueryMap active_queries_;
331 // Queries waiting for completion.
332 typedef std::deque<scoped_refptr<Query> > QueryQueue;
333 QueryQueue pending_queries_;
335 // Async pixel transfer queries waiting for completion.
336 QueryQueue pending_transfer_queries_;
338 scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_;
340 DISALLOW_COPY_AND_ASSIGN(QueryManager);
343 } // namespace gles2
344 } // namespace gpu
346 #endif // GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_