• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef VK_QSRI_TIMELINE_H
2 #define VK_QSRI_TIMELINE_H
3 
4 #include <cstdint>
5 #include <functional>
6 #include <map>
7 #include <mutex>
8 #include <sstream>
9 
10 #include "host-common/logging.h"
11 
12 namespace gfxstream {
13 namespace vk {
14 
15 class VkQsriTimeline {
16    public:
17     using Callback = std::function<void()>;
18 
signalNextPresentAndPoll()19     void signalNextPresentAndPoll() {
20         std::lock_guard<std::mutex> guard(mLock);
21         mPresentCount++;
22         pollLocked();
23     }
24 
registerCallbackForNextPresentAndPoll(Callback callback)25     void registerCallbackForNextPresentAndPoll(Callback callback) {
26         std::lock_guard<std::mutex> guard(mLock);
27         uint64_t requestPresentCount = mRequestPresentCount;
28         mRequestPresentCount++;
29         mPendingCallbacks.emplace(requestPresentCount, std::move(callback));
30         pollLocked();
31     }
32 
VkQsriTimeline()33     VkQsriTimeline() : mPresentCount(0), mRequestPresentCount(0) {}
~VkQsriTimeline()34     ~VkQsriTimeline() {
35         std::lock_guard<std::mutex> guard(mLock);
36         if (mPendingCallbacks.empty()) {
37             return;
38         }
39         std::stringstream ss;
40         ss << mPendingCallbacks.size()
41            << " pending QSRI callbacks found when destroying the timeline, waiting for: ";
42         for (auto& [requiredPresentCount, callback] : mPendingCallbacks) {
43             callback();
44             ss << requiredPresentCount << ", ";
45         }
46         ss << "just call all of callbacks.";
47         ERR("%s", ss.str().c_str());
48     }
49 
50    private:
51     std::map<uint64_t, Callback> mPendingCallbacks;
52     std::mutex mLock;
53     uint64_t mPresentCount;
54     uint64_t mRequestPresentCount;
55 
pollLocked()56     void pollLocked() {
57         auto firstPendingCallback = mPendingCallbacks.lower_bound(mPresentCount);
58         for (auto readyCallback = mPendingCallbacks.begin(); readyCallback != firstPendingCallback;
59              readyCallback++) {
60             readyCallback->second();
61         }
62         mPendingCallbacks.erase(mPendingCallbacks.begin(), firstPendingCallback);
63     }
64 };
65 
66 }  // namespace vk
67 }  // namespace gfxstream
68 
69 #endif  // VK_QSRI_TIMELINE_H