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

Commit 4608442d authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

Add shouldBeSeamless to setFrameRate

This CL adds a new parameter shouldBeSeamless to the existing
setFrameRate APIs. This parameter indicates whether the desired
refresh rate should be achieved only seamlessly or also switches
with visual interruptions for the user are allowed. The default
value of the new parameter is "true".

Test: atest RefreshRateConfigsTest
Test: atest SetFrameRateTest
Test: atest libsurfaceflinger_unittest
Test: atest libgui_test

Bug: 161776961
Change-Id: I0df16e09f77c8c198fd3733fb581a2aaadfed685
parent 6bb6836c
Loading
Loading
Loading
Loading
+30 −8
Original line number Diff line number Diff line
@@ -410,7 +410,23 @@ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transactio
#if __ANDROID_API__ >= 30

/**
 * Sets the intended frame rate for |surface_control|.
 * Same as ASurfaceTransaction_setFrameRateWithSeamlessness(transaction, surface_control,
 * frameRate, compatibility, true).
 *
 * See ASurfaceTransaction_setFrameRateWithSeamlessness().
 *
 * Available since API level 30.
 */
void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* transaction,
                                      ASurfaceControl* surface_control, float frameRate,
                                      int8_t compatibility) __INTRODUCED_IN(30);

#endif // __ANDROID_API__ >= 30

#if __ANDROID_API__ >= 31

/**
 * Sets the intended frame rate for \a surface_control.
 *
 * On devices that are capable of running the display at different refresh rates, the system may
 * choose a display refresh rate to better match this surface's frame rate. Usage of this API won't
@@ -419,24 +435,30 @@ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transactio
 * callback timings, and changes to the time interval at which the system releases buffers back to
 * the application.
 *
 * |frameRate| is the intended frame rate of this surface, in frames per second. 0 is a special
 * \param frameRate is the intended frame rate of this surface, in frames per second. 0 is a special
 * value that indicates the app will accept the system's choice for the display frame rate, which is
 * the default behavior if this function isn't called. The frameRate param does <em>not</em> need to
 * be a valid refresh rate for this device's display - e.g., it's fine to pass 30fps to a device
 * that can only run the display at 60fps.
 *
 * |compatibility| The frame rate compatibility of this surface. The compatibility value may
 * \param compatibility The frame rate compatibility of this surface. The compatibility value may
 * influence the system's choice of display frame rate. To specify a compatibility use the
 * ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* enum.
 *
 * Available since API level 30.
 * \param shouldBeSeamless Whether display refresh rate transitions should be seamless. A
 * seamless transition is one that doesn't have any visual interruptions, such as a black
 * screen for a second or two. True indicates that any frame rate changes caused by this
 * request should be seamless. False indicates that non-seamless refresh rates are also
 * acceptable.
 *
 * Available since API level 31.
 */
void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* transaction,
void ASurfaceTransaction_setFrameRateWithSeamlessness(ASurfaceTransaction* transaction,
                                      ASurfaceControl* surface_control, float frameRate,
                                      int8_t compatibility) __INTRODUCED_IN(30);

#endif // __ANDROID_API__ >= 30
                                      int8_t compatibility, bool shouldBeSeamless)
                                      __INTRODUCED_IN(31);

#endif // __ANDROID_API__ >= 31
__END_DECLS

#endif // ANDROID_SURFACE_CONTROL_H
+5 −5
Original line number Diff line number Diff line
@@ -378,11 +378,11 @@ public:
        }).detach();
    }

    status_t setFrameRate(float frameRate, int8_t compatibility) override {
    status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless) override {
        if (!ValidateFrameRate(frameRate, compatibility, "BBQSurface::setFrameRate")) {
            return BAD_VALUE;
        }
        return mBbq->setFrameRate(frameRate, compatibility);
        return mBbq->setFrameRate(frameRate, compatibility, shouldBeSeamless);
    }

    status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId) override {
@@ -392,12 +392,12 @@ public:

// TODO: Can we coalesce this with frame updates? Need to confirm
// no timing issues.
status_t BLASTBufferQueue::setFrameRate(float frameRate, int8_t compatibility) {
status_t BLASTBufferQueue::setFrameRate(float frameRate, int8_t compatibility,
                                        bool shouldBeSeamless) {
    std::unique_lock _lock{mMutex};
    SurfaceComposerClient::Transaction t;

    return t.setFrameRate(mSurfaceControl, frameRate, compatibility)
        .apply();
    return t.setFrameRate(mSurfaceControl, frameRate, compatibility, shouldBeSeamless).apply();
}

status_t BLASTBufferQueue::setFrameTimelineVsync(int64_t frameTimelineVsyncId) {
+14 −2
Original line number Diff line number Diff line
@@ -1114,7 +1114,7 @@ public:
    }

    virtual status_t setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate,
                                  int8_t compatibility) {
                                  int8_t compatibility, bool shouldBeSeamless) {
        Parcel data, reply;
        status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        if (err != NO_ERROR) {
@@ -1140,6 +1140,12 @@ public:
            return err;
        }

        err = data.writeBool(shouldBeSeamless);
        if (err != NO_ERROR) {
            ALOGE("setFrameRate: failed writing bool: %s (%d)", strerror(-err), -err);
            return err;
        }

        err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply);
        if (err != NO_ERROR) {
            ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err);
@@ -2033,7 +2039,13 @@ status_t BnSurfaceComposer::onTransact(
                ALOGE("setFrameRate: failed to read byte: %s (%d)", strerror(-err), -err);
                return err;
            }
            status_t result = setFrameRate(surface, frameRate, compatibility);
            bool shouldBeSeamless;
            err = data.readBool(&shouldBeSeamless);
            if (err != NO_ERROR) {
                ALOGE("setFrameRate: failed to read bool: %s (%d)", strerror(-err), -err);
                return err;
            }
            status_t result = setFrameRate(surface, frameRate, compatibility, shouldBeSeamless);
            reply->writeInt32(result);
            return NO_ERROR;
        }
+4 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ layer_state_t::layer_state_t()
        frameRateSelectionPriority(-1),
        frameRate(0.0f),
        frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
        shouldBeSeamless(true),
        fixedTransformHint(ui::Transform::ROT_INVALID),
        frameNumber(0) {
    matrix.dsdx = matrix.dtdy = 1.0f;
@@ -144,6 +145,7 @@ status_t layer_state_t::write(Parcel& output) const
    SAFE_PARCEL(output.writeInt32, frameRateSelectionPriority);
    SAFE_PARCEL(output.writeFloat, frameRate);
    SAFE_PARCEL(output.writeByte, frameRateCompatibility);
    SAFE_PARCEL(output.writeBool, shouldBeSeamless);
    SAFE_PARCEL(output.writeUint32, fixedTransformHint);
    SAFE_PARCEL(output.writeUint64, frameNumber);
    SAFE_PARCEL(output.writeInt64, frameTimelineVsyncId);
@@ -262,6 +264,7 @@ status_t layer_state_t::read(const Parcel& input)
    SAFE_PARCEL(input.readInt32, &frameRateSelectionPriority);
    SAFE_PARCEL(input.readFloat, &frameRate);
    SAFE_PARCEL(input.readByte, &frameRateCompatibility);
    SAFE_PARCEL(input.readBool, &shouldBeSeamless);
    SAFE_PARCEL(input.readUint32, &tmpUint32);
    fixedTransformHint = static_cast<ui::Transform::RotationFlags>(tmpUint32);
    SAFE_PARCEL(input.readUint64, &frameNumber);
@@ -521,6 +524,7 @@ void layer_state_t::merge(const layer_state_t& other) {
        what |= eFrameRateChanged;
        frameRate = other.frameRate;
        frameRateCompatibility = other.frameRateCompatibility;
        shouldBeSeamless = other.shouldBeSeamless;
    }
    if (other.what & eFixedTransformHintChanged) {
        what |= eFixedTransformHintChanged;
+5 −3
Original line number Diff line number Diff line
@@ -1443,7 +1443,8 @@ int Surface::dispatchGetLastQueueDuration(va_list args) {
int Surface::dispatchSetFrameRate(va_list args) {
    float frameRate = static_cast<float>(va_arg(args, double));
    int8_t compatibility = static_cast<int8_t>(va_arg(args, int));
    return setFrameRate(frameRate, compatibility);
    bool shouldBeSeamless = static_cast<bool>(va_arg(args, int));
    return setFrameRate(frameRate, compatibility, shouldBeSeamless);
}

int Surface::dispatchAddCancelInterceptor(va_list args) {
@@ -2279,7 +2280,7 @@ void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_
    mSurfaceListener->onBuffersDiscarded(discardedBufs);
}

status_t Surface::setFrameRate(float frameRate, int8_t compatibility) {
status_t Surface::setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless) {
    ATRACE_CALL();
    ALOGV("Surface::setFrameRate");

@@ -2287,7 +2288,8 @@ status_t Surface::setFrameRate(float frameRate, int8_t compatibility) {
        return BAD_VALUE;
    }

    return composerService()->setFrameRate(mGraphicBufferProducer, frameRate, compatibility);
    return composerService()->setFrameRate(mGraphicBufferProducer, frameRate, compatibility,
                                           shouldBeSeamless);
}

status_t Surface::setFrameTimelineVsync(int64_t frameTimelineVsyncId) {
Loading