diff options
Diffstat (limited to 'ui/gl/gpu_timing.h')
-rw-r--r-- | ui/gl/gpu_timing.h | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/ui/gl/gpu_timing.h b/ui/gl/gpu_timing.h new file mode 100644 index 0000000..9702fe1 --- /dev/null +++ b/ui/gl/gpu_timing.h @@ -0,0 +1,136 @@ +// 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 GPU_COMMAND_BUFFER_SERVICE_GPU_TIMING_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GPU_TIMING_H_ + +#include "base/callback.h" +#include "base/memory/scoped_ptr.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 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 GPU trace they will +// create GPUTimer objects. +// GPUTimer - Once a user decides to trace 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 gfx { + +class GLContextReal; +class GPUTimingClient; + +class GPUTiming { + public: + enum TimerType { + kTimerTypeInvalid = -1, + + kTimerTypeARB, // ARB_timer_query + kTimerTypeDisjoint // EXT_disjoint_timer_query + }; + + TimerType GetTimerType() const { return timer_type_; } + + private: + friend struct base::DefaultDeleter<GPUTiming>; + friend class GLContextReal; + explicit GPUTiming(GLContextReal* context); + ~GPUTiming(); + + scoped_refptr<GPUTimingClient> CreateGPUTimingClient(); + + TimerType timer_type_ = kTimerTypeInvalid; + 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: + ~GPUTimer(); + + void Start(); + void End(); + bool IsAvailable(); + + void GetStartEndTimestamps(int64* start, int64* end); + int64 GetDeltaElapsed(); + + private: + friend class GPUTimingClient; + + explicit GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client); + + unsigned int queries_[2]; + int64 offset_ = 0; + bool end_requested_ = false; + scoped_refptr<GPUTimingClient> gpu_timing_client_; + + 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(GPUTiming* gpu_timing = nullptr); + + scoped_ptr<GPUTimer> CreateGPUTimer(); + 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(); + + // Returns the offset between the current gpu time and the cpu time. + int64 CalculateTimerOffset(); + void InvalidateTimerOffset(); + + void SetCpuTimeForTesting(const base::Callback<int64(void)>& cpu_time); + + private: + friend class base::RefCounted<GPUTimingClient>; + friend class GPUTimer; + friend class GPUTiming; + + virtual ~GPUTimingClient(); + + GPUTiming* gpu_timing_; + GPUTiming::TimerType timer_type_ = GPUTiming::kTimerTypeInvalid; + int64 offset_ = 0; // offset cache when timer_type_ == kTimerTypeARB + bool offset_valid_ = false; + base::Callback<int64(void)> cpu_time_for_testing_; + + DISALLOW_COPY_AND_ASSIGN(GPUTimingClient); +}; + +} // namespace gfx + +#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_TIMING_H_ |