| // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef UI_GL_GPU_TIMING_H_ |
| #define UI_GL_GPU_TIMING_H_ |
| |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <queue> |
| |
| #include "base/callback.h" |
| #include "base/macros.h" |
| #include "ui/gl/gl_export.h" |
| |
| // The gpu_timing classes handles the abstraction of GL GPU Timing extensions |
| // into a common set of functions. Currently the different timer extensions that |
| // are supported are EXT_timer_query, ARB_timer_query and |
| // EXT_disjoint_timer_query. |
| // |
| // Explanation of Classes: |
| // GPUTiming - GPU Timing is a private class which is only owned by the |
| // underlying GLContextReal class. This class handles any GL Context level |
| // states which may need to be redistributed to users of GPUTiming. For |
| // example, there exists only a single disjoint flag for each real GL |
| // Context. Once the disjoint flag is checked, internally it is reset to |
| // false. In order to support multiple virtual contexts each checking the |
| // disjoint flag seperately, GPUTiming is in charge of checking the |
| // disjoint flag and broadcasting out the disjoint state to all the |
| // various users of GPUTiming (GPUTimingClient below). |
| // GPUTimingClient - The GLContextReal holds the GPUTiming class and is the |
| // factory that creates GPUTimingClient objects. If a user would like to |
| // obtain various GPU times they would access CreateGPUTimingClient() from |
| // their GLContext and use the returned object for their timing calls. |
| // Each virtual context as well as any other classes which need GPU times |
| // will hold one of these. When they want to time a set of GL commands they |
| // will create GPUTimer objects. |
| // GPUTimer - Once a user decides to time something, the user creates a new |
| // GPUTimer object from a GPUTimingClient and issue Start() and Stop() calls |
| // around various GL calls. Once IsAvailable() returns true, the GPU times |
| // will be available through the various time stamp related functions. |
| // The constructor and destructor of this object handles the actual |
| // creation and deletion of the GL Queries within GL. |
| |
| namespace gl { |
| |
| class GLContextReal; |
| class GPUTimingClient; |
| class GPUTimingImpl; |
| class QueryResult; |
| |
| class GPUTiming { |
| public: |
| enum TimerType { |
| kTimerTypeInvalid = -1, |
| |
| kTimerTypeEXT, // EXT_timer_query |
| kTimerTypeARB, // ARB_timer_query |
| kTimerTypeDisjoint // EXT_disjoint_timer_query |
| }; |
| |
| protected: |
| friend std::default_delete<GPUTiming>; |
| friend class GLContextReal; |
| |
| static GPUTiming* CreateGPUTiming(GLContextReal* context); |
| |
| GPUTiming(); |
| virtual ~GPUTiming(); |
| |
| virtual scoped_refptr<GPUTimingClient> CreateGPUTimingClient() = 0; |
| |
| DISALLOW_COPY_AND_ASSIGN(GPUTiming); |
| }; |
| |
| // Class to compute the amount of time it takes to fully |
| // complete a set of GL commands |
| class GL_EXPORT GPUTimer { |
| public: |
| static void DisableTimestampQueries(); |
| |
| ~GPUTimer(); |
| |
| // Destroy the timer object. This must be explicitly called before destroying |
| // this object. |
| void Destroy(bool have_context); |
| |
| // Clears current queries. |
| void Reset(); |
| |
| // Start an instant timer, start and end will be equal. |
| void QueryTimeStamp(); |
| |
| // Start a timer range. |
| void Start(); |
| void End(); |
| |
| bool IsAvailable(); |
| |
| void GetStartEndTimestamps(int64_t* start, int64_t* end); |
| int64_t GetDeltaElapsed(); |
| |
| private: |
| friend class GPUTimingClient; |
| |
| explicit GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client, |
| bool use_elapsed_timer); |
| |
| bool use_elapsed_timer_ = false; |
| enum TimerState { |
| kTimerState_Ready, |
| kTimerState_WaitingForEnd, |
| kTimerState_WaitingForResult, |
| kTimerState_ResultAvailable |
| } timer_state_ = kTimerState_Ready; |
| scoped_refptr<GPUTimingClient> gpu_timing_client_; |
| scoped_refptr<QueryResult> time_stamp_result_; |
| scoped_refptr<QueryResult> elapsed_timer_result_; |
| |
| DISALLOW_COPY_AND_ASSIGN(GPUTimer); |
| }; |
| |
| // GPUTimingClient contains all the gl timing logic that is not specific |
| // to a single GPUTimer. |
| class GL_EXPORT GPUTimingClient |
| : public base::RefCounted<GPUTimingClient> { |
| public: |
| explicit GPUTimingClient(GPUTimingImpl* gpu_timing = nullptr); |
| |
| std::unique_ptr<GPUTimer> CreateGPUTimer(bool prefer_elapsed_time); |
| bool IsAvailable(); |
| |
| const char* GetTimerTypeName() const; |
| |
| // CheckAndResetTimerErrors has to be called before reading timestamps |
| // from GPUTimers instances and after making sure all the timers |
| // were available. |
| // If the returned value is false, all the previous timers should be |
| // discarded. |
| bool CheckAndResetTimerErrors(); |
| |
| int64_t GetCurrentCPUTime(); |
| void SetCpuTimeForTesting(const base::Callback<int64_t(void)>& cpu_time); |
| |
| bool IsForceTimeElapsedQuery(); |
| void ForceTimeElapsedQuery(); |
| |
| private: |
| friend class base::RefCounted<GPUTimingClient>; |
| friend class GPUTimer; |
| |
| virtual ~GPUTimingClient(); |
| |
| GPUTimingImpl* gpu_timing_; |
| GPUTiming::TimerType timer_type_ = GPUTiming::kTimerTypeInvalid; |
| uint32_t disjoint_counter_ = 0; |
| |
| DISALLOW_COPY_AND_ASSIGN(GPUTimingClient); |
| }; |
| |
| } // namespace gl |
| |
| #endif // UI_GL_GPU_TIMING_H_ |