Loading include/android/surface_control.h +142 −15 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <sys/cdefs.h> #include <android/hardware_buffer.h> #include <android/hdr_metadata.h> #include <android/native_window.h> __BEGIN_DECLS Loading Loading @@ -60,10 +61,11 @@ ASurfaceControl* ASurfaceControl_create(ASurfaceControl* parent, const char* deb __INTRODUCED_IN(29); /** * Destroys the |surface_control| object. After releasing the ASurfaceControl the caller no longer * has ownership of the AsurfaceControl. * Releases the |surface_control| object. After releasing the ASurfaceControl the caller no longer * has ownership of the AsurfaceControl. The surface and it's children may remain on display as long * as their parent remains on display. */ void ASurfaceControl_destroy(ASurfaceControl* surface_control) __INTRODUCED_IN(29); void ASurfaceControl_release(ASurfaceControl* surface_control) __INTRODUCED_IN(29); struct ASurfaceTransaction; Loading Loading @@ -93,6 +95,13 @@ void ASurfaceTransaction_delete(ASurfaceTransaction* transaction) __INTRODUCED_I */ void ASurfaceTransaction_apply(ASurfaceTransaction* transaction) __INTRODUCED_IN(29); /** * An opaque handle returned during a callback that can be used to query general stats and stats for * surfaces which were either removed or for which buffers were updated after this transaction was * applied. */ typedef struct ASurfaceTransactionStats ASurfaceTransactionStats; /** * Since the transactions are applied asynchronously, the * ASurfaceTransaction_OnComplete callback can be used to be notified when a frame Loading @@ -100,18 +109,81 @@ void ASurfaceTransaction_apply(ASurfaceTransaction* transaction) __INTRODUCED_IN * * |context| is the optional context provided by the client that is passed into * the callback. * |present_fence| is the sync fence that signals when the transaction has been presented. * The recipient of the callback takes ownership of the present_fence and is responsible for closing * it. * * It is safe to assume that once the present fence singals, that reads for all buffers, * submitted in previous transactions, which are not in the surface tree after a transaction is * applied, are finished and the buffers may be reused. * |stats| is an opaque handle that can be passed to ASurfaceTransactionStats functions to query * information about the transaction. The handle is only valid during the the callback. * * THREADING * The transaction completed callback can be invoked on any thread. */ typedef void (*ASurfaceTransaction_OnComplete)(void* context, int32_t present_fence); typedef void (*ASurfaceTransaction_OnComplete)(void* context, ASurfaceTransactionStats* stats) __INTRODUCED_IN(29); /** * Returns the timestamp of when the frame was latched by the framework. Once a frame is * latched by the framework, it is presented at the following hardware vsync. */ int64_t ASurfaceTransactionStats_getLatchTime(ASurfaceTransactionStats* surface_transaction_stats) __INTRODUCED_IN(29); /** * Returns a sync fence that signals when the transaction has been presented. * The recipient of the callback takes ownership of the fence and is responsible for closing * it. */ int ASurfaceTransactionStats_getPresentFenceFd(ASurfaceTransactionStats* surface_transaction_stats) __INTRODUCED_IN(29); /** * |outASurfaceControls| returns an array of ASurfaceControl pointers that were updated during the * transaction. Stats for the surfaces can be queried through ASurfaceTransactionStats functions. * When the client is done using the array, it must release it by calling * ASurfaceTransactionStats_releaseASurfaceControls. * * |outASurfaceControlsSize| returns the size of the ASurfaceControls array. */ void ASurfaceTransactionStats_getASurfaceControls(ASurfaceTransactionStats* surface_transaction_stats, ASurfaceControl*** outASurfaceControls, size_t* outASurfaceControlsSize) __INTRODUCED_IN(29); /** * Releases the array of ASurfaceControls that were returned by * ASurfaceTransactionStats_getASurfaceControls. */ void ASurfaceTransactionStats_releaseASurfaceControls(ASurfaceControl** surface_controls) __INTRODUCED_IN(29); /** * Returns the timestamp of when the CURRENT buffer was acquired. A buffer is considered * acquired when its acquire_fence_fd has signaled. A buffer cannot be latched or presented until * it is acquired. If no acquire_fence_fd was provided, this timestamp will be set to -1. */ int64_t ASurfaceTransactionStats_getAcquireTime(ASurfaceTransactionStats* surface_transaction_stats, ASurfaceControl* surface_control) __INTRODUCED_IN(29); /** * The returns the fence used to signal the release of the PREVIOUS buffer set on * this surface. If this fence is valid (>=0), the PREVIOUS buffer has not yet been released and the * fence will signal when the PREVIOUS buffer has been released. If the fence is -1 , the PREVIOUS * buffer is already released. The recipient of the callback takes ownership of the * previousReleaseFenceFd and is responsible for closing it. * * Each time a buffer is set through ASurfaceTransaction_setBuffer()/_setCachedBuffer() on a * transaction which is applied, the framework takes a ref on this buffer. The framework treats the * addition of a buffer to a particular surface as a unique ref. When a transaction updates or * removes a buffer from a surface, or removes the surface itself from the tree, this ref is * guaranteed to be released in the OnComplete callback for this transaction. The * ASurfaceControlStats provided in the callback for this surface may contain an optional fence * which must be signaled before the ref is assumed to be released. * * The client must ensure that all pending refs on a buffer are released before attempting to reuse * this buffer, otherwise synchronization errors may occur. */ int ASurfaceTransactionStats_getPreviousReleaseFenceFd( ASurfaceTransactionStats* surface_transaction_stats, ASurfaceControl* surface_control) __INTRODUCED_IN(29); /** * Sets the callback that will be invoked when the updates from this transaction Loading @@ -121,6 +193,16 @@ typedef void (*ASurfaceTransaction_OnComplete)(void* context, int32_t present_fe void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* transaction, void* context, ASurfaceTransaction_OnComplete func) __INTRODUCED_IN(29); /** * Reparents the |surface_control| from its old parent to the |new_parent| surface control. * Any children of the* reparented |surface_control| will remain children of the |surface_control|. * * The |new_parent| can be null. Surface controls with a null parent do not appear on the display. */ void ASurfaceTransaction_reparent(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, ASurfaceControl* new_parent) __INTRODUCED_IN(29); /* Parameter for ASurfaceTransaction_setVisibility */ enum { ASURFACE_TRANSACTION_VISIBILITY_HIDE = 0, Loading Loading @@ -148,15 +230,15 @@ void ASurfaceTransaction_setZOrder(ASurfaceTransaction* transaction, /** * Updates the AHardwareBuffer displayed for |surface_control|. If not -1, the * fence_fd should be a file descriptor that is signaled when all pending work * acquire_fence_fd should be a file descriptor that is signaled when all pending work * for the buffer is complete and the buffer can be safely read. * * The frameworks takes ownership of the |fence_fd| passed and is responsible * The frameworks takes ownership of the |acquire_fence_fd| passed and is responsible * for closing it. */ void ASurfaceTransaction_setBuffer(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, AHardwareBuffer* buffer, int fence_fd = -1) __INTRODUCED_IN(29); int acquire_fence_fd = -1) __INTRODUCED_IN(29); /** * |source| the sub-rect within the buffer's content to be rendered inside the surface's area Loading Loading @@ -189,7 +271,8 @@ enum { * opaque or visual errors can occur. */ void ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, int8_t transparency) ASurfaceControl* surface_control, int8_t transparency) __INTRODUCED_IN(29); /** Loading @@ -200,6 +283,50 @@ void ASurfaceTransaction_setDamageRegion(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, const ARect rects[], uint32_t count) __INTRODUCED_IN(29); /** * Specifies a desiredPresentTime for the transaction. The framework will try to present * the transaction at or after the time specified. * * Transactions will not be presented until all of their acquire fences have signaled even if the * app requests an earlier present time. * * If an earlier transaction has a desired present time of x, and a later transaction has a desired * present time that is before x, the later transaction will not preempt the earlier transaction. */ void ASurfaceTransaction_setDesiredPresentTime(ASurfaceTransaction* transaction, int64_t desiredPresentTime) __INTRODUCED_IN(29); /** * Sets the alpha for the buffer. It uses a premultiplied blending. * * The |alpha| must be between 0.0 and 1.0. */ void ASurfaceTransaction_setBufferAlpha(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, float alpha) __INTRODUCED_IN(29); /* * SMPTE ST 2086 "Mastering Display Color Volume" static metadata * * When |metadata| is set to null, the framework does not use any smpte2086 metadata when rendering * the surface's buffer. */ void ASurfaceTransaction_setHdrMetadata_smpte2086(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, struct AHdrMetadata_smpte2086* metadata) __INTRODUCED_IN(29); /* * Sets the CTA 861.3 "HDR Static Metadata Extension" static metadata on a surface. * * When |metadata| is set to null, the framework does not use any cta861.3 metadata when rendering * the surface's buffer. */ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, struct AHdrMetadata_cta861_3* metadata) __INTRODUCED_IN(29); #endif // __ANDROID_API__ >= 29 __END_DECLS Loading libs/gui/SurfaceComposerClient.cpp +65 −8 Original line number Diff line number Diff line Loading @@ -132,26 +132,76 @@ void TransactionCompletedListener::startListeningLocked() { mListening = true; } CallbackId TransactionCompletedListener::addCallback(const TransactionCompletedCallback& callback) { CallbackId TransactionCompletedListener::addCallbackFunction( const TransactionCompletedCallback& callbackFunction, const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>& surfaceControls) { std::lock_guard<std::mutex> lock(mMutex); startListeningLocked(); CallbackId callbackId = getNextIdLocked(); mCallbacks.emplace(callbackId, callback); mCallbacks[callbackId].callbackFunction = callbackFunction; auto& callbackSurfaceControls = mCallbacks[callbackId].surfaceControls; for (const auto& surfaceControl : surfaceControls) { callbackSurfaceControls[surfaceControl->getHandle()] = surfaceControl; } return callbackId; } void TransactionCompletedListener::addSurfaceControlToCallbacks( const sp<SurfaceControl>& surfaceControl, const std::unordered_set<CallbackId>& callbackIds) { std::lock_guard<std::mutex> lock(mMutex); for (auto callbackId : callbackIds) { mCallbacks[callbackId].surfaceControls.emplace(std::piecewise_construct, std::forward_as_tuple( surfaceControl->getHandle()), std::forward_as_tuple(surfaceControl)); } } void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) { std::lock_guard lock(mMutex); /* This listener knows all the sp<IBinder> to sp<SurfaceControl> for all its registered * callbackIds, except for when Transactions are merged together. This probably cannot be * solved before this point because the Transactions could be merged together and applied in a * different process. * * Fortunately, we get all the callbacks for this listener for the same frame together at the * same time. This means if any Transactions were merged together, we will get their callbacks * at the same time. We can combine all the sp<IBinder> to sp<SurfaceControl> maps for all the * callbackIds to generate one super map that contains all the sp<IBinder> to sp<SurfaceControl> * that could possibly exist for the callbacks. */ std::unordered_map<sp<IBinder>, sp<SurfaceControl>, IBinderHash> surfaceControls; for (const auto& [callbackIds, transactionStats] : listenerStats.transactionStats) { for (auto callbackId : callbackIds) { auto& [callbackFunction, callbackSurfaceControls] = mCallbacks[callbackId]; surfaceControls.insert(callbackSurfaceControls.begin(), callbackSurfaceControls.end()); } } for (const auto& [callbackIds, transactionStats] : listenerStats.transactionStats) { for (auto callbackId : callbackIds) { const auto& callback = mCallbacks[callbackId]; if (!callback) { auto& [callbackFunction, callbackSurfaceControls] = mCallbacks[callbackId]; if (!callbackFunction) { ALOGE("cannot call null callback function, skipping"); continue; } callback(transactionStats); std::vector<SurfaceControlStats> surfaceControlStats; for (const auto& surfaceStats : transactionStats.surfaceStats) { surfaceControlStats.emplace_back(surfaceControls[surfaceStats.surfaceControl], surfaceStats.acquireTime, surfaceStats.previousReleaseFence); } callbackFunction(transactionStats.latchTime, transactionStats.presentFence, surfaceControlStats); mCallbacks.erase(callbackId); } } Loading Loading @@ -329,7 +379,11 @@ layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<Surfac void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback( const sp<SurfaceControl>& sc) { mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls.insert(sc); auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()]; callbackInfo.surfaceControls.insert(sc); TransactionCompletedListener::getInstance() ->addSurfaceControlToCallbacks(sc, callbackInfo.callbackIds); } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( Loading Loading @@ -770,9 +824,12 @@ SurfaceComposerClient::Transaction::addTransactionCompletedCallback( TransactionCompletedCallbackTakesContext callback, void* callbackContext) { auto listener = TransactionCompletedListener::getInstance(); auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1); auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); const auto& surfaceControls = mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls; CallbackId callbackId = listener->addCallback(callbackWithContext); CallbackId callbackId = listener->addCallbackFunction(callbackWithContext, surfaceControls); mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace( callbackId); Loading libs/gui/include/gui/SurfaceComposerClient.h +60 −27 Original line number Diff line number Diff line Loading @@ -53,35 +53,24 @@ class Region; // --------------------------------------------------------------------------- using TransactionCompletedCallbackTakesContext = std::function<void(void* /*context*/, const TransactionStats&)>; using TransactionCompletedCallback = std::function<void(const TransactionStats&)>; class TransactionCompletedListener : public BnTransactionCompletedListener { TransactionCompletedListener(); CallbackId getNextIdLocked() REQUIRES(mMutex); std::mutex mMutex; bool mListening GUARDED_BY(mMutex) = false; CallbackId mCallbackIdCounter GUARDED_BY(mMutex) = 1; std::map<CallbackId, TransactionCompletedCallback> mCallbacks GUARDED_BY(mMutex); public: static sp<TransactionCompletedListener> getInstance(); static sp<ITransactionCompletedListener> getIInstance(); void startListeningLocked() REQUIRES(mMutex); CallbackId addCallback(const TransactionCompletedCallback& callback); // Overrides BnTransactionCompletedListener's onTransactionCompleted void onTransactionCompleted(ListenerStats stats) override; struct SurfaceControlStats { SurfaceControlStats(const sp<SurfaceControl>& sc, nsecs_t time, const sp<Fence>& prevReleaseFence) : surfaceControl(sc), acquireTime(time), previousReleaseFence(prevReleaseFence) {} sp<SurfaceControl> surfaceControl; nsecs_t acquireTime = -1; sp<Fence> previousReleaseFence; }; using TransactionCompletedCallbackTakesContext = std::function<void(void* /*context*/, nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const std::vector<SurfaceControlStats>& /*stats*/)>; using TransactionCompletedCallback = std::function<void(nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const std::vector<SurfaceControlStats>& /*stats*/)>; // --------------------------------------------------------------------------- class SurfaceComposerClient : public RefBase Loading Loading @@ -465,6 +454,50 @@ public: // --------------------------------------------------------------------------- class TransactionCompletedListener : public BnTransactionCompletedListener { TransactionCompletedListener(); CallbackId getNextIdLocked() REQUIRES(mMutex); std::mutex mMutex; bool mListening GUARDED_BY(mMutex) = false; CallbackId mCallbackIdCounter GUARDED_BY(mMutex) = 1; struct IBinderHash { std::size_t operator()(const sp<IBinder>& iBinder) const { return std::hash<IBinder*>{}(iBinder.get()); } }; struct CallbackTranslation { TransactionCompletedCallback callbackFunction; std::unordered_map<sp<IBinder>, sp<SurfaceControl>, IBinderHash> surfaceControls; }; std::unordered_map<CallbackId, CallbackTranslation> mCallbacks GUARDED_BY(mMutex); public: static sp<TransactionCompletedListener> getInstance(); static sp<ITransactionCompletedListener> getIInstance(); void startListeningLocked() REQUIRES(mMutex); CallbackId addCallbackFunction( const TransactionCompletedCallback& callbackFunction, const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>& surfaceControls); void addSurfaceControlToCallbacks(const sp<SurfaceControl>& surfaceControl, const std::unordered_set<CallbackId>& callbackIds); // Overrides BnTransactionCompletedListener's onTransactionCompleted void onTransactionCompleted(ListenerStats stats) override; }; // --------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H libs/nativewindow/include/android/hdr_metadata.h 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * Copyright 2019 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. */ /** * @file hdr_metadata.h */ #ifndef ANDROID_HDR_METADATA_H #define ANDROID_HDR_METADATA_H #include <inttypes.h> #include <sys/cdefs.h> __BEGIN_DECLS /** * These structures are used to define the display's capabilities for HDR content. * They can be used to better tone map content to user's display. */ /** * Color is defined in CIE XYZ coordinates. */ struct AColor_xy { float x; float y; }; /** * SMPTE ST 2086 "Mastering Display Color Volume" static metadata */ struct AHdrMetadata_smpte2086 { struct AColor_xy displayPrimaryRed; struct AColor_xy displayPrimaryGreen; struct AColor_xy displayPrimaryBlue; struct AColor_xy whitePoint; float maxLuminance; float minLuminance; }; /** * CTA 861.3 "HDR Static Metadata Extension" static metadata */ struct AHdrMetadata_cta861_3 { float maxContentLightLevel; float maxFrameAverageLightLevel; }; __END_DECLS #endif // ANDROID_HDR_METADATA_H services/surfaceflinger/tests/Transaction_test.cpp +39 −25 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
include/android/surface_control.h +142 −15 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include <sys/cdefs.h> #include <android/hardware_buffer.h> #include <android/hdr_metadata.h> #include <android/native_window.h> __BEGIN_DECLS Loading Loading @@ -60,10 +61,11 @@ ASurfaceControl* ASurfaceControl_create(ASurfaceControl* parent, const char* deb __INTRODUCED_IN(29); /** * Destroys the |surface_control| object. After releasing the ASurfaceControl the caller no longer * has ownership of the AsurfaceControl. * Releases the |surface_control| object. After releasing the ASurfaceControl the caller no longer * has ownership of the AsurfaceControl. The surface and it's children may remain on display as long * as their parent remains on display. */ void ASurfaceControl_destroy(ASurfaceControl* surface_control) __INTRODUCED_IN(29); void ASurfaceControl_release(ASurfaceControl* surface_control) __INTRODUCED_IN(29); struct ASurfaceTransaction; Loading Loading @@ -93,6 +95,13 @@ void ASurfaceTransaction_delete(ASurfaceTransaction* transaction) __INTRODUCED_I */ void ASurfaceTransaction_apply(ASurfaceTransaction* transaction) __INTRODUCED_IN(29); /** * An opaque handle returned during a callback that can be used to query general stats and stats for * surfaces which were either removed or for which buffers were updated after this transaction was * applied. */ typedef struct ASurfaceTransactionStats ASurfaceTransactionStats; /** * Since the transactions are applied asynchronously, the * ASurfaceTransaction_OnComplete callback can be used to be notified when a frame Loading @@ -100,18 +109,81 @@ void ASurfaceTransaction_apply(ASurfaceTransaction* transaction) __INTRODUCED_IN * * |context| is the optional context provided by the client that is passed into * the callback. * |present_fence| is the sync fence that signals when the transaction has been presented. * The recipient of the callback takes ownership of the present_fence and is responsible for closing * it. * * It is safe to assume that once the present fence singals, that reads for all buffers, * submitted in previous transactions, which are not in the surface tree after a transaction is * applied, are finished and the buffers may be reused. * |stats| is an opaque handle that can be passed to ASurfaceTransactionStats functions to query * information about the transaction. The handle is only valid during the the callback. * * THREADING * The transaction completed callback can be invoked on any thread. */ typedef void (*ASurfaceTransaction_OnComplete)(void* context, int32_t present_fence); typedef void (*ASurfaceTransaction_OnComplete)(void* context, ASurfaceTransactionStats* stats) __INTRODUCED_IN(29); /** * Returns the timestamp of when the frame was latched by the framework. Once a frame is * latched by the framework, it is presented at the following hardware vsync. */ int64_t ASurfaceTransactionStats_getLatchTime(ASurfaceTransactionStats* surface_transaction_stats) __INTRODUCED_IN(29); /** * Returns a sync fence that signals when the transaction has been presented. * The recipient of the callback takes ownership of the fence and is responsible for closing * it. */ int ASurfaceTransactionStats_getPresentFenceFd(ASurfaceTransactionStats* surface_transaction_stats) __INTRODUCED_IN(29); /** * |outASurfaceControls| returns an array of ASurfaceControl pointers that were updated during the * transaction. Stats for the surfaces can be queried through ASurfaceTransactionStats functions. * When the client is done using the array, it must release it by calling * ASurfaceTransactionStats_releaseASurfaceControls. * * |outASurfaceControlsSize| returns the size of the ASurfaceControls array. */ void ASurfaceTransactionStats_getASurfaceControls(ASurfaceTransactionStats* surface_transaction_stats, ASurfaceControl*** outASurfaceControls, size_t* outASurfaceControlsSize) __INTRODUCED_IN(29); /** * Releases the array of ASurfaceControls that were returned by * ASurfaceTransactionStats_getASurfaceControls. */ void ASurfaceTransactionStats_releaseASurfaceControls(ASurfaceControl** surface_controls) __INTRODUCED_IN(29); /** * Returns the timestamp of when the CURRENT buffer was acquired. A buffer is considered * acquired when its acquire_fence_fd has signaled. A buffer cannot be latched or presented until * it is acquired. If no acquire_fence_fd was provided, this timestamp will be set to -1. */ int64_t ASurfaceTransactionStats_getAcquireTime(ASurfaceTransactionStats* surface_transaction_stats, ASurfaceControl* surface_control) __INTRODUCED_IN(29); /** * The returns the fence used to signal the release of the PREVIOUS buffer set on * this surface. If this fence is valid (>=0), the PREVIOUS buffer has not yet been released and the * fence will signal when the PREVIOUS buffer has been released. If the fence is -1 , the PREVIOUS * buffer is already released. The recipient of the callback takes ownership of the * previousReleaseFenceFd and is responsible for closing it. * * Each time a buffer is set through ASurfaceTransaction_setBuffer()/_setCachedBuffer() on a * transaction which is applied, the framework takes a ref on this buffer. The framework treats the * addition of a buffer to a particular surface as a unique ref. When a transaction updates or * removes a buffer from a surface, or removes the surface itself from the tree, this ref is * guaranteed to be released in the OnComplete callback for this transaction. The * ASurfaceControlStats provided in the callback for this surface may contain an optional fence * which must be signaled before the ref is assumed to be released. * * The client must ensure that all pending refs on a buffer are released before attempting to reuse * this buffer, otherwise synchronization errors may occur. */ int ASurfaceTransactionStats_getPreviousReleaseFenceFd( ASurfaceTransactionStats* surface_transaction_stats, ASurfaceControl* surface_control) __INTRODUCED_IN(29); /** * Sets the callback that will be invoked when the updates from this transaction Loading @@ -121,6 +193,16 @@ typedef void (*ASurfaceTransaction_OnComplete)(void* context, int32_t present_fe void ASurfaceTransaction_setOnComplete(ASurfaceTransaction* transaction, void* context, ASurfaceTransaction_OnComplete func) __INTRODUCED_IN(29); /** * Reparents the |surface_control| from its old parent to the |new_parent| surface control. * Any children of the* reparented |surface_control| will remain children of the |surface_control|. * * The |new_parent| can be null. Surface controls with a null parent do not appear on the display. */ void ASurfaceTransaction_reparent(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, ASurfaceControl* new_parent) __INTRODUCED_IN(29); /* Parameter for ASurfaceTransaction_setVisibility */ enum { ASURFACE_TRANSACTION_VISIBILITY_HIDE = 0, Loading Loading @@ -148,15 +230,15 @@ void ASurfaceTransaction_setZOrder(ASurfaceTransaction* transaction, /** * Updates the AHardwareBuffer displayed for |surface_control|. If not -1, the * fence_fd should be a file descriptor that is signaled when all pending work * acquire_fence_fd should be a file descriptor that is signaled when all pending work * for the buffer is complete and the buffer can be safely read. * * The frameworks takes ownership of the |fence_fd| passed and is responsible * The frameworks takes ownership of the |acquire_fence_fd| passed and is responsible * for closing it. */ void ASurfaceTransaction_setBuffer(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, AHardwareBuffer* buffer, int fence_fd = -1) __INTRODUCED_IN(29); int acquire_fence_fd = -1) __INTRODUCED_IN(29); /** * |source| the sub-rect within the buffer's content to be rendered inside the surface's area Loading Loading @@ -189,7 +271,8 @@ enum { * opaque or visual errors can occur. */ void ASurfaceTransaction_setBufferTransparency(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, int8_t transparency) ASurfaceControl* surface_control, int8_t transparency) __INTRODUCED_IN(29); /** Loading @@ -200,6 +283,50 @@ void ASurfaceTransaction_setDamageRegion(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, const ARect rects[], uint32_t count) __INTRODUCED_IN(29); /** * Specifies a desiredPresentTime for the transaction. The framework will try to present * the transaction at or after the time specified. * * Transactions will not be presented until all of their acquire fences have signaled even if the * app requests an earlier present time. * * If an earlier transaction has a desired present time of x, and a later transaction has a desired * present time that is before x, the later transaction will not preempt the earlier transaction. */ void ASurfaceTransaction_setDesiredPresentTime(ASurfaceTransaction* transaction, int64_t desiredPresentTime) __INTRODUCED_IN(29); /** * Sets the alpha for the buffer. It uses a premultiplied blending. * * The |alpha| must be between 0.0 and 1.0. */ void ASurfaceTransaction_setBufferAlpha(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, float alpha) __INTRODUCED_IN(29); /* * SMPTE ST 2086 "Mastering Display Color Volume" static metadata * * When |metadata| is set to null, the framework does not use any smpte2086 metadata when rendering * the surface's buffer. */ void ASurfaceTransaction_setHdrMetadata_smpte2086(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, struct AHdrMetadata_smpte2086* metadata) __INTRODUCED_IN(29); /* * Sets the CTA 861.3 "HDR Static Metadata Extension" static metadata on a surface. * * When |metadata| is set to null, the framework does not use any cta861.3 metadata when rendering * the surface's buffer. */ void ASurfaceTransaction_setHdrMetadata_cta861_3(ASurfaceTransaction* transaction, ASurfaceControl* surface_control, struct AHdrMetadata_cta861_3* metadata) __INTRODUCED_IN(29); #endif // __ANDROID_API__ >= 29 __END_DECLS Loading
libs/gui/SurfaceComposerClient.cpp +65 −8 Original line number Diff line number Diff line Loading @@ -132,26 +132,76 @@ void TransactionCompletedListener::startListeningLocked() { mListening = true; } CallbackId TransactionCompletedListener::addCallback(const TransactionCompletedCallback& callback) { CallbackId TransactionCompletedListener::addCallbackFunction( const TransactionCompletedCallback& callbackFunction, const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>& surfaceControls) { std::lock_guard<std::mutex> lock(mMutex); startListeningLocked(); CallbackId callbackId = getNextIdLocked(); mCallbacks.emplace(callbackId, callback); mCallbacks[callbackId].callbackFunction = callbackFunction; auto& callbackSurfaceControls = mCallbacks[callbackId].surfaceControls; for (const auto& surfaceControl : surfaceControls) { callbackSurfaceControls[surfaceControl->getHandle()] = surfaceControl; } return callbackId; } void TransactionCompletedListener::addSurfaceControlToCallbacks( const sp<SurfaceControl>& surfaceControl, const std::unordered_set<CallbackId>& callbackIds) { std::lock_guard<std::mutex> lock(mMutex); for (auto callbackId : callbackIds) { mCallbacks[callbackId].surfaceControls.emplace(std::piecewise_construct, std::forward_as_tuple( surfaceControl->getHandle()), std::forward_as_tuple(surfaceControl)); } } void TransactionCompletedListener::onTransactionCompleted(ListenerStats listenerStats) { std::lock_guard lock(mMutex); /* This listener knows all the sp<IBinder> to sp<SurfaceControl> for all its registered * callbackIds, except for when Transactions are merged together. This probably cannot be * solved before this point because the Transactions could be merged together and applied in a * different process. * * Fortunately, we get all the callbacks for this listener for the same frame together at the * same time. This means if any Transactions were merged together, we will get their callbacks * at the same time. We can combine all the sp<IBinder> to sp<SurfaceControl> maps for all the * callbackIds to generate one super map that contains all the sp<IBinder> to sp<SurfaceControl> * that could possibly exist for the callbacks. */ std::unordered_map<sp<IBinder>, sp<SurfaceControl>, IBinderHash> surfaceControls; for (const auto& [callbackIds, transactionStats] : listenerStats.transactionStats) { for (auto callbackId : callbackIds) { auto& [callbackFunction, callbackSurfaceControls] = mCallbacks[callbackId]; surfaceControls.insert(callbackSurfaceControls.begin(), callbackSurfaceControls.end()); } } for (const auto& [callbackIds, transactionStats] : listenerStats.transactionStats) { for (auto callbackId : callbackIds) { const auto& callback = mCallbacks[callbackId]; if (!callback) { auto& [callbackFunction, callbackSurfaceControls] = mCallbacks[callbackId]; if (!callbackFunction) { ALOGE("cannot call null callback function, skipping"); continue; } callback(transactionStats); std::vector<SurfaceControlStats> surfaceControlStats; for (const auto& surfaceStats : transactionStats.surfaceStats) { surfaceControlStats.emplace_back(surfaceControls[surfaceStats.surfaceControl], surfaceStats.acquireTime, surfaceStats.previousReleaseFence); } callbackFunction(transactionStats.latchTime, transactionStats.presentFence, surfaceControlStats); mCallbacks.erase(callbackId); } } Loading Loading @@ -329,7 +379,11 @@ layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<Surfac void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback( const sp<SurfaceControl>& sc) { mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls.insert(sc); auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()]; callbackInfo.surfaceControls.insert(sc); TransactionCompletedListener::getInstance() ->addSurfaceControlToCallbacks(sc, callbackInfo.callbackIds); } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( Loading Loading @@ -770,9 +824,12 @@ SurfaceComposerClient::Transaction::addTransactionCompletedCallback( TransactionCompletedCallbackTakesContext callback, void* callbackContext) { auto listener = TransactionCompletedListener::getInstance(); auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1); auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); const auto& surfaceControls = mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls; CallbackId callbackId = listener->addCallback(callbackWithContext); CallbackId callbackId = listener->addCallbackFunction(callbackWithContext, surfaceControls); mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace( callbackId); Loading
libs/gui/include/gui/SurfaceComposerClient.h +60 −27 Original line number Diff line number Diff line Loading @@ -53,35 +53,24 @@ class Region; // --------------------------------------------------------------------------- using TransactionCompletedCallbackTakesContext = std::function<void(void* /*context*/, const TransactionStats&)>; using TransactionCompletedCallback = std::function<void(const TransactionStats&)>; class TransactionCompletedListener : public BnTransactionCompletedListener { TransactionCompletedListener(); CallbackId getNextIdLocked() REQUIRES(mMutex); std::mutex mMutex; bool mListening GUARDED_BY(mMutex) = false; CallbackId mCallbackIdCounter GUARDED_BY(mMutex) = 1; std::map<CallbackId, TransactionCompletedCallback> mCallbacks GUARDED_BY(mMutex); public: static sp<TransactionCompletedListener> getInstance(); static sp<ITransactionCompletedListener> getIInstance(); void startListeningLocked() REQUIRES(mMutex); CallbackId addCallback(const TransactionCompletedCallback& callback); // Overrides BnTransactionCompletedListener's onTransactionCompleted void onTransactionCompleted(ListenerStats stats) override; struct SurfaceControlStats { SurfaceControlStats(const sp<SurfaceControl>& sc, nsecs_t time, const sp<Fence>& prevReleaseFence) : surfaceControl(sc), acquireTime(time), previousReleaseFence(prevReleaseFence) {} sp<SurfaceControl> surfaceControl; nsecs_t acquireTime = -1; sp<Fence> previousReleaseFence; }; using TransactionCompletedCallbackTakesContext = std::function<void(void* /*context*/, nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const std::vector<SurfaceControlStats>& /*stats*/)>; using TransactionCompletedCallback = std::function<void(nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/, const std::vector<SurfaceControlStats>& /*stats*/)>; // --------------------------------------------------------------------------- class SurfaceComposerClient : public RefBase Loading Loading @@ -465,6 +454,50 @@ public: // --------------------------------------------------------------------------- class TransactionCompletedListener : public BnTransactionCompletedListener { TransactionCompletedListener(); CallbackId getNextIdLocked() REQUIRES(mMutex); std::mutex mMutex; bool mListening GUARDED_BY(mMutex) = false; CallbackId mCallbackIdCounter GUARDED_BY(mMutex) = 1; struct IBinderHash { std::size_t operator()(const sp<IBinder>& iBinder) const { return std::hash<IBinder*>{}(iBinder.get()); } }; struct CallbackTranslation { TransactionCompletedCallback callbackFunction; std::unordered_map<sp<IBinder>, sp<SurfaceControl>, IBinderHash> surfaceControls; }; std::unordered_map<CallbackId, CallbackTranslation> mCallbacks GUARDED_BY(mMutex); public: static sp<TransactionCompletedListener> getInstance(); static sp<ITransactionCompletedListener> getIInstance(); void startListeningLocked() REQUIRES(mMutex); CallbackId addCallbackFunction( const TransactionCompletedCallback& callbackFunction, const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>& surfaceControls); void addSurfaceControlToCallbacks(const sp<SurfaceControl>& surfaceControl, const std::unordered_set<CallbackId>& callbackIds); // Overrides BnTransactionCompletedListener's onTransactionCompleted void onTransactionCompleted(ListenerStats stats) override; }; // --------------------------------------------------------------------------- }; // namespace android #endif // ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H
libs/nativewindow/include/android/hdr_metadata.h 0 → 100644 +65 −0 Original line number Diff line number Diff line /* * Copyright 2019 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. */ /** * @file hdr_metadata.h */ #ifndef ANDROID_HDR_METADATA_H #define ANDROID_HDR_METADATA_H #include <inttypes.h> #include <sys/cdefs.h> __BEGIN_DECLS /** * These structures are used to define the display's capabilities for HDR content. * They can be used to better tone map content to user's display. */ /** * Color is defined in CIE XYZ coordinates. */ struct AColor_xy { float x; float y; }; /** * SMPTE ST 2086 "Mastering Display Color Volume" static metadata */ struct AHdrMetadata_smpte2086 { struct AColor_xy displayPrimaryRed; struct AColor_xy displayPrimaryGreen; struct AColor_xy displayPrimaryBlue; struct AColor_xy whitePoint; float maxLuminance; float minLuminance; }; /** * CTA 861.3 "HDR Static Metadata Extension" static metadata */ struct AHdrMetadata_cta861_3 { float maxContentLightLevel; float maxFrameAverageLightLevel; }; __END_DECLS #endif // ANDROID_HDR_METADATA_H
services/surfaceflinger/tests/Transaction_test.cpp +39 −25 File changed.Preview size limit exceeded, changes collapsed. Show changes