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_CLIENT_QUERY_TRACKER_H_ 6#define GPU_COMMAND_BUFFER_CLIENT_QUERY_TRACKER_H_ 7 8#include <GLES2/gl2.h> 9 10#include <deque> 11#include <list> 12 13#include "base/atomicops.h" 14#include "base/containers/hash_tables.h" 15#include "gles2_impl_export.h" 16#include "gpu/command_buffer/common/gles2_cmd_format.h" 17 18namespace gpu { 19 20class CommandBufferHelper; 21class MappedMemoryManager; 22 23namespace gles2 { 24 25class GLES2Implementation; 26 27// Manages buckets of QuerySync instances in mapped memory. 28class GLES2_IMPL_EXPORT QuerySyncManager { 29 public: 30 static const size_t kSyncsPerBucket = 4096; 31 32 struct Bucket { 33 explicit Bucket(QuerySync* sync_mem) 34 : syncs(sync_mem), 35 used_query_count(0) { 36 } 37 QuerySync* syncs; 38 unsigned used_query_count; 39 }; 40 struct QueryInfo { 41 QueryInfo(Bucket* bucket, int32 id, uint32 offset, QuerySync* sync_mem) 42 : bucket(bucket), 43 shm_id(id), 44 shm_offset(offset), 45 sync(sync_mem) { 46 } 47 48 QueryInfo() 49 : bucket(NULL), 50 shm_id(0), 51 shm_offset(0), 52 sync(NULL) { 53 } 54 55 Bucket* bucket; 56 int32 shm_id; 57 uint32 shm_offset; 58 QuerySync* sync; 59 }; 60 61 explicit QuerySyncManager(MappedMemoryManager* manager); 62 ~QuerySyncManager(); 63 64 bool Alloc(QueryInfo* info); 65 void Free(const QueryInfo& sync); 66 void Shrink(); 67 68 private: 69 MappedMemoryManager* mapped_memory_; 70 std::deque<Bucket*> buckets_; 71 std::deque<QueryInfo> free_queries_; 72 73 DISALLOW_COPY_AND_ASSIGN(QuerySyncManager); 74}; 75 76// Tracks queries for client side of command buffer. 77class GLES2_IMPL_EXPORT QueryTracker { 78 public: 79 class GLES2_IMPL_EXPORT Query { 80 public: 81 enum State { 82 kUninitialized, // never used 83 kActive, // between begin - end 84 kPending, // not yet complete 85 kComplete // completed 86 }; 87 88 Query(GLuint id, GLenum target, const QuerySyncManager::QueryInfo& info); 89 90 GLenum target() const { 91 return target_; 92 } 93 94 GLenum id() const { 95 return id_; 96 } 97 98 int32 shm_id() const { 99 return info_.shm_id; 100 } 101 102 uint32 shm_offset() const { 103 return info_.shm_offset; 104 } 105 106 void MarkAsActive() { 107 state_ = kActive; 108 ++submit_count_; 109 if (submit_count_ == INT_MAX) 110 submit_count_ = 1; 111 } 112 113 void MarkAsPending(int32 token) { 114 token_ = token; 115 state_ = kPending; 116 } 117 118 base::subtle::Atomic32 submit_count() const { return submit_count_; } 119 120 int32 token() const { 121 return token_; 122 } 123 124 bool NeverUsed() const { 125 return state_ == kUninitialized; 126 } 127 128 bool Pending() const { 129 return state_ == kPending; 130 } 131 132 bool CheckResultsAvailable(CommandBufferHelper* helper); 133 134 uint32 GetResult() const; 135 136 void Begin(GLES2Implementation* gl); 137 void End(GLES2Implementation* gl); 138 139 private: 140 friend class QueryTracker; 141 friend class QueryTrackerTest; 142 143 GLuint id_; 144 GLenum target_; 145 QuerySyncManager::QueryInfo info_; 146 State state_; 147 base::subtle::Atomic32 submit_count_; 148 int32 token_; 149 uint32 flush_count_; 150 uint64 client_begin_time_us_; // Only used for latency query target. 151 uint32 result_; 152 }; 153 154 QueryTracker(MappedMemoryManager* manager); 155 ~QueryTracker(); 156 157 Query* CreateQuery(GLuint id, GLenum target); 158 Query* GetQuery(GLuint id); 159 void RemoveQuery(GLuint id); 160 void Shrink(); 161 void FreeCompletedQueries(); 162 163 private: 164 typedef base::hash_map<GLuint, Query*> QueryMap; 165 typedef std::list<Query*> QueryList; 166 167 QueryMap queries_; 168 QueryList removed_queries_; 169 QuerySyncManager query_sync_manager_; 170 171 DISALLOW_COPY_AND_ASSIGN(QueryTracker); 172}; 173 174} // namespace gles2 175} // namespace gpu 176 177#endif // GPU_COMMAND_BUFFER_CLIENT_QUERY_TRACKER_H_ 178