15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GPU_COMMAND_BUFFER_CLIENT_QUERY_TRACKER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPU_COMMAND_BUFFER_CLIENT_QUERY_TRACKER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <deque>
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <list>
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/atomicops.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/containers/hash_tables.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gles2_impl_export.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_format.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CommandBufferHelper;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MappedMemoryManager;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gles2 {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GLES2Implementation;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Manages buckets of QuerySync instances in mapped memory.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GLES2_IMPL_EXPORT QuerySyncManager {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const size_t kSyncsPerBucket = 4096;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct Bucket {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    explicit Bucket(QuerySync* sync_mem)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        : syncs(sync_mem),
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          used_query_count(0) {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuerySync* syncs;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned used_query_count;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct QueryInfo {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QueryInfo(Bucket* bucket, int32 id, uint32 offset, QuerySync* sync_mem)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        : bucket(bucket),
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          shm_id(id),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          shm_offset(offset),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sync(sync_mem) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QueryInfo()
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        : bucket(NULL),
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          shm_id(0),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          shm_offset(0),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          sync(NULL) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Bucket* bucket;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 shm_id;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 shm_offset;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuerySync* sync;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit QuerySyncManager(MappedMemoryManager* manager);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~QuerySyncManager();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Alloc(QueryInfo* info);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Free(const QueryInfo& sync);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Shrink();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MappedMemoryManager* mapped_memory_;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::deque<Bucket*> buckets_;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::deque<QueryInfo> free_queries_;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QuerySyncManager);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tracks queries for client side of command buffer.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GLES2_IMPL_EXPORT QueryTracker {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class GLES2_IMPL_EXPORT Query {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    enum State {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUninitialized,  // never used
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kActive,         // between begin - end
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kPending,        // not yet complete
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kComplete        // completed
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Query(GLuint id, GLenum target, const QuerySyncManager::QueryInfo& info);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target() const {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return target_;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum id() const {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return id_;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 shm_id() const {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return info_.shm_id;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 shm_offset() const {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return info_.shm_offset;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void MarkAsActive() {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      state_ = kActive;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++submit_count_;
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      if (submit_count_ == INT_MAX)
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        submit_count_ = 1;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void MarkAsPending(int32 token) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      token_ = token;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      state_ = kPending;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::subtle::Atomic32 submit_count() const { return submit_count_; }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 token() const {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return token_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool NeverUsed() const {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return state_ == kUninitialized;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool Pending() const {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return state_ == kPending;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool CheckResultsAvailable(CommandBufferHelper* helper);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 GetResult() const;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void Begin(GLES2Implementation* gl);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void End(GLES2Implementation* gl);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    friend class QueryTracker;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    friend class QueryTrackerTest;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLuint id_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GLenum target_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QuerySyncManager::QueryInfo info_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state_;
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::subtle::Atomic32 submit_count_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int32 token_;
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    uint32 flush_count_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint64 client_begin_time_us_; // Only used for latency query target.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 result_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryTracker(MappedMemoryManager* manager);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~QueryTracker();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Query* CreateQuery(GLuint id, GLenum target);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Query* GetQuery(GLuint id);
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void RemoveQuery(GLuint id);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Shrink();
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void FreeCompletedQueries();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  typedef base::hash_map<GLuint, Query*> QueryMap;
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  typedef std::list<Query*> QueryList;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryMap queries_;
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  QueryList removed_queries_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuerySyncManager query_sync_manager_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QueryTracker);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gles2
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GPU_COMMAND_BUFFER_CLIENT_QUERY_TRACKER_H_
178