Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / service / query_manager.h
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
36     GLenum target() const {
37       return target_;
38     }
39
40     bool IsDeleted() const {
41       return deleted_;
42     }
43
44     bool IsValid() const {
45       return target() && !IsDeleted();
46     }
47
48     bool pending() const {
49       return pending_;
50     }
51
52     int32 shm_id() const {
53       return shm_id_;
54     }
55
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(bool did_finish) = 0;
68
69     virtual void Destroy(bool have_context) = 0;
70
71     void AddCallback(base::Closure callback);
72
73    protected:
74     virtual ~Query();
75
76     QueryManager* manager() const {
77       return manager_;
78     }
79
80     void MarkAsDeleted() {
81       deleted_ = true;
82     }
83
84     // Returns false if shared memory for sync is invalid.
85     bool MarkAsCompleted(uint64 result);
86
87     void MarkAsPending(base::subtle::Atomic32 submit_count) {
88       DCHECK(!pending_);
89       pending_ = true;
90       submit_count_ = submit_count;
91     }
92
93     void UnmarkAsPending() {
94       DCHECK(pending_);
95       pending_ = false;
96     }
97
98     // Returns false if shared memory for sync is invalid.
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.
104     bool AddToPendingTransferQueue(base::subtle::Atomic32 submit_count) {
105       return manager_->AddPendingTransferQuery(this, submit_count);
106     }
107
108     void BeginQueryHelper(GLenum target, GLuint id) {
109       manager_->BeginQueryHelper(target, id);
110     }
111
112     void EndQueryHelper(GLenum target) {
113       manager_->EndQueryHelper(target);
114     }
115
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. |did_finish| is true if this is called as
174   // a result of calling glFinish().
175   bool ProcessPendingQueries(bool did_finish);
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
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_