Home | History | Annotate | Download | only in service
      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_SERVICE_QUERY_MANAGER_H_
      6 #define GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_
      7 
      8 #include <deque>
      9 #include <vector>
     10 #include "base/basictypes.h"
     11 #include "base/containers/hash_tables.h"
     12 #include "base/logging.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "gpu/command_buffer/service/feature_info.h"
     16 #include "gpu/command_buffer/service/gl_utils.h"
     17 #include "gpu/gpu_export.h"
     18 
     19 namespace gpu {
     20 
     21 class GLES2Decoder;
     22 
     23 namespace gles2 {
     24 
     25 class FeatureInfo;
     26 
     27 // This class keeps track of the queries and their state
     28 // As Queries are not shared there is one QueryManager per context.
     29 class GPU_EXPORT QueryManager {
     30  public:
     31   class GPU_EXPORT Query : public base::RefCounted<Query> {
     32    public:
     33     Query(
     34         QueryManager* manager, GLenum target, int32 shm_id, uint32 shm_offset);
     35 
     36     GLenum target() const {
     37       return target_;
     38     }
     39 
     40     bool IsDeleted() const {
     41       return deleted_;
     42     }
     43 
     44     bool IsValid() const {
     45       return target() && !IsDeleted();
     46     }
     47 
     48     bool pending() const {
     49       return pending_;
     50     }
     51 
     52     int32 shm_id() const {
     53       return shm_id_;
     54     }
     55 
     56     uint32 shm_offset() const {
     57       return shm_offset_;
     58     }
     59 
     60     // Returns false if shared memory for sync is invalid.
     61     virtual bool Begin() = 0;
     62 
     63     // Returns false if shared memory for sync is invalid.
     64     virtual bool End(uint32 submit_count) = 0;
     65 
     66     // Returns false if shared memory for sync is invalid.
     67     virtual bool Process() = 0;
     68 
     69     virtual void Destroy(bool have_context) = 0;
     70 
     71     void AddCallback(base::Closure callback);
     72 
     73    protected:
     74     virtual ~Query();
     75 
     76     QueryManager* manager() const {
     77       return manager_;
     78     }
     79 
     80     void MarkAsDeleted() {
     81       deleted_ = true;
     82     }
     83 
     84     // Returns false if shared memory for sync is invalid.
     85     bool MarkAsCompleted(uint64 result);
     86 
     87     void MarkAsPending(uint32 submit_count) {
     88       DCHECK(!pending_);
     89       pending_ = true;
     90       submit_count_ = submit_count;
     91     }
     92 
     93     void UnmarkAsPending() {
     94       DCHECK(pending_);
     95       pending_ = false;
     96     }
     97 
     98     // Returns false if shared memory for sync is invalid.
     99     bool AddToPendingQueue(uint32 submit_count) {
    100       return manager_->AddPendingQuery(this, submit_count);
    101     }
    102 
    103     // Returns false if shared memory for sync is invalid.
    104     bool AddToPendingTransferQueue(uint32 submit_count) {
    105       return manager_->AddPendingTransferQuery(this, submit_count);
    106     }
    107 
    108     void BeginQueryHelper(GLenum target, GLuint id) {
    109       manager_->BeginQueryHelper(target, id);
    110     }
    111 
    112     void EndQueryHelper(GLenum target) {
    113       manager_->EndQueryHelper(target);
    114     }
    115 
    116     uint32 submit_count() const {
    117       return submit_count_;
    118     }
    119 
    120    private:
    121     friend class QueryManager;
    122     friend class QueryManagerTest;
    123     friend class base::RefCounted<Query>;
    124 
    125     void RunCallbacks();
    126 
    127     // The manager that owns this Query.
    128     QueryManager* manager_;
    129 
    130     // The type of query.
    131     GLenum target_;
    132 
    133     // The shared memory used with this Query.
    134     int32 shm_id_;
    135     uint32 shm_offset_;
    136 
    137     // Count to set process count do when completed.
    138     uint32 submit_count_;
    139 
    140     // True if in the queue.
    141     bool pending_;
    142 
    143     // True if deleted.
    144     bool deleted_;
    145 
    146     // List of callbacks to run when result is available.
    147     std::vector<base::Closure> callbacks_;
    148   };
    149 
    150   QueryManager(
    151       GLES2Decoder* decoder,
    152       FeatureInfo* feature_info);
    153   ~QueryManager();
    154 
    155   // Must call before destruction.
    156   void Destroy(bool have_context);
    157 
    158   // Creates a Query for the given query.
    159   Query* CreateQuery(
    160       GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset);
    161 
    162   // Gets the query info for the given query.
    163   Query* GetQuery(GLuint client_id);
    164 
    165   // Removes a query info for the given query.
    166   void RemoveQuery(GLuint client_id);
    167 
    168   // Returns false if any query is pointing to invalid shared memory.
    169   bool BeginQuery(Query* query);
    170 
    171   // Returns false if any query is pointing to invalid shared memory.
    172   bool EndQuery(Query* query, uint32 submit_count);
    173 
    174   // Processes pending queries. Returns false if any queries are pointing
    175   // to invalid shared memory.
    176   bool ProcessPendingQueries();
    177 
    178   // True if there are pending queries.
    179   bool HavePendingQueries();
    180 
    181   // Processes pending transfer queries. Returns false if any queries are
    182   // pointing to invalid shared memory.
    183   bool ProcessPendingTransferQueries();
    184 
    185   // True if there are pending transfer queries.
    186   bool HavePendingTransferQueries();
    187 
    188   GLES2Decoder* decoder() const {
    189     return decoder_;
    190   }
    191 
    192  private:
    193   void StartTracking(Query* query);
    194   void StopTracking(Query* query);
    195 
    196   // Wrappers for BeginQueryARB and EndQueryARB to hide differences between
    197   // ARB_occlusion_query2 and EXT_occlusion_query_boolean.
    198   void BeginQueryHelper(GLenum target, GLuint id);
    199   void EndQueryHelper(GLenum target);
    200 
    201   // Adds to queue of queries waiting for completion.
    202   // Returns false if any query is pointing to invalid shared memory.
    203   bool AddPendingQuery(Query* query, uint32 submit_count);
    204 
    205   // Adds to queue of transfer queries waiting for completion.
    206   // Returns false if any query is pointing to invalid shared memory.
    207   bool AddPendingTransferQuery(Query* query, uint32 submit_count);
    208 
    209   // Removes a query from the queue of pending queries.
    210   // Returns false if any query is pointing to invalid shared memory.
    211   bool RemovePendingQuery(Query* query);
    212 
    213   // Returns a target used for the underlying GL extension
    214   // used to emulate a query.
    215   GLenum AdjustTargetForEmulation(GLenum target);
    216 
    217   // Used to validate shared memory and get GL errors.
    218   GLES2Decoder* decoder_;
    219 
    220   bool use_arb_occlusion_query2_for_occlusion_query_boolean_;
    221   bool use_arb_occlusion_query_for_occlusion_query_boolean_;
    222 
    223   // Counts the number of Queries allocated with 'this' as their manager.
    224   // Allows checking no Query will outlive this.
    225   unsigned query_count_;
    226 
    227   // Info for each query in the system.
    228   typedef base::hash_map<GLuint, scoped_refptr<Query> > QueryMap;
    229   QueryMap queries_;
    230 
    231   // Queries waiting for completion.
    232   typedef std::deque<scoped_refptr<Query> > QueryQueue;
    233   QueryQueue pending_queries_;
    234 
    235   // Async pixel transfer queries waiting for completion.
    236   QueryQueue pending_transfer_queries_;
    237 
    238   DISALLOW_COPY_AND_ASSIGN(QueryManager);
    239 };
    240 
    241 }  // namespace gles2
    242 }  // namespace gpu
    243 
    244 #endif  // GPU_COMMAND_BUFFER_SERVICE_QUERY_MANAGER_H_
    245