diff options
Diffstat (limited to 'libs')
21 files changed, 179 insertions, 6 deletions
diff --git a/libs/gui/BufferHubConsumer.cpp b/libs/gui/BufferHubConsumer.cpp index b5cdeb280a..0ddb87e0be 100644 --- a/libs/gui/BufferHubConsumer.cpp +++ b/libs/gui/BufferHubConsumer.cpp @@ -147,6 +147,16 @@ status_t BufferHubConsumer::discardFreeBuffers() { return INVALID_OPERATION; } +status_t BufferHubConsumer::setFrameRate(float /*frameRate*/) { + ALOGE("BufferHubConsumer::setFrameRate: not implemented."); + return INVALID_OPERATION; +} + +status_t BufferHubConsumer::getFrameRate(float* /*frameRate*/) const { + ALOGE("BufferHubConsumer::getFrameRate: not implemented."); + return INVALID_OPERATION; +} + status_t BufferHubConsumer::dumpState(const String8& /*prefix*/, String8* /*outResult*/) const { ALOGE("BufferHubConsumer::dumpState: not implemented."); return INVALID_OPERATION; diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index 6418e8c9a9..9b74fef752 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -775,6 +775,18 @@ status_t BufferQueueConsumer::discardFreeBuffers() { return NO_ERROR; } +status_t BufferQueueConsumer::setFrameRate(float frameRate) { + std::lock_guard<std::mutex> lock(mCore->mMutex); + mCore->mFrameRate = frameRate; + return NO_ERROR; +} + +status_t BufferQueueConsumer::getFrameRate(float* frameRate) const { + std::lock_guard<std::mutex> lock(mCore->mMutex); + *frameRate = mCore->mFrameRate; + return NO_ERROR; +} + status_t BufferQueueConsumer::dumpState(const String8& prefix, String8* outResult) const { struct passwd* pwd = getpwnam("shell"); uid_t shellUid = pwd ? pwd->pw_uid : 0; diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp index e6df7572de..6b11a54e2b 100644 --- a/libs/gui/BufferQueueProducer.cpp +++ b/libs/gui/BufferQueueProducer.cpp @@ -1670,4 +1670,14 @@ status_t BufferQueueProducer::setAutoPrerotation(bool autoPrerotation) { return NO_ERROR; } +status_t BufferQueueProducer::setFrameRate(float frameRate) { + ATRACE_CALL(); + BQ_LOGV("setFrameRate: %.0f", frameRate); + + std::lock_guard<std::mutex> lock(mCore->mMutex); + + mCore->mFrameRate = frameRate; + return NO_ERROR; +} + } // namespace android diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp index 9f91d9d3aa..515f45c546 100644 --- a/libs/gui/ConsumerBase.cpp +++ b/libs/gui/ConsumerBase.cpp @@ -363,6 +363,24 @@ status_t ConsumerBase::discardFreeBuffers() { return OK; } +status_t ConsumerBase::setFrameRate(float frameRate) { + Mutex::Autolock _l(mMutex); + if (mAbandoned) { + CB_LOGE("setFrameRate: ConsumerBase is abandoned!"); + return NO_INIT; + } + return mConsumer->setFrameRate(frameRate); +} + +status_t ConsumerBase::getFrameRate(float* frameRate) { + Mutex::Autolock _l(mMutex); + if (mAbandoned) { + CB_LOGE("getFrameRate: ConsumerBase is abandoned!"); + return NO_INIT; + } + return mConsumer->getFrameRate(frameRate); +} + void ConsumerBase::dumpState(String8& result) const { dumpState(result, ""); } diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp index c705d3926d..2521a7cbd7 100644 --- a/libs/gui/IGraphicBufferConsumer.cpp +++ b/libs/gui/IGraphicBufferConsumer.cpp @@ -51,6 +51,8 @@ enum class Tag : uint32_t { GET_SIDEBAND_STREAM, GET_OCCUPANCY_HISTORY, DISCARD_FREE_BUFFERS, + SET_FRAME_RATE, + GET_FRAME_RATE, DUMP_STATE, LAST = DUMP_STATE, }; @@ -163,6 +165,16 @@ public: Tag::DISCARD_FREE_BUFFERS); } + status_t setFrameRate(float frameRate) override { + using Signature = decltype(&IGraphicBufferConsumer::setFrameRate); + return callRemote<Signature>(Tag::SET_FRAME_RATE, frameRate); + } + + status_t getFrameRate(float* frameRate) const override { + using Signature = decltype(&IGraphicBufferConsumer::getFrameRate); + return callRemote<Signature>(Tag::GET_FRAME_RATE, frameRate); + } + status_t dumpState(const String8& prefix, String8* outResult) const override { using Signature = status_t (IGraphicBufferConsumer::*)(const String8&, String8*) const; return callRemote<Signature>(Tag::DUMP_STATE, prefix, outResult); @@ -220,6 +232,10 @@ status_t BnGraphicBufferConsumer::onTransact(uint32_t code, const Parcel& data, return callLocal(data, reply, &IGraphicBufferConsumer::getOccupancyHistory); case Tag::DISCARD_FREE_BUFFERS: return callLocal(data, reply, &IGraphicBufferConsumer::discardFreeBuffers); + case Tag::SET_FRAME_RATE: + return callLocal(data, reply, &IGraphicBufferConsumer::setFrameRate); + case Tag::GET_FRAME_RATE: + return callLocal(data, reply, &IGraphicBufferConsumer::getFrameRate); case Tag::DUMP_STATE: { using Signature = status_t (IGraphicBufferConsumer::*)(const String8&, String8*) const; return callLocal<Signature>(data, reply, &IGraphicBufferConsumer::dumpState); diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 0009a57653..75876f26f3 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -74,6 +74,7 @@ enum { GET_CONSUMER_USAGE, SET_LEGACY_BUFFER_DROP, SET_AUTO_PREROTATION, + SET_FRAME_RATE, }; class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> @@ -559,6 +560,14 @@ public: } return result; } + + virtual status_t setFrameRate(float frameRate) { + Parcel data, reply; + data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); + data.writeFloat(frameRate); + status_t result = remote()->transact(SET_FRAME_RATE, data, &reply, IBinder::FLAG_ONEWAY); + return result; + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -691,6 +700,8 @@ public: status_t setAutoPrerotation(bool autoPrerotation) override { return mBase->setAutoPrerotation(autoPrerotation); } + + status_t setFrameRate(float frameRate) override { return mBase->setFrameRate(frameRate); } }; IMPLEMENT_HYBRID_META_INTERFACE(GraphicBufferProducer, @@ -710,6 +721,12 @@ status_t IGraphicBufferProducer::setAutoPrerotation(bool autoPrerotation) { return INVALID_OPERATION; } +status_t IGraphicBufferProducer::setFrameRate(float frameRate) { + // No-op for IGBP other than BufferQueue. + (void)frameRate; + return INVALID_OPERATION; +} + status_t IGraphicBufferProducer::exportToParcel(Parcel* parcel) { status_t res = OK; res = parcel->writeUint32(USE_BUFFER_QUEUE); @@ -1079,6 +1096,13 @@ status_t BnGraphicBufferProducer::onTransact( reply->writeInt32(result); return NO_ERROR; } + case SET_FRAME_RATE: { + CHECK_INTERFACE(IGraphicBuffer, data, reply); + float frameRate = data.readFloat(); + status_t result = setFrameRate(frameRate); + reply->writeInt32(result); + return NO_ERROR; + } } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 8b448ff3f6..39b4d4bbb6 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -110,9 +110,8 @@ status_t layer_state_t::write(Parcel& output) const } } output.writeFloat(shadowRadius); - output.writeInt32(frameRateSelectionPriority); - + output.writeFloat(frameRate); return NO_ERROR; } @@ -191,9 +190,8 @@ status_t layer_state_t::read(const Parcel& input) listeners.emplace_back(listener, callbackIds); } shadowRadius = input.readFloat(); - frameRateSelectionPriority = input.readInt32(); - + frameRate = input.readFloat(); return NO_ERROR; } @@ -420,6 +418,10 @@ void layer_state_t::merge(const layer_state_t& other) { what |= eFrameRateSelectionPriority; frameRateSelectionPriority = other.frameRateSelectionPriority; } + if (other.what & eFrameRateChanged) { + what |= eFrameRateChanged; + frameRate = other.frameRate; + } if ((other.what & what) != other.what) { ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? " "other.what=0x%" PRIu64 " what=0x%" PRIu64, diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index e490d6d17d..d5cf11d305 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -1093,6 +1093,9 @@ int Surface::perform(int operation, va_list args) case NATIVE_WINDOW_GET_LAST_QUEUE_DURATION: res = dispatchGetLastQueueDuration(args); break; + case NATIVE_WINDOW_SET_FRAME_RATE: + res = dispatchSetFrameRate(args); + break; default: res = NAME_NOT_FOUND; break; @@ -1321,6 +1324,11 @@ int Surface::dispatchGetLastQueueDuration(va_list args) { return NO_ERROR; } +int Surface::dispatchSetFrameRate(va_list args) { + float frameRate = static_cast<float>(va_arg(args, double)); + return setFrameRate(frameRate); +} + bool Surface::transformToDisplayInverse() { return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; @@ -2064,4 +2072,11 @@ void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_ mSurfaceListener->onBuffersDiscarded(discardedBufs); } +status_t Surface::setFrameRate(float frameRate) { + ATRACE_CALL(); + ALOGV("Surface::setTargetFrameRate"); + Mutex::Autolock lock(mMutex); + return mGraphicBufferProducer->setFrameRate(frameRate); +} + }; // namespace android diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 2ef33cf253..20614f8d85 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -1376,6 +1376,18 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setShado return *this; } +SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameRate( + const sp<SurfaceControl>& sc, float frameRate) { + layer_state_t* s = getLayerState(sc); + if (!s) { + mStatus = BAD_INDEX; + return *this; + } + s->what |= layer_state_t::eFrameRateChanged; + s->frameRate = frameRate; + return *this; +} + // --------------------------------------------------------------------------- DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) { diff --git a/libs/gui/include/gui/BufferHubConsumer.h b/libs/gui/include/gui/BufferHubConsumer.h index d38077014b..d75620342e 100644 --- a/libs/gui/include/gui/BufferHubConsumer.h +++ b/libs/gui/include/gui/BufferHubConsumer.h @@ -93,6 +93,12 @@ public: // See |IGraphicBufferConsumer::discardFreeBuffers| status_t discardFreeBuffers() override; + // See |IGraphicBufferConsumer::setFrameRate| + status_t setFrameRate(float frameRate) override; + + // See |IGraphicBufferConsumer::getFrameRate| + status_t getFrameRate(float* frameRate) const override; + // See |IGraphicBufferConsumer::dumpState| status_t dumpState(const String8& prefix, String8* outResult) const override; diff --git a/libs/gui/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h index 7db69eca9d..e9f04490d8 100644 --- a/libs/gui/include/gui/BufferQueueConsumer.h +++ b/libs/gui/include/gui/BufferQueueConsumer.h @@ -149,6 +149,12 @@ public: // See IGraphicBufferConsumer::discardFreeBuffers virtual status_t discardFreeBuffers() override; + // See IGraphicBufferConsumer::setFrameRate. + virtual status_t setFrameRate(float frameRate) override; + + // See IGraphicBufferConsumer::getFrameRate. + virtual status_t getFrameRate(float* frameRate) const override; + // dump our state in a String status_t dumpState(const String8& prefix, String8* outResult) const override; diff --git a/libs/gui/include/gui/BufferQueueCore.h b/libs/gui/include/gui/BufferQueueCore.h index 557c28b1b7..05c20742f9 100644 --- a/libs/gui/include/gui/BufferQueueCore.h +++ b/libs/gui/include/gui/BufferQueueCore.h @@ -354,6 +354,9 @@ private: // mTransformHintInUse is to cache the mTransformHint used by the producer. uint32_t mTransformHintInUse; + // The frame rate the app intends to run at. + float mFrameRate; + }; // class BufferQueueCore } // namespace android diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h index 9ad92a6e78..2dec663183 100644 --- a/libs/gui/include/gui/BufferQueueProducer.h +++ b/libs/gui/include/gui/BufferQueueProducer.h @@ -193,6 +193,9 @@ public: // See IGraphicBufferProducer::setAutoPrerotation virtual status_t setAutoPrerotation(bool autoPrerotation); + // See IGraphicBufferProducer::setFrameRate + virtual status_t setFrameRate(float frameRate) override; + private: // This is required by the IBinder::DeathRecipient interface virtual void binderDied(const wp<IBinder>& who); diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h index 8ff0cd0f6e..cfed9aa6bd 100644 --- a/libs/gui/include/gui/ConsumerBase.h +++ b/libs/gui/include/gui/ConsumerBase.h @@ -111,6 +111,12 @@ public: // See IGraphicBufferConsumer::discardFreeBuffers status_t discardFreeBuffers(); + // See IGraphicBufferConsumer::setFrameRate + status_t setFrameRate(float frameRate); + + // See IGraphicBufferConsumer::getFrameRate + status_t getFrameRate(float* frameRate); + private: ConsumerBase(const ConsumerBase&); void operator=(const ConsumerBase&); diff --git a/libs/gui/include/gui/IGraphicBufferConsumer.h b/libs/gui/include/gui/IGraphicBufferConsumer.h index 9fb7580912..54f77b424a 100644 --- a/libs/gui/include/gui/IGraphicBufferConsumer.h +++ b/libs/gui/include/gui/IGraphicBufferConsumer.h @@ -271,6 +271,16 @@ public: // call to free up any of its locally cached buffers. virtual status_t discardFreeBuffers() = 0; + // Set the frame rate the producer will run at. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t setFrameRate(float frameRate) = 0; + + // Get the frame rate the producer will run at. + // + // Return of a value other than NO_ERROR means an unknown error has occurred. + virtual status_t getFrameRate(float* frameRate) const = 0; + // dump state into a string virtual status_t dumpState(const String8& prefix, String8* outResult) const = 0; diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h index 25ce1ca3dc..680d64ed75 100644 --- a/libs/gui/include/gui/IGraphicBufferProducer.h +++ b/libs/gui/include/gui/IGraphicBufferProducer.h @@ -637,6 +637,9 @@ public: // the width and height used for dequeueBuffer will be additionally swapped. virtual status_t setAutoPrerotation(bool autoPrerotation); + // Sets the apps intended frame rate. + virtual status_t setFrameRate(float frameRate); + // Static method exports any IGraphicBufferProducer object to a parcel. It // handles null producer as well. static status_t exportToParcel(const sp<IGraphicBufferProducer>& producer, diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 03e91c4905..cf641939e8 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -100,6 +100,7 @@ struct layer_state_t { eMetadataChanged = 0x8'00000000, eColorSpaceAgnosticChanged = 0x10'00000000, eFrameRateSelectionPriority = 0x20'00000000, + eFrameRateChanged = 0x40'00000000, }; layer_state_t() @@ -130,7 +131,8 @@ struct layer_state_t { bgColorDataspace(ui::Dataspace::UNKNOWN), colorSpaceAgnostic(false), shadowRadius(0.0f), - frameRateSelectionPriority(-1) { + frameRateSelectionPriority(-1), + frameRate(0.0f) { matrix.dsdx = matrix.dtdy = 1.0f; matrix.dsdy = matrix.dtdx = 0.0f; hdrMetadata.validTypes = 0; @@ -214,6 +216,8 @@ struct layer_state_t { // Priority of the layer assigned by Window Manager. int32_t frameRateSelectionPriority; + + float frameRate; }; struct ComposerState { diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h index e582509b6e..86cc61f3ec 100644 --- a/libs/gui/include/gui/Surface.h +++ b/libs/gui/include/gui/Surface.h @@ -179,6 +179,9 @@ public: status_t getUniqueId(uint64_t* outId) const; status_t getConsumerUsage(uint64_t* outUsage) const; + // See IGraphicBufferProducer::setFrameRate + status_t setFrameRate(float frameRate); + protected: virtual ~Surface(); @@ -248,6 +251,7 @@ private: int dispatchSetDequeueTimeout(va_list args); int dispatchGetLastDequeueDuration(va_list args); int dispatchGetLastQueueDuration(va_list args); + int dispatchSetFrameRate(va_list args); bool transformToDisplayInverse(); protected: diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 6a3f452f77..71ee82a72f 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -520,6 +520,8 @@ public: const Rect& source, const Rect& dst, int transform); Transaction& setShadowRadius(const sp<SurfaceControl>& sc, float cornerRadius); + Transaction& setFrameRate(const sp<SurfaceControl>& sc, float frameRate); + status_t setDisplaySurface(const sp<IBinder>& token, const sp<IGraphicBufferProducer>& bufferProducer); diff --git a/libs/gui/include/gui/mock/GraphicBufferConsumer.h b/libs/gui/include/gui/mock/GraphicBufferConsumer.h index 98f24c2d44..e940cf3248 100644 --- a/libs/gui/include/gui/mock/GraphicBufferConsumer.h +++ b/libs/gui/include/gui/mock/GraphicBufferConsumer.h @@ -49,6 +49,8 @@ public: MOCK_CONST_METHOD1(getSidebandStream, status_t(sp<NativeHandle>*)); MOCK_METHOD2(getOccupancyHistory, status_t(bool, std::vector<OccupancyTracker::Segment>*)); MOCK_METHOD0(discardFreeBuffers, status_t()); + MOCK_METHOD1(setFrameRate, status_t(float)); + MOCK_CONST_METHOD1(getFrameRate, status_t(float*)); MOCK_CONST_METHOD2(dumpState, status_t(const String8&, String8*)); }; diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h index 1814ab5568..14f7214882 100644 --- a/libs/nativewindow/include/system/window.h +++ b/libs/nativewindow/include/system/window.h @@ -34,12 +34,12 @@ #include <cutils/native_handle.h> #include <errno.h> #include <limits.h> +#include <stdbool.h> #include <stdint.h> #include <string.h> #include <sys/cdefs.h> #include <system/graphics.h> #include <unistd.h> -#include <stdbool.h> // system/window.h is a superset of the vndk and apex apis #include <apex/window.h> @@ -247,6 +247,7 @@ enum { NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT = 37, /* private */ NATIVE_WINDOW_GET_LAST_DEQUEUE_DURATION = 38, /* private */ NATIVE_WINDOW_GET_LAST_QUEUE_DURATION = 39, /* private */ + NATIVE_WINDOW_SET_FRAME_RATE = 40, // clang-format on }; @@ -1008,4 +1009,8 @@ static inline int native_window_set_auto_prerotation(struct ANativeWindow* windo return window->perform(window, NATIVE_WINDOW_SET_AUTO_PREROTATION, autoPrerotation); } +static inline int native_window_set_frame_rate(struct ANativeWindow* window, float frameRate) { + return window->perform(window, NATIVE_WINDOW_SET_FRAME_RATE, (double)frameRate); +} + __END_DECLS |