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 <sys/types.h> 19 #include <tuple> 20 #include <unistd.h> 21 #include <memory> 22 #include <drm/msm_drm.h> 23 #include <drm/msm_drm_pp.h> 24 #include <xf86drm.h> 25 #include <xf86drmMode.h> 26 #include <array> 27 #include <deque> 28 #include <mutex> 29 #include <utils/Timers.h> 30 31 namespace histogram { 32 33 struct TimeKeeper { 34 virtual nsecs_t current_time() const = 0; 35 virtual ~TimeKeeper() = default; 36 protected: 37 TimeKeeper() = default; 38 TimeKeeper& operator=(TimeKeeper const&) = delete; 39 TimeKeeper(TimeKeeper const&) = delete; 40 }; 41 42 struct DefaultTimeKeeper final : TimeKeeper 43 { 44 nsecs_t current_time() const final; 45 }; 46 47 class Ringbuffer 48 { 49 public: 50 static std::unique_ptr<Ringbuffer> create(size_t ringbuffer_size, std::unique_ptr<TimeKeeper> tk); 51 void insert(drm_msm_hist const& frame); 52 bool resize(size_t ringbuffer_size); 53 54 using Sample = std::tuple<uint64_t /* numFrames */, std::array<uint64_t, HIST_V_SIZE> /* bins */>; 55 Sample collect_cumulative() const; 56 Sample collect_ringbuffer_all() const; 57 Sample collect_after(nsecs_t timestamp) const; 58 Sample collect_max(uint32_t max_frames) const; 59 Sample collect_max_after(nsecs_t timestamp, uint32_t max_frames) const; 60 ~Ringbuffer() = default; 61 62 private: 63 Ringbuffer(size_t ringbuffer_size, std::unique_ptr<TimeKeeper> tk); 64 Ringbuffer(Ringbuffer const&) = delete; 65 Ringbuffer& operator=(Ringbuffer const&) = delete; 66 67 Sample collect_max(uint32_t max_frames, std::unique_lock<std::mutex> const&) const; 68 Sample collect_max_after(nsecs_t timestamp, uint32_t max_frames, std::unique_lock<std::mutex> const&) const; 69 void update_cumulative(nsecs_t now, uint64_t& count, std::array<uint64_t, HIST_V_SIZE>& bins) const; 70 71 std::mutex mutable mutex; 72 struct HistogramEntry { 73 drm_msm_hist histogram; 74 nsecs_t start_timestamp; 75 nsecs_t end_timestamp; 76 }; 77 std::deque<HistogramEntry> ringbuffer; 78 size_t rb_max_size; 79 std::unique_ptr<TimeKeeper> const timekeeper; 80 81 uint64_t cumulative_frame_count; 82 std::array<uint64_t, HIST_V_SIZE> cumulative_bins; 83 }; 84 85 } 86