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