// 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 #include #include #include #include #include #include #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 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 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 QueryIdMap; typedef base::hash_map QueryTargetMap; typedef std::list 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_