• 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 goldfish_vk {
13 class VkQsriTimeline {
14    public:
15     using Callback = std::function<void()>;
16 
signalNextPresentAndPoll()17     void signalNextPresentAndPoll() {
18         std::lock_guard<std::mutex> guard(mLock);
19         mPresentCount++;
20         pollLocked();
21     }
22 
registerCallbackForNextPresentAndPoll(Callback callback)23     void registerCallbackForNextPresentAndPoll(Callback callback) {
24         std::lock_guard<std::mutex> guard(mLock);
25         uint64_t requestPresentCount = mRequestPresentCount;
26         mRequestPresentCount++;
27         mPendingCallbacks.emplace(requestPresentCount, std::move(callback));
28         pollLocked();
29     }
30 
VkQsriTimeline()31     VkQsriTimeline() : mPresentCount(0), mRequestPresentCount(0) {}
~VkQsriTimeline()32     ~VkQsriTimeline() {
33         std::lock_guard<std::mutex> guard(mLock);
34         if (mPendingCallbacks.empty()) {
35             return;
36         }
37         std::stringstream ss;
38         ss << mPendingCallbacks.size()
39            << " pending QSRI callbacks found when destroying the timeline, waiting for: ";
40         for (auto& [requiredPresentCount, callback] : mPendingCallbacks) {
41             callback();
42             ss << requiredPresentCount << ", ";
43         }
44         ss << "just call all of callbacks.";
45         ERR("%s", ss.str().c_str());
46     }
47 
48    private:
49     std::map<uint64_t, Callback> mPendingCallbacks;
50     std::mutex mLock;
51     uint64_t mPresentCount;
52     uint64_t mRequestPresentCount;
53 
pollLocked()54     void pollLocked() {
55         auto firstPendingCallback = mPendingCallbacks.lower_bound(mPresentCount);
56         for (auto readyCallback = mPendingCallbacks.begin(); readyCallback != firstPendingCallback;
57              readyCallback++) {
58             readyCallback->second();
59         }
60         mPendingCallbacks.erase(mPendingCallbacks.begin(), firstPendingCallback);
61     }
62 };
63 }  // namespace goldfish_vk
64 
65 #endif  // VK_QSRI_TIMELINE_H