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 37 GLenum target() const { 38 return target_; 39 } 40 41 bool IsDeleted() const { 42 return deleted_; 43 } 44 45 bool IsValid() const { 46 return target() && !IsDeleted(); 47 } 48 49 bool pending() const { 50 return pending_; 51 } 52 53 int32 shm_id() const { 54 return shm_id_; 55 } 56 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 77 QueryManager* manager() const { 78 return manager_; 79 } 80 81 void MarkAsDeleted() { 82 deleted_ = true; 83 } 84 85 // Returns false if shared memory for sync is invalid. 86 bool MarkAsCompleted(uint64 result); 87 88 void MarkAsPending(base::subtle::Atomic32 submit_count) { 89 DCHECK(!pending_); 90 pending_ = true; 91 submit_count_ = submit_count; 92 } 93 94 void UnmarkAsPending() { 95 DCHECK(pending_); 96 pending_ = false; 97 } 98 99 // Returns false if shared memory for sync is invalid. 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. 105 bool AddToPendingTransferQueue(base::subtle::Atomic32 submit_count) { 106 return manager_->AddPendingTransferQuery(this, submit_count); 107 } 108 109 void BeginQueryHelper(GLenum target, GLuint id) { 110 manager_->BeginQueryHelper(target, id); 111 } 112 113 void EndQueryHelper(GLenum target) { 114 manager_->EndQueryHelper(target); 115 } 116 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 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