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