aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVamsidhar reddy Gaddam <gvamsi@google.com>2023-09-21 08:21:47 +0000
committerVamsidhar reddy Gaddam <gvamsi@google.com>2023-09-22 08:06:37 +0000
commit11d24d9e41fc46b61cc7cfef814d001ab32b2bf7 (patch)
tree59f86a19e4a61b08f8991004a227396ef084bdd2
parent6a008f161d9130eb96b7c6c45dfd721e049d681b (diff)
downloadgamesdk-11d24d9e41fc46b61cc7cfef814d001ab32b2bf7.tar.gz
Add tracking of tracers for swappy vulkan
SwappyVk_injectTracer acts differently from SwappyGL_injectTracer applying tracers only to the swapchain instances initialized until the call. In this commit, I add a list to the swappy singleton instance where all the tracers are saved and added to the swappy implementation when each swapchain instance is initialized automatically. There is no performance impact as the new logic only executes once at swapchain init time. Bug: 301242456 Test: Manual testing Change-Id: I0439a870bdeb367e5cdae90492a0252562f70d09
-rw-r--r--games-frame-pacing/vulkan/SwappyVk.cpp59
-rw-r--r--games-frame-pacing/vulkan/SwappyVk.h3
-rw-r--r--games-frame-pacing/vulkan/SwappyVkBase.cpp4
3 files changed, 60 insertions, 6 deletions
diff --git a/games-frame-pacing/vulkan/SwappyVk.cpp b/games-frame-pacing/vulkan/SwappyVk.cpp
index 8b1fae1b..5257433f 100644
--- a/games-frame-pacing/vulkan/SwappyVk.cpp
+++ b/games-frame-pacing/vulkan/SwappyVk.cpp
@@ -19,6 +19,39 @@
#define LOG_TAG "SwappyVk"
#include "SwappyLog.h"
+/* For tracking tracers internally within vulkan instance, we cannot store the
+ * pointers as there is no requirement for the life of the object once the
+ * SwappyVk_injectTracer(*t) call is returned. So we store the struct objects by
+ * value. In turn, this implies that we have to compare the whole struct for
+ * managing it. So we define a local "==" operator to this file in order to
+ * handle the C struct API in the std::list.
+ *
+ * In addition, there is a risk that updates to the SwappyTracer struct could go
+ * unnoticed silently. So we have a copy here and we check at compile time that
+ * the sizes are the same, it is a weak check, but it is better than nothing.
+ */
+
+typedef struct SwappyTracerLocalStruct {
+ SwappyPreWaitCallback preWait;
+ SwappyPostWaitCallback postWait;
+ SwappyPreSwapBuffersCallback preSwapBuffers;
+ SwappyPostSwapBuffersCallback postSwapBuffers;
+ SwappyStartFrameCallback startFrame;
+ void* userData;
+ SwappySwapIntervalChangedCallback swapIntervalChanged;
+} SwappyTracerLocalStruct;
+
+static bool operator==(const SwappyTracer& t1, const SwappyTracer& t2) {
+ static_assert(sizeof(SwappyTracer) == sizeof(SwappyTracerLocalStruct),
+ "SwappyTracer struct appears to have changed, please "
+ "consider updating locally.");
+ return (t1.preWait == t2.preWait) && (t1.postWait == t2.postWait) &&
+ (t1.preSwapBuffers == t2.preSwapBuffers) &&
+ (t1.postSwapBuffers == t2.postSwapBuffers) &&
+ (t1.startFrame == t2.startFrame) && (t1.userData == t2.userData) &&
+ (t1.swapIntervalChanged == t2.swapIntervalChanged);
+}
+
namespace swappy {
class DefaultSwappyVkFunctionProvider {
@@ -158,6 +191,14 @@ bool SwappyVk::GetRefreshCycleDuration(JNIEnv* env, jobject jactivity,
}
}
+ // SwappyBase is constructed by this point, so we can add the tracers we
+ // have so far.
+ {
+ std::lock_guard<std::mutex> lock(tracer_list_lock);
+ for (const auto& tracer : tracer_list) {
+ pImplementation->addTracer(&tracer);
+ }
+ }
// Now, call that derived class to get the refresh duration to return
return pImplementation->doGetRefreshCycleDuration(swapchain,
pRefreshDuration);
@@ -291,14 +332,24 @@ std::chrono::nanoseconds SwappyVk::GetSwapInterval(VkSwapchainKHR swapchain) {
}
void SwappyVk::addTracer(const SwappyTracer* t) {
- for (auto i : perSwapchainImplementation) {
- i.second->addTracer(t);
+ if (t != nullptr) {
+ std::lock_guard<std::mutex> lock(tracer_list_lock);
+ tracer_list.push_back(*t);
+
+ for (const auto& i : perSwapchainImplementation) {
+ i.second->addTracer(t);
+ }
}
}
void SwappyVk::removeTracer(const SwappyTracer* t) {
- for (auto i : perSwapchainImplementation) {
- i.second->removeTracer(t);
+ if (t != nullptr) {
+ std::lock_guard<std::mutex> lock(tracer_list_lock);
+ tracer_list.remove(*t);
+
+ for (const auto& i : perSwapchainImplementation) {
+ i.second->removeTracer(t);
+ }
}
}
diff --git a/games-frame-pacing/vulkan/SwappyVk.h b/games-frame-pacing/vulkan/SwappyVk.h
index 02ef4f71..7ff15225 100644
--- a/games-frame-pacing/vulkan/SwappyVk.h
+++ b/games-frame-pacing/vulkan/SwappyVk.h
@@ -121,6 +121,9 @@ class SwappyVk {
// Forbid copies.
SwappyVk(SwappyVk const&) = delete;
void operator=(SwappyVk const&) = delete;
+
+ std::mutex tracer_list_lock;
+ std::list<SwappyTracer> tracer_list GUARDED_BY(tracer_list_lock);
};
} // namespace swappy
diff --git a/games-frame-pacing/vulkan/SwappyVkBase.cpp b/games-frame-pacing/vulkan/SwappyVkBase.cpp
index a059b974..bd779efa 100644
--- a/games-frame-pacing/vulkan/SwappyVkBase.cpp
+++ b/games-frame-pacing/vulkan/SwappyVkBase.cpp
@@ -425,11 +425,11 @@ std::chrono::nanoseconds SwappyVkBase::getSwapInterval() {
}
void SwappyVkBase::addTracer(const SwappyTracer* tracer) {
- if (tracer != nullptr) mCommonBase.addTracerCallbacks(*tracer);
+ mCommonBase.addTracerCallbacks(*tracer);
}
void SwappyVkBase::removeTracer(const SwappyTracer* tracer) {
- if (tracer != nullptr) mCommonBase.removeTracerCallbacks(*tracer);
+ mCommonBase.removeTracerCallbacks(*tracer);
}
int SwappyVkBase::getSupportedRefreshPeriodsNS(uint64_t* out_refreshrates,