ASurfaceControl: add more support to NDK (2/2)
Adds several new functions and updates existing functions.
- release fences
- desired present time
- alpha
- hdr metadata
Test: atest CtsViewTestCases:android.view.cts.ASurfaceControlTest
Bug: 80477568
Change-Id: I6f6c4c6e295530cdb9e86b308483818062149cc1
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 35659e9..1ed8a0d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -132,26 +132,76 @@
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) {
- const auto& callback = mCallbacks[callbackId];
- if (!callback) {
+ auto& [callbackFunction, callbackSurfaceControls] = mCallbacks[callbackId];
+ surfaceControls.insert(callbackSurfaceControls.begin(), callbackSurfaceControls.end());
+ }
+ }
+
+ for (const auto& [callbackIds, transactionStats] : listenerStats.transactionStats) {
+ for (auto callbackId : callbackIds) {
+ 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);
}
}
@@ -329,7 +379,11 @@
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(
@@ -770,9 +824,12 @@
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);
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 78515d0..29b467f 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -53,35 +53,24 @@
// ---------------------------------------------------------------------------
-using TransactionCompletedCallbackTakesContext =
- std::function<void(void* /*context*/, const TransactionStats&)>;
-using TransactionCompletedCallback = std::function<void(const TransactionStats&)>;
+struct SurfaceControlStats {
+ SurfaceControlStats(const sp<SurfaceControl>& sc, nsecs_t time,
+ const sp<Fence>& prevReleaseFence)
+ : surfaceControl(sc), acquireTime(time), previousReleaseFence(prevReleaseFence) {}
-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;
+ 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
@@ -459,6 +448,50 @@
// ---------------------------------------------------------------------------
+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
diff --git a/libs/nativewindow/include/android/hdr_metadata.h b/libs/nativewindow/include/android/hdr_metadata.h
new file mode 100644
index 0000000..7e1313b
--- /dev/null
+++ b/libs/nativewindow/include/android/hdr_metadata.h
@@ -0,0 +1,65 @@
+/*
+ * 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