blob: c4505f1d55bcea822b45cc2ebd984e07cde8b58e [file] [log] [blame]
// 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_