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