/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <sys/types.h> #include <tuple> #include <unistd.h> #include <memory> #include <drm/msm_drm.h> #include <drm/msm_drm_pp.h> #include <xf86drm.h> #include <xf86drmMode.h> #include <array> #include <deque> #include <mutex> #include <utils/Timers.h> namespace histogram { struct TimeKeeper { virtual nsecs_t current_time() const = 0; virtual ~TimeKeeper() = default; protected: TimeKeeper() = default; TimeKeeper& operator=(TimeKeeper const&) = delete; TimeKeeper(TimeKeeper const&) = delete; }; struct DefaultTimeKeeper final : TimeKeeper { nsecs_t current_time() const final; }; class Ringbuffer { public: static std::unique_ptr<Ringbuffer> create(size_t ringbuffer_size, std::unique_ptr<TimeKeeper> tk); void insert(drm_msm_hist const& frame); bool resize(size_t ringbuffer_size); using Sample = std::tuple<uint64_t /* numFrames */, std::array<uint64_t, HIST_V_SIZE> /* bins */>; Sample collect_cumulative() const; Sample collect_ringbuffer_all() const; Sample collect_after(nsecs_t timestamp) const; Sample collect_max(uint32_t max_frames) const; Sample collect_max_after(nsecs_t timestamp, uint32_t max_frames) const; ~Ringbuffer() = default; private: Ringbuffer(size_t ringbuffer_size, std::unique_ptr<TimeKeeper> tk); Ringbuffer(Ringbuffer const&) = delete; Ringbuffer& operator=(Ringbuffer const&) = delete; Sample collect_max(uint32_t max_frames, std::unique_lock<std::mutex> const&) const; Sample collect_max_after(nsecs_t timestamp, uint32_t max_frames, std::unique_lock<std::mutex> const&) const; void update_cumulative(nsecs_t now, uint64_t& count, std::array<uint64_t, HIST_V_SIZE>& bins) const; std::mutex mutable mutex; struct HistogramEntry { drm_msm_hist histogram; nsecs_t start_timestamp; nsecs_t end_timestamp; }; std::deque<HistogramEntry> ringbuffer; size_t rb_max_size; std::unique_ptr<TimeKeeper> const timekeeper; uint64_t cumulative_frame_count; std::array<uint64_t, HIST_V_SIZE> cumulative_bins; }; }