• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 #include <drm/msm_drm.h>
19 #include <drm/msm_drm_pp.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 #include <utils/Timers.h>
23 #include <xf86drm.h>
24 #include <xf86drmMode.h>
25 #include <array>
26 #include <deque>
27 #include <memory>
28 #include <mutex>
29 #include <tuple>
30 
31 namespace histogram {
32 
33 struct TimeKeeper {
34   virtual nsecs_t current_time() const = 0;
35   virtual ~TimeKeeper() = default;
36 
37  protected:
38   TimeKeeper() = default;
39   TimeKeeper &operator=(TimeKeeper const &) = delete;
40   TimeKeeper(TimeKeeper const &) = delete;
41 };
42 
43 struct DefaultTimeKeeper final : TimeKeeper {
44   nsecs_t current_time() const final;
45 };
46 
47 class Ringbuffer {
48  public:
49   static std::unique_ptr<Ringbuffer> create(size_t ringbuffer_size, std::unique_ptr<TimeKeeper> tk);
50   void insert(drm_msm_hist const &frame);
51   bool resize(size_t ringbuffer_size);
52 
53   using Sample = std::tuple<uint64_t /* numFrames */, std::array<uint64_t, HIST_V_SIZE> /* bins */>;
54   Sample collect_cumulative() const;
55   Sample collect_ringbuffer_all() const;
56   Sample collect_after(nsecs_t timestamp) const;
57   Sample collect_max(uint32_t max_frames) const;
58   Sample collect_max_after(nsecs_t timestamp, uint32_t max_frames) const;
59   ~Ringbuffer() = default;
60 
61  private:
62   Ringbuffer(size_t ringbuffer_size, std::unique_ptr<TimeKeeper> tk);
63   Ringbuffer(Ringbuffer const &) = delete;
64   Ringbuffer &operator=(Ringbuffer const &) = delete;
65 
66   Sample collect_max(uint32_t max_frames, std::unique_lock<std::mutex> const &) const;
67   Sample collect_max_after(nsecs_t timestamp, uint32_t max_frames,
68                            std::unique_lock<std::mutex> const &) const;
69   void update_cumulative(nsecs_t now, uint64_t &count,
70                          std::array<uint64_t, HIST_V_SIZE> &bins) const;
71 
72   std::mutex mutable mutex;
73   struct HistogramEntry {
74     drm_msm_hist histogram;
75     nsecs_t start_timestamp;
76     nsecs_t end_timestamp;
77   };
78   std::deque<HistogramEntry> ringbuffer;
79   size_t rb_max_size;
80   std::unique_ptr<TimeKeeper> const timekeeper;
81 
82   uint64_t cumulative_frame_count;
83   std::array<uint64_t, HIST_V_SIZE> cumulative_bins;
84 };
85 
86 }  // namespace histogram
87