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