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