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