Merge "Adapt SurfaceControl to libgui API for display info"
This commit is contained in:
committed by
Android (Google) Code Review
commit
5e135fe823
@@ -42,10 +42,10 @@
|
||||
|
||||
#include <android-base/properties.h>
|
||||
|
||||
#include <ui/DisplayConfig.h>
|
||||
#include <ui/PixelFormat.h>
|
||||
#include <ui/Rect.h>
|
||||
#include <ui/Region.h>
|
||||
#include <ui/DisplayInfo.h>
|
||||
|
||||
#include <gui/ISurfaceComposer.h>
|
||||
#include <gui/Surface.h>
|
||||
@@ -283,16 +283,19 @@ status_t BootAnimation::readyToRun() {
|
||||
|
||||
mDisplayToken = SurfaceComposerClient::getInternalDisplayToken();
|
||||
if (mDisplayToken == nullptr)
|
||||
return -1;
|
||||
return NAME_NOT_FOUND;
|
||||
|
||||
DisplayInfo dinfo;
|
||||
status_t status = SurfaceComposerClient::getDisplayInfo(mDisplayToken, &dinfo);
|
||||
if (status)
|
||||
return -1;
|
||||
DisplayConfig displayConfig;
|
||||
const status_t error =
|
||||
SurfaceComposerClient::getActiveDisplayConfig(mDisplayToken, &displayConfig);
|
||||
if (error != NO_ERROR)
|
||||
return error;
|
||||
|
||||
const ui::Size& resolution = displayConfig.resolution;
|
||||
|
||||
// create the native surface
|
||||
sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
|
||||
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
|
||||
resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565);
|
||||
|
||||
SurfaceComposerClient::Transaction t;
|
||||
|
||||
|
||||
@@ -152,7 +152,8 @@ public final class SurfaceControl implements Parcelable {
|
||||
int L, int T, int R, int B);
|
||||
private static native void nativeSetDisplaySize(long transactionObj, IBinder displayToken,
|
||||
int width, int height);
|
||||
private static native SurfaceControl.PhysicalDisplayInfo[] nativeGetDisplayConfigs(
|
||||
private static native SurfaceControl.DisplayInfo nativeGetDisplayInfo(IBinder displayToken);
|
||||
private static native SurfaceControl.DisplayConfig[] nativeGetDisplayConfigs(
|
||||
IBinder displayToken);
|
||||
private static native DisplayedContentSamplingAttributes
|
||||
nativeGetDisplayedContentSamplingAttributes(IBinder displayToken);
|
||||
@@ -1278,140 +1279,45 @@ public final class SurfaceControl implements Parcelable {
|
||||
Integer.toHexString(System.identityHashCode(this));
|
||||
}
|
||||
|
||||
/*
|
||||
* set display parameters.
|
||||
* needs to be inside open/closeTransaction block
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes the properties of a physical display known to surface flinger.
|
||||
* Immutable information about physical display.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final class PhysicalDisplayInfo {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public int width;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public int height;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public float refreshRate;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static final class DisplayInfo {
|
||||
public float density;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public float xDpi;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public float yDpi;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public boolean secure;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public long appVsyncOffsetNanos;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public long presentationDeadlineNanos;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public PhysicalDisplayInfo() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
|
||||
copyFrom(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public boolean equals(PhysicalDisplayInfo other) {
|
||||
return other != null
|
||||
&& width == other.width
|
||||
&& height == other.height
|
||||
&& refreshRate == other.refreshRate
|
||||
&& density == other.density
|
||||
&& xDpi == other.xDpi
|
||||
&& yDpi == other.yDpi
|
||||
&& secure == other.secure
|
||||
&& appVsyncOffsetNanos == other.appVsyncOffsetNanos
|
||||
&& presentationDeadlineNanos == other.presentationDeadlineNanos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 0; // don't care
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void copyFrom(PhysicalDisplayInfo other) {
|
||||
width = other.width;
|
||||
height = other.height;
|
||||
refreshRate = other.refreshRate;
|
||||
density = other.density;
|
||||
xDpi = other.xDpi;
|
||||
yDpi = other.yDpi;
|
||||
secure = other.secure;
|
||||
appVsyncOffsetNanos = other.appVsyncOffsetNanos;
|
||||
presentationDeadlineNanos = other.presentationDeadlineNanos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
|
||||
+ "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
|
||||
+ ", appVsyncOffset " + appVsyncOffsetNanos
|
||||
+ ", bufferDeadline " + presentationDeadlineNanos + "}";
|
||||
return "DisplayInfo{density=" + density + ", secure=" + secure + "}";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration supported by physical display.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static final class DisplayConfig {
|
||||
public int width;
|
||||
public int height;
|
||||
public float xDpi;
|
||||
public float yDpi;
|
||||
|
||||
public float refreshRate;
|
||||
public long appVsyncOffsetNanos;
|
||||
public long presentationDeadlineNanos;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DisplayConfig{width=" + width
|
||||
+ ", height=" + height
|
||||
+ ", xDpi=" + xDpi
|
||||
+ ", yDpi=" + yDpi
|
||||
+ ", refreshRate=" + refreshRate
|
||||
+ ", appVsyncOffsetNanos=" + appVsyncOffsetNanos
|
||||
+ ", presentationDeadlineNanos=" + presentationDeadlineNanos + "}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1428,8 +1334,17 @@ public final class SurfaceControl implements Parcelable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) {
|
||||
public static SurfaceControl.DisplayInfo getDisplayInfo(IBinder displayToken) {
|
||||
if (displayToken == null) {
|
||||
throw new IllegalArgumentException("displayToken must not be null");
|
||||
}
|
||||
return nativeGetDisplayInfo(displayToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static SurfaceControl.DisplayConfig[] getDisplayConfigs(IBinder displayToken) {
|
||||
if (displayToken == null) {
|
||||
throw new IllegalArgumentException("displayToken must not be null");
|
||||
}
|
||||
@@ -1825,7 +1740,7 @@ public final class SurfaceControl implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO(116025192): Remove this stopgap once framework is display-agnostic.
|
||||
* TODO(b/116025192): Remove this stopgap once framework is display-agnostic.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
|
||||
@@ -22,20 +22,22 @@
|
||||
#include "android_hardware_input_InputWindowHandle.h"
|
||||
#include "core_jni_helpers.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <android-base/chrono_utils.h>
|
||||
#include <android/graphics/region.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <android-base/chrono_utils.h>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <nativehelper/ScopedUtfChars.h>
|
||||
#include <android_runtime/android_view_Surface.h>
|
||||
#include <android_runtime/android_view_SurfaceSession.h>
|
||||
#include <gui/Surface.h>
|
||||
#include <gui/SurfaceComposerClient.h>
|
||||
#include <jni.h>
|
||||
#include <memory>
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <nativehelper/ScopedUtfChars.h>
|
||||
#include <stdio.h>
|
||||
#include <system/graphics.h>
|
||||
#include <ui/ConfigStoreTypes.h>
|
||||
#include <ui/DisplayConfig.h>
|
||||
#include <ui/DisplayInfo.h>
|
||||
#include <ui/DisplayedFrameStats.h>
|
||||
#include <ui/FrameStats.h>
|
||||
@@ -60,19 +62,24 @@ static void doThrowIAE(JNIEnv* env, const char* msg = nullptr) {
|
||||
static const char* const OutOfResourcesException =
|
||||
"android/view/Surface$OutOfResourcesException";
|
||||
|
||||
static struct {
|
||||
jclass clazz;
|
||||
jmethodID ctor;
|
||||
jfieldID density;
|
||||
jfieldID secure;
|
||||
} gDisplayInfoClassInfo;
|
||||
|
||||
static struct {
|
||||
jclass clazz;
|
||||
jmethodID ctor;
|
||||
jfieldID width;
|
||||
jfieldID height;
|
||||
jfieldID refreshRate;
|
||||
jfieldID density;
|
||||
jfieldID xDpi;
|
||||
jfieldID yDpi;
|
||||
jfieldID secure;
|
||||
jfieldID refreshRate;
|
||||
jfieldID appVsyncOffsetNanos;
|
||||
jfieldID presentationDeadlineNanos;
|
||||
} gPhysicalDisplayInfoClassInfo;
|
||||
} gDisplayConfigClassInfo;
|
||||
|
||||
static struct {
|
||||
jfieldID bottom;
|
||||
@@ -766,37 +773,46 @@ static void nativeSetDisplaySize(JNIEnv* env, jclass clazz,
|
||||
}
|
||||
}
|
||||
|
||||
static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz,
|
||||
jobject tokenObj) {
|
||||
sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
|
||||
if (token == NULL) return NULL;
|
||||
|
||||
Vector<DisplayInfo> configs;
|
||||
if (SurfaceComposerClient::getDisplayConfigs(token, &configs) != NO_ERROR ||
|
||||
configs.size() == 0) {
|
||||
return NULL;
|
||||
static jobject nativeGetDisplayInfo(JNIEnv* env, jclass clazz, jobject tokenObj) {
|
||||
DisplayInfo info;
|
||||
if (const auto token = ibinderForJavaObject(env, tokenObj);
|
||||
!token || SurfaceComposerClient::getDisplayInfo(token, &info) != NO_ERROR) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
jobjectArray configArray = env->NewObjectArray(configs.size(),
|
||||
gPhysicalDisplayInfoClassInfo.clazz, NULL);
|
||||
jobject object = env->NewObject(gDisplayInfoClassInfo.clazz, gDisplayInfoClassInfo.ctor);
|
||||
env->SetFloatField(object, gDisplayInfoClassInfo.density, info.density);
|
||||
env->SetBooleanField(object, gDisplayInfoClassInfo.secure, info.secure);
|
||||
return object;
|
||||
}
|
||||
|
||||
static jobjectArray nativeGetDisplayConfigs(JNIEnv* env, jclass clazz, jobject tokenObj) {
|
||||
Vector<DisplayConfig> configs;
|
||||
if (const auto token = ibinderForJavaObject(env, tokenObj); !token ||
|
||||
SurfaceComposerClient::getDisplayConfigs(token, &configs) != NO_ERROR ||
|
||||
configs.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
jobjectArray configArray =
|
||||
env->NewObjectArray(configs.size(), gDisplayConfigClassInfo.clazz, nullptr);
|
||||
|
||||
for (size_t c = 0; c < configs.size(); ++c) {
|
||||
const DisplayInfo& info = configs[c];
|
||||
jobject infoObj = env->NewObject(gPhysicalDisplayInfoClassInfo.clazz,
|
||||
gPhysicalDisplayInfoClassInfo.ctor);
|
||||
env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w);
|
||||
env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h);
|
||||
env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps);
|
||||
env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density);
|
||||
env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi);
|
||||
env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi);
|
||||
env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure);
|
||||
env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos,
|
||||
info.appVsyncOffset);
|
||||
env->SetLongField(infoObj, gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos,
|
||||
info.presentationDeadline);
|
||||
env->SetObjectArrayElement(configArray, static_cast<jsize>(c), infoObj);
|
||||
env->DeleteLocalRef(infoObj);
|
||||
const DisplayConfig& config = configs[c];
|
||||
jobject object =
|
||||
env->NewObject(gDisplayConfigClassInfo.clazz, gDisplayConfigClassInfo.ctor);
|
||||
env->SetIntField(object, gDisplayConfigClassInfo.width, config.resolution.getWidth());
|
||||
env->SetIntField(object, gDisplayConfigClassInfo.height, config.resolution.getHeight());
|
||||
env->SetFloatField(object, gDisplayConfigClassInfo.xDpi, config.xDpi);
|
||||
env->SetFloatField(object, gDisplayConfigClassInfo.yDpi, config.yDpi);
|
||||
|
||||
env->SetFloatField(object, gDisplayConfigClassInfo.refreshRate, config.refreshRate);
|
||||
env->SetLongField(object, gDisplayConfigClassInfo.appVsyncOffsetNanos,
|
||||
config.appVsyncOffset);
|
||||
env->SetLongField(object, gDisplayConfigClassInfo.presentationDeadlineNanos,
|
||||
config.presentationDeadline);
|
||||
env->SetObjectArrayElement(configArray, static_cast<jsize>(c), object);
|
||||
env->DeleteLocalRef(object);
|
||||
}
|
||||
|
||||
return configArray;
|
||||
@@ -1409,7 +1425,9 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
|
||||
(void*)nativeSetDisplayProjection },
|
||||
{"nativeSetDisplaySize", "(JLandroid/os/IBinder;II)V",
|
||||
(void*)nativeSetDisplaySize },
|
||||
{"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$PhysicalDisplayInfo;",
|
||||
{"nativeGetDisplayInfo", "(Landroid/os/IBinder;)Landroid/view/SurfaceControl$DisplayInfo;",
|
||||
(void*)nativeGetDisplayInfo },
|
||||
{"nativeGetDisplayConfigs", "(Landroid/os/IBinder;)[Landroid/view/SurfaceControl$DisplayConfig;",
|
||||
(void*)nativeGetDisplayConfigs },
|
||||
{"nativeGetActiveConfig", "(Landroid/os/IBinder;)I",
|
||||
(void*)nativeGetActiveConfig },
|
||||
@@ -1507,21 +1525,24 @@ int register_android_view_SurfaceControl(JNIEnv* env)
|
||||
int err = RegisterMethodsOrDie(env, "android/view/SurfaceControl",
|
||||
sSurfaceControlMethods, NELEM(sSurfaceControlMethods));
|
||||
|
||||
jclass clazz = FindClassOrDie(env, "android/view/SurfaceControl$PhysicalDisplayInfo");
|
||||
gPhysicalDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
|
||||
gPhysicalDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env,
|
||||
gPhysicalDisplayInfoClassInfo.clazz, "<init>", "()V");
|
||||
gPhysicalDisplayInfoClassInfo.width = GetFieldIDOrDie(env, clazz, "width", "I");
|
||||
gPhysicalDisplayInfoClassInfo.height = GetFieldIDOrDie(env, clazz, "height", "I");
|
||||
gPhysicalDisplayInfoClassInfo.refreshRate = GetFieldIDOrDie(env, clazz, "refreshRate", "F");
|
||||
gPhysicalDisplayInfoClassInfo.density = GetFieldIDOrDie(env, clazz, "density", "F");
|
||||
gPhysicalDisplayInfoClassInfo.xDpi = GetFieldIDOrDie(env, clazz, "xDpi", "F");
|
||||
gPhysicalDisplayInfoClassInfo.yDpi = GetFieldIDOrDie(env, clazz, "yDpi", "F");
|
||||
gPhysicalDisplayInfoClassInfo.secure = GetFieldIDOrDie(env, clazz, "secure", "Z");
|
||||
gPhysicalDisplayInfoClassInfo.appVsyncOffsetNanos = GetFieldIDOrDie(env,
|
||||
clazz, "appVsyncOffsetNanos", "J");
|
||||
gPhysicalDisplayInfoClassInfo.presentationDeadlineNanos = GetFieldIDOrDie(env,
|
||||
clazz, "presentationDeadlineNanos", "J");
|
||||
jclass infoClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayInfo");
|
||||
gDisplayInfoClassInfo.clazz = MakeGlobalRefOrDie(env, infoClazz);
|
||||
gDisplayInfoClassInfo.ctor = GetMethodIDOrDie(env, infoClazz, "<init>", "()V");
|
||||
gDisplayInfoClassInfo.density = GetFieldIDOrDie(env, infoClazz, "density", "F");
|
||||
gDisplayInfoClassInfo.secure = GetFieldIDOrDie(env, infoClazz, "secure", "Z");
|
||||
|
||||
jclass configClazz = FindClassOrDie(env, "android/view/SurfaceControl$DisplayConfig");
|
||||
gDisplayConfigClassInfo.clazz = MakeGlobalRefOrDie(env, configClazz);
|
||||
gDisplayConfigClassInfo.ctor = GetMethodIDOrDie(env, configClazz, "<init>", "()V");
|
||||
gDisplayConfigClassInfo.width = GetFieldIDOrDie(env, configClazz, "width", "I");
|
||||
gDisplayConfigClassInfo.height = GetFieldIDOrDie(env, configClazz, "height", "I");
|
||||
gDisplayConfigClassInfo.xDpi = GetFieldIDOrDie(env, configClazz, "xDpi", "F");
|
||||
gDisplayConfigClassInfo.yDpi = GetFieldIDOrDie(env, configClazz, "yDpi", "F");
|
||||
gDisplayConfigClassInfo.refreshRate = GetFieldIDOrDie(env, configClazz, "refreshRate", "F");
|
||||
gDisplayConfigClassInfo.appVsyncOffsetNanos =
|
||||
GetFieldIDOrDie(env, configClazz, "appVsyncOffsetNanos", "J");
|
||||
gDisplayConfigClassInfo.presentationDeadlineNanos =
|
||||
GetFieldIDOrDie(env, configClazz, "presentationDeadlineNanos", "J");
|
||||
|
||||
jclass rectClazz = FindClassOrDie(env, "android/graphics/Rect");
|
||||
gRectClassInfo.bottom = GetFieldIDOrDie(env, rectClazz, "bottom", "I");
|
||||
|
||||
@@ -22,43 +22,50 @@ namespace android {
|
||||
namespace uirenderer {
|
||||
namespace test {
|
||||
|
||||
static const int IDENT_DISPLAYEVENT = 1;
|
||||
|
||||
static android::DisplayInfo DUMMY_DISPLAY{
|
||||
1080, // w
|
||||
1920, // h
|
||||
320.0, // xdpi
|
||||
320.0, // ydpi
|
||||
60.0, // fps
|
||||
2.0, // density
|
||||
ui::ROTATION_0, // orientation
|
||||
false, // secure?
|
||||
0, // appVsyncOffset
|
||||
0, // presentationDeadline
|
||||
};
|
||||
|
||||
DisplayInfo getInternalDisplay() {
|
||||
#if !HWUI_NULL_GPU
|
||||
DisplayInfo display;
|
||||
const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
|
||||
LOG_ALWAYS_FATAL_IF(token == nullptr,
|
||||
"Failed to get display info because internal display is disconnected\n");
|
||||
status_t status = SurfaceComposerClient::getDisplayInfo(token, &display);
|
||||
LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n");
|
||||
return display;
|
||||
const DisplayInfo& getDisplayInfo() {
|
||||
static DisplayInfo info = [] {
|
||||
DisplayInfo info;
|
||||
#if HWUI_NULL_GPU
|
||||
info.density = 2.f;
|
||||
#else
|
||||
return DUMMY_DISPLAY;
|
||||
const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
|
||||
LOG_ALWAYS_FATAL_IF(!token, "%s: No internal display", __FUNCTION__);
|
||||
|
||||
const status_t status = SurfaceComposerClient::getDisplayInfo(token, &info);
|
||||
LOG_ALWAYS_FATAL_IF(status, "%s: Failed to get display info", __FUNCTION__);
|
||||
#endif
|
||||
return info;
|
||||
}();
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
// Initialize to a dummy default
|
||||
android::DisplayInfo gDisplay = DUMMY_DISPLAY;
|
||||
const DisplayConfig& getActiveDisplayConfig() {
|
||||
static DisplayConfig config = [] {
|
||||
DisplayConfig config;
|
||||
#if HWUI_NULL_GPU
|
||||
config.resolution = ui::Size(1080, 1920);
|
||||
config.xDpi = config.yDpi = 320.f;
|
||||
config.refreshRate = 60.f;
|
||||
#else
|
||||
const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
|
||||
LOG_ALWAYS_FATAL_IF(!token, "%s: No internal display", __FUNCTION__);
|
||||
|
||||
const status_t status = SurfaceComposerClient::getActiveDisplayConfig(token, &config);
|
||||
LOG_ALWAYS_FATAL_IF(status, "%s: Failed to get active display config", __FUNCTION__);
|
||||
#endif
|
||||
return config;
|
||||
}();
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
TestContext::TestContext() {
|
||||
mLooper = new Looper(true);
|
||||
mSurfaceComposerClient = new SurfaceComposerClient();
|
||||
mLooper->addFd(mDisplayEventReceiver.getFd(), IDENT_DISPLAYEVENT, Looper::EVENT_INPUT, nullptr,
|
||||
nullptr);
|
||||
|
||||
constexpr int EVENT_ID = 1;
|
||||
mLooper->addFd(mDisplayEventReceiver.getFd(), EVENT_ID, Looper::EVENT_INPUT, nullptr, nullptr);
|
||||
}
|
||||
|
||||
TestContext::~TestContext() {}
|
||||
@@ -79,8 +86,10 @@ void TestContext::createSurface() {
|
||||
}
|
||||
|
||||
void TestContext::createWindowSurface() {
|
||||
mSurfaceControl = mSurfaceComposerClient->createSurface(String8("HwuiTest"), gDisplay.w,
|
||||
gDisplay.h, PIXEL_FORMAT_RGBX_8888);
|
||||
const ui::Size& resolution = getActiveDisplayResolution();
|
||||
mSurfaceControl =
|
||||
mSurfaceComposerClient->createSurface(String8("HwuiTest"), resolution.getWidth(),
|
||||
resolution.getHeight(), PIXEL_FORMAT_RGBX_8888);
|
||||
|
||||
SurfaceComposerClient::Transaction t;
|
||||
t.setLayer(mSurfaceControl, 0x7FFFFFF).show(mSurfaceControl).apply();
|
||||
@@ -94,7 +103,8 @@ void TestContext::createOffscreenSurface() {
|
||||
producer->setMaxDequeuedBufferCount(3);
|
||||
producer->setAsyncMode(true);
|
||||
mConsumer = new BufferItemConsumer(consumer, GRALLOC_USAGE_HW_COMPOSER, 4);
|
||||
mConsumer->setDefaultBufferSize(gDisplay.w, gDisplay.h);
|
||||
const ui::Size& resolution = getActiveDisplayResolution();
|
||||
mConsumer->setDefaultBufferSize(resolution.getWidth(), resolution.getHeight());
|
||||
mSurface = new Surface(producer);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,20 +23,25 @@
|
||||
#include <gui/Surface.h>
|
||||
#include <gui/SurfaceComposerClient.h>
|
||||
#include <gui/SurfaceControl.h>
|
||||
#include <ui/DisplayConfig.h>
|
||||
#include <ui/DisplayInfo.h>
|
||||
#include <utils/Looper.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#define dp(x) ((x) * android::uirenderer::test::getDisplayInfo().density)
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
namespace test {
|
||||
|
||||
extern DisplayInfo gDisplay;
|
||||
#define dp(x) ((x)*android::uirenderer::test::gDisplay.density)
|
||||
const DisplayInfo& getDisplayInfo();
|
||||
const DisplayConfig& getActiveDisplayConfig();
|
||||
|
||||
DisplayInfo getInternalDisplay();
|
||||
inline const ui::Size& getActiveDisplayResolution() {
|
||||
return getActiveDisplayConfig().resolution;
|
||||
}
|
||||
|
||||
class TestContext {
|
||||
public:
|
||||
|
||||
@@ -109,16 +109,14 @@ void outputBenchmarkReport(const TestScene::Info& info, const TestScene::Options
|
||||
|
||||
void run(const TestScene::Info& info, const TestScene::Options& opts,
|
||||
benchmark::BenchmarkReporter* reporter) {
|
||||
// Switch to the real display
|
||||
gDisplay = getInternalDisplay();
|
||||
|
||||
Properties::forceDrawFrame = true;
|
||||
TestContext testContext;
|
||||
testContext.setRenderOffscreen(opts.renderOffscreen);
|
||||
|
||||
// create the native surface
|
||||
const int width = gDisplay.w;
|
||||
const int height = gDisplay.h;
|
||||
const ui::Size& resolution = getActiveDisplayResolution();
|
||||
const int width = resolution.getWidth();
|
||||
const int height = resolution.getHeight();
|
||||
sp<Surface> surface = testContext.surface();
|
||||
|
||||
std::unique_ptr<TestScene> scene(info.createScene(opts));
|
||||
|
||||
@@ -91,8 +91,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private void tryConnectDisplayLocked(long physicalDisplayId) {
|
||||
final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(physicalDisplayId);
|
||||
if (displayToken != null) {
|
||||
SurfaceControl.PhysicalDisplayInfo[] configs =
|
||||
SurfaceControl.getDisplayConfigs(displayToken);
|
||||
SurfaceControl.DisplayInfo info = SurfaceControl.getDisplayInfo(displayToken);
|
||||
if (info == null) {
|
||||
Slog.w(TAG, "No valid info found for display device " + physicalDisplayId);
|
||||
return;
|
||||
}
|
||||
SurfaceControl.DisplayConfig[] configs = SurfaceControl.getDisplayConfigs(displayToken);
|
||||
if (configs == null) {
|
||||
// There are no valid configs for this device, so we can't use it
|
||||
Slog.w(TAG, "No valid configs found for display device " + physicalDisplayId);
|
||||
@@ -115,19 +119,19 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
activeColorMode = Display.COLOR_MODE_INVALID;
|
||||
}
|
||||
int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken);
|
||||
SurfaceControl.DesiredDisplayConfigSpecs desiredDisplayConfigSpecs =
|
||||
SurfaceControl.DesiredDisplayConfigSpecs configSpecs =
|
||||
SurfaceControl.getDesiredDisplayConfigSpecs(displayToken);
|
||||
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
|
||||
if (device == null) {
|
||||
// Display was added.
|
||||
final boolean isInternal = mDevices.size() == 0;
|
||||
device = new LocalDisplayDevice(displayToken, physicalDisplayId, configs,
|
||||
activeConfig, desiredDisplayConfigSpecs, colorModes, activeColorMode,
|
||||
device = new LocalDisplayDevice(displayToken, physicalDisplayId, info,
|
||||
configs, activeConfig, configSpecs, colorModes, activeColorMode,
|
||||
isInternal);
|
||||
mDevices.put(physicalDisplayId, device);
|
||||
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
|
||||
} else if (device.updatePhysicalDisplayInfoLocked(configs, activeConfig,
|
||||
desiredDisplayConfigSpecs, colorModes, activeColorMode)) {
|
||||
} else if (device.updateDisplayConfigsLocked(configs, activeConfig, configSpecs,
|
||||
colorModes, activeColorMode)) {
|
||||
// Display properties changed.
|
||||
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
|
||||
}
|
||||
@@ -179,7 +183,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private DisplayModeDirector.DesiredDisplayModeSpecs mDisplayModeSpecs =
|
||||
new DisplayModeDirector.DesiredDisplayModeSpecs();
|
||||
private boolean mDisplayModeSpecsInvalid;
|
||||
private int mActivePhysIndex;
|
||||
private int mActiveConfigId;
|
||||
private int mActiveColorMode;
|
||||
private boolean mActiveColorModeInvalid;
|
||||
private Display.HdrCapabilities mHdrCapabilities;
|
||||
@@ -189,21 +193,25 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private boolean mGameContentTypeRequested;
|
||||
private boolean mSidekickActive;
|
||||
private SidekickInternal mSidekickInternal;
|
||||
private SurfaceControl.PhysicalDisplayInfo[] mDisplayInfos;
|
||||
private SurfaceControl.DisplayInfo mDisplayInfo;
|
||||
private SurfaceControl.DisplayConfig[] mDisplayConfigs;
|
||||
private Spline mSystemBrightnessToNits;
|
||||
private Spline mNitsToHalBrightness;
|
||||
private boolean mHalBrightnessSupport;
|
||||
|
||||
LocalDisplayDevice(IBinder displayToken, long physicalDisplayId,
|
||||
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
|
||||
SurfaceControl.DesiredDisplayConfigSpecs physicalDisplayConfigSpecs,
|
||||
SurfaceControl.DisplayInfo info, SurfaceControl.DisplayConfig[] configs,
|
||||
int activeConfigId, SurfaceControl.DesiredDisplayConfigSpecs configSpecs,
|
||||
int[] colorModes, int activeColorMode, boolean isInternal) {
|
||||
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId);
|
||||
mPhysicalDisplayId = physicalDisplayId;
|
||||
mIsInternal = isInternal;
|
||||
updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo,
|
||||
physicalDisplayConfigSpecs, colorModes, activeColorMode);
|
||||
mDisplayInfo = info;
|
||||
|
||||
updateDisplayConfigsLocked(configs, activeConfigId, configSpecs, colorModes,
|
||||
activeColorMode);
|
||||
updateColorModesLocked(colorModes, activeColorMode);
|
||||
|
||||
mSidekickInternal = LocalServices.getService(SidekickInternal.class);
|
||||
if (mIsInternal) {
|
||||
LightsManager lights = LocalServices.getService(LightsManager.class);
|
||||
@@ -226,23 +234,24 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean updatePhysicalDisplayInfoLocked(
|
||||
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
|
||||
SurfaceControl.DesiredDisplayConfigSpecs physicalDisplayConfigSpecs,
|
||||
int[] colorModes, int activeColorMode) {
|
||||
mDisplayInfos = Arrays.copyOf(physicalDisplayInfos, physicalDisplayInfos.length);
|
||||
mActivePhysIndex = activeDisplayInfo;
|
||||
public boolean updateDisplayConfigsLocked(
|
||||
SurfaceControl.DisplayConfig[] configs, int activeConfigId,
|
||||
SurfaceControl.DesiredDisplayConfigSpecs configSpecs, int[] colorModes,
|
||||
int activeColorMode) {
|
||||
mDisplayConfigs = Arrays.copyOf(configs, configs.length);
|
||||
mActiveConfigId = activeConfigId;
|
||||
|
||||
// Build an updated list of all existing modes.
|
||||
ArrayList<DisplayModeRecord> records = new ArrayList<DisplayModeRecord>();
|
||||
boolean modesAdded = false;
|
||||
for (int i = 0; i < physicalDisplayInfos.length; i++) {
|
||||
SurfaceControl.PhysicalDisplayInfo info = physicalDisplayInfos[i];
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
SurfaceControl.DisplayConfig config = configs[i];
|
||||
// First, check to see if we've already added a matching mode. Since not all
|
||||
// configuration options are exposed via Display.Mode, it's possible that we have
|
||||
// multiple PhysicalDisplayInfos that would generate the same Display.Mode.
|
||||
// multiple DisplayConfigs that would generate the same Display.Mode.
|
||||
boolean existingMode = false;
|
||||
for (int j = 0; j < records.size(); j++) {
|
||||
if (records.get(j).hasMatchingMode(info)) {
|
||||
if (records.get(j).hasMatchingMode(config)) {
|
||||
existingMode = true;
|
||||
break;
|
||||
}
|
||||
@@ -253,9 +262,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
// If we haven't already added a mode for this configuration to the new set of
|
||||
// supported modes then check to see if we have one in the prior set of supported
|
||||
// modes to reuse.
|
||||
DisplayModeRecord record = findDisplayModeRecord(info);
|
||||
DisplayModeRecord record = findDisplayModeRecord(config);
|
||||
if (record == null) {
|
||||
record = new DisplayModeRecord(info);
|
||||
record = new DisplayModeRecord(config);
|
||||
modesAdded = true;
|
||||
}
|
||||
records.add(record);
|
||||
@@ -265,7 +274,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
DisplayModeRecord activeRecord = null;
|
||||
for (int i = 0; i < records.size(); i++) {
|
||||
DisplayModeRecord record = records.get(i);
|
||||
if (record.hasMatchingMode(physicalDisplayInfos[activeDisplayInfo])){
|
||||
if (record.hasMatchingMode(configs[activeConfigId])) {
|
||||
activeRecord = record;
|
||||
break;
|
||||
}
|
||||
@@ -282,17 +291,15 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
// Check whether surface flinger spontaneously changed display config specs out from
|
||||
// under us. If so, schedule a traversal to reapply our display config specs.
|
||||
if (mDisplayModeSpecs.baseModeId != 0) {
|
||||
int activeBaseMode =
|
||||
findMatchingModeIdLocked(physicalDisplayConfigSpecs.defaultConfig);
|
||||
int activeBaseMode = findMatchingModeIdLocked(configSpecs.defaultConfig);
|
||||
// If we can't map the defaultConfig index to a mode, then the physical display
|
||||
// configs must have changed, and the code below for handling changes to the
|
||||
// list of available modes will take care of updating display config specs.
|
||||
if (activeBaseMode != 0) {
|
||||
if (mDisplayModeSpecs.baseModeId != activeBaseMode
|
||||
|| mDisplayModeSpecs.refreshRateRange.min
|
||||
!= physicalDisplayConfigSpecs.minRefreshRate
|
||||
|| mDisplayModeSpecs.refreshRateRange.min != configSpecs.minRefreshRate
|
||||
|| mDisplayModeSpecs.refreshRateRange.max
|
||||
!= physicalDisplayConfigSpecs.maxRefreshRate) {
|
||||
!= configSpecs.maxRefreshRate) {
|
||||
mDisplayModeSpecsInvalid = true;
|
||||
sendTraversalRequestLocked();
|
||||
}
|
||||
@@ -313,7 +320,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
// Update the default mode, if needed.
|
||||
if (findDisplayInfoIndexLocked(mDefaultModeId) < 0) {
|
||||
if (findDisplayConfigIdLocked(mDefaultModeId) < 0) {
|
||||
if (mDefaultModeId != 0) {
|
||||
Slog.w(TAG, "Default display mode no longer available, using currently"
|
||||
+ " active mode as default.");
|
||||
@@ -434,10 +441,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
return true;
|
||||
}
|
||||
|
||||
private DisplayModeRecord findDisplayModeRecord(SurfaceControl.PhysicalDisplayInfo info) {
|
||||
private DisplayModeRecord findDisplayModeRecord(SurfaceControl.DisplayConfig config) {
|
||||
for (int i = 0; i < mSupportedModes.size(); i++) {
|
||||
DisplayModeRecord record = mSupportedModes.valueAt(i);
|
||||
if (record.hasMatchingMode(info)) {
|
||||
if (record.hasMatchingMode(config)) {
|
||||
return record;
|
||||
}
|
||||
}
|
||||
@@ -455,10 +462,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
@Override
|
||||
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
|
||||
if (mInfo == null) {
|
||||
SurfaceControl.PhysicalDisplayInfo phys = mDisplayInfos[mActivePhysIndex];
|
||||
SurfaceControl.DisplayConfig config = mDisplayConfigs[mActiveConfigId];
|
||||
mInfo = new DisplayDeviceInfo();
|
||||
mInfo.width = phys.width;
|
||||
mInfo.height = phys.height;
|
||||
mInfo.width = config.width;
|
||||
mInfo.height = config.height;
|
||||
mInfo.modeId = mActiveModeId;
|
||||
mInfo.defaultModeId = mDefaultModeId;
|
||||
mInfo.supportedModes = getDisplayModes(mSupportedModes);
|
||||
@@ -471,20 +478,20 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
mInfo.supportedColorModes[i] = mSupportedColorModes.get(i);
|
||||
}
|
||||
mInfo.hdrCapabilities = mHdrCapabilities;
|
||||
mInfo.appVsyncOffsetNanos = phys.appVsyncOffsetNanos;
|
||||
mInfo.presentationDeadlineNanos = phys.presentationDeadlineNanos;
|
||||
mInfo.appVsyncOffsetNanos = config.appVsyncOffsetNanos;
|
||||
mInfo.presentationDeadlineNanos = config.presentationDeadlineNanos;
|
||||
mInfo.state = mState;
|
||||
mInfo.uniqueId = getUniqueId();
|
||||
final DisplayAddress.Physical physicalAddress =
|
||||
DisplayAddress.fromPhysicalDisplayId(mPhysicalDisplayId);
|
||||
mInfo.address = physicalAddress;
|
||||
mInfo.densityDpi = (int) (phys.density * 160 + 0.5f);
|
||||
mInfo.xDpi = phys.xDpi;
|
||||
mInfo.yDpi = phys.yDpi;
|
||||
mInfo.densityDpi = (int) (mDisplayInfo.density * 160 + 0.5f);
|
||||
mInfo.xDpi = config.xDpi;
|
||||
mInfo.yDpi = config.yDpi;
|
||||
|
||||
// Assume that all built-in displays that have secure output (eg. HDCP) also
|
||||
// support compositing from gralloc protected buffers.
|
||||
if (phys.secure) {
|
||||
if (mDisplayInfo.secure) {
|
||||
mInfo.flags = DisplayDeviceInfo.FLAG_SECURE
|
||||
| DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
|
||||
}
|
||||
@@ -721,8 +728,8 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
// a valid mode.
|
||||
return;
|
||||
}
|
||||
int basePhysIndex = findDisplayInfoIndexLocked(displayModeSpecs.baseModeId);
|
||||
if (basePhysIndex < 0) {
|
||||
int baseConfigId = findDisplayConfigIdLocked(displayModeSpecs.baseModeId);
|
||||
if (baseConfigId < 0) {
|
||||
// When a display is hotplugged, it's possible for a mode to be removed that was
|
||||
// previously valid. Because of the way display changes are propagated through the
|
||||
// framework, and the caching of the display mode specs in LogicalDisplay, it's
|
||||
@@ -740,7 +747,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
getHandler().sendMessage(PooledLambda.obtainMessage(
|
||||
LocalDisplayDevice::setDesiredDisplayModeSpecsAsync, this,
|
||||
getDisplayTokenLocked(),
|
||||
new SurfaceControl.DesiredDisplayConfigSpecs(basePhysIndex,
|
||||
new SurfaceControl.DesiredDisplayConfigSpecs(baseConfigId,
|
||||
mDisplayModeSpecs.refreshRateRange.min,
|
||||
mDisplayModeSpecs.refreshRateRange.max)));
|
||||
}
|
||||
@@ -764,22 +771,22 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
updateDeviceInfoLocked();
|
||||
}
|
||||
|
||||
public void onActivePhysicalDisplayModeChangedLocked(int physIndex) {
|
||||
if (updateActiveModeLocked(physIndex)) {
|
||||
public void onActiveDisplayConfigChangedLocked(int configId) {
|
||||
if (updateActiveModeLocked(configId)) {
|
||||
updateDeviceInfoLocked();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean updateActiveModeLocked(int activePhysIndex) {
|
||||
if (mActivePhysIndex == activePhysIndex) {
|
||||
public boolean updateActiveModeLocked(int activeConfigId) {
|
||||
if (mActiveConfigId == activeConfigId) {
|
||||
return false;
|
||||
}
|
||||
mActivePhysIndex = activePhysIndex;
|
||||
mActiveModeId = findMatchingModeIdLocked(activePhysIndex);
|
||||
mActiveConfigId = activeConfigId;
|
||||
mActiveModeId = findMatchingModeIdLocked(activeConfigId);
|
||||
mActiveModeInvalid = mActiveModeId == 0;
|
||||
if (mActiveModeInvalid) {
|
||||
Slog.w(TAG, "In unknown mode after setting allowed configs"
|
||||
+ ", activePhysIndex=" + mActivePhysIndex);
|
||||
+ ", activeConfigId=" + mActiveConfigId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -850,7 +857,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
pw.println("mPhysicalDisplayId=" + mPhysicalDisplayId);
|
||||
pw.println("mDisplayModeSpecs={" + mDisplayModeSpecs + "}");
|
||||
pw.println("mDisplayModeSpecsInvalid=" + mDisplayModeSpecsInvalid);
|
||||
pw.println("mActivePhysIndex=" + mActivePhysIndex);
|
||||
pw.println("mActiveConfigId=" + mActiveConfigId);
|
||||
pw.println("mActiveModeId=" + mActiveModeId);
|
||||
pw.println("mActiveColorMode=" + mActiveColorMode);
|
||||
pw.println("mDefaultModeId=" + mDefaultModeId);
|
||||
@@ -861,9 +868,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
pw.println("mAllmRequested=" + mAllmRequested);
|
||||
pw.println("mGameContentTypeSupported" + mGameContentTypeSupported);
|
||||
pw.println("mGameContentTypeRequested" + mGameContentTypeRequested);
|
||||
pw.println("mDisplayInfos=");
|
||||
for (int i = 0; i < mDisplayInfos.length; i++) {
|
||||
pw.println(" " + mDisplayInfos[i]);
|
||||
pw.println("mDisplayInfo=" + mDisplayInfo);
|
||||
pw.println("mDisplayConfigs=");
|
||||
for (int i = 0; i < mDisplayConfigs.length; i++) {
|
||||
pw.println(" " + mDisplayConfigs[i]);
|
||||
}
|
||||
pw.println("mSupportedModes=");
|
||||
for (int i = 0; i < mSupportedModes.size(); i++) {
|
||||
@@ -879,12 +887,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
pw.println("]");
|
||||
}
|
||||
|
||||
private int findDisplayInfoIndexLocked(int modeId) {
|
||||
private int findDisplayConfigIdLocked(int modeId) {
|
||||
DisplayModeRecord record = mSupportedModes.get(modeId);
|
||||
if (record != null) {
|
||||
for (int i = 0; i < mDisplayInfos.length; i++) {
|
||||
SurfaceControl.PhysicalDisplayInfo info = mDisplayInfos[i];
|
||||
if (record.hasMatchingMode(info)){
|
||||
for (int i = 0; i < mDisplayConfigs.length; i++) {
|
||||
SurfaceControl.DisplayConfig config = mDisplayConfigs[i];
|
||||
if (record.hasMatchingMode(config)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -892,11 +900,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int findMatchingModeIdLocked(int physIndex) {
|
||||
SurfaceControl.PhysicalDisplayInfo info = mDisplayInfos[physIndex];
|
||||
private int findMatchingModeIdLocked(int configId) {
|
||||
SurfaceControl.DisplayConfig config = mDisplayConfigs[configId];
|
||||
for (int i = 0; i < mSupportedModes.size(); i++) {
|
||||
DisplayModeRecord record = mSupportedModes.valueAt(i);
|
||||
if (record.hasMatchingMode(info)) {
|
||||
if (record.hasMatchingMode(config)) {
|
||||
return record.mMode.getModeId();
|
||||
}
|
||||
}
|
||||
@@ -948,23 +956,23 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
private static final class DisplayModeRecord {
|
||||
public final Display.Mode mMode;
|
||||
|
||||
public DisplayModeRecord(SurfaceControl.PhysicalDisplayInfo phys) {
|
||||
mMode = createMode(phys.width, phys.height, phys.refreshRate);
|
||||
DisplayModeRecord(SurfaceControl.DisplayConfig config) {
|
||||
mMode = createMode(config.width, config.height, config.refreshRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the mode generated by the given PhysicalDisplayInfo matches the mode
|
||||
* Returns whether the mode generated by the given DisplayConfig matches the mode
|
||||
* contained by the record modulo mode ID.
|
||||
*
|
||||
* Note that this doesn't necessarily mean the the PhysicalDisplayInfos are identical, just
|
||||
* Note that this doesn't necessarily mean that the DisplayConfigs are identical, just
|
||||
* that they generate identical modes.
|
||||
*/
|
||||
public boolean hasMatchingMode(SurfaceControl.PhysicalDisplayInfo info) {
|
||||
public boolean hasMatchingMode(SurfaceControl.DisplayConfig config) {
|
||||
int modeRefreshRate = Float.floatToIntBits(mMode.getRefreshRate());
|
||||
int displayInfoRefreshRate = Float.floatToIntBits(info.refreshRate);
|
||||
return mMode.getPhysicalWidth() == info.width
|
||||
&& mMode.getPhysicalHeight() == info.height
|
||||
&& modeRefreshRate == displayInfoRefreshRate;
|
||||
int configRefreshRate = Float.floatToIntBits(config.refreshRate);
|
||||
return mMode.getPhysicalWidth() == config.width
|
||||
&& mMode.getPhysicalHeight() == config.height
|
||||
&& modeRefreshRate == configRefreshRate;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@@ -989,12 +997,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigChanged(long timestampNanos, long physicalDisplayId, int physIndex) {
|
||||
public void onConfigChanged(long timestampNanos, long physicalDisplayId, int configId) {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "onConfigChanged("
|
||||
+ "timestampNanos=" + timestampNanos
|
||||
+ ", physicalDisplayId=" + physicalDisplayId
|
||||
+ ", physIndex=" + physIndex + ")");
|
||||
+ ", configId=" + configId + ")");
|
||||
}
|
||||
synchronized (getSyncRoot()) {
|
||||
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
|
||||
@@ -1005,7 +1013,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
return;
|
||||
}
|
||||
device.onActivePhysicalDisplayModeChangedLocked(physIndex);
|
||||
device.onActiveDisplayConfigChangedLocked(configId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,10 +109,11 @@ public class LocalDisplayAdapterTest {
|
||||
*/
|
||||
@Test
|
||||
public void testPrivateDisplay() throws Exception {
|
||||
setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_A), createDummyDisplayInfo()));
|
||||
setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_B), createDummyDisplayInfo()));
|
||||
setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_C), createDummyDisplayInfo()));
|
||||
setUpDisplay(new FakeDisplay(PORT_A));
|
||||
setUpDisplay(new FakeDisplay(PORT_B));
|
||||
setUpDisplay(new FakeDisplay(PORT_C));
|
||||
updateAvailableDisplays();
|
||||
|
||||
doReturn(new int[]{ PORT_B }).when(mMockedResources)
|
||||
.getIntArray(com.android.internal.R.array.config_localPrivateDisplayPorts);
|
||||
mAdapter.registerLocked();
|
||||
@@ -135,9 +136,10 @@ public class LocalDisplayAdapterTest {
|
||||
*/
|
||||
@Test
|
||||
public void testPublicDisplaysForNoConfigLocalPrivateDisplayPorts() throws Exception {
|
||||
setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_A), createDummyDisplayInfo()));
|
||||
setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_C), createDummyDisplayInfo()));
|
||||
setUpDisplay(new FakeDisplay(PORT_A));
|
||||
setUpDisplay(new FakeDisplay(PORT_C));
|
||||
updateAvailableDisplays();
|
||||
|
||||
// config_localPrivateDisplayPorts is null
|
||||
mAdapter.registerLocked();
|
||||
|
||||
@@ -165,9 +167,8 @@ public class LocalDisplayAdapterTest {
|
||||
*/
|
||||
@Test
|
||||
public void testDpiValues() throws Exception {
|
||||
// needs default one always
|
||||
setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_A), createDummyDisplayInfo()));
|
||||
setUpDisplay(new DisplayConfig(createDisplayAddress(PORT_B), createDummyDisplayInfo()));
|
||||
setUpDisplay(new FakeDisplay(PORT_A));
|
||||
setUpDisplay(new FakeDisplay(PORT_B));
|
||||
updateAvailableDisplays();
|
||||
mAdapter.registerLocked();
|
||||
|
||||
@@ -193,32 +194,32 @@ public class LocalDisplayAdapterTest {
|
||||
assertEquals(expectedDensityDpi, info.densityDpi);
|
||||
}
|
||||
|
||||
private class DisplayConfig {
|
||||
private static class FakeDisplay {
|
||||
public final DisplayAddress.Physical address;
|
||||
public final IBinder displayToken = new Binder();
|
||||
public final SurfaceControl.PhysicalDisplayInfo displayInfo;
|
||||
public final IBinder token = new Binder();
|
||||
public final SurfaceControl.DisplayInfo info;
|
||||
public final SurfaceControl.DisplayConfig config;
|
||||
|
||||
private DisplayConfig(
|
||||
DisplayAddress.Physical address, SurfaceControl.PhysicalDisplayInfo displayInfo) {
|
||||
this.address = address;
|
||||
this.displayInfo = displayInfo;
|
||||
private FakeDisplay(int port) {
|
||||
this.address = createDisplayAddress(port);
|
||||
this.info = createFakeDisplayInfo();
|
||||
this.config = createFakeDisplayConfig();
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpDisplay(DisplayConfig config) {
|
||||
mAddresses.add(config.address);
|
||||
doReturn(config.displayToken).when(() ->
|
||||
SurfaceControl.getPhysicalDisplayToken(config.address.getPhysicalDisplayId()));
|
||||
doReturn(new SurfaceControl.PhysicalDisplayInfo[]{
|
||||
config.displayInfo
|
||||
}).when(() -> SurfaceControl.getDisplayConfigs(config.displayToken));
|
||||
doReturn(0).when(() -> SurfaceControl.getActiveConfig(config.displayToken));
|
||||
doReturn(0).when(() -> SurfaceControl.getActiveColorMode(config.displayToken));
|
||||
doReturn(new int[]{
|
||||
0
|
||||
}).when(() -> SurfaceControl.getDisplayColorModes(config.displayToken));
|
||||
private void setUpDisplay(FakeDisplay display) {
|
||||
mAddresses.add(display.address);
|
||||
doReturn(display.token).when(() ->
|
||||
SurfaceControl.getPhysicalDisplayToken(display.address.getPhysicalDisplayId()));
|
||||
doReturn(display.info).when(() -> SurfaceControl.getDisplayInfo(display.token));
|
||||
doReturn(new SurfaceControl.DisplayConfig[] { display.config }).when(
|
||||
() -> SurfaceControl.getDisplayConfigs(display.token));
|
||||
doReturn(0).when(() -> SurfaceControl.getActiveConfig(display.token));
|
||||
doReturn(0).when(() -> SurfaceControl.getActiveColorMode(display.token));
|
||||
doReturn(new int[] { 0 }).when(
|
||||
() -> SurfaceControl.getDisplayColorModes(display.token));
|
||||
doReturn(new SurfaceControl.DesiredDisplayConfigSpecs(0, 60.f, 60.f))
|
||||
.when(() -> SurfaceControl.getDesiredDisplayConfigSpecs(config.displayToken));
|
||||
.when(() -> SurfaceControl.getDesiredDisplayConfigSpecs(display.token));
|
||||
}
|
||||
|
||||
private void updateAvailableDisplays() {
|
||||
@@ -235,18 +236,21 @@ public class LocalDisplayAdapterTest {
|
||||
return DisplayAddress.fromPortAndModel((byte) port, DISPLAY_MODEL);
|
||||
}
|
||||
|
||||
private static SurfaceControl.PhysicalDisplayInfo createDummyDisplayInfo() {
|
||||
SurfaceControl.PhysicalDisplayInfo info = new SurfaceControl.PhysicalDisplayInfo();
|
||||
private static SurfaceControl.DisplayInfo createFakeDisplayInfo() {
|
||||
final SurfaceControl.DisplayInfo info = new SurfaceControl.DisplayInfo();
|
||||
info.density = 100;
|
||||
info.xDpi = 100;
|
||||
info.yDpi = 100;
|
||||
info.secure = false;
|
||||
info.width = 800;
|
||||
info.height = 600;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private static SurfaceControl.DisplayConfig createFakeDisplayConfig() {
|
||||
final SurfaceControl.DisplayConfig config = new SurfaceControl.DisplayConfig();
|
||||
config.width = 800;
|
||||
config.height = 600;
|
||||
config.xDpi = 100;
|
||||
config.yDpi = 100;
|
||||
return config;
|
||||
}
|
||||
|
||||
private void waitForHandlerToComplete(Handler handler, long waitTimeMs)
|
||||
throws InterruptedException {
|
||||
final Object lock = new Object();
|
||||
|
||||
Reference in New Issue
Block a user