Grab display information for render thread through java

With HWUI becoming an APEX module, we need to use public apis wherever
possible - since there aren't plans to expose a stable api for physical
display information through native, instead grab the system context
from ActivityThread so that we can use DisplayManager's public apis.

The api for retrieving the system context is left as a hidden api - a
future change should stabilize the API or switch to a new api that does
not yet exist. But, this is the right shape for plumbing through the
display information, as the old code retrieved it through SurfaceFlinger
which should not be stabilized as the source of truth for display
information is DisplayManagerService.

Bug: 146387012
Bug: 150880248
Test: builds, boots, verified that the correct display info is plumbed
down

Change-Id: I1a99a72244969bdece2903993e3beb27a6e534b1
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index 1c947a7..1a84313 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -15,6 +15,8 @@
  */
 
 #include <DeviceInfo.h>
+#include <android/hardware_buffer.h>
+#include <apex/display.h>
 #include <log/log.h>
 #include <utils/Errors.h>
 
@@ -30,14 +32,47 @@
 
 DeviceInfo::DeviceInfo() {
 #if HWUI_NULL_GPU
-        mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
+    mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
 #else
-        mMaxTextureSize = -1;
+    mMaxTextureSize = -1;
 #endif
-        updateDisplayInfo();
 }
-DeviceInfo::~DeviceInfo() {
-    ADisplay_release(mDisplays);
+
+void DeviceInfo::updateDisplayInfo() {
+    if (Properties::isolatedProcess) {
+        return;
+    }
+
+    ADisplay** displays;
+    int size = ADisplay_acquirePhysicalDisplays(&displays);
+
+    if (size <= 0) {
+        LOG_ALWAYS_FATAL("Failed to acquire physical displays for WCG support!");
+    }
+
+    for (int i = 0; i < size; ++i) {
+        // Pick the first internal display for querying the display type
+        // In practice this is controlled by a sysprop so it doesn't really
+        // matter which display we use.
+        if (ADisplay_getDisplayType(displays[i]) == DISPLAY_TYPE_INTERNAL) {
+            // We get the dataspace from DisplayManager already. Allocate space
+            // for the result here but we don't actually care about using it.
+            ADataSpace dataspace;
+            AHardwareBuffer_Format pixelFormat;
+            ADisplay_getPreferredWideColorFormat(displays[i], &dataspace, &pixelFormat);
+
+            if (pixelFormat == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM) {
+                mWideColorType = SkColorType::kN32_SkColorType;
+            } else if (pixelFormat == AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT) {
+                mWideColorType = SkColorType::kRGBA_F16_SkColorType;
+            } else {
+                LOG_ALWAYS_FATAL("Unreachable: unsupported pixel format: %d", pixelFormat);
+            }
+            ADisplay_release(displays);
+            return;
+        }
+    }
+    LOG_ALWAYS_FATAL("Failed to find a valid physical display for WCG support!");
 }
 
 int DeviceInfo::maxTextureSize() const {
@@ -49,73 +84,26 @@
     DeviceInfo::get()->mMaxTextureSize = maxTextureSize;
 }
 
-void DeviceInfo::onRefreshRateChanged(int64_t vsyncPeriod) {
-    mVsyncPeriod = vsyncPeriod;
+void DeviceInfo::setWideColorDataspace(ADataSpace dataspace) {
+    switch (dataspace) {
+        case ADATASPACE_DISPLAY_P3:
+            get()->mWideColorSpace =
+                    SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
+            break;
+        case ADATASPACE_SCRGB:
+            get()->mWideColorSpace = SkColorSpace::MakeSRGB();
+            break;
+        case ADATASPACE_SRGB:
+            // when sRGB is returned, it means wide color gamut is not supported.
+            get()->mWideColorSpace = SkColorSpace::MakeSRGB();
+            break;
+        default:
+            LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
+    }
 }
 
-void DeviceInfo::updateDisplayInfo() {
-    if (Properties::isolatedProcess) {
-        return;
-    }
-
-    if (mCurrentConfig == nullptr) {
-        mDisplaysSize = ADisplay_acquirePhysicalDisplays(&mDisplays);
-        LOG_ALWAYS_FATAL_IF(mDisplays == nullptr || mDisplaysSize <= 0,
-                            "Failed to get physical displays: no connected display: %d!", mDisplaysSize);
-        for (size_t i = 0; i < mDisplaysSize; i++) {
-            ADisplayType type = ADisplay_getDisplayType(mDisplays[i]);
-            if (type == ADisplayType::DISPLAY_TYPE_INTERNAL) {
-                mPhysicalDisplayIndex = i;
-                break;
-            }
-        }
-        LOG_ALWAYS_FATAL_IF(mPhysicalDisplayIndex < 0, "Failed to find a connected physical display!");
-
-
-        // Since we now just got the primary display for the first time, then
-        // store the primary display metadata here.
-        ADisplay* primaryDisplay = mDisplays[mPhysicalDisplayIndex];
-        mMaxRefreshRate = ADisplay_getMaxSupportedFps(primaryDisplay);
-        ADataSpace dataspace;
-        AHardwareBuffer_Format format;
-        ADisplay_getPreferredWideColorFormat(primaryDisplay, &dataspace, &format);
-        switch (dataspace) {
-            case ADATASPACE_DISPLAY_P3:
-                mWideColorSpace =
-                        SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
-                break;
-            case ADATASPACE_SCRGB:
-                mWideColorSpace = SkColorSpace::MakeSRGB();
-                break;
-            case ADATASPACE_SRGB:
-                // when sRGB is returned, it means wide color gamut is not supported.
-                mWideColorSpace = SkColorSpace::MakeSRGB();
-                break;
-            default:
-                LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
-        }
-        switch (format) {
-            case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
-                mWideColorType = SkColorType::kN32_SkColorType;
-                break;
-            case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
-                mWideColorType = SkColorType::kRGBA_F16_SkColorType;
-                break;
-            default:
-                LOG_ALWAYS_FATAL("Unreachable: unsupported pixel format.");
-        }
-    }
-    // This method may have been called when the display config changed, so
-    // sync with the current configuration.
-    ADisplay* primaryDisplay = mDisplays[mPhysicalDisplayIndex];
-    status_t status = ADisplay_getCurrentConfig(primaryDisplay, &mCurrentConfig);
-    LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status);
-
-    mWidth = ADisplayConfig_getWidth(mCurrentConfig);
-    mHeight = ADisplayConfig_getHeight(mCurrentConfig);
-    mVsyncPeriod = static_cast<int64_t>(1000000000 / ADisplayConfig_getFps(mCurrentConfig));
-    mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig);
-    mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig);
+void DeviceInfo::onRefreshRateChanged(int64_t vsyncPeriod) {
+    mVsyncPeriod = vsyncPeriod;
 }
 
 std::atomic<float> DeviceInfo::sDensity = 2.0;
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index bcc9301..191dcd8 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -16,8 +16,10 @@
 #ifndef DEVICEINFO_H
 #define DEVICEINFO_H
 
-#include <apex/display.h>
 #include <SkImageInfo.h>
+#include <android/data_space.h>
+
+#include <mutex>
 
 #include "utils/Macros.h"
 
@@ -39,16 +41,34 @@
     // Gets the density in density-independent pixels
     static float getDensity() { return sDensity.load(); }
     static int64_t getVsyncPeriod() { return get()->mVsyncPeriod; }
-    static int64_t getCompositorOffset() { return get()->mCompositorOffset; }
-    static int64_t getAppOffset() { return get()->mAppOffset; }
+    static int64_t getCompositorOffset() { return get()->getCompositorOffsetInternal(); }
+    static int64_t getAppOffset() { return get()->mAppVsyncOffsetNanos; }
     // Sets the density in density-independent pixels
     static void setDensity(float density) { sDensity.store(density); }
+    static void setMaxRefreshRate(float refreshRate) { get()->mMaxRefreshRate = refreshRate; }
+    static void setWidth(int32_t width) { get()->mWidth = width; }
+    static void setHeight(int32_t height) { get()->mHeight = height; }
+    static void setRefreshRate(float refreshRate) {
+        get()->mVsyncPeriod = static_cast<int64_t>(1000000000 / refreshRate);
+    }
+    static void setPresentationDeadlineNanos(int64_t deadlineNanos) {
+        get()->mPresentationDeadlineNanos = deadlineNanos;
+    }
+    static void setAppVsyncOffsetNanos(int64_t offsetNanos) {
+        get()->mAppVsyncOffsetNanos = offsetNanos;
+    }
+    static void setWideColorDataspace(ADataSpace dataspace);
 
     // this value is only valid after the GPU has been initialized and there is a valid graphics
     // context or if you are using the HWUI_NULL_GPU
     int maxTextureSize() const;
     sk_sp<SkColorSpace> getWideColorSpace() const { return mWideColorSpace; }
-    SkColorType getWideColorType() const { return mWideColorType; }
+    SkColorType getWideColorType() {
+        static std::once_flag kFlag;
+        // lazily update display info from SF here, so that the call is performed by RenderThread.
+        std::call_once(kFlag, [&, this]() { updateDisplayInfo(); });
+        return mWideColorType;
+    }
 
     // This method should be called whenever the display refresh rate changes.
     void onRefreshRateChanged(int64_t vsyncPeriod);
@@ -57,23 +77,26 @@
     friend class renderthread::RenderThread;
     static void setMaxTextureSize(int maxTextureSize);
     void updateDisplayInfo();
+    int64_t getCompositorOffsetInternal() const {
+        // Assume that SF takes around a millisecond to latch buffers after
+        // waking up
+        return mVsyncPeriod - (mPresentationDeadlineNanos - 1000000);
+    }
 
     DeviceInfo();
-    ~DeviceInfo();
+    ~DeviceInfo() = default;
 
     int mMaxTextureSize;
     sk_sp<SkColorSpace> mWideColorSpace = SkColorSpace::MakeSRGB();
     SkColorType mWideColorType = SkColorType::kN32_SkColorType;
-    ADisplayConfig* mCurrentConfig = nullptr;
-    ADisplay** mDisplays = nullptr;
     int mDisplaysSize = 0;
     int mPhysicalDisplayIndex = -1;
     float mMaxRefreshRate = 60.0;
     int32_t mWidth = 1080;
     int32_t mHeight = 1920;
     int64_t mVsyncPeriod = 16666666;
-    int64_t mCompositorOffset = 0;
-    int64_t mAppOffset = 0;
+    int64_t mPresentationDeadlineNanos = 0;
+    int64_t mAppVsyncOffsetNanos = 0;
 
     // Density is not retrieved from the ADisplay apis, so this may potentially
     // be called on multiple threads.
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 4f8efa0..614db30 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -600,6 +600,21 @@
     DeviceInfo::setDensity(density);
 }
 
+static void android_view_ThreadedRenderer_initDisplayInfo(JNIEnv*, jclass, jint physicalWidth,
+                                                          jint physicalHeight, jfloat refreshRate,
+                                                          jfloat maxRefreshRate,
+                                                          jint wideColorDataspace,
+                                                          jlong appVsyncOffsetNanos,
+                                                          jlong presentationDeadlineNanos) {
+    DeviceInfo::setWidth(physicalWidth);
+    DeviceInfo::setHeight(physicalHeight);
+    DeviceInfo::setRefreshRate(refreshRate);
+    DeviceInfo::setMaxRefreshRate(maxRefreshRate);
+    DeviceInfo::setWideColorDataspace(static_cast<ADataSpace>(wideColorDataspace));
+    DeviceInfo::setAppVsyncOffsetNanos(appVsyncOffsetNanos);
+    DeviceInfo::setPresentationDeadlineNanos(presentationDeadlineNanos);
+}
+
 // ----------------------------------------------------------------------------
 // HardwareRendererObserver
 // ----------------------------------------------------------------------------
@@ -644,68 +659,83 @@
 const char* const kClassPathName = "android/graphics/HardwareRenderer";
 
 static const JNINativeMethod gMethods[] = {
-    { "nRotateProcessStatsBuffer", "()V", (void*) android_view_ThreadedRenderer_rotateProcessStatsBuffer },
-    { "nSetProcessStatsBuffer", "(I)V", (void*) android_view_ThreadedRenderer_setProcessStatsBuffer },
-    { "nGetRenderThreadTid", "(J)I", (void*) android_view_ThreadedRenderer_getRenderThreadTid },
-    { "nCreateRootRenderNode", "()J", (void*) android_view_ThreadedRenderer_createRootRenderNode },
-    { "nCreateProxy", "(ZZJ)J", (void*) android_view_ThreadedRenderer_createProxy },
-    { "nDeleteProxy", "(J)V", (void*) android_view_ThreadedRenderer_deleteProxy },
-    { "nLoadSystemProperties", "(J)Z", (void*) android_view_ThreadedRenderer_loadSystemProperties },
-    { "nSetName", "(JLjava/lang/String;)V", (void*) android_view_ThreadedRenderer_setName },
-    { "nSetSurface", "(JLandroid/view/Surface;Z)V", (void*) android_view_ThreadedRenderer_setSurface },
-    { "nPause", "(J)Z", (void*) android_view_ThreadedRenderer_pause },
-    { "nSetStopped", "(JZ)V", (void*) android_view_ThreadedRenderer_setStopped },
-    { "nSetLightAlpha", "(JFF)V", (void*) android_view_ThreadedRenderer_setLightAlpha },
-    { "nSetLightGeometry", "(JFFFF)V", (void*) android_view_ThreadedRenderer_setLightGeometry },
-    { "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
-    { "nSetWideGamut", "(JZ)V", (void*) android_view_ThreadedRenderer_setWideGamut },
-    { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
-    { "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
-    { "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
-    { "nRegisterVectorDrawableAnimator", "(JJ)V", (void*) android_view_ThreadedRenderer_registerVectorDrawableAnimator },
-    { "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
-    { "nCreateTextureLayer", "(J)J", (void*) android_view_ThreadedRenderer_createTextureLayer },
-    { "nBuildLayer", "(JJ)V", (void*) android_view_ThreadedRenderer_buildLayer },
-    { "nCopyLayerInto", "(JJJ)Z", (void*) android_view_ThreadedRenderer_copyLayerInto },
-    { "nPushLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_pushLayerUpdate },
-    { "nCancelLayerUpdate", "(JJ)V", (void*) android_view_ThreadedRenderer_cancelLayerUpdate },
-    { "nDetachSurfaceTexture", "(JJ)V", (void*) android_view_ThreadedRenderer_detachSurfaceTexture },
-    { "nDestroyHardwareResources", "(J)V", (void*) android_view_ThreadedRenderer_destroyHardwareResources },
-    { "nTrimMemory", "(I)V", (void*) android_view_ThreadedRenderer_trimMemory },
-    { "nOverrideProperty", "(Ljava/lang/String;Ljava/lang/String;)V",  (void*) android_view_ThreadedRenderer_overrideProperty },
-    { "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence },
-    { "nStopDrawing", "(J)V", (void*) android_view_ThreadedRenderer_stopDrawing },
-    { "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending },
-    { "nDumpProfileInfo", "(JLjava/io/FileDescriptor;I)V", (void*) android_view_ThreadedRenderer_dumpProfileInfo },
-    { "setupShadersDiskCache", "(Ljava/lang/String;Ljava/lang/String;)V",
-                (void*) android_view_ThreadedRenderer_setupShadersDiskCache },
-    { "nAddRenderNode", "(JJZ)V", (void*) android_view_ThreadedRenderer_addRenderNode},
-    { "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode},
-    { "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode},
-    { "nSetContentDrawBounds", "(JIIII)V", (void*)android_view_ThreadedRenderer_setContentDrawBounds},
-    { "nSetPictureCaptureCallback", "(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)V",
-            (void*) android_view_ThreadedRenderer_setPictureCapturedCallbackJNI },
-    { "nSetFrameCallback", "(JLandroid/graphics/HardwareRenderer$FrameDrawingCallback;)V",
-            (void*)android_view_ThreadedRenderer_setFrameCallback},
-    { "nSetFrameCompleteCallback", "(JLandroid/graphics/HardwareRenderer$FrameCompleteCallback;)V",
-            (void*)android_view_ThreadedRenderer_setFrameCompleteCallback },
-    { "nAddObserver", "(JJ)V", (void*)android_view_ThreadedRenderer_addObserver },
-    { "nRemoveObserver", "(JJ)V", (void*)android_view_ThreadedRenderer_removeObserver },
-    { "nCopySurfaceInto", "(Landroid/view/Surface;IIIIJ)I",
-                (void*)android_view_ThreadedRenderer_copySurfaceInto },
-    { "nCreateHardwareBitmap", "(JII)Landroid/graphics/Bitmap;",
-            (void*)android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode },
-    { "disableVsync", "()V", (void*)android_view_ThreadedRenderer_disableVsync },
-    { "nSetHighContrastText", "(Z)V", (void*)android_view_ThreadedRenderer_setHighContrastText },
-    { "nHackySetRTAnimationsEnabled", "(Z)V",
-            (void*)android_view_ThreadedRenderer_hackySetRTAnimationsEnabled },
-    { "nSetDebuggingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDebuggingEnabled },
-    { "nSetIsolatedProcess", "(Z)V", (void*)android_view_ThreadedRenderer_setIsolatedProcess },
-    { "nSetContextPriority", "(I)V", (void*)android_view_ThreadedRenderer_setContextPriority },
-    { "nAllocateBuffers", "(J)V", (void*)android_view_ThreadedRenderer_allocateBuffers },
-    { "nSetForceDark", "(JZ)V", (void*)android_view_ThreadedRenderer_setForceDark },
-    { "nSetDisplayDensityDpi", "(I)V", (void*)android_view_ThreadedRenderer_setDisplayDensityDpi },
-    { "preload", "()V", (void*)android_view_ThreadedRenderer_preload },
+        {"nRotateProcessStatsBuffer", "()V",
+         (void*)android_view_ThreadedRenderer_rotateProcessStatsBuffer},
+        {"nSetProcessStatsBuffer", "(I)V",
+         (void*)android_view_ThreadedRenderer_setProcessStatsBuffer},
+        {"nGetRenderThreadTid", "(J)I", (void*)android_view_ThreadedRenderer_getRenderThreadTid},
+        {"nCreateRootRenderNode", "()J", (void*)android_view_ThreadedRenderer_createRootRenderNode},
+        {"nCreateProxy", "(ZZJ)J", (void*)android_view_ThreadedRenderer_createProxy},
+        {"nDeleteProxy", "(J)V", (void*)android_view_ThreadedRenderer_deleteProxy},
+        {"nLoadSystemProperties", "(J)Z",
+         (void*)android_view_ThreadedRenderer_loadSystemProperties},
+        {"nSetName", "(JLjava/lang/String;)V", (void*)android_view_ThreadedRenderer_setName},
+        {"nSetSurface", "(JLandroid/view/Surface;Z)V",
+         (void*)android_view_ThreadedRenderer_setSurface},
+        {"nPause", "(J)Z", (void*)android_view_ThreadedRenderer_pause},
+        {"nSetStopped", "(JZ)V", (void*)android_view_ThreadedRenderer_setStopped},
+        {"nSetLightAlpha", "(JFF)V", (void*)android_view_ThreadedRenderer_setLightAlpha},
+        {"nSetLightGeometry", "(JFFFF)V", (void*)android_view_ThreadedRenderer_setLightGeometry},
+        {"nSetOpaque", "(JZ)V", (void*)android_view_ThreadedRenderer_setOpaque},
+        {"nSetWideGamut", "(JZ)V", (void*)android_view_ThreadedRenderer_setWideGamut},
+        {"nSyncAndDrawFrame", "(J[JI)I", (void*)android_view_ThreadedRenderer_syncAndDrawFrame},
+        {"nDestroy", "(JJ)V", (void*)android_view_ThreadedRenderer_destroy},
+        {"nRegisterAnimatingRenderNode", "(JJ)V",
+         (void*)android_view_ThreadedRenderer_registerAnimatingRenderNode},
+        {"nRegisterVectorDrawableAnimator", "(JJ)V",
+         (void*)android_view_ThreadedRenderer_registerVectorDrawableAnimator},
+        {"nInvokeFunctor", "(JZ)V", (void*)android_view_ThreadedRenderer_invokeFunctor},
+        {"nCreateTextureLayer", "(J)J", (void*)android_view_ThreadedRenderer_createTextureLayer},
+        {"nBuildLayer", "(JJ)V", (void*)android_view_ThreadedRenderer_buildLayer},
+        {"nCopyLayerInto", "(JJJ)Z", (void*)android_view_ThreadedRenderer_copyLayerInto},
+        {"nPushLayerUpdate", "(JJ)V", (void*)android_view_ThreadedRenderer_pushLayerUpdate},
+        {"nCancelLayerUpdate", "(JJ)V", (void*)android_view_ThreadedRenderer_cancelLayerUpdate},
+        {"nDetachSurfaceTexture", "(JJ)V",
+         (void*)android_view_ThreadedRenderer_detachSurfaceTexture},
+        {"nDestroyHardwareResources", "(J)V",
+         (void*)android_view_ThreadedRenderer_destroyHardwareResources},
+        {"nTrimMemory", "(I)V", (void*)android_view_ThreadedRenderer_trimMemory},
+        {"nOverrideProperty", "(Ljava/lang/String;Ljava/lang/String;)V",
+         (void*)android_view_ThreadedRenderer_overrideProperty},
+        {"nFence", "(J)V", (void*)android_view_ThreadedRenderer_fence},
+        {"nStopDrawing", "(J)V", (void*)android_view_ThreadedRenderer_stopDrawing},
+        {"nNotifyFramePending", "(J)V", (void*)android_view_ThreadedRenderer_notifyFramePending},
+        {"nDumpProfileInfo", "(JLjava/io/FileDescriptor;I)V",
+         (void*)android_view_ThreadedRenderer_dumpProfileInfo},
+        {"setupShadersDiskCache", "(Ljava/lang/String;Ljava/lang/String;)V",
+         (void*)android_view_ThreadedRenderer_setupShadersDiskCache},
+        {"nAddRenderNode", "(JJZ)V", (void*)android_view_ThreadedRenderer_addRenderNode},
+        {"nRemoveRenderNode", "(JJ)V", (void*)android_view_ThreadedRenderer_removeRenderNode},
+        {"nDrawRenderNode", "(JJ)V", (void*)android_view_ThreadedRendererd_drawRenderNode},
+        {"nSetContentDrawBounds", "(JIIII)V",
+         (void*)android_view_ThreadedRenderer_setContentDrawBounds},
+        {"nSetPictureCaptureCallback",
+         "(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)V",
+         (void*)android_view_ThreadedRenderer_setPictureCapturedCallbackJNI},
+        {"nSetFrameCallback", "(JLandroid/graphics/HardwareRenderer$FrameDrawingCallback;)V",
+         (void*)android_view_ThreadedRenderer_setFrameCallback},
+        {"nSetFrameCompleteCallback",
+         "(JLandroid/graphics/HardwareRenderer$FrameCompleteCallback;)V",
+         (void*)android_view_ThreadedRenderer_setFrameCompleteCallback},
+        {"nAddObserver", "(JJ)V", (void*)android_view_ThreadedRenderer_addObserver},
+        {"nRemoveObserver", "(JJ)V", (void*)android_view_ThreadedRenderer_removeObserver},
+        {"nCopySurfaceInto", "(Landroid/view/Surface;IIIIJ)I",
+         (void*)android_view_ThreadedRenderer_copySurfaceInto},
+        {"nCreateHardwareBitmap", "(JII)Landroid/graphics/Bitmap;",
+         (void*)android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode},
+        {"disableVsync", "()V", (void*)android_view_ThreadedRenderer_disableVsync},
+        {"nSetHighContrastText", "(Z)V", (void*)android_view_ThreadedRenderer_setHighContrastText},
+        {"nHackySetRTAnimationsEnabled", "(Z)V",
+         (void*)android_view_ThreadedRenderer_hackySetRTAnimationsEnabled},
+        {"nSetDebuggingEnabled", "(Z)V", (void*)android_view_ThreadedRenderer_setDebuggingEnabled},
+        {"nSetIsolatedProcess", "(Z)V", (void*)android_view_ThreadedRenderer_setIsolatedProcess},
+        {"nSetContextPriority", "(I)V", (void*)android_view_ThreadedRenderer_setContextPriority},
+        {"nAllocateBuffers", "(J)V", (void*)android_view_ThreadedRenderer_allocateBuffers},
+        {"nSetForceDark", "(JZ)V", (void*)android_view_ThreadedRenderer_setForceDark},
+        {"nSetDisplayDensityDpi", "(I)V",
+         (void*)android_view_ThreadedRenderer_setDisplayDensityDpi},
+        {"nInitDisplayInfo", "(IIFFIJJ)V", (void*)android_view_ThreadedRenderer_initDisplayInfo},
+        {"preload", "()V", (void*)android_view_ThreadedRenderer_preload},
 };
 
 static JavaVM* mJvm = nullptr;