// 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_
