|  | // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef GPU_COMMAND_BUFFER_CLIENT_QUERY_TRACKER_H_ | 
|  | #define GPU_COMMAND_BUFFER_CLIENT_QUERY_TRACKER_H_ | 
|  |  | 
|  | #include <GLES2/gl2.h> | 
|  | #include <limits.h> | 
|  | #include <stddef.h> | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <bitset> | 
|  | #include <deque> | 
|  | #include <list> | 
|  |  | 
|  | #include "base/atomicops.h" | 
|  | #include "base/containers/hash_tables.h" | 
|  | #include "base/macros.h" | 
|  | #include "gles2_impl_export.h" | 
|  | #include "gpu/command_buffer/common/gles2_cmd_format.h" | 
|  |  | 
|  | namespace gpu { | 
|  |  | 
|  | class CommandBufferHelper; | 
|  | class MappedMemoryManager; | 
|  |  | 
|  | namespace gles2 { | 
|  |  | 
|  | class GLES2Implementation; | 
|  |  | 
|  | // Manages buckets of QuerySync instances in mapped memory. | 
|  | class GLES2_IMPL_EXPORT QuerySyncManager { | 
|  | public: | 
|  | static const size_t kSyncsPerBucket = 256; | 
|  |  | 
|  | struct Bucket { | 
|  | Bucket(QuerySync* sync_mem, int32_t shm_id, uint32_t shm_offset); | 
|  | ~Bucket(); | 
|  | QuerySync* syncs; | 
|  | int32_t shm_id; | 
|  | uint32_t base_shm_offset; | 
|  | std::bitset<kSyncsPerBucket> in_use_queries; | 
|  | }; | 
|  | struct QueryInfo { | 
|  | QueryInfo(Bucket* bucket, int32_t id, uint32_t offset, QuerySync* sync_mem) | 
|  | : bucket(bucket), shm_id(id), shm_offset(offset), sync(sync_mem) {} | 
|  |  | 
|  | QueryInfo() | 
|  | : bucket(NULL), | 
|  | shm_id(0), | 
|  | shm_offset(0), | 
|  | sync(NULL) { | 
|  | } | 
|  |  | 
|  | Bucket* bucket; | 
|  | int32_t shm_id; | 
|  | uint32_t shm_offset; | 
|  | QuerySync* sync; | 
|  | }; | 
|  |  | 
|  | explicit QuerySyncManager(MappedMemoryManager* manager); | 
|  | ~QuerySyncManager(); | 
|  |  | 
|  | bool Alloc(QueryInfo* info); | 
|  | void Free(const QueryInfo& sync); | 
|  | void Shrink(); | 
|  |  | 
|  | private: | 
|  | MappedMemoryManager* mapped_memory_; | 
|  | std::deque<Bucket*> buckets_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(QuerySyncManager); | 
|  | }; | 
|  |  | 
|  | // Tracks queries for client side of command buffer. | 
|  | class GLES2_IMPL_EXPORT QueryTracker { | 
|  | public: | 
|  | class GLES2_IMPL_EXPORT Query { | 
|  | public: | 
|  | enum State { | 
|  | kUninitialized,  // never used | 
|  | kActive,         // between begin - end | 
|  | kPending,        // not yet complete | 
|  | kComplete        // completed | 
|  | }; | 
|  |  | 
|  | Query(GLuint id, GLenum target, const QuerySyncManager::QueryInfo& info); | 
|  |  | 
|  | GLenum target() const { | 
|  | return target_; | 
|  | } | 
|  |  | 
|  | GLuint id() const { | 
|  | return id_; | 
|  | } | 
|  |  | 
|  | int32_t shm_id() const { return info_.shm_id; } | 
|  |  | 
|  | uint32_t shm_offset() const { return info_.shm_offset; } | 
|  |  | 
|  | void MarkAsActive() { | 
|  | state_ = kActive; | 
|  | ++submit_count_; | 
|  | if (submit_count_ == INT_MAX) | 
|  | submit_count_ = 1; | 
|  | } | 
|  |  | 
|  | void MarkAsPending(int32_t token) { | 
|  | token_ = token; | 
|  | state_ = kPending; | 
|  | } | 
|  |  | 
|  | base::subtle::Atomic32 submit_count() const { return submit_count_; } | 
|  |  | 
|  | int32_t token() const { return token_; } | 
|  |  | 
|  | bool NeverUsed() const { | 
|  | return state_ == kUninitialized; | 
|  | } | 
|  |  | 
|  | bool Active() const { | 
|  | return state_ == kActive; | 
|  | } | 
|  |  | 
|  | bool Pending() const { | 
|  | return state_ == kPending; | 
|  | } | 
|  |  | 
|  | bool CheckResultsAvailable(CommandBufferHelper* helper); | 
|  |  | 
|  | uint64_t GetResult() const; | 
|  |  | 
|  | private: | 
|  | friend class QueryTracker; | 
|  | friend class QueryTrackerTest; | 
|  |  | 
|  | void Begin(GLES2Implementation* gl); | 
|  | void End(GLES2Implementation* gl); | 
|  | void QueryCounter(GLES2Implementation* gl); | 
|  |  | 
|  | GLuint id_; | 
|  | GLenum target_; | 
|  | QuerySyncManager::QueryInfo info_; | 
|  | State state_; | 
|  | base::subtle::Atomic32 submit_count_; | 
|  | int32_t token_; | 
|  | uint32_t flush_count_; | 
|  | uint64_t client_begin_time_us_;  // Only used for latency query target. | 
|  | uint64_t result_; | 
|  | }; | 
|  |  | 
|  | QueryTracker(MappedMemoryManager* manager); | 
|  | ~QueryTracker(); | 
|  |  | 
|  | Query* CreateQuery(GLuint id, GLenum target); | 
|  | Query* GetQuery(GLuint id); | 
|  | Query* GetCurrentQuery(GLenum target); | 
|  | void RemoveQuery(GLuint id); | 
|  | void Shrink(); | 
|  | void FreeCompletedQueries(); | 
|  |  | 
|  | bool BeginQuery(GLuint id, GLenum target, GLES2Implementation* gl); | 
|  | bool EndQuery(GLenum target, GLES2Implementation* gl); | 
|  | bool QueryCounter(GLuint id, GLenum target, GLES2Implementation* gl); | 
|  | bool SetDisjointSync(GLES2Implementation* gl); | 
|  | bool CheckAndResetDisjoint(); | 
|  |  | 
|  | int32_t DisjointCountSyncShmID() const { | 
|  | return disjoint_count_sync_shm_id_; | 
|  | } | 
|  |  | 
|  | uint32_t DisjointCountSyncShmOffset() const { | 
|  | return disjoint_count_sync_shm_offset_; | 
|  | } | 
|  |  | 
|  | private: | 
|  | typedef base::hash_map<GLuint, Query*> QueryIdMap; | 
|  | typedef base::hash_map<GLenum, Query*> QueryTargetMap; | 
|  | typedef std::list<Query*> QueryList; | 
|  |  | 
|  | QueryIdMap queries_; | 
|  | QueryTargetMap current_queries_; | 
|  | QueryList removed_queries_; | 
|  | QuerySyncManager query_sync_manager_; | 
|  |  | 
|  | // The shared memory used for synchronizing timer disjoint values. | 
|  | MappedMemoryManager* mapped_memory_; | 
|  | int32_t disjoint_count_sync_shm_id_; | 
|  | uint32_t disjoint_count_sync_shm_offset_; | 
|  | DisjointValueSync* disjoint_count_sync_; | 
|  | uint32_t local_disjoint_count_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(QueryTracker); | 
|  | }; | 
|  |  | 
|  | }  // namespace gles2 | 
|  | }  // namespace gpu | 
|  |  | 
|  | #endif  // GPU_COMMAND_BUFFER_CLIENT_QUERY_TRACKER_H_ |