Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e135fe8 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Adapt SurfaceControl to libgui API for display info"

parents d1395ead 69b281d5
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -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;

+38 −123
Original line number Diff line number Diff line
@@ -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,158 +1279,72 @@ 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.
     * @hide
     */
    public static final class PhysicalDisplayInfo {
        /**
         * @hide
         */
        @UnsupportedAppUsage
        public int width;

        /**
         * @hide
         */
        @UnsupportedAppUsage
        public int height;

        /**
         * @hide
         */
        @UnsupportedAppUsage
        public float refreshRate;

    /**
     * Immutable information about physical display.
     *
     * @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() {
        @Override
        public String toString() {
            return "DisplayInfo{density=" + density + ", secure=" + secure + "}";
        }

        /**
         * @hide
         */
        public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
            copyFrom(other);
    }

    /**
     * Configuration supported by physical display.
     *
     * @hide
     */
        @Override
        public boolean equals(Object o) {
            return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
        }
    public static final class DisplayConfig {
        public int width;
        public int height;
        public float xDpi;
        public float yDpi;

        /**
         * @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;
        }
        public float refreshRate;
        public long appVsyncOffsetNanos;
        public long presentationDeadlineNanos;

        /**
         * @hide
         */
        @Override
        public int hashCode() {
            return 0; // don't care
        public String toString() {
            return "DisplayConfig{width=" + width
                    + ", height=" + height
                    + ", xDpi=" + xDpi
                    + ", yDpi=" + yDpi
                    + ", refreshRate=" + refreshRate
                    + ", appVsyncOffsetNanos=" + appVsyncOffsetNanos
                    + ", presentationDeadlineNanos=" + presentationDeadlineNanos + "}";
        }

        /**
         * @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 + "}";
    public static void setDisplayPowerMode(IBinder displayToken, int mode) {
        if (displayToken == null) {
            throw new IllegalArgumentException("displayToken must not be null");
        }
        nativeSetDisplayPowerMode(displayToken, mode);
    }

    /**
     * @hide
     */
    public static void setDisplayPowerMode(IBinder displayToken, int mode) {
    public static SurfaceControl.DisplayInfo getDisplayInfo(IBinder displayToken) {
        if (displayToken == null) {
            throw new IllegalArgumentException("displayToken must not be null");
        }
        nativeSetDisplayPowerMode(displayToken, mode);
        return nativeGetDisplayInfo(displayToken);
    }

    /**
     * @hide
     */
    @UnsupportedAppUsage
    public static SurfaceControl.PhysicalDisplayInfo[] getDisplayConfigs(IBinder displayToken) {
    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
     */
+71 −50
Original line number Diff line number Diff line
@@ -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;
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;
    }

    Vector<DisplayInfo> configs;
    if (SurfaceComposerClient::getDisplayConfigs(token, &configs) != NO_ERROR ||
            configs.size() == 0) {
        return 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(),
            gPhysicalDisplayInfoClassInfo.clazz, NULL);
    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");
+42 −32
Original line number Diff line number Diff line
@@ -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);
}

+8 −3
Original line number Diff line number Diff line
@@ -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:
Loading