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

Commit 4ee1e867 authored by Rachel Lee's avatar Rachel Lee
Browse files

Add setFrameRateCategory SurfaceControl java API

This new API allows users to set a "frame rate category" to the surface
control to specify a range of desired frame rates. This may affect the
display refresh rate choice.

The new test CtsSurfaceControlTestsStaging is similar to
SetFrameRateTest CTS, while the API is not public.

Bug: 284911776
Test: atest CtsSurfaceControlTestsStaging
Change-Id: Ib8d5e7f16750aaf12eb202a325c26a7c640d393b
parent ed36a343
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
@@ -261,6 +261,50 @@ public class Surface implements Parcelable {
     */
    public static final int CHANGE_FRAME_RATE_ALWAYS = 1;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"FRAME_RATE_CATEGORY_"},
            value = {FRAME_RATE_CATEGORY_DEFAULT, FRAME_RATE_CATEGORY_NO_PREFERENCE,
                    FRAME_RATE_CATEGORY_LOW, FRAME_RATE_CATEGORY_NORMAL, FRAME_RATE_CATEGORY_HIGH})
    public @interface FrameRateCategory {}

    // From native_window.h or window.h. Keep these in sync.
    /**
     * Default value. This value can also be set to return to default behavior, indicating that this
     * layer has no data for the frame rate.
     * @hide
     */
    public static final int FRAME_RATE_CATEGORY_DEFAULT = 0;

    /**
     * The layer will explicitly not influence the frame rate.
     * This may indicate a frame rate suitable for no animation updates (such as a cursor blinking
     * or a sporadic update).
     * @hide
     */
    public static final int FRAME_RATE_CATEGORY_NO_PREFERENCE = 1;

    /**
     * Indicates a frame rate suitable for animations that looks fine even if played at a low frame
     * rate.
     * @hide
     */
    public static final int FRAME_RATE_CATEGORY_LOW = 2;

    /**
     * Indicates a middle frame rate suitable for animations that do not require higher frame
     * rates, or do not benefit from high smoothness. This is normally 60 Hz or close to it.
     * @hide
     */
    public static final int FRAME_RATE_CATEGORY_NORMAL = 3;

    /**
     * Indicates a frame rate suitable for animations that require a high frame rate, which may
     * increase smoothness but may also increase power usage.
     * @hide
     */
    public static final int FRAME_RATE_CATEGORY_HIGH = 4;

    /**
     * Create an empty surface, which will later be filled in by readFromParcel().
     * @hide
+41 −0
Original line number Diff line number Diff line
@@ -261,6 +261,8 @@ public final class SurfaceControl implements Parcelable {
            float frameRate, int compatibility, int changeFrameRateStrategy);
    private static native void nativeSetDefaultFrameRateCompatibility(long transactionObj,
            long nativeObject, int compatibility);
    private static native void nativeSetFrameRateCategory(
            long transactionObj, long nativeObject, int category);
    private static native long nativeGetHandle(long nativeObject);

    private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject,
@@ -3627,6 +3629,45 @@ public final class SurfaceControl implements Parcelable {
            return this;
        }

        /**
         * Sets the frame rate category for the {@link SurfaceControl}.
         *
         * This helps instruct the system on choosing a display refresh rate based on the surface's
         * chosen category, which is a device-specific range of frame rates.
         * {@link #setFrameRateCategory} should be used by components such as animations that do not
         * require an exact frame rate, but has an opinion on an approximate desirable frame rate.
         * The values of {@code category} gives example use cases for which category to choose.
         *
         * To instead specify an exact frame rate, use
         * {@link #setFrameRate(SurfaceControl, float, int, int)}, which is more suitable for
         * content that knows specifically which frame rate is optimal.
         * Although not a common use case, {@link #setFrameRateCategory} and {@link #setFrameRate}
         * can be called together, with both calls potentially influencing the display refresh rate.
         * For example, considering only one {@link SurfaceControl}: if {@link #setFrameRate}'s
         * value is 24 and {@link #setFrameRateCategory}'s value is
         * {@link Surface#FRAME_RATE_CATEGORY_HIGH}, defined to be the range [90,120] fps for an
         * example device, then the best refresh rate for the SurfaceControl should be 120 fps.
         * This is because 120 fps is a multiple of 24 fps, and 120 fps is in the specified
         * category's range.
         *
         * @param sc The SurfaceControl to specify the frame rate category of.
         * @param category The frame rate category of this surface. The category value may influence
         * the system's choice of display frame rate.
         *
         * @return This transaction object.
         *
         * @see #setFrameRate(SurfaceControl, float, int, int)
         *
         * @hide
         */
        @NonNull
        public Transaction setFrameRateCategory(
                @NonNull SurfaceControl sc, @Surface.FrameRateCategory int category) {
            checkPreconditions(sc);
            nativeSetFrameRateCategory(mNativeObject, sc.mNativeObject, category);
            return this;
        }

        /**
         * Sets focus on the window identified by the input {@code token} if the window is focusable
         * otherwise the request is dropped.
+9 −0
Original line number Diff line number Diff line
@@ -960,6 +960,13 @@ static void nativeSetDefaultFrameRateCompatibility(JNIEnv* env, jclass clazz, jl
    transaction->setDefaultFrameRateCompatibility(ctrl, static_cast<int8_t>(compatibility));
}

static void nativeSetFrameRateCategory(JNIEnv* env, jclass clazz, jlong transactionObj,
                                       jlong nativeObject, jint category) {
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
    const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
    transaction->setFrameRateCategory(ctrl, static_cast<int8_t>(category));
}

static void nativeSetFixedTransformHint(JNIEnv* env, jclass clazz, jlong transactionObj,
                                        jlong nativeObject, jint transformHint) {
    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
@@ -2164,6 +2171,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeSetFrameRate },
    {"nativeSetDefaultFrameRateCompatibility", "(JJI)V",
            (void*)nativeSetDefaultFrameRateCompatibility},
    {"nativeSetFrameRateCategory", "(JJI)V",
            (void*)nativeSetFrameRateCategory},
    {"nativeSetDisplaySurface", "(JLandroid/os/IBinder;J)V",
            (void*)nativeSetDisplaySurface },
    {"nativeSetDisplayLayerStack", "(JLandroid/os/IBinder;I)V",
+48 −0
Original line number Diff line number Diff line
// Copyright 2023 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package {
    // See: http://go/android-license-faq
    // A large-scale-change added 'default_applicable_licenses' to import
    // all of the 'license_kinds' from "frameworks_base_license"
    // to get the below license kinds:
    //   SPDX-license-identifier-Apache-2.0
    default_applicable_licenses: ["frameworks_base_license"],
}

android_test {
    // SurfaceControl tests for APIs that are not public. If an API becomes public, they should
    // live in CtsSurfaceControlTests instead.
    name: "CtsSurfaceControlTestsStaging",
    srcs: ["src/**/*.java"],
    libs: [
        "android.test.runner",
        "android.test.base",
    ],
    static_libs: [
        "androidx.test.core",
        "androidx.test.ext.junit",
        "androidx.test.rules",
        "compatibility-device-util-axt",
        "com.google.android.material_material",
        "truth-prebuilt",
    ],
    resource_dirs: ["src/main/res"],
    certificate: "platform",
    platform_apis: true,
    test_suites: ["device-tests"],
    optimize: {
        enabled: false,
    },
}
+33 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright 2023 The Android Open Source Project
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.view.surfacecontroltests">

    <application android:debuggable="true" android:testOnly="true">
        <uses-library android:name="android.test.runner"/>
        <activity
            android:name=".GraphicsActivity"
            android:exported="false">
        </activity>
    </application>

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
        android:targetPackage="android.view.surfacecontroltests"
        android:label="Tests of android.view.surfacecontroltests">
    </instrumentation>
</manifest>
 No newline at end of file
Loading