Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2016 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef GpuTimer_DEFINED
      9 #define GpuTimer_DEFINED
     10 
     11 #include "SkTypes.h"
     12 #include "SkExchange.h"
     13 #include <chrono>
     14 
     15 namespace sk_gpu_test {
     16 
     17 using PlatformTimerQuery = uint64_t;
     18 static constexpr PlatformTimerQuery kInvalidTimerQuery = 0;
     19 
     20 /**
     21  * Platform-independent interface for timing operations on the GPU.
     22  */
     23 class GpuTimer {
     24 public:
     25     GpuTimer(bool disjointSupport)
     26         : fDisjointSupport(disjointSupport)
     27         , fActiveTimer(kInvalidTimerQuery) {
     28     }
     29     virtual ~GpuTimer() { SkASSERT(!fActiveTimer); }
     30 
     31     /**
     32      * Returns whether this timer can detect disjoint GPU operations while timing. If false, a query
     33      * has less confidence when it completes with QueryStatus::kAccurate.
     34      */
     35     bool disjointSupport() const { return fDisjointSupport; }
     36 
     37     /**
     38      * Inserts a "start timing" command in the GPU command stream.
     39      */
     40     void queueStart() {
     41         SkASSERT(!fActiveTimer);
     42         fActiveTimer = this->onQueueTimerStart();
     43     }
     44 
     45     /**
     46      * Inserts a "stop timing" command in the GPU command stream.
     47      *
     48      * @return a query object that can retrieve the time elapsed once the timer has completed.
     49      */
     50     PlatformTimerQuery SK_WARN_UNUSED_RESULT queueStop() {
     51         SkASSERT(fActiveTimer);
     52         this->onQueueTimerStop(fActiveTimer);
     53         return skstd::exchange(fActiveTimer, kInvalidTimerQuery);
     54     }
     55 
     56     enum class QueryStatus {
     57         kInvalid,  //<! the timer query is invalid.
     58         kPending,  //<! the timer is still running on the GPU.
     59         kDisjoint, //<! the query is complete, but dubious due to disjoint GPU operations.
     60         kAccurate  //<! the query is complete and reliable.
     61     };
     62 
     63     virtual QueryStatus checkQueryStatus(PlatformTimerQuery) = 0;
     64     virtual std::chrono::nanoseconds getTimeElapsed(PlatformTimerQuery) = 0;
     65     virtual void deleteQuery(PlatformTimerQuery) = 0;
     66 
     67 private:
     68     virtual PlatformTimerQuery onQueueTimerStart() const = 0;
     69     virtual void onQueueTimerStop(PlatformTimerQuery) const = 0;
     70 
     71     bool const           fDisjointSupport;
     72     PlatformTimerQuery   fActiveTimer;
     73 };
     74 
     75 }  // namespace sk_gpu_test
     76 
     77 #endif
     78