[HWUI] Get DeviceInfo through stable ABI
This also removes the dependency on ui/DeviceInfo other than in test
code.
Bug: 136263392
Bug: 136263238
Test: builds, boots
Change-Id: I6a4687e981359f0e6beb83be8a5501ed7fd16f15
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 0505fe3..6ba9699 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -260,6 +260,7 @@
"libhidltransport",
"libhwbinder",
"libvintf",
+ "libnativedisplay",
"libnativewindow",
"libdl",
"libdl_android",
@@ -439,6 +440,7 @@
],
shared_libs: [
"libandroidfw",
+ "libnativedisplay",
"libnativewindow",
"libgui",
"libpdfium",
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index ae90f11..b19aa2f 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -88,6 +88,7 @@
"libvulkan",
"libui",
"libgui",
+ "libnativedisplay",
"libnativewindow",
"libprotobuf-cpp-lite",
"libft2",
diff --git a/libs/hwui/DeviceInfo.cpp b/libs/hwui/DeviceInfo.cpp
index a0d3ff9..41e9b4b 100644
--- a/libs/hwui/DeviceInfo.cpp
+++ b/libs/hwui/DeviceInfo.cpp
@@ -15,74 +15,21 @@
*/
#include <DeviceInfo.h>
-
-#include "Properties.h"
-
#include <gui/SurfaceComposerClient.h>
+#include <log/log.h>
#include <ui/GraphicTypes.h>
#include <mutex>
#include <thread>
-#include <log/log.h>
+#include "Properties.h"
namespace android {
namespace uirenderer {
-static constexpr android::DisplayInfo sDummyDisplay{
- 1080, // w
- 1920, // h
- 320.0, // xdpi
- 320.0, // ydpi
- 60.0, // fps
- 2.0, // density
- 0, // orientation
- false, // secure?
- 0, // appVsyncOffset
- 0, // presentationDeadline
- 1080, // viewportW
- 1920, // viewportH
-};
-
DeviceInfo* DeviceInfo::get() {
- static DeviceInfo sDeviceInfo;
- return &sDeviceInfo;
-}
-
-static DisplayInfo QueryDisplayInfo() {
- if (Properties::isolatedProcess) {
- return sDummyDisplay;
- }
-
- const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
- LOG_ALWAYS_FATAL_IF(token == nullptr,
- "Failed to get display info because internal display is disconnected");
-
- DisplayInfo displayInfo;
- status_t status = SurfaceComposerClient::getDisplayInfo(token, &displayInfo);
- LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status);
- return displayInfo;
-}
-
-static float QueryMaxRefreshRate() {
- if (Properties::isolatedProcess) {
- return sDummyDisplay.fps;
- }
-
- const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
- LOG_ALWAYS_FATAL_IF(token == nullptr,
- "Failed to get display info because internal display is disconnected");
-
- Vector<DisplayInfo> configs;
- configs.reserve(10);
- status_t status = SurfaceComposerClient::getDisplayConfigs(token, &configs);
- LOG_ALWAYS_FATAL_IF(status, "Failed to getDisplayConfigs, error %d", status);
- LOG_ALWAYS_FATAL_IF(configs.size() == 0, "getDisplayConfigs returned 0 configs?");
- float max = 0.0f;
- for (auto& info : configs) {
- max = std::max(max, info.fps);
- }
- return max;
+ static DeviceInfo sDeviceInfo;
+ return &sDeviceInfo;
}
static void queryWideColorGamutPreference(sk_sp<SkColorSpace>* colorSpace, SkColorType* colorType) {
@@ -123,14 +70,17 @@
}
}
-DeviceInfo::DeviceInfo() : mMaxRefreshRate(QueryMaxRefreshRate()) {
+DeviceInfo::DeviceInfo() {
#if HWUI_NULL_GPU
mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
#else
mMaxTextureSize = -1;
#endif
- mDisplayInfo = QueryDisplayInfo();
- queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType);
+ updateDisplayInfo();
+ queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType);
+}
+DeviceInfo::~DeviceInfo() {
+ ADisplay_release(mDisplays);
}
int DeviceInfo::maxTextureSize() const {
@@ -143,7 +93,36 @@
}
void DeviceInfo::onDisplayConfigChanged() {
- mDisplayInfo = QueryDisplayInfo();
+ updateDisplayInfo();
+}
+
+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!");
+ mMaxRefreshRate = ADisplay_getMaxSupportedFps(mDisplays[mPhysicalDisplayIndex]);
+ }
+ status_t status = ADisplay_getCurrentConfig(mDisplays[mPhysicalDisplayIndex], &mCurrentConfig);
+ LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status);
+ mWidth = ADisplayConfig_getWidth(mCurrentConfig);
+ mHeight = ADisplayConfig_getHeight(mCurrentConfig);
+ mDensity = ADisplayConfig_getDensity(mCurrentConfig);
+ mRefreshRate = ADisplayConfig_getFps(mCurrentConfig);
+ mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig);
+ mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig);
}
} /* namespace uirenderer */
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index 0e3f119..3431583 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -16,8 +16,8 @@
#ifndef DEVICEINFO_H
#define DEVICEINFO_H
+#include <apex/display.h>
#include <SkImageInfo.h>
-#include <ui/DisplayInfo.h>
#include "utils/Macros.h"
@@ -33,28 +33,44 @@
public:
static DeviceInfo* get();
+ 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; }
+ static float getRefreshRate() { return get()->mRefreshRate; }
+ static int64_t getCompositorOffset() { return get()->mCompositorOffset; }
+ static int64_t getAppOffset() { return get()->mAppOffset; }
// 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;
- const DisplayInfo& displayInfo() const { return mDisplayInfo; }
sk_sp<SkColorSpace> getWideColorSpace() const { return mWideColorSpace; }
SkColorType getWideColorType() const { return mWideColorType; }
- float getMaxRefreshRate() const { return mMaxRefreshRate; }
void onDisplayConfigChanged();
private:
friend class renderthread::RenderThread;
static void setMaxTextureSize(int maxTextureSize);
+ void updateDisplayInfo();
DeviceInfo();
+ ~DeviceInfo();
int mMaxTextureSize;
- DisplayInfo mDisplayInfo;
sk_sp<SkColorSpace> mWideColorSpace;
SkColorType mWideColorType;
- const float mMaxRefreshRate;
+ ADisplayConfig* mCurrentConfig = nullptr;
+ ADisplay** mDisplays = nullptr;
+ int mDisplaysSize = 0;
+ int mPhysicalDisplayIndex = -1;
+ float mMaxRefreshRate = 60.0;
+ int32_t mWidth = 1080;
+ int32_t mHeight = 1920;
+ float mDensity = 2.0;
+ float mRefreshRate = 60.0;
+ int64_t mCompositorOffset = 0;
+ int64_t mAppOffset = 0;
};
} /* namespace uirenderer */
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index eae3584..10e7160 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -16,8 +16,10 @@
#include "JankTracker.h"
+#include <cutils/ashmem.h>
#include <errno.h>
#include <inttypes.h>
+#include <log/log.h>
#include <statslog.h>
#include <sys/mman.h>
@@ -25,11 +27,9 @@
#include <cmath>
#include <cstdio>
#include <limits>
-
-#include <cutils/ashmem.h>
-#include <log/log.h>
#include <sstream>
+#include "DeviceInfo.h"
#include "Properties.h"
#include "utils/TimeUtils.h"
#include "utils/Trace.h"
@@ -79,11 +79,11 @@
// and filter it out of the frame profile data
static FrameInfoIndex sFrameStart = FrameInfoIndex::IntendedVsync;
-JankTracker::JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo) {
+JankTracker::JankTracker(ProfileDataContainer* globalData) {
mGlobalData = globalData;
- nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / displayInfo.fps);
- nsecs_t sfOffset = frameIntervalNanos - (displayInfo.presentationDeadline - 1_ms);
- nsecs_t offsetDelta = sfOffset - displayInfo.appVsyncOffset;
+ nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1_s / DeviceInfo::getRefreshRate());
+ nsecs_t sfOffset = DeviceInfo::getCompositorOffset();
+ nsecs_t offsetDelta = sfOffset - DeviceInfo::getAppOffset();
// There are two different offset cases. If the offsetDelta is positive
// and small, then the intention is to give apps extra time by leveraging
// pipelining between the UI & RT threads. If the offsetDelta is large or
diff --git a/libs/hwui/JankTracker.h b/libs/hwui/JankTracker.h
index 08059268..4460266 100644
--- a/libs/hwui/JankTracker.h
+++ b/libs/hwui/JankTracker.h
@@ -23,7 +23,6 @@
#include "utils/RingBuffer.h"
#include <cutils/compiler.h>
-#include <ui/DisplayInfo.h>
#include <array>
#include <memory>
@@ -49,7 +48,7 @@
// TODO: Replace DrawProfiler with this
class JankTracker {
public:
- explicit JankTracker(ProfileDataContainer* globalData, const DisplayInfo& displayInfo);
+ explicit JankTracker(ProfileDataContainer* globalData);
void setDescription(JankTrackerType type, const std::string&& name) {
mDescription.type = type;
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 4e7df88..446e81e 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -16,7 +16,6 @@
#include "Properties.h"
#include "Debug.h"
-#include "DeviceInfo.h"
#ifdef __ANDROID__
#include "HWUIProperties.sysprop.h"
#endif
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
index e979448..24f6035 100644
--- a/libs/hwui/RenderProperties.h
+++ b/libs/hwui/RenderProperties.h
@@ -16,7 +16,10 @@
#pragma once
+#ifdef __ANDROID__ // Layoutlib does not support device info
#include "DeviceInfo.h"
+#endif // __ANDROID__
+
#include "Outline.h"
#include "Rect.h"
#include "RevealClip.h"
diff --git a/libs/hwui/renderthread/CacheManager.cpp b/libs/hwui/renderthread/CacheManager.cpp
index dc07f0d..b78c50a 100644
--- a/libs/hwui/renderthread/CacheManager.cpp
+++ b/libs/hwui/renderthread/CacheManager.cpp
@@ -16,6 +16,7 @@
#include "CacheManager.h"
+#include "DeviceInfo.h"
#include "Layer.h"
#include "Properties.h"
#include "RenderThread.h"
@@ -42,8 +43,8 @@
#define SURFACE_SIZE_MULTIPLIER (5.0f * 4.0f)
#define BACKGROUND_RETENTION_PERCENTAGE (0.5f)
-CacheManager::CacheManager(const DisplayInfo& display)
- : mMaxSurfaceArea(display.w * display.h)
+CacheManager::CacheManager()
+ : mMaxSurfaceArea(DeviceInfo::getWidth() * DeviceInfo::getHeight())
, mMaxResourceBytes(mMaxSurfaceArea * SURFACE_SIZE_MULTIPLIER)
, mBackgroundResourceBytes(mMaxResourceBytes * BACKGROUND_RETENTION_PERCENTAGE)
// This sets the maximum size for a single texture atlas in the GPU font cache. If
@@ -52,9 +53,9 @@
, mMaxGpuFontAtlasBytes(GrNextSizePow2(mMaxSurfaceArea))
// This sets the maximum size of the CPU font cache to be at least the same size as the
// total number of GPU font caches (i.e. 4 separate GPU atlases).
- , mMaxCpuFontCacheBytes(std::max(mMaxGpuFontAtlasBytes*4, SkGraphics::GetFontCacheLimit()))
+ , mMaxCpuFontCacheBytes(
+ std::max(mMaxGpuFontAtlasBytes * 4, SkGraphics::GetFontCacheLimit()))
, mBackgroundCpuFontCacheBytes(mMaxCpuFontCacheBytes * BACKGROUND_RETENTION_PERCENTAGE) {
-
SkGraphics::SetFontCacheLimit(mMaxCpuFontCacheBytes);
mVectorDrawableAtlas = new skiapipeline::VectorDrawableAtlas(
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index d7977cc..dacb7bd 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -21,7 +21,6 @@
#include <GrContext.h>
#endif
#include <SkSurface.h>
-#include <ui/DisplayInfo.h>
#include <utils/String8.h>
#include <vector>
@@ -59,7 +58,7 @@
private:
friend class RenderThread;
- explicit CacheManager(const DisplayInfo& display);
+ explicit CacheManager();
#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
void reset(sk_sp<GrContext> grContext);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 93fd0c8..323f622 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -102,13 +102,13 @@
, mGenerationID(0)
, mOpaque(!translucent)
, mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord()))
- , mJankTracker(&thread.globalProfileData(), DeviceInfo::get()->displayInfo())
+ , mJankTracker(&thread.globalProfileData())
, mProfiler(mJankTracker.frames(), thread.timeLord().frameIntervalNanos())
, mContentDrawBounds(0, 0, 0, 0)
, mRenderPipeline(std::move(renderPipeline)) {
rootRenderNode->makeRoot();
mRenderNodes.emplace_back(rootRenderNode);
- mProfiler.setDensity(DeviceInfo::get()->displayInfo().density);
+ mProfiler.setDensity(DeviceInfo::getDensity());
setRenderAheadDepth(Properties::defaultRenderAhead);
}
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index ee1a7ce..a446858 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -179,12 +179,11 @@
mEglManager = new EglManager();
mRenderState = new RenderState(*this);
mVkManager = new VulkanManager();
- mCacheManager = new CacheManager(DeviceInfo::get()->displayInfo());
+ mCacheManager = new CacheManager();
}
void RenderThread::setupFrameInterval() {
- auto& displayInfo = DeviceInfo::get()->displayInfo();
- nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / displayInfo.fps);
+ nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / DeviceInfo::getRefreshRate());
mTimeLord.setFrameInterval(frameIntervalNanos);
mDispatchFrameDelay = static_cast<nsecs_t>(frameIntervalNanos * .25f);
}
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 5aa1af3..bdd80721 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -29,7 +29,6 @@
#include <GrContext.h>
#include <SkBitmap.h>
#include <cutils/compiler.h>
-#include <ui/DisplayInfo.h>
#include <utils/Looper.h>
#include <utils/Thread.h>
diff --git a/libs/hwui/tests/unit/CacheManagerTests.cpp b/libs/hwui/tests/unit/CacheManagerTests.cpp
index 3f1ef93..c83a3c8 100644
--- a/libs/hwui/tests/unit/CacheManagerTests.cpp
+++ b/libs/hwui/tests/unit/CacheManagerTests.cpp
@@ -33,7 +33,8 @@
}
RENDERTHREAD_SKIA_PIPELINE_TEST(CacheManager, trimMemory) {
- DisplayInfo displayInfo = DeviceInfo::get()->displayInfo();
+ int32_t width = DeviceInfo::get()->getWidth();
+ int32_t height = DeviceInfo::get()->getHeight();
GrContext* grContext = renderThread.getGrContext();
ASSERT_TRUE(grContext != nullptr);
@@ -42,7 +43,7 @@
std::vector<sk_sp<SkSurface>> surfaces;
while (getCacheUsage(grContext) <= renderThread.cacheManager().getBackgroundCacheSize()) {
- SkImageInfo info = SkImageInfo::MakeA8(displayInfo.w, displayInfo.h);
+ SkImageInfo info = SkImageInfo::MakeA8(width, height);
sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
surface->getCanvas()->drawColor(SK_AlphaTRANSPARENT);
@@ -52,8 +53,7 @@
}
// create an image and pin it so that we have something with a unique key in the cache
- sk_sp<Bitmap> bitmap =
- Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(displayInfo.w, displayInfo.h));
+ sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height));
sk_sp<SkImage> image = bitmap->makeImage();
ASSERT_TRUE(SkImage_pinAsTexture(image.get(), grContext));