Loading Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -43,3 +43,8 @@ filegroup { ":framework_native_aidl_gui", ], } cc_library_headers{ name: "libandroid_headers_private", export_include_dirs: ["include/private"], } No newline at end of file include/private/surface_control_private.h 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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. */ #ifndef ANDROID_PRIVATE_NATIVE_SURFACE_CONTROL_H #define ANDROID_PRIVATE_NATIVE_SURFACE_CONTROL_H #include <stdint.h> __BEGIN_DECLS struct ASurfaceControl; struct ASurfaceControlStats; typedef struct ASurfaceControlStats ASurfaceControlStats; /** * Callback to be notified when surface stats for a specific surface control are available. */ typedef void (*ASurfaceControl_SurfaceStatsListener)(void* context, ASurfaceControl* control, ASurfaceControlStats* stats); /** * Registers a callback to be invoked when surface stats from a specific surface are available. * * \param context Optional context provided by the client that is passed into * the callback. * * \param control The surface to retrieve callbacks for. * * \param func The callback to be invoked when surface stats are available. */ void ASurfaceControl_registerSurfaceStatsListener(ASurfaceControl* control, void* context, ASurfaceControl_SurfaceStatsListener func); /** * Unregisters a callback to be invoked when surface stats from a specific surface are available. * * \param context The context passed into ASurfaceControl_registerSurfaceStatsListener * * \param func The callback passed into ASurfaceControl_registerSurfaceStatsListener */ void ASurfaceControl_unregisterSurfaceStatsListener(void* context, ASurfaceControl_SurfaceStatsListener func); /** * Returns the timestamp of when the buffer was acquired for a specific frame with frame number * obtained from ASurfaceControlStats_getFrameNumber. */ int64_t ASurfaceControlStats_getAcquireTime(ASurfaceControlStats* stats); /** * Returns the frame number of the surface stats object passed into the callback. */ uint64_t ASurfaceControlStats_getFrameNumber(ASurfaceControlStats* stats); __END_DECLS #endif //ANDROID_PRIVATE_NATIVE_SURFACE_CONTROL_H libs/gui/SurfaceComposerClient.cpp +30 −2 Original line number Diff line number Diff line Loading @@ -194,6 +194,25 @@ void TransactionCompletedListener::removeJankListener(const sp<JankDataListener> } } void TransactionCompletedListener::addSurfaceStatsListener(void* context, void* cookie, sp<SurfaceControl> surfaceControl, SurfaceStatsCallback listener) { std::lock_guard<std::mutex> lock(mMutex); mSurfaceStatsListeners.insert({surfaceControl->getHandle(), SurfaceStatsCallbackEntry(context, cookie, listener)}); } void TransactionCompletedListener::removeSurfaceStatsListener(void* context, void* cookie) { std::lock_guard<std::mutex> lock(mMutex); for (auto it = mSurfaceStatsListeners.begin(); it != mSurfaceStatsListeners.end();) { auto [itContext, itCookie, itListener] = it->second; if (itContext == context && itCookie == cookie) { it = mSurfaceStatsListeners.erase(it); } else { it++; } } } void TransactionCompletedListener::addSurfaceControlToCallbacks( const sp<SurfaceControl>& surfaceControl, const std::unordered_set<CallbackId>& callbackIds) { Loading @@ -210,6 +229,7 @@ void TransactionCompletedListener::addSurfaceControlToCallbacks( void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) { std::unordered_map<CallbackId, CallbackTranslation> callbacksMap; std::multimap<sp<IBinder>, sp<JankDataListener>> jankListenersMap; std::multimap<sp<IBinder>, SurfaceStatsCallbackEntry> surfaceListeners; { std::lock_guard<std::mutex> lock(mMutex); Loading @@ -226,6 +246,7 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener */ callbacksMap = mCallbacks; jankListenersMap = mJankListeners; surfaceListeners = mSurfaceStatsListeners; for (const auto& transactionStats : listenerStats.transactionStats) { for (auto& callbackId : transactionStats.callbackIds) { mCallbacks.erase(callbackId); Loading Loading @@ -259,9 +280,16 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener surfaceControlStats); } for (const auto& surfaceStats : transactionStats.surfaceStats) { auto listenerRange = surfaceListeners.equal_range(surfaceStats.surfaceControl); for (auto it = listenerRange.first; it != listenerRange.second; it++) { auto entry = it->second; entry.callback(entry.context, transactionStats.latchTime, transactionStats.presentFence, surfaceStats); } if (surfaceStats.jankData.empty()) continue; for (auto it = jankListenersMap.find(surfaceStats.surfaceControl); it != jankListenersMap.end(); it++) { auto jankRange = jankListenersMap.equal_range(surfaceStats.surfaceControl); for (auto it = jankRange.first; it != jankRange.second; it++) { it->second->onJankDataAvailable(surfaceStats.jankData); } } Loading libs/gui/include/gui/SurfaceComposerClient.h +21 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,10 @@ using TransactionCompletedCallbackTakesContext = using TransactionCompletedCallback = std::function<void(nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const std::vector<SurfaceControlStats>& /*stats*/)>; using SurfaceStatsCallback = std::function<void(void* /*context*/, nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const SurfaceStats& /*stats*/)>; // --------------------------------------------------------------------------- Loading Loading @@ -650,8 +654,21 @@ class TransactionCompletedListener : public BnTransactionCompletedListener { surfaceControls; }; struct SurfaceStatsCallbackEntry { SurfaceStatsCallbackEntry(void* context, void* cookie, SurfaceStatsCallback callback) : context(context), cookie(cookie), callback(callback) {} void* context; void* cookie; SurfaceStatsCallback callback; }; std::unordered_map<CallbackId, CallbackTranslation> mCallbacks GUARDED_BY(mMutex); std::multimap<sp<IBinder>, sp<JankDataListener>> mJankListeners GUARDED_BY(mMutex); std::multimap<sp<IBinder>, SurfaceStatsCallbackEntry> mSurfaceStatsListeners GUARDED_BY(mMutex); public: static sp<TransactionCompletedListener> getInstance(); Loading Loading @@ -679,6 +696,10 @@ public: */ void removeJankListener(const sp<JankDataListener>& listener); void addSurfaceStatsListener(void* context, void* cookie, sp<SurfaceControl> surfaceControl, SurfaceStatsCallback listener); void removeSurfaceStatsListener(void* context, void* cookie); // Overrides BnTransactionCompletedListener's onTransactionCompleted void onTransactionCompleted(ListenerStats stats) override; }; Loading Loading
Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -43,3 +43,8 @@ filegroup { ":framework_native_aidl_gui", ], } cc_library_headers{ name: "libandroid_headers_private", export_include_dirs: ["include/private"], } No newline at end of file
include/private/surface_control_private.h 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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. */ #ifndef ANDROID_PRIVATE_NATIVE_SURFACE_CONTROL_H #define ANDROID_PRIVATE_NATIVE_SURFACE_CONTROL_H #include <stdint.h> __BEGIN_DECLS struct ASurfaceControl; struct ASurfaceControlStats; typedef struct ASurfaceControlStats ASurfaceControlStats; /** * Callback to be notified when surface stats for a specific surface control are available. */ typedef void (*ASurfaceControl_SurfaceStatsListener)(void* context, ASurfaceControl* control, ASurfaceControlStats* stats); /** * Registers a callback to be invoked when surface stats from a specific surface are available. * * \param context Optional context provided by the client that is passed into * the callback. * * \param control The surface to retrieve callbacks for. * * \param func The callback to be invoked when surface stats are available. */ void ASurfaceControl_registerSurfaceStatsListener(ASurfaceControl* control, void* context, ASurfaceControl_SurfaceStatsListener func); /** * Unregisters a callback to be invoked when surface stats from a specific surface are available. * * \param context The context passed into ASurfaceControl_registerSurfaceStatsListener * * \param func The callback passed into ASurfaceControl_registerSurfaceStatsListener */ void ASurfaceControl_unregisterSurfaceStatsListener(void* context, ASurfaceControl_SurfaceStatsListener func); /** * Returns the timestamp of when the buffer was acquired for a specific frame with frame number * obtained from ASurfaceControlStats_getFrameNumber. */ int64_t ASurfaceControlStats_getAcquireTime(ASurfaceControlStats* stats); /** * Returns the frame number of the surface stats object passed into the callback. */ uint64_t ASurfaceControlStats_getFrameNumber(ASurfaceControlStats* stats); __END_DECLS #endif //ANDROID_PRIVATE_NATIVE_SURFACE_CONTROL_H
libs/gui/SurfaceComposerClient.cpp +30 −2 Original line number Diff line number Diff line Loading @@ -194,6 +194,25 @@ void TransactionCompletedListener::removeJankListener(const sp<JankDataListener> } } void TransactionCompletedListener::addSurfaceStatsListener(void* context, void* cookie, sp<SurfaceControl> surfaceControl, SurfaceStatsCallback listener) { std::lock_guard<std::mutex> lock(mMutex); mSurfaceStatsListeners.insert({surfaceControl->getHandle(), SurfaceStatsCallbackEntry(context, cookie, listener)}); } void TransactionCompletedListener::removeSurfaceStatsListener(void* context, void* cookie) { std::lock_guard<std::mutex> lock(mMutex); for (auto it = mSurfaceStatsListeners.begin(); it != mSurfaceStatsListeners.end();) { auto [itContext, itCookie, itListener] = it->second; if (itContext == context && itCookie == cookie) { it = mSurfaceStatsListeners.erase(it); } else { it++; } } } void TransactionCompletedListener::addSurfaceControlToCallbacks( const sp<SurfaceControl>& surfaceControl, const std::unordered_set<CallbackId>& callbackIds) { Loading @@ -210,6 +229,7 @@ void TransactionCompletedListener::addSurfaceControlToCallbacks( void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) { std::unordered_map<CallbackId, CallbackTranslation> callbacksMap; std::multimap<sp<IBinder>, sp<JankDataListener>> jankListenersMap; std::multimap<sp<IBinder>, SurfaceStatsCallbackEntry> surfaceListeners; { std::lock_guard<std::mutex> lock(mMutex); Loading @@ -226,6 +246,7 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener */ callbacksMap = mCallbacks; jankListenersMap = mJankListeners; surfaceListeners = mSurfaceStatsListeners; for (const auto& transactionStats : listenerStats.transactionStats) { for (auto& callbackId : transactionStats.callbackIds) { mCallbacks.erase(callbackId); Loading Loading @@ -259,9 +280,16 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener surfaceControlStats); } for (const auto& surfaceStats : transactionStats.surfaceStats) { auto listenerRange = surfaceListeners.equal_range(surfaceStats.surfaceControl); for (auto it = listenerRange.first; it != listenerRange.second; it++) { auto entry = it->second; entry.callback(entry.context, transactionStats.latchTime, transactionStats.presentFence, surfaceStats); } if (surfaceStats.jankData.empty()) continue; for (auto it = jankListenersMap.find(surfaceStats.surfaceControl); it != jankListenersMap.end(); it++) { auto jankRange = jankListenersMap.equal_range(surfaceStats.surfaceControl); for (auto it = jankRange.first; it != jankRange.second; it++) { it->second->onJankDataAvailable(surfaceStats.jankData); } } Loading
libs/gui/include/gui/SurfaceComposerClient.h +21 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,10 @@ using TransactionCompletedCallbackTakesContext = using TransactionCompletedCallback = std::function<void(nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const std::vector<SurfaceControlStats>& /*stats*/)>; using SurfaceStatsCallback = std::function<void(void* /*context*/, nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const SurfaceStats& /*stats*/)>; // --------------------------------------------------------------------------- Loading Loading @@ -650,8 +654,21 @@ class TransactionCompletedListener : public BnTransactionCompletedListener { surfaceControls; }; struct SurfaceStatsCallbackEntry { SurfaceStatsCallbackEntry(void* context, void* cookie, SurfaceStatsCallback callback) : context(context), cookie(cookie), callback(callback) {} void* context; void* cookie; SurfaceStatsCallback callback; }; std::unordered_map<CallbackId, CallbackTranslation> mCallbacks GUARDED_BY(mMutex); std::multimap<sp<IBinder>, sp<JankDataListener>> mJankListeners GUARDED_BY(mMutex); std::multimap<sp<IBinder>, SurfaceStatsCallbackEntry> mSurfaceStatsListeners GUARDED_BY(mMutex); public: static sp<TransactionCompletedListener> getInstance(); Loading Loading @@ -679,6 +696,10 @@ public: */ void removeJankListener(const sp<JankDataListener>& listener); void addSurfaceStatsListener(void* context, void* cookie, sp<SurfaceControl> surfaceControl, SurfaceStatsCallback listener); void removeSurfaceStatsListener(void* context, void* cookie); // Overrides BnTransactionCompletedListener's onTransactionCompleted void onTransactionCompleted(ListenerStats stats) override; }; Loading