diff --git a/android/filament-android/src/main/cpp/Engine.cpp b/android/filament-android/src/main/cpp/Engine.cpp
index 4b3b33e530..f571422255 100644
--- a/android/filament-android/src/main/cpp/Engine.cpp
+++ b/android/filament-android/src/main/cpp/Engine.cpp
@@ -571,3 +571,9 @@ Java_com_google_android_filament_Engine_nBuilderBuild(JNIEnv*, jclass, jlong nat
Engine::Builder* builder = (Engine::Builder*) nativeBuilder;
return (jlong) builder->build();
}
+
+extern "C"
+JNIEXPORT jlong JNICALL
+Java_com_google_android_filament_Engine_getSteadyClockTimeNano(JNIEnv *env, jclass clazz) {
+ return (jlong)Engine::getSteadyClockTimeNano();
+}
diff --git a/android/filament-android/src/main/cpp/Renderer.cpp b/android/filament-android/src/main/cpp/Renderer.cpp
index c48b616f56..1dc252d356 100644
--- a/android/filament-android/src/main/cpp/Renderer.cpp
+++ b/android/filament-android/src/main/cpp/Renderer.cpp
@@ -187,3 +187,10 @@ Java_com_google_android_filament_Renderer_nSetPresentationTime(JNIEnv *, jclass
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->setPresentationTime(monotonicClockNanos);
}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_android_filament_Renderer_nSetVsyncTime(JNIEnv *, jclass,
+ jlong nativeRenderer, jlong steadyClockTimeNano) {
+ Renderer *renderer = (Renderer *) nativeRenderer;
+ renderer->setVsyncTime(steadyClockTimeNano);
+}
diff --git a/android/filament-android/src/main/java/com/google/android/filament/Engine.java b/android/filament-android/src/main/java/com/google/android/filament/Engine.java
index 5a28d1eae8..6c4c5119e3 100644
--- a/android/filament-android/src/main/java/com/google/android/filament/Engine.java
+++ b/android/filament-android/src/main/java/com/google/android/filament/Engine.java
@@ -1292,7 +1292,6 @@ public class Engine {
/**
* Switch the command queue to unprotected mode. Protected mode can be activated via
* Renderer::beginFrame() using a protected SwapChain.
-
* @see Renderer
* @see SwapChain
*/
@@ -1300,6 +1299,13 @@ public class Engine {
nUnprotected(getNativeObject());
}
+ /**
+ * Get the current time. This is a convenience function that simply returns the
+ * time in nanosecond since epoch of std::chrono::steady_clock.
+ * @return current time in nanosecond since epoch of std::chrono::steady_clock.
+ * @see Renderer#beginFrame
+ */
+ public static native long getSteadyClockTimeNano();
@UsedByReflection("TextureHelper.java")
public long getNativeObject() {
diff --git a/android/filament-android/src/main/java/com/google/android/filament/Renderer.java b/android/filament-android/src/main/java/com/google/android/filament/Renderer.java
index ab70e9ed38..4fb447db2c 100644
--- a/android/filament-android/src/main/java/com/google/android/filament/Renderer.java
+++ b/android/filament-android/src/main/java/com/google/android/filament/Renderer.java
@@ -284,6 +284,19 @@ public class Renderer {
nSetPresentationTime(getNativeObject(), monotonicClockNanos);
}
+ /**
+ * The use of this method is optional. It sets the VSYNC time expressed as the duration in
+ * nanosecond since epoch of std::chrono::steady_clock.
+ * If called, passing 0 to frameTimeNanos in Renderer.BeginFrame will use this
+ * time instead.
+ * @param steadyClockTimeNano duration in nanosecond since epoch of std::chrono::steady_clock
+ * @see Engine#getSteadyClockTimeNano
+ * @see Renderer#beginFrame
+ */
+ public void setVsyncTime(long steadyClockTimeNano) {
+ nSetVsyncTime(getNativeObject(), steadyClockTimeNano);
+ }
+
/**
* Sets up a frame for this Renderer.
*
beginFrame manages frame pacing, and returns whether or not a frame should be
@@ -702,6 +715,7 @@ public class Renderer {
}
private static native void nSetPresentationTime(long nativeObject, long monotonicClockNanos);
+ private static native void nSetVsyncTime(long nativeObject, long steadyClockTimeNano);
private static native boolean nBeginFrame(long nativeRenderer, long nativeSwapChain, long frameTimeNanos);
private static native void nEndFrame(long nativeRenderer);
private static native void nRender(long nativeRenderer, long nativeView);
diff --git a/filament/include/filament/Engine.h b/filament/include/filament/Engine.h
index 2aed82736f..1c44fe9ab9 100644
--- a/filament/include/filament/Engine.h
+++ b/filament/include/filament/Engine.h
@@ -1021,6 +1021,21 @@ public:
void resetBackendState() noexcept;
#endif
+ /**
+ * Get the current time. This is a convenience function that simply returns the
+ * time in nanosecond since epoch of std::chrono::steady_clock.
+ * A possible implementation is:
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * return std::chrono::steady_clock::now().time_since_epoch().count();
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * @return current time in nanosecond since epoch of std::chrono::steady_clock.
+ * @see Renderer::beginFrame()
+ */
+ static uint64_t getSteadyClockTimeNano() noexcept;
+
+
DebugRegistry& getDebugRegistry() noexcept;
protected:
diff --git a/filament/include/filament/Renderer.h b/filament/include/filament/Renderer.h
index fdc291b1fd..83b6281604 100644
--- a/filament/include/filament/Renderer.h
+++ b/filament/include/filament/Renderer.h
@@ -227,6 +227,17 @@ public:
static constexpr CopyFrameFlag CLEAR = 0x4;
+ /**
+ * The use of this method is optional. It sets the VSYNC time expressed as the duration in
+ * nanosecond since epoch of std::chrono::steady_clock.
+ * If called, passing 0 to vsyncSteadyClockTimeNano in Renderer::BeginFrame will use this
+ * time instead.
+ * @param steadyClockTimeNano duration in nanosecond since epoch of std::chrono::steady_clock
+ * @see Engine::getSteadyClockTimeNano()
+ * @see Renderer::BeginFrame()
+ */
+ void setVsyncTime(uint64_t steadyClockTimeNano) noexcept;
+
/**
* Set-up a frame for this Renderer.
*
diff --git a/filament/src/Engine.cpp b/filament/src/Engine.cpp
index ad110dbc92..477a0871c8 100644
--- a/filament/src/Engine.cpp
+++ b/filament/src/Engine.cpp
@@ -39,6 +39,8 @@
#include