diff --git a/android/build.gradle b/android/build.gradle
index e8c336d865..f8ddf93662 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -24,11 +24,9 @@ buildscript {
}
def hasVulkan = project.hasProperty("filament_supports_vulkan")
- // Our minSdkVersion is actually 19, we lie and say 14 here so apps don't have
- // to increase their minSdkVersion unnecessarily. It is however up to them to
- // ensure they do not initialize Filament on API levels < 19.
+ // Our minSdkVersion is 19.
ext.versions = [
- 'minSdk': 14,
+ 'minSdk': 19,
'targetSdk': 29,
'compileSdk': 29,
'kotlin': '1.3.61',
diff --git a/android/filament-android/src/main/cpp/Renderer.cpp b/android/filament-android/src/main/cpp/Renderer.cpp
index 9b91062abe..4f7d88f319 100644
--- a/android/filament-android/src/main/cpp/Renderer.cpp
+++ b/android/filament-android/src/main/cpp/Renderer.cpp
@@ -144,3 +144,12 @@ Java_com_google_android_filament_Renderer_nResetUserTime(JNIEnv*, jclass, jlong
Renderer *renderer = (Renderer *) nativeRenderer;
renderer->resetUserTime();
}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_android_filament_Renderer_nSetDisplayInfo(JNIEnv*, jclass, jlong nativeRenderer,
+ jfloat refreshRate, jlong presentationDeadlineNanos, jlong vsyncOffsetNanos) {
+ Renderer *renderer = (Renderer *) nativeRenderer;
+ renderer->setDisplayInfo({ .refreshRate = refreshRate,
+ .presentationDeadlineNanos = (uint64_t)presentationDeadlineNanos,
+ .vsyncOffsetNanos = (uint64_t)vsyncOffsetNanos });
+}
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 28f1bb7d10..5479563a4a 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
@@ -45,6 +45,29 @@ public class Renderer {
private final Engine mEngine;
private long mNativeObject;
+ /**
+ * Information about the display this renderer is associated to
+ */
+ public static class DisplayInfo {
+ /**
+ * Refresh rate of the display in Hz. Set to 0 for offscreen or turn off frame-pacing.
+ * On Android you can use {@link android.view.Display#getRefreshRate()}.
+ */
+ public float refreshRate = 60.0f;
+
+ /**
+ * How far in advance a buffer must be queued for presentation at a given time in ns
+ * On Android you can use {@link android.view.Display#getPresentationDeadlineNanos()}.
+ */
+ public long presentationDeadlineNanos = 0;
+
+ /**
+ * Offset by which vsyncSteadyClockTimeNano provided in beginFrame() is offset in ns
+ * On Android you can use {@link android.view.Display#getAppVsyncOffsetNanos()}.
+ */
+ public long vsyncOffsetNanos = 0;
+ };
+
/**
* Indicates that the dstSwapChain passed into {@link #copyFrame} should be
* committed after the frame has been copied.
@@ -75,6 +98,14 @@ public class Renderer {
mNativeObject = nativeRenderer;
}
+ /**
+ * Information about the display this Renderer is associated to. This information is needed
+ * to accurately compute dynamic-resolution scaling and for frame-pacing.
+ */
+ public void setDisplayInfo(@NonNull DisplayInfo info) {
+ nSetDisplayInfo(getNativeObject(), info.refreshRate, info.presentationDeadlineNanos, info.vsyncOffsetNanos);
+ }
+
/**
* Gets the {@link Engine} that created this Renderer.
*
@@ -487,4 +518,6 @@ public class Renderer {
Object handler, Runnable callback);
private static native double nGetUserTime(long nativeRenderer);
private static native void nResetUserTime(long nativeRenderer);
+ private static native void nSetDisplayInfo(long nativeRenderer,
+ float refreshRate, long presentationDeadlineNanos, long vsyncOffsetNanos);
}
diff --git a/android/filament-android/src/main/java/com/google/android/filament/android/DisplayHelper.java b/android/filament-android/src/main/java/com/google/android/filament/android/DisplayHelper.java
new file mode 100644
index 0000000000..1187aae1ff
--- /dev/null
+++ b/android/filament-android/src/main/java/com/google/android/filament/android/DisplayHelper.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.android.filament.android;
+
+import android.os.Build;
+import android.view.Display;
+
+import com.google.android.filament.Renderer;
+
+import androidx.annotation.NonNull;
+
+public class DisplayHelper {
+ public static long getAppVsyncOffsetNanos(Display display) {
+ if (Build.VERSION.SDK_INT >= 29) {
+ return display.getAppVsyncOffsetNanos();
+ }
+ return 0;
+ }
+
+ public static long getPresentationDeadlineNanos(Display display) {
+ if (Build.VERSION.SDK_INT >= 29) {
+ return display.getPresentationDeadlineNanos();
+ }
+ return 0;
+ }
+
+ public static long getRefreshPeriodNanos(Display display) {
+ return (long) (1000000000.0 / display.getRefreshRate());
+ }
+
+ public static float getRefreshRate(Display display) {
+ return display.getRefreshRate();
+ }
+
+
+ @NonNull
+ public static Renderer.DisplayInfo getDisplayInfo(Display display, @NonNull Renderer.DisplayInfo info) {
+ info.refreshRate = DisplayHelper.getRefreshRate(display);
+ info.presentationDeadlineNanos = DisplayHelper.getPresentationDeadlineNanos(display);
+ info.vsyncOffsetNanos = DisplayHelper.getAppVsyncOffsetNanos(display);
+ return info;
+ }
+}
diff --git a/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt b/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt
index 9c5c62536c..8dc199df8d 100644
--- a/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt
+++ b/android/filament-utils-android/src/main/java/com/google/android/filament/utils/ModelViewer.kt
@@ -21,6 +21,7 @@ import android.view.Surface
import android.view.SurfaceView
import android.view.TextureView
import com.google.android.filament.*
+import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
import com.google.android.filament.gltfio.*
import java.nio.Buffer
@@ -72,6 +73,7 @@ class ModelViewer : android.view.View.OnTouchListener {
private val cameraManipulator: Manipulator
private val gestureDetector: GestureDetector
private val renderer: Renderer
+ private lateinit var surfaceView: SurfaceView
private var swapChain: SwapChain? = null
private var assetLoader: AssetLoader
private var resourceLoader: ResourceLoader
@@ -122,6 +124,7 @@ class ModelViewer : android.view.View.OnTouchListener {
.viewport(surfaceView.width, surfaceView.height)
.build(Manipulator.Mode.ORBIT)
+ this.surfaceView = surfaceView
gestureDetector = GestureDetector(surfaceView, cameraManipulator)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(surfaceView)
@@ -273,6 +276,7 @@ class ModelViewer : android.view.View.OnTouchListener {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/android/samples/sample-gltf-viewer/build.gradle b/android/samples/sample-gltf-viewer/build.gradle
index 35e5abe836..eb8b8aaadc 100644
--- a/android/samples/sample-gltf-viewer/build.gradle
+++ b/android/samples/sample-gltf-viewer/build.gradle
@@ -26,7 +26,7 @@ android {
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.gltf"
- minSdkVersion 16
+ minSdkVersion 19
targetSdkVersion versions.targetSdk
missingDimensionStrategy 'functionality', 'full'
}
diff --git a/android/samples/sample-hello-camera/src/main/java/com/google/android/filament/hellocam/MainActivity.kt b/android/samples/sample-hello-camera/src/main/java/com/google/android/filament/hellocam/MainActivity.kt
index e9769e6513..790b451354 100644
--- a/android/samples/sample-hello-camera/src/main/java/com/google/android/filament/hellocam/MainActivity.kt
+++ b/android/samples/sample-hello-camera/src/main/java/com/google/android/filament/hellocam/MainActivity.kt
@@ -29,6 +29,7 @@ import androidx.core.app.ActivityCompat
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.*
import com.google.android.filament.VertexBuffer.*
+import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
@@ -375,6 +376,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/android/samples/sample-hello-triangle/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt b/android/samples/sample-hello-triangle/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt
index 39aeed653e..ade6720e6f 100644
--- a/android/samples/sample-hello-triangle/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt
+++ b/android/samples/sample-hello-triangle/src/main/java/com/google/android/filament/hellotriangle/MainActivity.kt
@@ -28,6 +28,7 @@ import com.google.android.filament.*
import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
+import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
@@ -302,6 +303,7 @@ class MainActivity : Activity() {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/android/samples/sample-image-based-lighting/src/main/java/com/google/android/filament/ibl/MainActivity.kt b/android/samples/sample-image-based-lighting/src/main/java/com/google/android/filament/ibl/MainActivity.kt
index 4e2f533385..be7704596d 100644
--- a/android/samples/sample-image-based-lighting/src/main/java/com/google/android/filament/ibl/MainActivity.kt
+++ b/android/samples/sample-image-based-lighting/src/main/java/com/google/android/filament/ibl/MainActivity.kt
@@ -25,6 +25,7 @@ import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
+import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
@@ -280,6 +281,7 @@ class MainActivity : Activity() {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/android/samples/sample-lit-cube/src/main/java/com/google/android/filament/litcube/MainActivity.kt b/android/samples/sample-lit-cube/src/main/java/com/google/android/filament/litcube/MainActivity.kt
index 91f41d8178..3f424a0786 100644
--- a/android/samples/sample-lit-cube/src/main/java/com/google/android/filament/litcube/MainActivity.kt
+++ b/android/samples/sample-lit-cube/src/main/java/com/google/android/filament/litcube/MainActivity.kt
@@ -28,6 +28,7 @@ import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.*
import com.google.android.filament.VertexBuffer.*
+import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
@@ -390,6 +391,7 @@ class MainActivity : Activity() {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/android/samples/sample-material-builder/src/main/java/com/google/android/filament/material_builder/MainActivity.kt b/android/samples/sample-material-builder/src/main/java/com/google/android/filament/material_builder/MainActivity.kt
index bc507e65d8..f6aa585d21 100644
--- a/android/samples/sample-material-builder/src/main/java/com/google/android/filament/material_builder/MainActivity.kt
+++ b/android/samples/sample-material-builder/src/main/java/com/google/android/filament/material_builder/MainActivity.kt
@@ -25,6 +25,7 @@ import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
+import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
import com.google.android.filament.filamat.MaterialBuilder
@@ -320,6 +321,7 @@ class MainActivity : Activity() {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/android/samples/sample-stream-test/src/main/java/com/google/android/filament/streamtest/MainActivity.kt b/android/samples/sample-stream-test/src/main/java/com/google/android/filament/streamtest/MainActivity.kt
index a8e76cabe0..4ef1ee5cd5 100644
--- a/android/samples/sample-stream-test/src/main/java/com/google/android/filament/streamtest/MainActivity.kt
+++ b/android/samples/sample-stream-test/src/main/java/com/google/android/filament/streamtest/MainActivity.kt
@@ -34,6 +34,7 @@ import java.nio.ByteOrder
import java.nio.channels.Channels
import android.opengl.*
import android.view.MotionEvent
+import com.google.android.filament.android.DisplayHelper
class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallback {
@@ -362,6 +363,7 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/android/samples/sample-texture-view/src/main/java/com/google/android/filament/textureview/MainActivity.kt b/android/samples/sample-texture-view/src/main/java/com/google/android/filament/textureview/MainActivity.kt
index 36fd34d55a..bfb10febca 100644
--- a/android/samples/sample-texture-view/src/main/java/com/google/android/filament/textureview/MainActivity.kt
+++ b/android/samples/sample-texture-view/src/main/java/com/google/android/filament/textureview/MainActivity.kt
@@ -28,6 +28,7 @@ import com.google.android.filament.*
import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
+import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
@@ -302,6 +303,7 @@ class MainActivity : Activity() {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(textureView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/android/samples/sample-textured-object/src/main/java/com/google/android/filament/textured/MainActivity.kt b/android/samples/sample-textured-object/src/main/java/com/google/android/filament/textured/MainActivity.kt
index 8bac236ffe..15930b8701 100644
--- a/android/samples/sample-textured-object/src/main/java/com/google/android/filament/textured/MainActivity.kt
+++ b/android/samples/sample-textured-object/src/main/java/com/google/android/filament/textured/MainActivity.kt
@@ -25,6 +25,7 @@ import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
+import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.utils.*
import com.google.android.filament.android.UiHelper
@@ -302,6 +303,7 @@ class MainActivity : Activity() {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/android/samples/sample-transparent-view/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt b/android/samples/sample-transparent-view/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt
index 94dab1644e..9148962871 100644
--- a/android/samples/sample-transparent-view/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt
+++ b/android/samples/sample-transparent-view/src/main/java/com/google/android/filament/transparentrendering/MainActivity.kt
@@ -32,6 +32,7 @@ import android.widget.TextView
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.*
import com.google.android.filament.VertexBuffer.*
+import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
@@ -320,6 +321,7 @@ class MainActivity : Activity() {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
+ renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
}
override fun onDetachedFromSurface() {
diff --git a/filament/include/filament/Renderer.h b/filament/include/filament/Renderer.h
index 057312f9bf..ddd77a3ed6 100644
--- a/filament/include/filament/Renderer.h
+++ b/filament/include/filament/Renderer.h
@@ -68,11 +68,31 @@ class PixelBufferDescriptor;
*/
class UTILS_PUBLIC Renderer : public FilamentAPI {
public:
- /**
- * Get the Engine that created this Renderer.
- *
- * @return A pointer to the Engine instance this Renderer is associated to.
- */
+
+ struct DisplayInfo {
+ // refresh-rate of the display in Hz. set to 0 for offscreen or turn off frame-pacing.
+ float refreshRate = 60.0f;
+
+ // how far in advance a buffer must be queued for presentation at a given time in ns
+ uint64_t presentationDeadlineNanos = 0;
+
+ // offset by which vsyncSteadyClockTimeNano provided in beginFrame() is offset in ns
+ uint64_t vsyncOffsetNanos = 0;
+ };
+
+ /**
+ * Information about the display this Renderer is associated to. This information is needed
+ * to accurately compute dynamic-resolution scaling and for frame-pacing.
+ *
+ * @param info
+ */
+ void setDisplayInfo(const DisplayInfo& info) noexcept;
+
+ /**
+ * Get the Engine that created this Renderer.
+ *
+ * @return A pointer to the Engine instance this Renderer is associated to.
+ */
Engine* getEngine() noexcept;
/**
diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp
index 11f050a64e..f8e233ad7c 100644
--- a/filament/src/Renderer.cpp
+++ b/filament/src/Renderer.cpp
@@ -688,9 +688,15 @@ void FRenderer::copyFrame(FSwapChain* dstSwapChain, filament::Viewport const& ds
bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeNano,
backend::FrameFinishedCallback callback, void* user) {
+ assert(swapChain);
+
SYSTRACE_CALL();
- assert(swapChain);
+ // get the timestamp as soon as possible
+ using namespace std::chrono;
+ const steady_clock::time_point now{ steady_clock::now() };
+ const steady_clock::time_point vsync{steady_clock::duration(vsyncSteadyClockTimeNano) };
+ const time_point vsyncTp(vsyncSteadyClockTimeNano ? vsync : now);
mFrameId++;
@@ -709,9 +715,7 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN
// NOTE: this makes synchronous calls to the driver
driver.updateStreams(&driver);
- int64_t timestamp = vsyncSteadyClockTimeNano ?
- vsyncSteadyClockTimeNano : std::chrono::steady_clock::now().time_since_epoch().count();
- driver.beginFrame(timestamp, mFrameId, callback, user);
+ driver.beginFrame(vsyncTp.time_since_epoch().count(), mFrameId, callback, user);
if (!mFrameSkipper.beginFrame()) {
driver.endFrame(mFrameId);
@@ -724,7 +728,7 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN
mFrameInfoManager.beginFrame(mFrameId);
// latch the frame time
- std::chrono::duration time{ getUserTime() };
+ std::chrono::duration time(vsync - mUserEpoch);
float h = float(time.count());
float l = float(time.count() - h);
mShaderUserTime = { h, l, 0, 0 };
@@ -875,4 +879,8 @@ void Renderer::resetUserTime() {
upcast(this)->resetUserTime();
}
+void Renderer::setDisplayInfo(const DisplayInfo& info) noexcept {
+ upcast(this)->setDisplayInfo(info);
+}
+
} // namespace filament
diff --git a/filament/src/details/Renderer.h b/filament/src/details/Renderer.h
index 6deb91bc9f..a663a66823 100644
--- a/filament/src/details/Renderer.h
+++ b/filament/src/details/Renderer.h
@@ -91,6 +91,10 @@ public:
// Clean-up everything, this is typically called when the client calls Engine::destroyRenderer()
void terminate(FEngine& engine);
+ void setDisplayInfo(DisplayInfo const& info) noexcept {
+ mDisplayInfo = info;
+ }
+
private:
friend class Renderer;
using Command = RenderPass::Command;
@@ -154,6 +158,7 @@ private:
bool mIsRGB8Supported : 1;
Epoch mUserEpoch;
math::float4 mShaderUserTime{};
+ DisplayInfo mDisplayInfo;
// per-frame arena for this Renderer
LinearAllocatorArena& mPerRenderPassArena;