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/basictypes.h" 11 #include "base/containers/hash_tables.h" 12 #include "base/logging.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "gpu/command_buffer/service/feature_info.h" 16 #include "gpu/command_buffer/service/gl_utils.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(uint32 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 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(uint32 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(uint32 submit_count) { 100 return manager_->AddPendingQuery(this, submit_count); 101 } 102 103 // Returns false if shared memory for sync is invalid. 104 bool AddToPendingTransferQueue(uint32 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 uint32 submit_count() const { 117 return submit_count_; 118 } 119 120 private: 121 friend class QueryManager; 122 friend class QueryManagerTest; 123 friend class base::RefCounted<Query>; 124 125 void RunCallbacks(); 126 127 // The manager that owns this Query. 128 QueryManager* manager_; 129 130 // The type of query. 131 GLenum target_; 132 133 // The shared memory used with this Query. 134 int32 shm_id_; 135 uint32 shm_offset_; 136 137 // Count to set process count do when completed. 138 uint32 submit_count_; 139 140 // True if in the queue. 141 bool pending_; 142 143 // True if deleted. 144 bool deleted_; 145 146 // List of callbacks to run when result is available. 147 std::vector<base::Closure> callbacks_; 148 }; 149 150 QueryManager( 151 GLES2Decoder* decoder, 152 FeatureInfo* feature_info); 153 ~QueryManager(); 154 155 // Must call before destruction. 156 void Destroy(bool have_context); 157 158 // Creates a Query for the given query. 159 Query* CreateQuery( 160 GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset); 161 162 // Gets the query info for the given query. 163 Query* GetQuery(GLuint client_id); 164 165 // Removes a query info for the given query. 166 void RemoveQuery(GLuint client_id); 167 168 // Returns false if any query is pointing to invalid shared memory. 169 bool BeginQuery(Query* query); 170 171 // Returns false if any query is pointing to invalid shared memory. 172 bool EndQuery(Query* query, uint32 submit_count); 173 174 // Processes pending queries. Returns false if any queries are pointing 175 // to invalid shared memory. 176 bool ProcessPendingQueries(); 177 178 // True if there are pending queries. 179 bool HavePendingQueries(); 180 181 // Processes pending transfer queries. Returns false if any queries are 182 // pointing to invalid shared memory. 183 bool ProcessPendingTransferQueries(); 184 185 // True if there are pending transfer queries. 186 bool HavePendingTransferQueries(); 187 188 GLES2Decoder* decoder() const { 189 return decoder_; 190 } 191 192 private: 193 void StartTracking(Query* query); 194 void StopTracking(Query* query); 195 196 // Wrappers for BeginQueryARB and EndQueryARB to hide differences between 197 // ARB_occlusion_query2 and EXT_occlusion_query_boolean. 198 void BeginQueryHelper(GLenum target, GLuint id); 199 void EndQueryHelper(GLenum target); 200 201 // Adds to queue of queries waiting for completion. 202 // Returns false if any query is pointing to invalid shared memory. 203 bool AddPendingQuery(Query* query, uint32 submit_count); 204 205 // Adds to queue of transfer queries waiting for completion. 206 // Returns false if any query is pointing to invalid shared memory. 207 bool AddPendingTransferQuery(Query* query, uint32 submit_count); 208 209 // Removes a query from the queue of pending queries. 210 // Returns false if any query is pointing to invalid shared memory. 211 bool RemovePendingQuery(Query* query); 212 213 // Returns a target used for the underlying GL extension 214 // used to emulate a query. 215 GLenum AdjustTargetForEmulation(GLenum target); 216 217 // Used to validate shared memory and get GL errors. 218 GLES2Decoder* decoder_; 219 220 bool use_arb_occlusion_query2_for_occlusion_query_boolean_; 221 bool use_arb_occlusion_query_for_occlusion_query_boolean_; 222 223 // Counts the number of Queries allocated with 'this' as their manager. 224 // Allows checking no Query will outlive this. 225 unsigned query_count_; 226 227 // Info for each query in the system. 228 typedef base::hash_map<GLuint, scoped_refptr<Query> > QueryMap; 229 QueryMap queries_; 230 231 // Queries waiting for completion. 232 typedef std::deque<scoped_refptr<Query> > QueryQueue; 233 QueryQueue pending_queries_; 234 235 // Async pixel transfer queries waiting for completion. 236 QueryQueue pending_transfer_queries_; 237 238 DISALLOW_COPY_AND_ASSIGN(QueryManager); 239 }; 240 241 } // namespace gles2 242 } // namespace gpu 243 244 #endif // GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_ 245