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

Commit 0a588706 authored by Steven Thomas's avatar Steven Thomas Committed by Android (Google) Code Review
Browse files

Merge "Add compatibility param to setFrameRate() api"

parents 453f2c3e 62a4cf8c
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -425,12 +425,15 @@ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transactio
 * 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
 * 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.
 */
void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* transaction,
                                      ASurfaceControl* surface_control,
                                      float frameRate)
                                      __INTRODUCED_IN(30);
                                      ASurfaceControl* surface_control, float frameRate,
                                      int8_t compatibility) __INTRODUCED_IN(30);

#endif // __ANDROID_API__ >= 30

+66 −0
Original line number Diff line number Diff line
@@ -1112,6 +1112,42 @@ public:
        }
        return NO_ERROR;
    }

    virtual status_t setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate,
                                  int8_t compatibility) {
        Parcel data, reply;
        status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
        if (err != NO_ERROR) {
            ALOGE("setFrameRate: failed writing interface token: %s (%d)", strerror(-err), -err);
            return err;
        }

        err = data.writeStrongBinder(IInterface::asBinder(surface));
        if (err != NO_ERROR) {
            ALOGE("setFrameRate: failed writing strong binder: %s (%d)", strerror(-err), -err);
            return err;
        }

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

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

        err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply,
                                 IBinder::FLAG_ONEWAY);
        if (err != NO_ERROR) {
            ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err);
            return err;
        }
        return NO_ERROR;
    }
};

// Out-of-line virtual method definition to trigger vtable emission in this
@@ -1877,6 +1913,36 @@ status_t BnSurfaceComposer::onTransact(
            return setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ,
                                           lightRadius);
        }
        case SET_FRAME_RATE: {
            CHECK_INTERFACE(ISurfaceComposer, data, reply);
            sp<IBinder> binder;
            status_t err = data.readStrongBinder(&binder);
            if (err != NO_ERROR) {
                ALOGE("setFrameRate: failed to read strong binder: %s (%d)", strerror(-err), -err);
                return err;
            }
            sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(binder);
            if (!surface) {
                ALOGE("setFrameRate: failed to cast to IGraphicBufferProducer: %s (%d)",
                      strerror(-err), -err);
                return err;
            }
            float frameRate;
            err = data.readFloat(&frameRate);
            if (err != NO_ERROR) {
                ALOGE("setFrameRate: failed to read float: %s (%d)", strerror(-err), -err);
                return err;
            }
            int8_t compatibility;
            err = data.readByte(&compatibility);
            if (err != NO_ERROR) {
                ALOGE("setFrameRate: failed to read byte: %s (%d)", strerror(-err), -err);
                return err;
            }
            status_t result = setFrameRate(surface, frameRate, compatibility);
            reply->writeInt32(result);
            return NO_ERROR;
        }
        default: {
            return BBinder::onTransact(code, data, reply, flags);
        }
+22 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
#include <gui/IGraphicBufferProducer.h>
#include <gui/LayerState.h>

#include <cmath>

namespace android {

status_t layer_state_t::write(Parcel& output) const
@@ -113,6 +115,7 @@ status_t layer_state_t::write(Parcel& output) const
    output.writeFloat(shadowRadius);
    output.writeInt32(frameRateSelectionPriority);
    output.writeFloat(frameRate);
    output.writeByte(frameRateCompatibility);
    return NO_ERROR;
}

@@ -194,6 +197,7 @@ status_t layer_state_t::read(const Parcel& input)
    shadowRadius = input.readFloat();
    frameRateSelectionPriority = input.readInt32();
    frameRate = input.readFloat();
    frameRateCompatibility = input.readByte();
    return NO_ERROR;
}

@@ -427,6 +431,7 @@ void layer_state_t::merge(const layer_state_t& other) {
    if (other.what & eFrameRateChanged) {
        what |= eFrameRateChanged;
        frameRate = other.frameRate;
        frameRateCompatibility = other.frameRateCompatibility;
    }
    if ((other.what & what) != other.what) {
        ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
@@ -474,4 +479,21 @@ void InputWindowCommands::read(const Parcel& input) {
    syncInputWindows = input.readBool();
}

bool ValidateFrameRate(float frameRate, int8_t compatibility, const char* inFunctionName) {
    const char* functionName = inFunctionName != nullptr ? inFunctionName : "call";
    int floatClassification = std::fpclassify(frameRate);
    if (frameRate < 0 || floatClassification == FP_INFINITE || floatClassification == FP_NAN) {
        ALOGE("%s failed - invalid frame rate %f", functionName, frameRate);
        return false;
    }

    if (compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT &&
        compatibility != ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE) {
        ALOGE("%s failed - invalid compatibility value %d", functionName, compatibility);
        return false;
    }

    return true;
}

}; // namespace android
+11 −5
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@
#include <gui/IProducerListener.h>

#include <gui/ISurfaceComposer.h>
#include <gui/LayerState.h>
#include <private/gui/ComposerService.h>

namespace android {
@@ -1413,7 +1414,8 @@ int Surface::dispatchGetLastQueueDuration(va_list args) {

int Surface::dispatchSetFrameRate(va_list args) {
    float frameRate = static_cast<float>(va_arg(args, double));
    return setFrameRate(frameRate);
    int8_t compatibility = static_cast<int8_t>(va_arg(args, int));
    return setFrameRate(frameRate, compatibility);
}

int Surface::dispatchAddCancelInterceptor(va_list args) {
@@ -2222,11 +2224,15 @@ void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_
    mSurfaceListener->onBuffersDiscarded(discardedBufs);
}

status_t Surface::setFrameRate(float frameRate) {
status_t Surface::setFrameRate(float frameRate, int8_t compatibility) {
    ATRACE_CALL();
    ALOGV("Surface::setTargetFrameRate");
    Mutex::Autolock lock(mMutex);
    return mGraphicBufferProducer->setFrameRate(frameRate);
    ALOGV("Surface::setFrameRate");

    if (!ValidateFrameRate(frameRate, compatibility, "Surface::setFrameRate")) {
        return BAD_VALUE;
    }

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

}; // namespace android
+6 −1
Original line number Diff line number Diff line
@@ -1387,14 +1387,19 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setShado
}

SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameRate(
        const sp<SurfaceControl>& sc, float frameRate) {
        const sp<SurfaceControl>& sc, float frameRate, int8_t compatibility) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    if (!ValidateFrameRate(frameRate, compatibility, "Transaction::setFrameRate")) {
        mStatus = BAD_VALUE;
        return *this;
    }
    s->what |= layer_state_t::eFrameRateChanged;
    s->frameRate = frameRate;
    s->frameRateCompatibility = compatibility;
    return *this;
}

Loading