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/containers/hash_tables.h"
14#include "gles2_impl_export.h"
15#include "gpu/command_buffer/common/gles2_cmd_format.h"
16
17namespace gpu {
18
19class CommandBufferHelper;
20class MappedMemoryManager;
21
22namespace gles2 {
23
24class GLES2Implementation;
25
26// Manages buckets of QuerySync instances in mapped memory.
27class GLES2_IMPL_EXPORT QuerySyncManager {
28 public:
29  static const size_t kSyncsPerBucket = 4096;
30
31  struct Bucket {
32    explicit Bucket(QuerySync* sync_mem)
33        : syncs(sync_mem),
34          used_query_count(0) {
35    }
36    QuerySync* syncs;
37    unsigned used_query_count;
38  };
39  struct QueryInfo {
40    QueryInfo(Bucket* bucket, int32 id, uint32 offset, QuerySync* sync_mem)
41        : bucket(bucket),
42          shm_id(id),
43          shm_offset(offset),
44          sync(sync_mem) {
45    }
46
47    QueryInfo()
48        : bucket(NULL),
49          shm_id(0),
50          shm_offset(0),
51          sync(NULL) {
52    }
53
54    Bucket* bucket;
55    int32 shm_id;
56    uint32 shm_offset;
57    QuerySync* sync;
58  };
59
60  explicit QuerySyncManager(MappedMemoryManager* manager);
61  ~QuerySyncManager();
62
63  bool Alloc(QueryInfo* info);
64  void Free(const QueryInfo& sync);
65  void Shrink();
66
67 private:
68  MappedMemoryManager* mapped_memory_;
69  std::deque<Bucket*> buckets_;
70  std::deque<QueryInfo> free_queries_;
71
72  DISALLOW_COPY_AND_ASSIGN(QuerySyncManager);
73};
74
75// Tracks queries for client side of command buffer.
76class GLES2_IMPL_EXPORT QueryTracker {
77 public:
78  class GLES2_IMPL_EXPORT Query {
79   public:
80    enum State {
81      kUninitialized,  // never used
82      kActive,         // between begin - end
83      kPending,        // not yet complete
84      kComplete        // completed
85    };
86
87    Query(GLuint id, GLenum target, const QuerySyncManager::QueryInfo& info);
88
89    GLenum target() const {
90      return target_;
91    }
92
93    GLenum id() const {
94      return id_;
95    }
96
97    int32 shm_id() const {
98      return info_.shm_id;
99    }
100
101    uint32 shm_offset() const {
102      return info_.shm_offset;
103    }
104
105    void MarkAsActive() {
106      state_ = kActive;
107      ++submit_count_;
108    }
109
110    void MarkAsPending(int32 token) {
111      token_ = token;
112      state_ = kPending;
113      flushed_ = false;
114    }
115
116    uint32 submit_count() const {
117      return submit_count_;
118    }
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    uint32 submit_count_;
148    int32 token_;
149    bool flushed_;
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