• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_
7 
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"
18 
19 namespace gpu {
20 
21 class GLES2Decoder;
22 
23 namespace gles2 {
24 
25 class FeatureInfo;
26 
27 // This class keeps track of the queries and their state
28 // As Queries are not shared there is one QueryManager per context.
29 class GPU_EXPORT QueryManager {
30  public:
31   class GPU_EXPORT Query : public base::RefCounted<Query> {
32    public:
33     Query(
34         QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
35 
target()36     GLenum target() const {
37       return target_;
38     }
39 
IsDeleted()40     bool IsDeleted() const {
41       return deleted_;
42     }
43 
IsValid()44     bool IsValid() const {
45       return target() && !IsDeleted();
46     }
47 
pending()48     bool pending() const {
49       return pending_;
50     }
51 
shm_id()52     int32 shm_id() const {
53       return shm_id_;
54     }
55 
shm_offset()56     uint32 shm_offset() const {
57       return shm_offset_;
58     }
59 
60     // Returns false if shared memory for sync is invalid.
61     virtual bool Begin() = 0;
62 
63     // Returns false if shared memory for sync is invalid.
64     virtual bool End(base::subtle::Atomic32 submit_count) = 0;
65 
66     // Returns false if shared memory for sync is invalid.
67     virtual bool Process() = 0;
68 
69     virtual void Destroy(bool have_context) = 0;
70 
71     void AddCallback(base::Closure callback);
72 
73    protected:
74     virtual ~Query();
75 
manager()76     QueryManager* manager() const {
77       return manager_;
78     }
79 
MarkAsDeleted()80     void MarkAsDeleted() {
81       deleted_ = true;
82     }
83 
84     // Returns false if shared memory for sync is invalid.
85     bool MarkAsCompleted(uint64 result);
86 
MarkAsPending(base::subtle::Atomic32 submit_count)87     void MarkAsPending(base::subtle::Atomic32 submit_count) {
88       DCHECK(!pending_);
89       pending_ = true;
90       submit_count_ = submit_count;
91     }
92 
UnmarkAsPending()93     void UnmarkAsPending() {
94       DCHECK(pending_);
95       pending_ = false;
96     }
97 
98     // Returns false if shared memory for sync is invalid.
AddToPendingQueue(base::subtle::Atomic32 submit_count)99     bool AddToPendingQueue(base::subtle::Atomic32 submit_count) {
100       return manager_->AddPendingQuery(this, submit_count);
101     }
102 
103     // Returns false if shared memory for sync is invalid.
AddToPendingTransferQueue(base::subtle::Atomic32 submit_count)104     bool AddToPendingTransferQueue(base::subtle::Atomic32 submit_count) {
105       return manager_->AddPendingTransferQuery(this, submit_count);
106     }
107 
BeginQueryHelper(GLenum target,GLuint id)108     void BeginQueryHelper(GLenum target, GLuint id) {
109       manager_->BeginQueryHelper(target, id);
110     }
111 
EndQueryHelper(GLenum target)112     void EndQueryHelper(GLenum target) {
113       manager_->EndQueryHelper(target);
114     }
115 
submit_count()116     base::subtle::Atomic32 submit_count() const { return submit_count_; }
117 
118    private:
119     friend class QueryManager;
120     friend class QueryManagerTest;
121     friend class base::RefCounted<Query>;
122 
123     void RunCallbacks();
124 
125     // The manager that owns this Query.
126     QueryManager* manager_;
127 
128     // The type of query.
129     GLenum target_;
130 
131     // The shared memory used with this Query.
132     int32 shm_id_;
133     uint32 shm_offset_;
134 
135     // Count to set process count do when completed.
136     base::subtle::Atomic32 submit_count_;
137 
138     // True if in the queue.
139     bool pending_;
140 
141     // True if deleted.
142     bool deleted_;
143 
144     // List of callbacks to run when result is available.
145     std::vector<base::Closure> callbacks_;
146   };
147 
148   QueryManager(
149       GLES2Decoder* decoder,
150       FeatureInfo* feature_info);
151   ~QueryManager();
152 
153   // Must call before destruction.
154   void Destroy(bool have_context);
155 
156   // Creates a Query for the given query.
157   Query* CreateQuery(
158       GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset);
159 
160   // Gets the query info for the given query.
161   Query* GetQuery(GLuint client_id);
162 
163   // Removes a query info for the given query.
164   void RemoveQuery(GLuint client_id);
165 
166   // Returns false if any query is pointing to invalid shared memory.
167   bool BeginQuery(Query* query);
168 
169   // Returns false if any query is pointing to invalid shared memory.
170   bool EndQuery(Query* query, base::subtle::Atomic32 submit_count);
171 
172   // Processes pending queries. Returns false if any queries are pointing
173   // to invalid shared memory.
174   bool ProcessPendingQueries();
175 
176   // True if there are pending queries.
177   bool HavePendingQueries();
178 
179   // Processes pending transfer queries. Returns false if any queries are
180   // pointing to invalid shared memory.
181   bool ProcessPendingTransferQueries();
182 
183   // True if there are pending transfer queries.
184   bool HavePendingTransferQueries();
185 
decoder()186   GLES2Decoder* decoder() const {
187     return decoder_;
188   }
189 
190   void GenQueries(GLsizei n, const GLuint* queries);
191   bool IsValidQuery(GLuint id);
192 
193  private:
194   void StartTracking(Query* query);
195   void StopTracking(Query* query);
196 
197   // Wrappers for BeginQueryARB and EndQueryARB to hide differences between
198   // ARB_occlusion_query2 and EXT_occlusion_query_boolean.
199   void BeginQueryHelper(GLenum target, GLuint id);
200   void EndQueryHelper(GLenum target);
201 
202   // Adds to queue of queries waiting for completion.
203   // Returns false if any query is pointing to invalid shared memory.
204   bool AddPendingQuery(Query* query, base::subtle::Atomic32 submit_count);
205 
206   // Adds to queue of transfer queries waiting for completion.
207   // Returns false if any query is pointing to invalid shared memory.
208   bool AddPendingTransferQuery(Query* query,
209                                base::subtle::Atomic32 submit_count);
210 
211   // Removes a query from the queue of pending queries.
212   // Returns false if any query is pointing to invalid shared memory.
213   bool RemovePendingQuery(Query* query);
214 
215   // Returns a target used for the underlying GL extension
216   // used to emulate a query.
217   GLenum AdjustTargetForEmulation(GLenum target);
218 
219   // Used to validate shared memory and get GL errors.
220   GLES2Decoder* decoder_;
221 
222   bool use_arb_occlusion_query2_for_occlusion_query_boolean_;
223   bool use_arb_occlusion_query_for_occlusion_query_boolean_;
224 
225   // Counts the number of Queries allocated with 'this' as their manager.
226   // Allows checking no Query will outlive this.
227   unsigned query_count_;
228 
229   // Info for each query in the system.
230   typedef base::hash_map<GLuint, scoped_refptr<Query> > QueryMap;
231   QueryMap queries_;
232 
233   typedef base::hash_set<GLuint> GeneratedQueryIds;
234   GeneratedQueryIds generated_query_ids_;
235 
236   // Queries waiting for completion.
237   typedef std::deque<scoped_refptr<Query> > QueryQueue;
238   QueryQueue pending_queries_;
239 
240   // Async pixel transfer queries waiting for completion.
241   QueryQueue pending_transfer_queries_;
242 
243   DISALLOW_COPY_AND_ASSIGN(QueryManager);
244 };
245 
246 }  // namespace gles2
247 }  // namespace gpu
248 
249 #endif  // GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_
250