Plumb display density to HWUI through ActivityThread.

Whenever an activity's configuration is updated, then tell
HardwareRenderer about it. That way, visualizating frame info does not
need to learn the display density from SurfaceFlinger, which reduces the
native-side api surface for displays.

For now, this method is kept hidden and will be stabilized when
HardwareRenderer's apis are stabilized for Mainline inclusion.

Bug: 146387012
Test: boots, builds
Test: jank visualizer
Change-Id: I51d2964bb78882516ebdff05b80819814894bdce
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index c24224c..1c947a7 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -113,11 +113,12 @@
 
     mWidth = ADisplayConfig_getWidth(mCurrentConfig);
     mHeight = ADisplayConfig_getHeight(mCurrentConfig);
-    mDensity = ADisplayConfig_getDensity(mCurrentConfig);
     mVsyncPeriod = static_cast<int64_t>(1000000000 / ADisplayConfig_getFps(mCurrentConfig));
     mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig);
     mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig);
 }
 
+std::atomic<float> DeviceInfo::sDensity = 2.0;
+
 } /* namespace uirenderer */
 } /* namespace android */
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index 16a22f4..bcc9301 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -36,10 +36,13 @@
     static float getMaxRefreshRate() { return get()->mMaxRefreshRate; }
     static int32_t getWidth() { return get()->mWidth; }
     static int32_t getHeight() { return get()->mHeight; }
-    static float getDensity() { return get()->mDensity; }
+    // 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; }
+    // Sets the density in density-independent pixels
+    static void setDensity(float density) { sDensity.store(density); }
 
     // 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
@@ -68,10 +71,14 @@
     float mMaxRefreshRate = 60.0;
     int32_t mWidth = 1080;
     int32_t mHeight = 1920;
-    float mDensity = 2.0;
     int64_t mVsyncPeriod = 16666666;
     int64_t mCompositorOffset = 0;
     int64_t mAppOffset = 0;
+
+    // Density is not retrieved from the ADisplay apis, so this may potentially
+    // be called on multiple threads.
+    // Unit is density-independent pixels
+    static std::atomic<float> sDensity;
 };
 
 } /* namespace uirenderer */
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 49c7fcd..4f8efa0 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -593,6 +593,13 @@
     RenderProxy::preload();
 }
 
+// Plumbs the display density down to DeviceInfo.
+static void android_view_ThreadedRenderer_setDisplayDensityDpi(JNIEnv*, jclass, jint densityDpi) {
+    // Convert from dpi to density-independent pixels.
+    const float density = densityDpi / 160.0;
+    DeviceInfo::setDensity(density);
+}
+
 // ----------------------------------------------------------------------------
 // HardwareRendererObserver
 // ----------------------------------------------------------------------------
@@ -697,6 +704,7 @@
     { "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 },
 };