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