Loading include/android/surface_control.h +6 −3 Original line number Diff line number Diff line Loading @@ -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 Loading libs/gui/ISurfaceComposer.cpp +66 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); } Loading libs/gui/LayerState.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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? " Loading Loading @@ -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 libs/gui/Surface.cpp +11 −5 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <gui/IProducerListener.h> #include <gui/ISurfaceComposer.h> #include <gui/LayerState.h> #include <private/gui/ComposerService.h> namespace android { Loading Loading @@ -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) { Loading Loading @@ -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 libs/gui/SurfaceComposerClient.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
include/android/surface_control.h +6 −3 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/gui/ISurfaceComposer.cpp +66 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); } Loading
libs/gui/LayerState.cpp +22 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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? " Loading Loading @@ -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
libs/gui/Surface.cpp +11 −5 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ #include <gui/IProducerListener.h> #include <gui/ISurfaceComposer.h> #include <gui/LayerState.h> #include <private/gui/ComposerService.h> namespace android { Loading Loading @@ -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) { Loading Loading @@ -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
libs/gui/SurfaceComposerClient.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -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