summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/binder/Android.bp9
-rw-r--r--libs/binder/rust/rpcbinder/src/lib.rs2
-rw-r--r--libs/binder/rust/rpcbinder/src/server/trusty.rs4
-rw-r--r--libs/binder/rust/src/binder.rs6
-rw-r--r--libs/gui/BLASTBufferQueue.cpp6
-rw-r--r--libs/gui/BufferQueueProducer.cpp6
-rw-r--r--libs/gui/ISurfaceComposer.cpp121
-rw-r--r--libs/gui/SurfaceComposerClient.cpp336
-rw-r--r--libs/gui/aidl/android/gui/StaticDisplayInfo.aidl1
-rw-r--r--libs/gui/include/gui/BLASTBufferQueue.h2
-rw-r--r--libs/gui/include/gui/ISurfaceComposer.h9
-rw-r--r--libs/gui/include/gui/InputTransferToken.h10
-rw-r--r--libs/gui/include/gui/SurfaceComposerClient.h66
-rw-r--r--libs/gui/include/gui/TransactionState.h6
-rw-r--r--libs/gui/libgui_flags.aconfig14
-rw-r--r--libs/gui/tests/EndToEndNativeInputTest.cpp8
-rw-r--r--libs/gui/tests/Surface_test.cpp57
-rw-r--r--libs/renderengine/Android.bp6
-rw-r--r--libs/renderengine/benchmark/Android.bp2
-rw-r--r--libs/renderengine/skia/SkiaRenderEngine.cpp10
-rw-r--r--libs/renderengine/skia/filters/LutShader.cpp7
-rw-r--r--libs/ui/Android.bp1
-rw-r--r--libs/ui/DependencyMonitor.cpp144
-rw-r--r--libs/ui/FenceTime.cpp13
-rw-r--r--libs/ui/GraphicBuffer.cpp14
-rw-r--r--libs/ui/include/ui/DependencyMonitor.h104
-rw-r--r--libs/ui/include/ui/DisplayId.h81
-rw-r--r--libs/ui/include/ui/FenceTime.h11
-rw-r--r--libs/ui/include/ui/GraphicBuffer.h5
-rw-r--r--libs/ui/include/ui/StaticDisplayInfo.h1
-rw-r--r--libs/ui/tests/Android.bp10
-rw-r--r--libs/ui/tests/DisplayId_test.cpp101
-rw-r--r--services/inputflinger/dispatcher/InputDispatcher.cpp6
-rw-r--r--services/stats/Android.bp32
-rw-r--r--services/stats/StatsAidl.cpp7
-rw-r--r--services/stats/StatsHal.cpp51
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h6
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h2
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h1
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h6
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h1
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h1
-rw-r--r--services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h1
-rw-r--r--services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp4
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Display.cpp63
-rw-r--r--services/surfaceflinger/CompositionEngine/src/Output.cpp15
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp73
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp6
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp48
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp16
-rw-r--r--services/surfaceflinger/DisplayDevice.h45
-rw-r--r--services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp1
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp53
-rw-r--r--services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h6
-rw-r--r--services/surfaceflinger/Layer.cpp10
-rw-r--r--services/surfaceflinger/Layer.h1
-rw-r--r--services/surfaceflinger/LayerFE.cpp13
-rw-r--r--services/surfaceflinger/LayerFE.h3
-rw-r--r--services/surfaceflinger/LayerVector.h3
-rw-r--r--services/surfaceflinger/PowerAdvisor/SessionManager.h5
-rw-r--r--services/surfaceflinger/QueuedTransactionState.h42
-rw-r--r--services/surfaceflinger/RegionSamplingThread.cpp2
-rw-r--r--services/surfaceflinger/Scheduler/Scheduler.cpp3
-rw-r--r--services/surfaceflinger/Scheduler/include/scheduler/interface/CompositionCoverage.h2
-rw-r--r--services/surfaceflinger/ScreenCaptureOutput.cpp24
-rw-r--r--services/surfaceflinger/ScreenCaptureOutput.h6
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp328
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h42
-rw-r--r--services/surfaceflinger/Tracing/TransactionProtoParser.cpp2
-rw-r--r--services/surfaceflinger/TransactionCallbackInvoker.cpp12
-rw-r--r--services/surfaceflinger/TransactionCallbackInvoker.h2
-rw-r--r--services/surfaceflinger/common/FlagManager.cpp4
-rw-r--r--services/surfaceflinger/common/include/common/FlagManager.h2
-rw-r--r--services/surfaceflinger/surfaceflinger_flags_new.aconfig7
-rw-r--r--services/surfaceflinger/tests/DereferenceSurfaceControl_test.cpp6
-rw-r--r--services/surfaceflinger/tests/IPC_test.cpp10
-rw-r--r--services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h26
-rw-r--r--services/surfaceflinger/tests/unittests/DualDisplayTransactionTest.h6
-rw-r--r--services/surfaceflinger/tests/unittests/FlagManagerTest.cpp4
-rw-r--r--services/surfaceflinger/tests/unittests/SchedulerTest.cpp24
-rw-r--r--services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp4
-rw-r--r--services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp45
-rw-r--r--services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp2
-rw-r--r--services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp20
-rw-r--r--services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp29
-rw-r--r--services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPhysicalDisplayPowerModeTest.cpp44
-rw-r--r--services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp4
-rw-r--r--services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h45
-rw-r--r--services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp116
-rw-r--r--services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp2
-rw-r--r--vulkan/vkjson/vkjson.cc2017
-rw-r--r--vulkan/vkjson/vkjson.h279
-rw-r--r--vulkan/vkjson/vkjson_instance.cc271
93 files changed, 3152 insertions, 1932 deletions
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index ea5343a2a0..a3499c1963 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -277,15 +277,6 @@ cc_defaults {
"-fvisibility=hidden",
"-DBUILDING_LIBBINDER",
],
-
- target: {
- vendor: {
- // Trimming the exported symbols reveals a bug in vendor code, so
- // disable it for the vendor variant for now. http://b/349657329
- // TODO: Fix the issue and remove this override.
- cflags: ["-fvisibility=default"],
- },
- },
}
cc_defaults {
diff --git a/libs/binder/rust/rpcbinder/src/lib.rs b/libs/binder/rust/rpcbinder/src/lib.rs
index 7e5c9ddc35..774bb21efe 100644
--- a/libs/binder/rust/rpcbinder/src/lib.rs
+++ b/libs/binder/rust/rpcbinder/src/lib.rs
@@ -20,6 +20,8 @@ mod server;
mod session;
pub use server::RpcServer;
+#[cfg(target_os = "trusty")]
+pub use server::RpcServerConnection;
#[cfg(not(target_os = "trusty"))]
pub use server::RpcServerRef;
pub use session::{FileDescriptorTransportMode, RpcSession, RpcSessionRef};
diff --git a/libs/binder/rust/rpcbinder/src/server/trusty.rs b/libs/binder/rust/rpcbinder/src/server/trusty.rs
index fe45decf25..54d82d5bd0 100644
--- a/libs/binder/rust/rpcbinder/src/server/trusty.rs
+++ b/libs/binder/rust/rpcbinder/src/server/trusty.rs
@@ -106,6 +106,10 @@ pub struct RpcServerConnection {
ctx: *mut c_void,
}
+// SAFETY: The opaque handle: `ctx` points into a dynamic allocation,
+// and not tied to anything specific to the current thread.
+unsafe impl Send for RpcServerConnection {}
+
impl Drop for RpcServerConnection {
fn drop(&mut self) {
// We do not need to close handle_fd since we do not own it.
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 6a8a69843a..771c65bf92 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -1160,6 +1160,12 @@ macro_rules! declare_binder_enum {
pub const fn enum_values() -> [Self; $size] {
[$(Self::$name),*]
}
+
+ #[inline(always)]
+ #[allow(missing_docs)]
+ pub const fn get(&self) -> $backing {
+ self.0
+ }
}
impl std::fmt::Debug for $enum {
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 1aae13c1f4..5b0f21de91 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -1032,7 +1032,7 @@ void BLASTBufferQueue::mergeWithNextTransaction(SurfaceComposerClient::Transacti
// Apply the transaction since we have already acquired the desired frame.
t->setApplyToken(mApplyToken).apply();
} else {
- mPendingTransactions.emplace_back(frameNumber, *t);
+ mPendingTransactions.emplace_back(frameNumber, std::move(*t));
// Clear the transaction so it can't be applied elsewhere.
t->clear();
}
@@ -1050,8 +1050,8 @@ void BLASTBufferQueue::applyPendingTransactions(uint64_t frameNumber) {
void BLASTBufferQueue::mergePendingTransactions(SurfaceComposerClient::Transaction* t,
uint64_t frameNumber) {
auto mergeTransaction =
- [&t, currentFrameNumber = frameNumber](
- std::tuple<uint64_t, SurfaceComposerClient::Transaction> pendingTransaction) {
+ [t, currentFrameNumber = frameNumber](
+ std::pair<uint64_t, SurfaceComposerClient::Transaction>& pendingTransaction) {
auto& [targetFrameNumber, transaction] = pendingTransaction;
if (currentFrameNumber < targetFrameNumber) {
return false;
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 5961b41478..bcf61e45de 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -364,8 +364,10 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller,
// Producers are not allowed to dequeue more than
// mMaxDequeuedBufferCount buffers.
// This check is only done if a buffer has already been queued
- if (mCore->mBufferHasBeenQueued &&
- dequeuedCount >= mCore->mMaxDequeuedBufferCount) {
+ using namespace com::android::graphics::libgui::flags;
+ bool flagGatedBufferHasBeenQueued =
+ bq_always_use_max_dequeued_buffer_count() || mCore->mBufferHasBeenQueued;
+ if (flagGatedBufferHasBeenQueued && dequeuedCount >= mCore->mMaxDequeuedBufferCount) {
// Supress error logs when timeout is non-negative.
if (mDequeueTimeout < 0) {
BQ_LOGE("%s: attempting to exceed the max dequeued buffer "
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 269936858a..ae4b74e03b 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -26,6 +26,7 @@
#include <gui/ISurfaceComposer.h>
#include <gui/LayerState.h>
#include <gui/SchedulingPolicy.h>
+#include <gui/TransactionState.h>
#include <private/gui/ParcelUtils.h>
#include <stdint.h>
#include <sys/types.h>
@@ -60,54 +61,12 @@ public:
virtual ~BpSurfaceComposer();
- status_t setTransactionState(
- const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state,
- Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
- InputWindowCommands commands, int64_t desiredPresentTime, bool isAutoTimestamp,
- const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks,
- const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId,
- const std::vector<uint64_t>& mergedTransactionIds) override {
+ status_t setTransactionState(TransactionState&& state) override {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+ SAFE_PARCEL(state.writeToParcel, &data);
- frameTimelineInfo.writeToParcel(&data);
-
- SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(state.size()));
- for (const auto& s : state) {
- SAFE_PARCEL(s.write, data);
- }
-
- SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(displays.size()));
- for (const auto& d : displays) {
- SAFE_PARCEL(d.write, data);
- }
-
- SAFE_PARCEL(data.writeUint32, flags);
- SAFE_PARCEL(data.writeStrongBinder, applyToken);
- SAFE_PARCEL(commands.write, data);
- SAFE_PARCEL(data.writeInt64, desiredPresentTime);
- SAFE_PARCEL(data.writeBool, isAutoTimestamp);
- SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(uncacheBuffers.size()));
- for (const client_cache_t& uncacheBuffer : uncacheBuffers) {
- SAFE_PARCEL(data.writeStrongBinder, uncacheBuffer.token.promote());
- SAFE_PARCEL(data.writeUint64, uncacheBuffer.id);
- }
- SAFE_PARCEL(data.writeBool, hasListenerCallbacks);
-
- SAFE_PARCEL(data.writeVectorSize, listenerCallbacks);
- for (const auto& [listener, callbackIds] : listenerCallbacks) {
- SAFE_PARCEL(data.writeStrongBinder, listener);
- SAFE_PARCEL(data.writeParcelableVector, callbackIds);
- }
-
- SAFE_PARCEL(data.writeUint64, transactionId);
-
- SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(mergedTransactionIds.size()));
- for (auto mergedTransactionId : mergedTransactionIds) {
- SAFE_PARCEL(data.writeUint64, mergedTransactionId);
- }
-
- if (flags & ISurfaceComposer::eOneWay) {
+ if (state.mFlags & ISurfaceComposer::eOneWay) {
return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE,
data, &reply, IBinder::FLAG_ONEWAY);
} else {
@@ -132,75 +91,9 @@ status_t BnSurfaceComposer::onTransact(
case SET_TRANSACTION_STATE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- FrameTimelineInfo frameTimelineInfo;
- frameTimelineInfo.readFromParcel(&data);
-
- uint32_t count = 0;
- SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
- Vector<ComposerState> state;
- state.setCapacity(count);
- for (size_t i = 0; i < count; i++) {
- ComposerState s;
- SAFE_PARCEL(s.read, data);
- state.add(s);
- }
-
- SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
- DisplayState d;
- Vector<DisplayState> displays;
- displays.setCapacity(count);
- for (size_t i = 0; i < count; i++) {
- SAFE_PARCEL(d.read, data);
- displays.add(d);
- }
-
- uint32_t stateFlags = 0;
- SAFE_PARCEL(data.readUint32, &stateFlags);
- sp<IBinder> applyToken;
- SAFE_PARCEL(data.readStrongBinder, &applyToken);
- InputWindowCommands inputWindowCommands;
- SAFE_PARCEL(inputWindowCommands.read, data);
-
- int64_t desiredPresentTime = 0;
- bool isAutoTimestamp = true;
- SAFE_PARCEL(data.readInt64, &desiredPresentTime);
- SAFE_PARCEL(data.readBool, &isAutoTimestamp);
-
- SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
- std::vector<client_cache_t> uncacheBuffers(count);
- sp<IBinder> tmpBinder;
- for (size_t i = 0; i < count; i++) {
- SAFE_PARCEL(data.readNullableStrongBinder, &tmpBinder);
- uncacheBuffers[i].token = tmpBinder;
- SAFE_PARCEL(data.readUint64, &uncacheBuffers[i].id);
- }
-
- bool hasListenerCallbacks = false;
- SAFE_PARCEL(data.readBool, &hasListenerCallbacks);
-
- std::vector<ListenerCallbacks> listenerCallbacks;
- int32_t listenersSize = 0;
- SAFE_PARCEL_READ_SIZE(data.readInt32, &listenersSize, data.dataSize());
- for (int32_t i = 0; i < listenersSize; i++) {
- SAFE_PARCEL(data.readStrongBinder, &tmpBinder);
- std::vector<CallbackId> callbackIds;
- SAFE_PARCEL(data.readParcelableVector, &callbackIds);
- listenerCallbacks.emplace_back(tmpBinder, callbackIds);
- }
-
- uint64_t transactionId = -1;
- SAFE_PARCEL(data.readUint64, &transactionId);
-
- SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
- std::vector<uint64_t> mergedTransactions(count);
- for (size_t i = 0; i < count; i++) {
- SAFE_PARCEL(data.readUint64, &mergedTransactions[i]);
- }
-
- return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken,
- std::move(inputWindowCommands), desiredPresentTime,
- isAutoTimestamp, uncacheBuffers, hasListenerCallbacks,
- listenerCallbacks, transactionId, mergedTransactions);
+ TransactionState state;
+ SAFE_PARCEL(state.readFromParcel, &data);
+ return setTransactionState(std::move(state));
}
case GET_SCHEDULING_POLICY: {
gui::SchedulingPolicy policy;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index e407a63d10..69ba1d731d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -824,34 +824,24 @@ void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId) {
// ---------------------------------------------------------------------------
SurfaceComposerClient::Transaction::Transaction() {
- mId = generateId();
+ mState.mId = generateId();
mTransactionCompletedListener = TransactionCompletedListener::getInstance();
}
-SurfaceComposerClient::Transaction::Transaction(const Transaction& other)
- : mId(other.mId),
- mFlags(other.mFlags),
- mMayContainBuffer(other.mMayContainBuffer),
- mDesiredPresentTime(other.mDesiredPresentTime),
- mIsAutoTimestamp(other.mIsAutoTimestamp),
- mFrameTimelineInfo(other.mFrameTimelineInfo),
- mApplyToken(other.mApplyToken) {
- mDisplayStates = other.mDisplayStates;
- mComposerStates = other.mComposerStates;
- mInputWindowCommands = other.mInputWindowCommands;
- mListenerCallbacks = other.mListenerCallbacks;
- mTransactionCompletedListener = TransactionCompletedListener::getInstance();
-}
+SurfaceComposerClient::Transaction::Transaction(Transaction&& other)
+ : mTransactionCompletedListener(TransactionCompletedListener::getInstance()),
+ mState(std::move(other.mState)),
+ mListenerCallbacks(std::move(other.mListenerCallbacks)) {}
void SurfaceComposerClient::Transaction::sanitize(int pid, int uid) {
uint32_t permissions = LayerStatePermissions::getTransactionPermissions(pid, uid);
- for (auto& composerState : mComposerStates) {
+ for (auto& composerState : mState.mComposerStates) {
composerState.state.sanitize(permissions);
}
- if (!mInputWindowCommands.empty() &&
+ if (!mState.mInputWindowCommands.empty() &&
(permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) {
ALOGE("Only privileged callers are allowed to send input commands.");
- mInputWindowCommands.clear();
+ mState.mInputWindowCommands.clear();
}
}
@@ -866,31 +856,10 @@ SurfaceComposerClient::Transaction::createFromParcel(const Parcel* parcel) {
status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel) {
- const uint64_t transactionId = parcel->readUint64();
- const uint32_t flags = parcel->readUint32();
- const int64_t desiredPresentTime = parcel->readInt64();
- const bool isAutoTimestamp = parcel->readBool();
- const bool logCallPoints = parcel->readBool();
- FrameTimelineInfo frameTimelineInfo;
- frameTimelineInfo.readFromParcel(parcel);
-
- sp<IBinder> applyToken;
- parcel->readNullableStrongBinder(&applyToken);
- size_t count = static_cast<size_t>(parcel->readUint32());
- if (count > parcel->dataSize()) {
- return BAD_VALUE;
- }
- Vector<DisplayState> displayStates;
- displayStates.setCapacity(count);
- for (size_t i = 0; i < count; i++) {
- DisplayState displayState;
- if (displayState.read(*parcel) == BAD_VALUE) {
- return BAD_VALUE;
- }
- displayStates.add(displayState);
- }
+ TransactionState tmpState;
+ SAFE_PARCEL(tmpState.readFromParcel, parcel);
- count = static_cast<size_t>(parcel->readUint32());
+ size_t count = static_cast<size_t>(parcel->readUint32());
if (count > parcel->dataSize()) {
return BAD_VALUE;
}
@@ -919,57 +888,8 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel
}
}
- count = static_cast<size_t>(parcel->readUint32());
- if (count > parcel->dataSize()) {
- return BAD_VALUE;
- }
- Vector<ComposerState> composerStates;
- composerStates.setCapacity(count);
- for (size_t i = 0; i < count; i++) {
- ComposerState composerState;
- if (composerState.read(*parcel) == BAD_VALUE) {
- return BAD_VALUE;
- }
- composerStates.add(composerState);
- }
-
- InputWindowCommands inputWindowCommands;
- inputWindowCommands.read(*parcel);
-
- count = static_cast<size_t>(parcel->readUint32());
- if (count > parcel->dataSize()) {
- return BAD_VALUE;
- }
- std::vector<client_cache_t> uncacheBuffers(count);
- for (size_t i = 0; i < count; i++) {
- sp<IBinder> tmpBinder;
- SAFE_PARCEL(parcel->readStrongBinder, &tmpBinder);
- uncacheBuffers[i].token = tmpBinder;
- SAFE_PARCEL(parcel->readUint64, &uncacheBuffers[i].id);
- }
-
- count = static_cast<size_t>(parcel->readUint32());
- if (count > parcel->dataSize()) {
- return BAD_VALUE;
- }
- std::vector<uint64_t> mergedTransactionIds(count);
- for (size_t i = 0; i < count; i++) {
- SAFE_PARCEL(parcel->readUint64, &mergedTransactionIds[i]);
- }
-
- // Parsing was successful. Update the object.
- mId = transactionId;
- mFlags = flags;
- mDesiredPresentTime = desiredPresentTime;
- mIsAutoTimestamp = isAutoTimestamp;
- mFrameTimelineInfo = frameTimelineInfo;
- mDisplayStates = std::move(displayStates);
- mListenerCallbacks = listenerCallbacks;
- mComposerStates = std::move(composerStates);
- mInputWindowCommands = inputWindowCommands;
- mApplyToken = applyToken;
- mUncacheBuffers = std::move(uncacheBuffers);
- mMergedTransactionIds = std::move(mergedTransactionIds);
+ mState = std::move(tmpState);
+ mListenerCallbacks = std::move(listenerCallbacks);
return NO_ERROR;
}
@@ -987,17 +907,7 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const
const_cast<SurfaceComposerClient::Transaction*>(this)->cacheBuffers();
- parcel->writeUint64(mId);
- parcel->writeUint32(mFlags);
- parcel->writeInt64(mDesiredPresentTime);
- parcel->writeBool(mIsAutoTimestamp);
- parcel->writeBool(mLogCallPoints);
- mFrameTimelineInfo.writeToParcel(parcel);
- parcel->writeStrongBinder(mApplyToken);
- parcel->writeUint32(static_cast<uint32_t>(mDisplayStates.size()));
- for (auto const& displayState : mDisplayStates) {
- displayState.write(*parcel);
- }
+ SAFE_PARCEL(mState.writeToParcel, parcel);
parcel->writeUint32(static_cast<uint32_t>(mListenerCallbacks.size()));
for (auto const& [listener, callbackInfo] : mListenerCallbacks) {
@@ -1012,24 +922,6 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const
}
}
- parcel->writeUint32(static_cast<uint32_t>(mComposerStates.size()));
- for (auto const& composerState : mComposerStates) {
- composerState.write(*parcel);
- }
-
- mInputWindowCommands.write(*parcel);
-
- SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mUncacheBuffers.size()));
- for (const client_cache_t& uncacheBuffer : mUncacheBuffers) {
- SAFE_PARCEL(parcel->writeStrongBinder, uncacheBuffer.token.promote());
- SAFE_PARCEL(parcel->writeUint64, uncacheBuffer.id);
- }
-
- SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mMergedTransactionIds.size()));
- for (auto mergedTransactionId : mMergedTransactionIds) {
- SAFE_PARCEL(parcel->writeUint64, mergedTransactionId);
- }
-
return NO_ERROR;
}
@@ -1054,50 +946,8 @@ void SurfaceComposerClient::Transaction::releaseBufferIfOverwriting(const layer_
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) {
- while (mMergedTransactionIds.size() + other.mMergedTransactionIds.size() >
- MAX_MERGE_HISTORY_LENGTH - 1 &&
- mMergedTransactionIds.size() > 0) {
- mMergedTransactionIds.pop_back();
- }
- if (other.mMergedTransactionIds.size() == MAX_MERGE_HISTORY_LENGTH) {
- mMergedTransactionIds.insert(mMergedTransactionIds.begin(),
- other.mMergedTransactionIds.begin(),
- other.mMergedTransactionIds.end() - 1);
- } else if (other.mMergedTransactionIds.size() > 0u) {
- mMergedTransactionIds.insert(mMergedTransactionIds.begin(),
- other.mMergedTransactionIds.begin(),
- other.mMergedTransactionIds.end());
- }
- mMergedTransactionIds.insert(mMergedTransactionIds.begin(), other.mId);
-
- for (auto const& otherState : other.mComposerStates) {
- if (auto it = std::find_if(mComposerStates.begin(), mComposerStates.end(),
- [&otherState](const auto& composerState) {
- return composerState.state.surface ==
- otherState.state.surface;
- });
- it != mComposerStates.end()) {
- if (otherState.state.what & layer_state_t::eBufferChanged) {
- releaseBufferIfOverwriting(it->state);
- }
- it->state.merge(otherState.state);
- } else {
- mComposerStates.add(otherState);
- }
- }
-
- for (auto const& state : other.mDisplayStates) {
- if (auto it = std::find_if(mDisplayStates.begin(), mDisplayStates.end(),
- [&state](const auto& displayState) {
- return displayState.token == state.token;
- });
- it != mDisplayStates.end()) {
- it->merge(state);
- } else {
- mDisplayStates.add(state);
- }
- }
-
+ mState.merge(std::move(other.mState),
+ std::bind(&Transaction::releaseBufferIfOverwriting, this, std::placeholders::_1));
for (const auto& [listener, callbackInfo] : other.mListenerCallbacks) {
auto& [callbackIds, surfaceControls] = callbackInfo;
mListenerCallbacks[listener].callbackIds.insert(std::make_move_iterator(
@@ -1121,50 +971,21 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr
}
}
- for (const auto& cacheId : other.mUncacheBuffers) {
- mUncacheBuffers.push_back(cacheId);
- }
-
- mInputWindowCommands.merge(other.mInputWindowCommands);
-
- mMayContainBuffer |= other.mMayContainBuffer;
- mFlags |= other.mFlags;
- mApplyToken = other.mApplyToken;
-
- mergeFrameTimelineInfo(mFrameTimelineInfo, other.mFrameTimelineInfo);
-
- mLogCallPoints |= other.mLogCallPoints;
- if (mLogCallPoints) {
- ALOG(LOG_DEBUG, LOG_SURFACE_CONTROL_REGISTRY,
- "Transaction %" PRIu64 " merged with transaction %" PRIu64, other.getId(), mId);
- }
-
other.clear();
return *this;
}
void SurfaceComposerClient::Transaction::clear() {
- mComposerStates.clear();
- mDisplayStates.clear();
+ mState.clear();
mListenerCallbacks.clear();
- mInputWindowCommands.clear();
- mUncacheBuffers.clear();
- mMayContainBuffer = false;
- mDesiredPresentTime = 0;
- mIsAutoTimestamp = true;
- mFrameTimelineInfo = {};
- mApplyToken = nullptr;
- mMergedTransactionIds.clear();
- mLogCallPoints = false;
- mFlags = 0;
}
-uint64_t SurfaceComposerClient::Transaction::getId() {
- return mId;
+uint64_t SurfaceComposerClient::Transaction::getId() const {
+ return mState.mId;
}
std::vector<uint64_t> SurfaceComposerClient::Transaction::getMergedTransactionIds() {
- return mMergedTransactionIds;
+ return mState.mMergedTransactionIds;
}
void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) {
@@ -1173,12 +994,13 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) {
client_cache_t uncacheBuffer;
uncacheBuffer.token = BufferCache::getInstance().getToken();
uncacheBuffer.id = cacheId;
- Vector<ComposerState> composerStates;
- Vector<DisplayState> displayStates;
- status_t status = sf->setTransactionState(FrameTimelineInfo{}, composerStates, displayStates,
- ISurfaceComposer::eOneWay,
- Transaction::getDefaultApplyToken(), {}, systemTime(),
- true, {uncacheBuffer}, false, {}, generateId(), {});
+ TransactionState state;
+ state.mId = generateId();
+ state.mApplyToken = Transaction::getDefaultApplyToken();
+ state.mUncacheBuffers.emplace_back(std::move(uncacheBuffer));
+ state.mFlags = ISurfaceComposer::eOneWay;
+ state.mDesiredPresentTime = systemTime();
+ status_t status = sf->setTransactionState(std::move(state));
if (status != NO_ERROR) {
ALOGE_AND_TRACE("SurfaceComposerClient::doUncacheBufferTransaction - %s",
strerror(-status));
@@ -1186,12 +1008,12 @@ void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) {
}
void SurfaceComposerClient::Transaction::cacheBuffers() {
- if (!mMayContainBuffer) {
+ if (!mState.mMayContainBuffer) {
return;
}
size_t count = 0;
- for (auto& cs : mComposerStates) {
+ for (auto& cs : mState.mComposerStates) {
layer_state_t* s = &cs.state;
if (!(s->what & layer_state_t::eBufferChanged)) {
continue;
@@ -1219,7 +1041,7 @@ void SurfaceComposerClient::Transaction::cacheBuffers() {
std::optional<client_cache_t> uncacheBuffer;
cacheId = BufferCache::getInstance().cache(s->bufferData->buffer, uncacheBuffer);
if (uncacheBuffer) {
- mUncacheBuffers.push_back(*uncacheBuffer);
+ mState.mUncacheBuffers.emplace_back(*uncacheBuffer);
}
}
s->bufferData->flags |= BufferData::BufferDataChange::cachedBufferChanged;
@@ -1288,8 +1110,7 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay
/*callbackContext=*/nullptr);
}
- bool hasListenerCallbacks = !mListenerCallbacks.empty();
- std::vector<ListenerCallbacks> listenerCallbacks;
+ mState.mHasListenerCallbacks = !mListenerCallbacks.empty();
// For every listener with registered callbacks
for (const auto& [listener, callbackInfo] : mListenerCallbacks) {
auto& [callbackIds, surfaceControls] = callbackInfo;
@@ -1298,7 +1119,8 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay
}
if (surfaceControls.empty()) {
- listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds));
+ mState.mListenerCallbacks.emplace_back(IInterface::asBinder(listener),
+ std::move(callbackIds));
} else {
// If the listener has any SurfaceControls set on this Transaction update the surface
// state
@@ -1310,7 +1132,7 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay
}
std::vector<CallbackId> callbacks(callbackIds.begin(), callbackIds.end());
s->what |= layer_state_t::eHasListenerCallbacksChanged;
- s->listeners.emplace_back(IInterface::asBinder(listener), callbacks);
+ s->listeners.emplace_back(IInterface::asBinder(listener), std::move(callbacks));
}
}
}
@@ -1322,25 +1144,21 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay
ALOGE("Transaction attempted to set synchronous and one way at the same time"
" this is an invalid request. Synchronous will win for safety");
} else {
- mFlags |= ISurfaceComposer::eOneWay;
+ mState.mFlags |= ISurfaceComposer::eOneWay;
}
}
// If both ISurfaceComposer::eEarlyWakeupStart and ISurfaceComposer::eEarlyWakeupEnd are set
// it is equivalent for none
uint32_t wakeupFlags = ISurfaceComposer::eEarlyWakeupStart | ISurfaceComposer::eEarlyWakeupEnd;
- if ((mFlags & wakeupFlags) == wakeupFlags) {
- mFlags &= ~(wakeupFlags);
+ if ((mState.mFlags & wakeupFlags) == wakeupFlags) {
+ mState.mFlags &= ~(wakeupFlags);
}
- sp<IBinder> applyToken = mApplyToken ? mApplyToken : getDefaultApplyToken();
+ if (!mState.mApplyToken) mState.mApplyToken = getDefaultApplyToken();
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- status_t binderStatus =
- sf->setTransactionState(mFrameTimelineInfo, mComposerStates, mDisplayStates, mFlags,
- applyToken, mInputWindowCommands, mDesiredPresentTime,
- mIsAutoTimestamp, mUncacheBuffers, hasListenerCallbacks,
- listenerCallbacks, mId, mMergedTransactionIds);
- mId = generateId();
+ status_t binderStatus = sf->setTransactionState(std::move(mState));
+ mState.mId = generateId();
// Clear the current states and flags
clear();
@@ -1349,8 +1167,8 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay
syncCallback->wait();
}
- if (mLogCallPoints) {
- ALOG(LOG_DEBUG, LOG_SURFACE_CONTROL_REGISTRY, "Transaction %" PRIu64 " applied", mId);
+ if (mState.mLogCallPoints) {
+ ALOG(LOG_DEBUG, LOG_SURFACE_CONTROL_REGISTRY, "Transaction %" PRIu64 " applied", getId());
}
mStatus = NO_ERROR;
@@ -1385,7 +1203,7 @@ status_t SurfaceComposerClient::Transaction::sendSurfaceFlushJankDataTransaction
}
void SurfaceComposerClient::Transaction::enableDebugLogCallPoints() {
- mLogCallPoints = true;
+ mState.mLogCallPoints = true;
}
// ---------------------------------------------------------------------------
@@ -1443,34 +1261,19 @@ std::optional<gui::StalledTransactionInfo> SurfaceComposerClient::getStalledTran
}
void SurfaceComposerClient::Transaction::setAnimationTransaction() {
- mFlags |= ISurfaceComposer::eAnimation;
+ mState.mFlags |= ISurfaceComposer::eAnimation;
}
void SurfaceComposerClient::Transaction::setEarlyWakeupStart() {
- mFlags |= ISurfaceComposer::eEarlyWakeupStart;
+ mState.mFlags |= ISurfaceComposer::eEarlyWakeupStart;
}
void SurfaceComposerClient::Transaction::setEarlyWakeupEnd() {
- mFlags |= ISurfaceComposer::eEarlyWakeupEnd;
+ mState.mFlags |= ISurfaceComposer::eEarlyWakeupEnd;
}
layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) {
- auto handle = sc->getLayerStateHandle();
- if (auto it = std::find_if(mComposerStates.begin(), mComposerStates.end(),
- [&handle](const auto& composerState) {
- return composerState.state.surface == handle;
- });
- it != mComposerStates.end()) {
- return &it->state;
- }
-
- // we don't have it, add an initialized layer_state to our list
- ComposerState s;
- s.state.surface = handle;
- s.state.layerId = sc->getLayerId();
- mComposerStates.add(s);
-
- return &mComposerStates.editItemAt(mComposerStates.size() - 1).state;
+ return mState.getLayerState(sc);
}
void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback(
@@ -1846,8 +1649,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe
setReleaseBufferCallback(bufferData.get(), callback);
}
- if (mIsAutoTimestamp) {
- mDesiredPresentTime = systemTime();
+ if (mState.mIsAutoTimestamp) {
+ mState.mDesiredPresentTime = systemTime();
}
s->what |= layer_state_t::eBufferChanged;
s->bufferData = std::move(bufferData);
@@ -1865,7 +1668,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe
const std::vector<SurfaceControlStats>&) {},
nullptr);
- mMayContainBuffer = true;
+ mState.mMayContainBuffer = true;
return *this;
}
@@ -2041,8 +1844,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSideb
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDesiredPresentTime(
nsecs_t desiredPresentTime) {
- mDesiredPresentTime = desiredPresentTime;
- mIsAutoTimestamp = false;
+ mState.mDesiredPresentTime = desiredPresentTime;
+ mState.mIsAutoTimestamp = false;
return *this;
}
@@ -2131,14 +1934,14 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setInput
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocusedWindow(
const FocusRequest& request) {
- mInputWindowCommands.addFocusRequest(request);
+ mState.mInputWindowCommands.addFocusRequest(request);
return *this;
}
SurfaceComposerClient::Transaction&
SurfaceComposerClient::Transaction::addWindowInfosReportedListener(
sp<gui::IWindowInfosReportedListener> windowInfosReportedListener) {
- mInputWindowCommands.addWindowInfosReportedListener(windowInfosReportedListener);
+ mState.mInputWindowCommands.addWindowInfosReportedListener(windowInfosReportedListener);
return *this;
}
@@ -2302,7 +2105,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixed
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineInfo(
const FrameTimelineInfo& frameTimelineInfo) {
- mergeFrameTimelineInfo(mFrameTimelineInfo, frameTimelineInfo);
+ mState.mergeFrameTimelineInfo(frameTimelineInfo);
return *this;
}
@@ -2341,7 +2144,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrust
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setApplyToken(
const sp<IBinder>& applyToken) {
- mApplyToken = applyToken;
+ mState.mApplyToken = applyToken;
return *this;
}
@@ -2469,17 +2272,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setConte
// ---------------------------------------------------------------------------
DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
- if (auto it = std::find_if(mDisplayStates.begin(), mDisplayStates.end(),
- [token](const auto& display) { return display.token == token; });
- it != mDisplayStates.end()) {
- return *it;
- }
-
- // If display state doesn't exist, add a new one.
- DisplayState s;
- s.token = token;
- mDisplayStates.add(s);
- return mDisplayStates.editItemAt(mDisplayStates.size() - 1);
+ return mState.getDisplayState(token);
}
status_t SurfaceComposerClient::Transaction::setDisplaySurface(const sp<IBinder>& token,
@@ -2532,20 +2325,6 @@ void SurfaceComposerClient::Transaction::setDisplaySize(const sp<IBinder>& token
s.what |= DisplayState::eDisplaySizeChanged;
}
-// copied from FrameTimelineInfo::merge()
-void SurfaceComposerClient::Transaction::mergeFrameTimelineInfo(FrameTimelineInfo& t,
- const FrameTimelineInfo& other) {
- // When merging vsync Ids we take the oldest valid one
- if (t.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID &&
- other.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
- if (other.vsyncId > t.vsyncId) {
- t = other;
- }
- } else if (t.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
- t = other;
- }
-}
-
SurfaceComposerClient::Transaction&
SurfaceComposerClient::Transaction::setTrustedPresentationCallback(
const sp<SurfaceControl>& sc, TrustedPresentationCallback cb,
@@ -2766,6 +2545,7 @@ status_t SurfaceComposerClient::getStaticDisplayInfo(int64_t displayId,
if (status.isOk()) {
// convert gui::StaticDisplayInfo to ui::StaticDisplayInfo
outInfo->connectionType = static_cast<ui::DisplayConnectionType>(ginfo.connectionType);
+ outInfo->port = ginfo.port;
outInfo->density = ginfo.density;
outInfo->secure = ginfo.secure;
outInfo->installOrientation = static_cast<ui::Rotation>(ginfo.installOrientation);
diff --git a/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl b/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl
index 0ccda56ef5..7ff332c29e 100644
--- a/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl
+++ b/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl
@@ -23,6 +23,7 @@ import android.gui.Rotation;
/** @hide */
parcelable StaticDisplayInfo {
DisplayConnectionType connectionType = DisplayConnectionType.Internal;
+ int port = -1;
float density;
boolean secure;
@nullable DeviceProductInfo deviceProductInfo;
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index db1b9fb8eb..c69b0a79ad 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -284,7 +284,7 @@ private:
std::function<void(SurfaceComposerClient::Transaction*)> mTransactionReadyCallback
GUARDED_BY(mMutex);
SurfaceComposerClient::Transaction* mSyncTransaction GUARDED_BY(mMutex);
- std::vector<std::tuple<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>>
+ std::vector<std::pair<uint64_t /* framenumber */, SurfaceComposerClient::Transaction>>
mPendingTransactions GUARDED_BY(mMutex);
std::queue<std::pair<uint64_t, FrameTimelineInfo>> mPendingFrameTimelines GUARDED_BY(mMutex);
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 9a422fd808..de553aef72 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -65,6 +65,7 @@ struct DisplayState;
struct InputWindowCommands;
class HdrCapabilities;
class Rect;
+class TransactionState;
using gui::FrameTimelineInfo;
using gui::IDisplayEventConnection;
@@ -105,13 +106,7 @@ public:
};
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
- virtual status_t setTransactionState(
- const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state,
- Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
- InputWindowCommands inputWindowCommands, int64_t desiredPresentTime,
- bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffer,
- bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
- uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) = 0;
+ virtual status_t setTransactionState(TransactionState&& state) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/InputTransferToken.h b/libs/gui/include/gui/InputTransferToken.h
index fb4aaa73ae..b83f24562b 100644
--- a/libs/gui/include/gui/InputTransferToken.h
+++ b/libs/gui/include/gui/InputTransferToken.h
@@ -39,15 +39,9 @@ public:
return NO_ERROR;
};
+ bool operator==(const InputTransferToken& other) const { return mToken == other.mToken; }
+
sp<IBinder> mToken;
};
-static inline bool operator==(const sp<InputTransferToken>& token1,
- const sp<InputTransferToken>& token2) {
- if (token1.get() == token2.get()) {
- return true;
- }
- return token1->mToken == token2->mToken;
-}
-
} // namespace android
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 4fda8deb9c..668bd6fbb8 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -52,6 +52,7 @@
#include <gui/ITransactionCompletedListener.h>
#include <gui/LayerState.h>
#include <gui/SurfaceControl.h>
+#include <gui/TransactionState.h>
#include <gui/WindowInfosListenerReporter.h>
#include <math/vec3.h>
@@ -442,61 +443,16 @@ public:
virtual ~PresentationCallbackRAII();
};
- class Transaction : public Parcelable {
+ class Transaction {
private:
static sp<IBinder> sApplyToken;
static std::mutex sApplyTokenMutex;
void releaseBufferIfOverwriting(const layer_state_t& state);
- static void mergeFrameTimelineInfo(FrameTimelineInfo& t, const FrameTimelineInfo& other);
// Tracks registered callbacks
sp<TransactionCompletedListener> mTransactionCompletedListener = nullptr;
- // Prints debug logs when enabled.
- bool mLogCallPoints = false;
- protected:
- Vector<ComposerState> mComposerStates;
- Vector<DisplayState> mDisplayStates;
- std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash>
- mListenerCallbacks;
- std::vector<client_cache_t> mUncacheBuffers;
-
- // We keep track of the last MAX_MERGE_HISTORY_LENGTH merged transaction ids.
- // Ordered most recently merged to least recently merged.
- static const size_t MAX_MERGE_HISTORY_LENGTH = 10u;
- std::vector<uint64_t> mMergedTransactionIds;
-
- uint64_t mId;
- uint32_t mFlags = 0;
-
- // Indicates that the Transaction may contain buffers that should be cached. The reason this
- // is only a guess is that buffers can be removed before cache is called. This is only a
- // hint that at some point a buffer was added to this transaction before apply was called.
- bool mMayContainBuffer = false;
-
- // mDesiredPresentTime is the time in nanoseconds that the client would like the transaction
- // to be presented. When it is not possible to present at exactly that time, it will be
- // presented after the time has passed.
- //
- // If the client didn't pass a desired presentation time, mDesiredPresentTime will be
- // populated to the time setBuffer was called, and mIsAutoTimestamp will be set to true.
- //
- // Desired present times that are more than 1 second in the future may be ignored.
- // When a desired present time has already passed, the transaction will be presented as soon
- // as possible.
- //
- // Transactions from the same process are presented in the same order that they are applied.
- // The desired present time does not affect this ordering.
- int64_t mDesiredPresentTime = 0;
- bool mIsAutoTimestamp = true;
-
- // The vsync id provided by Choreographer.getVsyncId and the input event id
- FrameTimelineInfo mFrameTimelineInfo;
-
- // If not null, transactions will be queued up using this token otherwise a common token
- // per process will be used.
- sp<IBinder> mApplyToken = nullptr;
+ TransactionState mState;
- InputWindowCommands mInputWindowCommands;
int mStatus = NO_ERROR;
layer_state_t* getLayerState(const sp<SurfaceControl>& sc);
@@ -506,23 +462,29 @@ public:
void registerSurfaceControlForCallback(const sp<SurfaceControl>& sc);
void setReleaseBufferCallback(BufferData*, ReleaseBufferCallback);
+ protected:
+ // Accessed in tests.
+ explicit Transaction(Transaction const& other) = default;
+ std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash>
+ mListenerCallbacks;
+
public:
Transaction();
- virtual ~Transaction() = default;
- Transaction(Transaction const& other);
+ Transaction(Transaction&& other);
+ Transaction& operator=(Transaction&& other) = default;
// Factory method that creates a new Transaction instance from the parcel.
static std::unique_ptr<Transaction> createFromParcel(const Parcel* parcel);
- status_t writeToParcel(Parcel* parcel) const override;
- status_t readFromParcel(const Parcel* parcel) override;
+ status_t writeToParcel(Parcel* parcel) const;
+ status_t readFromParcel(const Parcel* parcel);
// Clears the contents of the transaction without applying it.
void clear();
// Returns the current id of the transaction.
// The id is updated every time the transaction is applied.
- uint64_t getId();
+ uint64_t getId() const;
std::vector<uint64_t> getMergedTransactionIds();
diff --git a/libs/gui/include/gui/TransactionState.h b/libs/gui/include/gui/TransactionState.h
index 4358227dae..79124f3ed7 100644
--- a/libs/gui/include/gui/TransactionState.h
+++ b/libs/gui/include/gui/TransactionState.h
@@ -26,7 +26,8 @@ namespace android {
class TransactionState {
public:
explicit TransactionState() = default;
- TransactionState(TransactionState const& other) = default;
+ TransactionState(TransactionState&& other) = default;
+ TransactionState& operator=(TransactionState&& other) = default;
status_t writeToParcel(Parcel* parcel) const;
status_t readFromParcel(const Parcel* parcel);
layer_state_t* getLayerState(const sp<SurfaceControl>& sc);
@@ -86,6 +87,9 @@ public:
std::vector<ListenerCallbacks> mListenerCallbacks;
private:
+ explicit TransactionState(TransactionState const& other) = default;
+ friend class TransactionApplicationTest;
+ friend class SurfaceComposerClient;
// We keep track of the last MAX_MERGE_HISTORY_LENGTH merged transaction ids.
// Ordered most recently merged to least recently merged.
static constexpr size_t MAX_MERGE_HISTORY_LENGTH = 10u;
diff --git a/libs/gui/libgui_flags.aconfig b/libs/gui/libgui_flags.aconfig
index 2c3222dd82..ce1bc9512c 100644
--- a/libs/gui/libgui_flags.aconfig
+++ b/libs/gui/libgui_flags.aconfig
@@ -130,9 +130,6 @@ flag {
description: "Remove BufferQueueProducer::dequeue's wait on this fence (or the fence entirely) to prevent deadlocks"
bug: "339705065"
is_fixed_read_only: true
- metadata {
- purpose: PURPOSE_BUGFIX
- }
} # bq_gl_fence_cleanup
flag {
@@ -153,3 +150,14 @@ flag {
}
is_fixed_read_only: true
} # allocate_buffer_priority
+
+flag {
+ name: "bq_always_use_max_dequeued_buffer_count"
+ namespace: "core_graphics"
+ description: "BufferQueueProducer::dequeue's respects setMaxDequeuedBufferCount even before a buffer is dequeued."
+ bug: "399328309"
+ metadata {
+ purpose: PURPOSE_BUGFIX
+ }
+ is_fixed_read_only: true
+} # bq_always_use_max_dequeued_buffer_count
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index cf05fd4ba5..adf8fce472 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -222,8 +222,8 @@ public:
ASSERT_EQ(InputEventType::MOTION, ev->getType());
MotionEvent* mev = static_cast<MotionEvent*>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
- EXPECT_EQ(x, mev->getX(0));
- EXPECT_EQ(y, mev->getY(0));
+ EXPECT_NEAR(x, mev->getX(0), EPSILON);
+ EXPECT_NEAR(y, mev->getY(0), EPSILON);
EXPECT_EQ(flags, mev->getFlags() & flags);
ev = consumeEvent();
@@ -241,8 +241,8 @@ public:
MotionEvent* mev = static_cast<MotionEvent*>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
const PointerCoords& coords = *mev->getRawPointerCoords(0 /*pointerIndex*/);
- EXPECT_EQ(displayX, coords.getX());
- EXPECT_EQ(displayY, coords.getY());
+ EXPECT_NEAR(displayX, coords.getX(), EPSILON);
+ EXPECT_NEAR(displayY, coords.getY(), EPSILON);
EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
ev = consumeEvent();
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index e7690e2530..c4dcba856a 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -648,16 +648,7 @@ public:
mSupportsPresent = supportsPresent;
}
- status_t setTransactionState(
- const FrameTimelineInfo& /*frameTimelineInfo*/, Vector<ComposerState>& /*state*/,
- Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
- const sp<IBinder>& /*applyToken*/, InputWindowCommands /*inputWindowCommands*/,
- int64_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/,
- const std::vector<client_cache_t>& /*cachedBuffer*/, bool /*hasListenerCallbacks*/,
- const std::vector<ListenerCallbacks>& /*listenerCallbacks*/, uint64_t /*transactionId*/,
- const std::vector<uint64_t>& /*mergedTransactionIds*/) override {
- return NO_ERROR;
- }
+ status_t setTransactionState(TransactionState&&) override { return NO_ERROR; }
protected:
IBinder* onAsBinder() override { return nullptr; }
@@ -2246,6 +2237,52 @@ TEST_F(SurfaceTest, BatchIllegalOperations) {
ASSERT_EQ(NO_ERROR, surface->disconnect(NATIVE_WINDOW_API_CPU));
}
+TEST_F(SurfaceTest, setMaxDequeuedBufferCount_setMaxAcquiredBufferCount_allocations) {
+ //
+ // Set up the consumer and producer--nothing fancy.
+ //
+ auto [consumer, surface] =
+ BufferItemConsumer::create(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER);
+ sp<SurfaceListener> surfaceListener = sp<StubSurfaceListener>::make();
+ surface->connect(NATIVE_WINDOW_API_CPU, surfaceListener);
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+
+ //
+ // These values are independent. The consumer can dequeue 3 and the consumer can acquire 3 at
+ // the same time.
+ //
+ ASSERT_EQ(OK, consumer->setMaxAcquiredBufferCount(3));
+ ASSERT_EQ(OK, surface->setMaxDequeuedBufferCount(3));
+
+ //
+ // Take all three buffers out of the queue--a fourth can't be retrieved. Then queue them.
+ //
+ std::vector<Surface::BatchBuffer> dequeuedBuffers(3);
+ EXPECT_EQ(OK, surface->dequeueBuffers(&dequeuedBuffers));
+ if (::com::android::graphics::libgui::flags::bq_always_use_max_dequeued_buffer_count()) {
+ EXPECT_EQ(INVALID_OPERATION, surface->dequeueBuffer(&buffer, &fence));
+ }
+
+ for (auto& batchBuffer : dequeuedBuffers) {
+ EXPECT_EQ(OK,
+ surface->queueBuffer(GraphicBuffer::from(batchBuffer.buffer),
+ sp<Fence>::make(batchBuffer.fenceFd)));
+ }
+ dequeuedBuffers.assign(3, {});
+
+ //
+ // Acquire all three, then we should be able to dequeue 3 more.
+ //
+ std::vector<BufferItem> acquiredBuffers(3);
+ for (auto& bufferItem : acquiredBuffers) {
+ EXPECT_EQ(OK, consumer->acquireBuffer(&bufferItem, 0));
+ }
+
+ EXPECT_EQ(OK, surface->dequeueBuffers(&dequeuedBuffers));
+ EXPECT_EQ(INVALID_OPERATION, surface->dequeueBuffer(&buffer, &fence));
+}
+
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
TEST_F(SurfaceTest, PlatformBufferMethods) {
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index 7f207f0670..f9b84fa948 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -25,6 +25,7 @@ cc_defaults {
defaults: [
"android.hardware.graphics.composer3-ndk_shared",
"renderengine_defaults",
+ "libsurfaceflinger_common_deps",
],
cflags: [
"-DGL_GLEXT_PROTOTYPES",
@@ -117,7 +118,10 @@ filegroup {
// possible if libskia_renderengine is just pulled into librenderengine via whole_static_libs.
cc_defaults {
name: "librenderengine_deps",
- defaults: ["skia_renderengine_deps"],
+ defaults: [
+ "skia_renderengine_deps",
+ "libsurfaceflinger_common_deps",
+ ],
static_libs: ["libskia_renderengine"],
}
diff --git a/libs/renderengine/benchmark/Android.bp b/libs/renderengine/benchmark/Android.bp
index f84db0b04c..2d18ddb0aa 100644
--- a/libs/renderengine/benchmark/Android.bp
+++ b/libs/renderengine/benchmark/Android.bp
@@ -28,6 +28,7 @@ cc_benchmark {
"android.hardware.graphics.composer3-ndk_shared",
"librenderengine_deps",
"surfaceflinger_defaults",
+ "libsurfaceflinger_common_deps",
],
srcs: [
"main.cpp",
@@ -38,7 +39,6 @@ cc_benchmark {
static_libs: [
"librenderengine",
"libshaders",
- "libsurfaceflinger_common",
"libtonemap",
],
cflags: [
diff --git a/libs/renderengine/skia/SkiaRenderEngine.cpp b/libs/renderengine/skia/SkiaRenderEngine.cpp
index 25afc7b465..9e1c226371 100644
--- a/libs/renderengine/skia/SkiaRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaRenderEngine.cpp
@@ -1236,6 +1236,16 @@ void SkiaRenderEngine::drawLayersInternal(
LOG_ALWAYS_FATAL_IF(activeSurface != dstSurface);
auto drawFence = sp<Fence>::make(flushAndSubmit(context, dstSurface));
trace(drawFence);
+ FenceTimePtr fenceTime = FenceTime::makeValid(drawFence);
+ for (const auto& layer : layers) {
+ if (FlagManager::getInstance().monitor_buffer_fences()) {
+ if (layer.source.buffer.buffer) {
+ layer.source.buffer.buffer->getBuffer()
+ ->getDependencyMonitor()
+ .addAccessCompletion(fenceTime, "RE");
+ }
+ }
+ }
resultPromise->set_value(std::move(drawFence));
}
diff --git a/libs/renderengine/skia/filters/LutShader.cpp b/libs/renderengine/skia/filters/LutShader.cpp
index f262158f2c..6a577ff41f 100644
--- a/libs/renderengine/skia/filters/LutShader.cpp
+++ b/libs/renderengine/skia/filters/LutShader.cpp
@@ -24,7 +24,6 @@
#include <ui/ColorSpace.h>
#include "include/core/SkColorSpace.h"
-#include "src/core/SkColorFilterPriv.h"
using aidl::android::hardware::graphics::composer3::LutProperties;
@@ -116,7 +115,7 @@ static const SkString kShader = SkString(R"(
linear = mix(c0, c1, linear.b);
}
}
- return float4(linear, rgba.a);
+ return float4(fromLinearSrgb(linear), rgba.a);
})");
// same as shader::toColorSpace function
@@ -289,9 +288,7 @@ sk_sp<SkShader> LutShader::lutShader(sk_sp<SkShader>& input,
lutProperties[i].samplingKey, srcDataspace);
}
- auto colorXformLutToDst =
- SkColorFilterPriv::MakeColorSpaceXform(lutMathColorSpace, outColorSpace);
- input = input->makeWithColorFilter(colorXformLutToDst);
+ input = input->makeWithWorkingColorSpace(outColorSpace);
}
return input;
}
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 87e213e394..10cb992835 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -122,6 +122,7 @@ cc_library_shared {
srcs: [
"DebugUtils.cpp",
+ "DependencyMonitor.cpp",
"DeviceProductInfo.cpp",
"DisplayIdentification.cpp",
"DynamicDisplayInfo.cpp",
diff --git a/libs/ui/DependencyMonitor.cpp b/libs/ui/DependencyMonitor.cpp
new file mode 100644
index 0000000000..b7e490eba4
--- /dev/null
+++ b/libs/ui/DependencyMonitor.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2025 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.
+ */
+
+// #define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "DependencyMonitor"
+
+#include <ui/DependencyMonitor.h>
+#include <ui/Fence.h>
+#include <utils/Timers.h>
+
+#include <inttypes.h>
+
+namespace android {
+
+void DependencyMonitor::addIngress(FenceTimePtr fence, std::string annotation) {
+ std::lock_guard lock(mMutex);
+ resolveLocked();
+ if (mDependencies.isFull() && !mDependencies.front().updateSignalTimes(true)) {
+ ALOGD("%s: Clobbering unresolved dependencies -- make me bigger!", mToken.c_str());
+ }
+
+ auto& entry = mDependencies.next();
+ entry.reset(mToken.c_str());
+ ALOGV("%" PRId64 "/%s: addIngress at CPU time %" PRId64 " (%s)", mDependencies.back().id,
+ mToken.c_str(), systemTime(), annotation.c_str());
+
+ mDependencies.back().ingress = {std::move(fence), std::move(annotation)};
+}
+
+void DependencyMonitor::addAccessCompletion(FenceTimePtr fence, std::string annotation) {
+ std::lock_guard lock(mMutex);
+ if (mDependencies.size() == 0) {
+ return;
+ }
+ ALOGV("%" PRId64 "/%s: addAccessCompletion at CPU time %" PRId64 " (%s)",
+ mDependencies.back().id, mToken.c_str(), systemTime(), annotation.c_str());
+ mDependencies.back().accessCompletions.emplace_back(std::move(fence), std::move(annotation));
+}
+
+void DependencyMonitor::addEgress(FenceTimePtr fence, std::string annotation) {
+ std::lock_guard lock(mMutex);
+ if (mDependencies.size() == 0) {
+ return;
+ }
+ ALOGV("%" PRId64 "/%s: addEgress at CPU time %" PRId64 " (%s)", mDependencies.back().id,
+ mToken.c_str(), systemTime(), annotation.c_str());
+ mDependencies.back().egress = {std::move(fence), std::move(annotation)};
+}
+
+void DependencyMonitor::resolveLocked() {
+ if (mDependencies.size() == 0) {
+ return;
+ }
+
+ for (size_t i = mDependencies.size(); i > 0; i--) {
+ auto& dependencyBlock = mDependencies[i - 1];
+
+ if (dependencyBlock.validated) {
+ continue;
+ }
+
+ if (!dependencyBlock.updateSignalTimes(false)) {
+ break;
+ }
+
+ dependencyBlock.validated = true;
+ dependencyBlock.checkUnsafeAccess();
+ }
+}
+
+bool DependencyMonitor::DependencyBlock::updateSignalTimes(bool excludeIngress) {
+ if (egress.fence->getSignalTime() == Fence::SIGNAL_TIME_PENDING) {
+ return false;
+ }
+
+ if (!excludeIngress && ingress.fence->getSignalTime() == Fence::SIGNAL_TIME_PENDING) {
+ return false;
+ }
+
+ for (auto& accessCompletion : accessCompletions) {
+ if (accessCompletion.fence->getSignalTime() == Fence::SIGNAL_TIME_PENDING) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void DependencyMonitor::DependencyBlock::checkUnsafeAccess() const {
+ const nsecs_t egressTime = egress.fence->getCachedSignalTime();
+ const nsecs_t ingressTime = ingress.fence->getCachedSignalTime();
+
+ ALOGV_IF(egressTime != Fence::SIGNAL_TIME_INVALID,
+ "%" PRId64 "/%s: Egress time: %" PRId64 " (%s)", token, id, egressTime,
+ egress.annotation.c_str());
+ ALOGV_IF(Fence::isValidTimestamp(egressTime) && Fence::isValidTimestamp(ingressTime) &&
+ egressTime < ingressTime,
+ "%" PRId64 "/%s: Detected egress before ingress!: %" PRId64 " (%s) < %" PRId64 " (%s)",
+ id, token, egressTime, egress.annotation, ingressTime, ingress.annotation.c_str());
+
+ for (auto& accessCompletion : accessCompletions) {
+ const nsecs_t accessCompletionTime = accessCompletion.fence->getCachedSignalTime();
+ if (!Fence::isValidTimestamp(accessCompletionTime)) {
+ ALOGI("%" PRId64 "/%s: Detected invalid access completion! <%s>", id, token,
+ accessCompletion.annotation.c_str());
+ continue;
+ } else {
+ ALOGV("%" PRId64 "/%s: Access completion time: %" PRId64 " <%s>", id, token,
+ accessCompletionTime, accessCompletion.annotation.c_str());
+ }
+
+ ALOGI_IF(Fence::isValidTimestamp(egressTime) && accessCompletionTime > egressTime,
+ "%" PRId64 "/%s: Detected access completion after egress!: %" PRId64
+ " (%s) > %" PRId64 " (%s)",
+ id, token, accessCompletionTime, accessCompletion.annotation.c_str(), egressTime,
+ egress.annotation.c_str());
+
+ ALOGI_IF(Fence::isValidTimestamp(ingressTime) && accessCompletionTime < ingressTime,
+ "%" PRId64 "/%s: Detected access completion prior to ingress!: %" PRId64
+ " (%s) < %" PRId64 " (%s)",
+ id, token, accessCompletionTime, accessCompletion.annotation.c_str(), ingressTime,
+ ingress.annotation.c_str());
+ }
+
+ ALOGV_IF(ingressTime != Fence::SIGNAL_TIME_INVALID,
+ "%" PRId64 "/%s: Ingress time: %" PRId64 " (%s)", id, token, ingressTime,
+ ingress.annotation.c_str());
+}
+
+} // namespace android \ No newline at end of file
diff --git a/libs/ui/FenceTime.cpp b/libs/ui/FenceTime.cpp
index 4246c40f64..81afe9ef0e 100644
--- a/libs/ui/FenceTime.cpp
+++ b/libs/ui/FenceTime.cpp
@@ -59,6 +59,14 @@ FenceTime::FenceTime(nsecs_t signalTime)
}
}
+FenceTimePtr FenceTime::makeValid(const sp<Fence>& fence) {
+ if (fence && fence->isValid()) {
+ return std::make_shared<FenceTime>(fence);
+ } else {
+ return std::make_shared<FenceTime>(systemTime());
+ }
+}
+
void FenceTime::applyTrustedSnapshot(const Snapshot& src) {
if (CC_UNLIKELY(src.state != Snapshot::State::SIGNAL_TIME)) {
// Applying Snapshot::State::FENCE, could change the valid state of the
@@ -289,9 +297,10 @@ status_t FenceTime::Snapshot::unflatten(
// ============================================================================
void FenceTimeline::push(const std::shared_ptr<FenceTime>& fence) {
std::lock_guard<std::mutex> lock(mMutex);
- while (mQueue.size() >= MAX_ENTRIES) {
+ static constexpr size_t MAX_QUEUE_SIZE = 64;
+ while (mQueue.size() >= MAX_QUEUE_SIZE) {
// This is a sanity check to make sure the queue doesn't grow unbounded.
- // MAX_ENTRIES should be big enough not to trigger this path.
+ // MAX_QUEUE_SIZE should be big enough not to trigger this path.
// In case this path is taken though, users of FenceTime must make sure
// not to rely solely on FenceTimeline to get the final timestamp and
// should eventually call Fence::getSignalTime on their own.
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 18c9a6bc48..f7c94005f1 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -27,6 +27,8 @@
#include <ui/GraphicBufferMapper.h>
#include <utils/Trace.h>
+#include <string>
+
namespace android {
// ===========================================================================
@@ -104,6 +106,7 @@ GraphicBuffer::GraphicBuffer()
usage = 0;
layerCount = 0;
handle = nullptr;
+ mDependencyMonitor.setToken(std::to_string(mId));
}
// deprecated
@@ -155,6 +158,8 @@ GraphicBuffer::GraphicBuffer(const GraphicBufferAllocator::AllocationRequest& re
layerCount = request.layerCount;
usage = request.usage;
usage_deprecated = int(usage);
+ std::string name = request.requestorName;
+ mDependencyMonitor.setToken(name.append(":").append(std::to_string(mId)));
}
}
@@ -252,6 +257,7 @@ status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight,
usage = inUsage;
usage_deprecated = int(usage);
stride = static_cast<int>(outStride);
+ mDependencyMonitor.setToken(requestorName.append(":").append(std::to_string(mId)));
}
return err;
}
@@ -609,6 +615,14 @@ status_t GraphicBuffer::unflatten(void const*& buffer, size_t& size, int const*&
mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts);
}
+ std::string name;
+ status_t err = mBufferMapper.getName(handle, &name);
+ if (err != NO_ERROR) {
+ name = "<Unknown>";
+ }
+
+ mDependencyMonitor.setToken(name.append(":").append(std::to_string(mId)));
+
buffer = static_cast<void const*>(static_cast<uint8_t const*>(buffer) + sizeNeeded);
size -= sizeNeeded;
fds += numFds;
diff --git a/libs/ui/include/ui/DependencyMonitor.h b/libs/ui/include/ui/DependencyMonitor.h
new file mode 100644
index 0000000000..5ad1fd9528
--- /dev/null
+++ b/libs/ui/include/ui/DependencyMonitor.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2025 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.
+ */
+
+#pragma once
+
+#include <ui/FatVector.h>
+#include <ui/FenceTime.h>
+#include <ui/RingBuffer.h>
+
+namespace android {
+
+// Debugging class for that tries to add userspace logging for fence depencencies.
+// The model that a DependencyMonitor tries to follow is, for each access of some resource:
+// 1. There is a single ingress fence, that guards whether a resource is now safe to read from
+// another system.
+// 2. There are multiple access fences, that are fired when a resource is read.
+// 3. There is a single egress fence, that is fired when a resource is released and sent to another
+// system.
+//
+// Note that there can be repeated ingress and egress of a resource, but the assumption is that
+// there is exactly one egress for every ingress, unless the resource is destroyed rather than
+// released.
+//
+// The DependencyMonitor will log if there is an anomaly in the fences tracked for some resource.
+// This includes:
+// * If (2) happens before (1)
+// * If (2) happens after (3)
+//
+// Note that this class has no knowledge of the "other system". I.e., if the other system ignores
+// the fence reported in (3), but still takes a long time to write to the resource and produce (1),
+// then nothing will be logged. That other system must have its own DependencyMonitor. Conversely,
+// this class has imperfect knowledge of the system it is monitoring. For example, this class does
+// not know the precise start times of reading from a resource, the exact time that a read might
+// occur from a hardware unit is not known to userspace.
+//
+// In other words, this class logs specific classes of fence violations, but is not sensitive to
+// *all* violations. One property of this is that unless the system tracked by a DependencyMonitor
+// is feeding in literally incorrect fences, then there is no chance of a false positive.
+//
+// This class is thread safe.
+class DependencyMonitor {
+public:
+ // Sets a debug token identifying the resource this monitor is tracking.
+ void setToken(std::string token) { mToken = std::move(token); }
+
+ // Adds a fence that is fired when the resource ready to be ingested by the system using the
+ // DependencyMonitor.
+ void addIngress(FenceTimePtr fence, std::string annotation);
+ // Adds a fence that is fired when the resource is accessed.
+ void addAccessCompletion(FenceTimePtr fence, std::string annotation);
+ // Adds a fence that is fired when the resource is released to another system.
+ void addEgress(FenceTimePtr fence, std::string annotation);
+
+private:
+ struct AnnotatedFenceTime {
+ FenceTimePtr fence;
+ std::string annotation;
+ };
+
+ struct DependencyBlock {
+ int64_t id = -1;
+ AnnotatedFenceTime ingress = {FenceTime::NO_FENCE, ""};
+ FatVector<AnnotatedFenceTime> accessCompletions;
+ AnnotatedFenceTime egress = {FenceTime::NO_FENCE, ""};
+ bool validated = false;
+ const char* token = nullptr;
+
+ void reset(const char* newToken) {
+ static std::atomic<int64_t> counter = 0;
+ id = counter++;
+ ingress = {FenceTime::NO_FENCE, ""};
+ accessCompletions.clear();
+ egress = {FenceTime::NO_FENCE, ""};
+ validated = false;
+ token = newToken;
+ }
+
+ // Returns true if all fences in this block have valid signal times.
+ bool updateSignalTimes(bool excludeIngress);
+
+ void checkUnsafeAccess() const;
+ };
+
+ void resolveLocked() REQUIRES(mMutex);
+
+ std::string mToken;
+ std::mutex mMutex;
+ ui::RingBuffer<DependencyBlock, 10> mDependencies GUARDED_BY(mMutex);
+};
+
+} // namespace android \ No newline at end of file
diff --git a/libs/ui/include/ui/DisplayId.h b/libs/ui/include/ui/DisplayId.h
index 937e3f1486..1e1c77b9fc 100644
--- a/libs/ui/include/ui/DisplayId.h
+++ b/libs/ui/include/ui/DisplayId.h
@@ -20,6 +20,7 @@
#include <ostream>
#include <string>
+#include <ftl/match.h>
#include <ftl/optional.h>
namespace android {
@@ -36,7 +37,6 @@ struct DisplayId {
DisplayId& operator=(const DisplayId&) = default;
static constexpr DisplayId fromValue(uint64_t value) { return DisplayId(value); }
- constexpr bool isVirtual() const { return value & FLAG_VIRTUAL; }
uint64_t value;
@@ -66,13 +66,6 @@ struct PhysicalDisplayId : DisplayId {
// TODO: b/162612135 - Remove default constructor.
PhysicalDisplayId() = default;
- static constexpr ftl::Optional<PhysicalDisplayId> tryCast(DisplayId id) {
- if (id.isVirtual()) {
- return std::nullopt;
- }
- return PhysicalDisplayId(id);
- }
-
// Returns a stable ID based on EDID and port information.
static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId,
uint32_t modelHash) {
@@ -90,8 +83,6 @@ struct PhysicalDisplayId : DisplayId {
return PhysicalDisplayId(value);
}
- constexpr uint8_t getPort() const { return static_cast<uint8_t>(value); }
-
private:
// Flag indicating that the ID is stable across reboots.
static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
@@ -112,13 +103,6 @@ struct VirtualDisplayId : DisplayId {
// Flag indicating that this virtual display is backed by the GPU.
static constexpr uint64_t FLAG_GPU = 1ULL << 61;
- static constexpr std::optional<VirtualDisplayId> tryCast(DisplayId id) {
- if (id.isVirtual()) {
- return VirtualDisplayId(id);
- }
- return std::nullopt;
- }
-
static constexpr VirtualDisplayId fromValue(uint64_t value) {
return VirtualDisplayId(SkipVirtualFlag{}, value);
}
@@ -134,13 +118,6 @@ protected:
struct HalVirtualDisplayId : VirtualDisplayId {
explicit constexpr HalVirtualDisplayId(BaseId baseId) : VirtualDisplayId(baseId) {}
- static constexpr std::optional<HalVirtualDisplayId> tryCast(DisplayId id) {
- if (id.isVirtual() && !(id.value & FLAG_GPU)) {
- return HalVirtualDisplayId(id);
- }
- return std::nullopt;
- }
-
static constexpr HalVirtualDisplayId fromValue(uint64_t value) {
return HalVirtualDisplayId(SkipVirtualFlag{}, value);
}
@@ -152,13 +129,6 @@ private:
struct GpuVirtualDisplayId : VirtualDisplayId {
explicit constexpr GpuVirtualDisplayId(BaseId baseId) : VirtualDisplayId(FLAG_GPU | baseId) {}
- static constexpr std::optional<GpuVirtualDisplayId> tryCast(DisplayId id) {
- if (id.isVirtual() && (id.value & FLAG_GPU)) {
- return GpuVirtualDisplayId(id);
- }
- return std::nullopt;
- }
-
static constexpr GpuVirtualDisplayId fromValue(uint64_t value) {
return GpuVirtualDisplayId(SkipVirtualFlag{}, value);
}
@@ -172,14 +142,6 @@ private:
struct HalDisplayId : DisplayId {
constexpr HalDisplayId(HalVirtualDisplayId other) : DisplayId(other) {}
constexpr HalDisplayId(PhysicalDisplayId other) : DisplayId(other) {}
-
- static constexpr std::optional<HalDisplayId> tryCast(DisplayId id) {
- if (GpuVirtualDisplayId::tryCast(id)) {
- return std::nullopt;
- }
- return HalDisplayId(id);
- }
-
static constexpr HalDisplayId fromValue(uint64_t value) { return HalDisplayId(value); }
private:
@@ -187,6 +149,47 @@ private:
explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {}
};
+using DisplayIdVariant = std::variant<PhysicalDisplayId, GpuVirtualDisplayId, HalVirtualDisplayId>;
+using VirtualDisplayIdVariant = std::variant<GpuVirtualDisplayId, HalVirtualDisplayId>;
+
+template <typename DisplayIdType>
+inline auto asDisplayIdOfType(DisplayIdVariant variant) -> ftl::Optional<DisplayIdType> {
+ return ftl::match(
+ variant,
+ [](DisplayIdType id) -> ftl::Optional<DisplayIdType> { return ftl::Optional(id); },
+ [](auto) -> ftl::Optional<DisplayIdType> { return std::nullopt; });
+}
+
+template <typename Variant>
+inline auto asHalDisplayId(Variant variant) -> ftl::Optional<HalDisplayId> {
+ return ftl::match(
+ variant,
+ [](GpuVirtualDisplayId) -> ftl::Optional<HalDisplayId> { return std::nullopt; },
+ [](auto id) -> ftl::Optional<HalDisplayId> {
+ return ftl::Optional(static_cast<HalDisplayId>(id));
+ });
+}
+
+inline auto asPhysicalDisplayId(DisplayIdVariant variant) -> ftl::Optional<PhysicalDisplayId> {
+ return asDisplayIdOfType<PhysicalDisplayId>(variant);
+}
+
+inline auto asVirtualDisplayId(DisplayIdVariant variant) -> ftl::Optional<VirtualDisplayId> {
+ return ftl::match(
+ variant,
+ [](GpuVirtualDisplayId id) -> ftl::Optional<VirtualDisplayId> {
+ return ftl::Optional(static_cast<VirtualDisplayId>(id));
+ },
+ [](HalVirtualDisplayId id) -> ftl::Optional<VirtualDisplayId> {
+ return ftl::Optional(static_cast<VirtualDisplayId>(id));
+ },
+ [](auto) -> ftl::Optional<VirtualDisplayId> { return std::nullopt; });
+}
+
+inline auto asDisplayId(DisplayIdVariant variant) -> DisplayId {
+ return ftl::match(variant, [](auto id) -> DisplayId { return static_cast<DisplayId>(id); });
+}
+
static_assert(sizeof(DisplayId) == sizeof(uint64_t));
static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t));
diff --git a/libs/ui/include/ui/FenceTime.h b/libs/ui/include/ui/FenceTime.h
index 334106f0cf..3560d57cff 100644
--- a/libs/ui/include/ui/FenceTime.h
+++ b/libs/ui/include/ui/FenceTime.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_FENCE_TIME_H
#define ANDROID_FENCE_TIME_H
+#include <stddef.h>
#include <ui/Fence.h>
#include <utils/Flattenable.h>
#include <utils/Mutex.h>
@@ -30,6 +31,8 @@
namespace android {
class FenceToFenceTimeMap;
+class FenceTime;
+using FenceTimePtr = std::shared_ptr<FenceTime>;
// A wrapper around fence that only implements isValid and getSignalTime.
// It automatically closes the fence in a thread-safe manner once the signal
@@ -95,6 +98,10 @@ public:
FenceTime& operator=(const FenceTime&) = delete;
FenceTime& operator=(FenceTime&&) = delete;
+ // Constructs a FenceTime, falling back to a timestamp if the fence is
+ // invalid.
+ static FenceTimePtr makeValid(const sp<Fence>& fence);
+
// This method should only be called when replacing the fence with
// a signalTime. Since this is an indirect way of setting the signal time
// of a fence, the snapshot should come from a trusted source.
@@ -142,8 +149,6 @@ private:
std::atomic<nsecs_t> mSignalTime{Fence::SIGNAL_TIME_INVALID};
};
-using FenceTimePtr = std::shared_ptr<FenceTime>;
-
// A queue of FenceTimes that are expected to signal in FIFO order.
// Only maintains a queue of weak pointers so it doesn't keep references
// to Fences on its own.
@@ -162,8 +167,6 @@ using FenceTimePtr = std::shared_ptr<FenceTime>;
// different threads.
class FenceTimeline {
public:
- static constexpr size_t MAX_ENTRIES = 64;
-
void push(const std::shared_ptr<FenceTime>& fence);
void updateSignalTimes();
diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h
index 936bf8f862..9305180ecb 100644
--- a/libs/ui/include/ui/GraphicBuffer.h
+++ b/libs/ui/include/ui/GraphicBuffer.h
@@ -23,6 +23,7 @@
#include <string>
#include <utility>
#include <vector>
+#include "ui/DependencyMonitor.h"
#include <android/hardware_buffer.h>
#include <ui/ANativeObjectBase.h>
@@ -229,6 +230,8 @@ public:
void addDeathCallback(GraphicBufferDeathCallback deathCallback, void* context);
+ DependencyMonitor& getDependencyMonitor() { return mDependencyMonitor; }
+
private:
~GraphicBuffer();
@@ -295,6 +298,8 @@ private:
// and informs SurfaceFlinger that it should drop its strong pointer reference to the buffer.
std::vector<std::pair<GraphicBufferDeathCallback, void* /*mDeathCallbackContext*/>>
mDeathCallbacks;
+
+ DependencyMonitor mDependencyMonitor;
};
} // namespace android
diff --git a/libs/ui/include/ui/StaticDisplayInfo.h b/libs/ui/include/ui/StaticDisplayInfo.h
index 83da821f37..53164487f3 100644
--- a/libs/ui/include/ui/StaticDisplayInfo.h
+++ b/libs/ui/include/ui/StaticDisplayInfo.h
@@ -28,6 +28,7 @@ enum class DisplayConnectionType { Internal, External, ftl_last = External };
// Immutable information about physical display.
struct StaticDisplayInfo {
DisplayConnectionType connectionType = DisplayConnectionType::Internal;
+ uint8_t port;
float density = 0.f;
bool secure = false;
std::optional<DeviceProductInfo> deviceProductInfo;
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 2b11786df3..d950f2a23f 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -45,16 +45,6 @@ cc_test {
}
cc_test {
- name: "DisplayId_test",
- shared_libs: ["libui"],
- srcs: ["DisplayId_test.cpp"],
- cflags: [
- "-Wall",
- "-Werror",
- ],
-}
-
-cc_test {
name: "DisplayIdentification_test",
shared_libs: ["libui"],
static_libs: ["libgmock"],
diff --git a/libs/ui/tests/DisplayId_test.cpp b/libs/ui/tests/DisplayId_test.cpp
deleted file mode 100644
index 209acba672..0000000000
--- a/libs/ui/tests/DisplayId_test.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2020 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.
- */
-
-#include <ui/DisplayId.h>
-
-#include <gtest/gtest.h>
-
-namespace android::ui {
-
-TEST(DisplayIdTest, createPhysicalIdFromEdid) {
- constexpr uint8_t port = 1;
- constexpr uint16_t manufacturerId = 13;
- constexpr uint32_t modelHash = 42;
- const PhysicalDisplayId id = PhysicalDisplayId::fromEdid(port, manufacturerId, modelHash);
- EXPECT_EQ(port, id.getPort());
- EXPECT_FALSE(VirtualDisplayId::tryCast(id));
- EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
- EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
- EXPECT_TRUE(HalDisplayId::tryCast(id));
-
- EXPECT_EQ(id, DisplayId::fromValue(id.value));
- EXPECT_EQ(id, PhysicalDisplayId::fromValue(id.value));
-}
-
-TEST(DisplayIdTest, createPhysicalIdFromPort) {
- constexpr uint8_t port = 3;
- const PhysicalDisplayId id = PhysicalDisplayId::fromPort(port);
- EXPECT_EQ(port, id.getPort());
- EXPECT_FALSE(VirtualDisplayId::tryCast(id));
- EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
- EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
- EXPECT_TRUE(HalDisplayId::tryCast(id));
-
- EXPECT_EQ(id, DisplayId::fromValue(id.value));
- EXPECT_EQ(id, PhysicalDisplayId::fromValue(id.value));
-}
-
-TEST(DisplayIdTest, createGpuVirtualId) {
- const GpuVirtualDisplayId id(42);
- EXPECT_TRUE(VirtualDisplayId::tryCast(id));
- EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
- EXPECT_FALSE(HalDisplayId::tryCast(id));
-
- EXPECT_EQ(id, DisplayId::fromValue(id.value));
- EXPECT_EQ(id, GpuVirtualDisplayId::fromValue(id.value));
-}
-
-TEST(DisplayIdTest, createVirtualIdFromGpuVirtualId) {
- const VirtualDisplayId id(GpuVirtualDisplayId(42));
- EXPECT_TRUE(VirtualDisplayId::tryCast(id));
- EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
- EXPECT_FALSE(HalDisplayId::tryCast(id));
-
- const bool isGpuVirtualId = (id.value & VirtualDisplayId::FLAG_GPU);
- EXPECT_EQ((id.isVirtual() && isGpuVirtualId), GpuVirtualDisplayId::tryCast(id).has_value());
-}
-
-TEST(DisplayIdTest, createHalVirtualId) {
- const HalVirtualDisplayId id(42);
- EXPECT_TRUE(VirtualDisplayId::tryCast(id));
- EXPECT_TRUE(HalVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
- EXPECT_TRUE(HalDisplayId::tryCast(id));
-
- EXPECT_EQ(id, DisplayId::fromValue(id.value));
- EXPECT_EQ(id, HalVirtualDisplayId::fromValue(id.value));
-}
-
-TEST(DisplayIdTest, createVirtualIdFromHalVirtualId) {
- const VirtualDisplayId id(HalVirtualDisplayId(42));
- EXPECT_TRUE(VirtualDisplayId::tryCast(id));
- EXPECT_TRUE(HalVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
- EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
- EXPECT_TRUE(HalDisplayId::tryCast(id));
-
- const bool isGpuVirtualId = (id.value & VirtualDisplayId::FLAG_GPU);
- EXPECT_EQ((id.isVirtual() && !isGpuVirtualId), HalVirtualDisplayId::tryCast(id).has_value());
-}
-
-} // namespace android::ui
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 888fcfb592..95e1c06615 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -934,6 +934,7 @@ InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy,
mPendingEvent(nullptr),
mLastDropReason(DropReason::NOT_DROPPED),
mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
+ mWindowInfosVsyncId(-1),
mMinTimeBetweenUserActivityPokes(DEFAULT_USER_ACTIVITY_POKE_INTERVAL),
mConnectionManager(mLooper),
mTouchStates(mWindowInfos, mConnectionManager),
@@ -7049,11 +7050,6 @@ void InputDispatcher::onWindowInfosChanged(const gui::WindowInfosUpdate& update)
setInputWindowsLocked(handles, displayId);
}
- if (update.vsyncId < mWindowInfosVsyncId) {
- ALOGE("Received out of order window infos update. Last update vsync id: %" PRId64
- ", current update vsync id: %" PRId64,
- mWindowInfosVsyncId, update.vsyncId);
- }
mWindowInfosVsyncId = update.vsyncId;
}
// Wake up poll loop since it may need to make new input dispatching choices.
diff --git a/services/stats/Android.bp b/services/stats/Android.bp
index f698515545..d588017737 100644
--- a/services/stats/Android.bp
+++ b/services/stats/Android.bp
@@ -29,10 +29,15 @@ cc_library_shared {
"libexpresslog",
"libhidlbase",
"liblog",
- "libstatslog",
"libstatssocket",
"libutils",
],
+ generated_sources: [
+ "statslog_hidl.cpp",
+ ],
+ generated_headers: [
+ "statslog_hidl.h",
+ ],
export_include_dirs: [
"include/",
],
@@ -47,3 +52,28 @@ cc_library_shared {
"android.frameworks.stats-service.xml",
],
}
+
+genrule {
+ name: "statslog_hidl.h",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen)" +
+ " --header $(genDir)/statslog_hidl.h" +
+ " --module statshidl" +
+ " --namespace android,util,statshidl",
+ out: [
+ "statslog_hidl.h",
+ ],
+}
+
+genrule {
+ name: "statslog_hidl.cpp",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen)" +
+ " --cpp $(genDir)/statslog_hidl.cpp" +
+ " --module statshidl" +
+ " --namespace android,util,statshidl" +
+ " --importHeader statslog_hidl.h",
+ out: [
+ "statslog_hidl.cpp",
+ ],
+}
diff --git a/services/stats/StatsAidl.cpp b/services/stats/StatsAidl.cpp
index b22f903654..66f7682dd8 100644
--- a/services/stats/StatsAidl.cpp
+++ b/services/stats/StatsAidl.cpp
@@ -26,9 +26,8 @@
#include <log/log.h>
#include <stats_annotations.h>
#include <stats_event.h>
-#include <statslog.h>
-#include <unordered_map>
+#include <map>
namespace {
static const char* g_AtomErrorMetricName =
@@ -118,8 +117,8 @@ ndk::ScopedAStatus StatsHal::reportVendorAtom(const VendorAtom& vendorAtom) {
}
}
- // populate map for quickier access for VendorAtomValue associated annotations by value index
- std::unordered_map<int, int> fieldIndexToAnnotationSetMap;
+ // populate map for quicker access for VendorAtomValue associated annotations by value index
+ std::map<int, int> fieldIndexToAnnotationSetMap;
if (vendorAtom.valuesAnnotations) {
const std::vector<std::optional<AnnotationSet>>& valuesAnnotations =
*vendorAtom.valuesAnnotations;
diff --git a/services/stats/StatsHal.cpp b/services/stats/StatsHal.cpp
index 19176d9aaf..0ffa4c3947 100644
--- a/services/stats/StatsHal.cpp
+++ b/services/stats/StatsHal.cpp
@@ -20,7 +20,7 @@
#include "StatsHal.h"
#include <log/log.h>
-#include <statslog.h>
+#include <statslog_hidl.h>
namespace android {
namespace frameworks {
@@ -32,24 +32,27 @@ StatsHal::StatsHal() {
}
hardware::Return<void> StatsHal::reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) {
- android::util::stats_write(android::util::SPEAKER_IMPEDANCE_REPORTED,
- speakerImpedance.speakerLocation, speakerImpedance.milliOhms);
+ android::util::statshidl::stats_write(android::util::statshidl::SPEAKER_IMPEDANCE_REPORTED,
+ speakerImpedance.speakerLocation,
+ speakerImpedance.milliOhms);
return hardware::Void();
}
hardware::Return<void> StatsHal::reportHardwareFailed(const HardwareFailed& hardwareFailed) {
- android::util::stats_write(android::util::HARDWARE_FAILED, int32_t(hardwareFailed.hardwareType),
- hardwareFailed.hardwareLocation, int32_t(hardwareFailed.errorCode));
+ android::util::statshidl::stats_write(
+ android::util::statshidl::HARDWARE_FAILED, int32_t(hardwareFailed.hardwareType),
+ hardwareFailed.hardwareLocation, int32_t(hardwareFailed.errorCode));
return hardware::Void();
}
hardware::Return<void> StatsHal::reportPhysicalDropDetected(
const PhysicalDropDetected& physicalDropDetected) {
- android::util::stats_write(
- android::util::PHYSICAL_DROP_DETECTED, int32_t(physicalDropDetected.confidencePctg),
- physicalDropDetected.accelPeak, physicalDropDetected.freefallDuration);
+ android::util::statshidl::stats_write(android::util::statshidl::PHYSICAL_DROP_DETECTED,
+ int32_t(physicalDropDetected.confidencePctg),
+ physicalDropDetected.accelPeak,
+ physicalDropDetected.freefallDuration);
return hardware::Void();
}
@@ -60,19 +63,19 @@ hardware::Return<void> StatsHal::reportChargeCycles(const ChargeCycles& chargeCy
for (int i = 0; i < 10 - initialSize; i++) {
buckets.push_back(0); // Push 0 for buckets that do not exist.
}
- android::util::stats_write(android::util::CHARGE_CYCLES_REPORTED, buckets[0], buckets[1],
- buckets[2], buckets[3], buckets[4], buckets[5], buckets[6],
- buckets[7], buckets[8], buckets[9]);
+ android::util::statshidl::stats_write(
+ android::util::statshidl::CHARGE_CYCLES_REPORTED, buckets[0], buckets[1], buckets[2],
+ buckets[3], buckets[4], buckets[5], buckets[6], buckets[7], buckets[8], buckets[9]);
return hardware::Void();
}
hardware::Return<void> StatsHal::reportBatteryHealthSnapshot(
const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) {
- android::util::stats_write(
- android::util::BATTERY_HEALTH_SNAPSHOT, int32_t(batteryHealthSnapshotArgs.type),
- batteryHealthSnapshotArgs.temperatureDeciC, batteryHealthSnapshotArgs.voltageMicroV,
- batteryHealthSnapshotArgs.currentMicroA,
+ android::util::statshidl::stats_write(
+ android::util::statshidl::BATTERY_HEALTH_SNAPSHOT,
+ int32_t(batteryHealthSnapshotArgs.type), batteryHealthSnapshotArgs.temperatureDeciC,
+ batteryHealthSnapshotArgs.voltageMicroV, batteryHealthSnapshotArgs.currentMicroA,
batteryHealthSnapshotArgs.openCircuitVoltageMicroV,
batteryHealthSnapshotArgs.resistanceMicroOhm, batteryHealthSnapshotArgs.levelPercent);
@@ -80,23 +83,24 @@ hardware::Return<void> StatsHal::reportBatteryHealthSnapshot(
}
hardware::Return<void> StatsHal::reportSlowIo(const SlowIo& slowIo) {
- android::util::stats_write(android::util::SLOW_IO, int32_t(slowIo.operation), slowIo.count);
+ android::util::statshidl::stats_write(android::util::statshidl::SLOW_IO,
+ int32_t(slowIo.operation), slowIo.count);
return hardware::Void();
}
hardware::Return<void> StatsHal::reportBatteryCausedShutdown(
const BatteryCausedShutdown& batteryCausedShutdown) {
- android::util::stats_write(android::util::BATTERY_CAUSED_SHUTDOWN,
- batteryCausedShutdown.voltageMicroV);
+ android::util::statshidl::stats_write(android::util::statshidl::BATTERY_CAUSED_SHUTDOWN,
+ batteryCausedShutdown.voltageMicroV);
return hardware::Void();
}
hardware::Return<void> StatsHal::reportUsbPortOverheatEvent(
const UsbPortOverheatEvent& usbPortOverheatEvent) {
- android::util::stats_write(
- android::util::USB_PORT_OVERHEAT_EVENT_REPORTED,
+ android::util::statshidl::stats_write(
+ android::util::statshidl::USB_PORT_OVERHEAT_EVENT_REPORTED,
usbPortOverheatEvent.plugTemperatureDeciC, usbPortOverheatEvent.maxTemperatureDeciC,
usbPortOverheatEvent.timeToOverheat, usbPortOverheatEvent.timeToHysteresis,
usbPortOverheatEvent.timeToInactive);
@@ -105,9 +109,10 @@ hardware::Return<void> StatsHal::reportUsbPortOverheatEvent(
}
hardware::Return<void> StatsHal::reportSpeechDspStat(const SpeechDspStat& speechDspStat) {
- android::util::stats_write(android::util::SPEECH_DSP_STAT_REPORTED,
- speechDspStat.totalUptimeMillis, speechDspStat.totalDowntimeMillis,
- speechDspStat.totalCrashCount, speechDspStat.totalRecoverCount);
+ android::util::statshidl::stats_write(
+ android::util::statshidl::SPEECH_DSP_STAT_REPORTED, speechDspStat.totalUptimeMillis,
+ speechDspStat.totalDowntimeMillis, speechDspStat.totalCrashCount,
+ speechDspStat.totalRecoverCount);
return hardware::Void();
}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 252adaa8e3..2c0a66fac3 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
@@ -34,7 +34,7 @@ class CompositionEngine;
* A parameter object for creating Display instances
*/
struct DisplayCreationArgs {
- DisplayId id;
+ DisplayIdVariant idVariant;
// Size of the display in pixels
ui::Size pixels = ui::kInvalidSize;
@@ -68,8 +68,8 @@ class DisplayCreationArgsBuilder {
public:
DisplayCreationArgs build() { return std::move(mArgs); }
- DisplayCreationArgsBuilder& setId(DisplayId id) {
- mArgs.id = id;
+ DisplayCreationArgsBuilder& setId(DisplayIdVariant idVariant) {
+ mArgs.idVariant = idVariant;
return *this;
}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index 780758e2a3..e2ea0f1397 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -167,6 +167,8 @@ public:
// Checks if the buffer's release fence has been set
virtual LayerFE::ReleaseFencePromiseStatus getReleaseFencePromiseStatus() = 0;
+ virtual void setReleasedBuffer(sp<GraphicBuffer> buffer) = 0;
+
// Indicates that the picture profile request was applied to this layer.
virtual void onPictureProfileCommitted() = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index bda7856596..4266da4b07 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -170,6 +170,7 @@ public:
// Returns the DisplayId the output represents, if it has one
virtual ftl::Optional<DisplayId> getDisplayId() const = 0;
+ virtual ftl::Optional<DisplayIdVariant> getDisplayIdVariant() const = 0;
// Enables (or disables) composition on this output
virtual void setCompositionEnabled(bool) = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index 5519aafe11..ec87acc372 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -46,6 +46,7 @@ public:
// compositionengine::Output overrides
ftl::Optional<DisplayId> getDisplayId() const override;
+ ftl::Optional<DisplayIdVariant> getDisplayIdVariant() const override;
bool isValid() const override;
void dump(std::string&) const override;
using compositionengine::impl::Output::setReleasedLayers;
@@ -104,8 +105,11 @@ private:
override;
bool hasPictureProcessing() const override;
int32_t getMaxLayerPictureProfiles() const override;
+ bool isGpuVirtualDisplay() const {
+ return std::holds_alternative<GpuVirtualDisplayId>(mIdVariant);
+ }
- DisplayId mId;
+ DisplayIdVariant mIdVariant;
bool mIsDisconnected = false;
adpf::PowerAdvisor* mPowerAdvisor = nullptr;
bool mHasPictureProcessing = false;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
index 0ccdd22919..873764b065 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Output.h
@@ -45,6 +45,7 @@ public:
// compositionengine::Output overrides
bool isValid() const override;
ftl::Optional<DisplayId> getDisplayId() const override;
+ ftl::Optional<DisplayIdVariant> getDisplayIdVariant() const override;
void setCompositionEnabled(bool) override;
void setLayerCachingEnabled(bool) override;
void setLayerCachingTexturePoolEnabled(bool) override;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index d2a5a2066c..f65a9083c5 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -52,6 +52,7 @@ public:
MOCK_METHOD0(createReleaseFenceFuture, ftl::Future<FenceResult>());
MOCK_METHOD1(setReleaseFence, void(const FenceResult&));
+ MOCK_METHOD1(setReleasedBuffer, void(sp<GraphicBuffer>));
MOCK_METHOD0(getReleaseFencePromiseStatus, LayerFE::ReleaseFencePromiseStatus());
MOCK_CONST_METHOD0(getDebugName, const char*());
MOCK_CONST_METHOD0(getSequence, int32_t());
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
index f2c265ad2e..eaa3dd37ec 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Output.h
@@ -35,6 +35,7 @@ public:
MOCK_CONST_METHOD0(isValid, bool());
MOCK_CONST_METHOD0(getDisplayId, ftl::Optional<DisplayId>());
+ MOCK_CONST_METHOD0(getDisplayIdVariant, ftl::Optional<DisplayIdVariant>());
MOCK_METHOD1(setCompositionEnabled, void(bool));
MOCK_METHOD1(setLayerCachingEnabled, void(bool));
diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
index 989f8e3c5e..ab2a03cd60 100644
--- a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -91,13 +91,13 @@ nsecs_t CompositionEngine::getLastFrameRefreshTimestamp() const {
namespace {
void offloadOutputs(Outputs& outputs) {
- if (!FlagManager::getInstance().multithreaded_present() || outputs.size() < 2) {
+ if (outputs.size() < 2) {
return;
}
ui::PhysicalDisplayVector<compositionengine::Output*> outputsToOffload;
for (const auto& output : outputs) {
- if (!ftl::Optional(output->getDisplayId()).and_then(HalDisplayId::tryCast)) {
+ if (!output->getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) {
// Not HWC-enabled, so it is always client-composited. No need to offload.
continue;
}
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 8364f4efa0..5a546777f4 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -52,7 +52,7 @@ std::shared_ptr<Display> createDisplay(
Display::~Display() = default;
void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) {
- mId = args.id;
+ mIdVariant = args.idVariant;
mPowerAdvisor = args.powerAdvisor;
mHasPictureProcessing = args.hasPictureProcessing;
mMaxLayerPictureProfiles = args.maxLayerPictureProfiles;
@@ -67,7 +67,7 @@ bool Display::isValid() const {
}
DisplayId Display::getId() const {
- return mId;
+ return asDisplayId(mIdVariant);
}
bool Display::isSecure() const {
@@ -79,11 +79,15 @@ void Display::setSecure(bool secure) {
}
bool Display::isVirtual() const {
- return mId.isVirtual();
+ return !std::holds_alternative<PhysicalDisplayId>(mIdVariant);
}
ftl::Optional<DisplayId> Display::getDisplayId() const {
- return mId;
+ return getId();
+}
+
+ftl::Optional<DisplayIdVariant> Display::getDisplayIdVariant() const {
+ return mIdVariant;
}
void Display::disconnect() {
@@ -93,14 +97,14 @@ void Display::disconnect() {
mIsDisconnected = true;
- if (const auto id = HalDisplayId::tryCast(mId)) {
+ if (const auto id = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) {
getCompositionEngine().getHwComposer().disconnectDisplay(*id);
}
}
void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
Output::setColorTransform(args);
- const auto halDisplayId = HalDisplayId::tryCast(mId);
+ const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
if (mIsDisconnected || !halDisplayId || CC_LIKELY(!args.colorTransformMatrix)) {
return;
}
@@ -108,7 +112,7 @@ void Display::setColorTransform(const compositionengine::CompositionRefreshArgs&
auto& hwc = getCompositionEngine().getHwComposer();
status_t result = hwc.setColorTransform(*halDisplayId, *args.colorTransformMatrix);
ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display \"%s\": %d",
- to_string(mId).c_str(), result);
+ to_string(*halDisplayId).c_str(), result);
}
void Display::setColorProfile(const ColorProfile& colorProfile) {
@@ -125,7 +129,7 @@ void Display::setColorProfile(const ColorProfile& colorProfile) {
Output::setColorProfile(colorProfile);
- const auto physicalId = PhysicalDisplayId::tryCast(mId);
+ const auto physicalId = getDisplayIdVariant().and_then(asPhysicalDisplayId);
LOG_FATAL_IF(!physicalId);
getCompositionEngine().getHwComposer().setActiveColorMode(*physicalId, colorProfile.mode,
colorProfile.renderIntent);
@@ -133,7 +137,7 @@ void Display::setColorProfile(const ColorProfile& colorProfile) {
void Display::dump(std::string& out) const {
const char* const type = isVirtual() ? "virtual" : "physical";
- base::StringAppendF(&out, "Display %s (%s, \"%s\")", to_string(mId).c_str(), type,
+ base::StringAppendF(&out, "Display %s (%s, \"%s\")", to_string(getId()).c_str(), type,
getName().c_str());
out.append("\n Composition Display State:\n");
@@ -157,7 +161,7 @@ std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
const sp<compositionengine::LayerFE>& layerFE) const {
auto outputLayer = impl::createOutputLayer(*this, layerFE);
- if (const auto halDisplayId = HalDisplayId::tryCast(mId);
+ if (const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
outputLayer && !mIsDisconnected && halDisplayId) {
auto& hwc = getCompositionEngine().getHwComposer();
auto hwcLayer = hwc.createLayer(*halDisplayId);
@@ -171,8 +175,7 @@ std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
void Display::setReleasedLayers(const compositionengine::CompositionRefreshArgs& refreshArgs) {
Output::setReleasedLayers(refreshArgs);
- if (mIsDisconnected || GpuVirtualDisplayId::tryCast(mId) ||
- refreshArgs.layersWithQueuedFrames.empty()) {
+ if (mIsDisconnected || isGpuVirtualDisplay() || refreshArgs.layersWithQueuedFrames.empty()) {
return;
}
@@ -208,7 +211,7 @@ void Display::applyDisplayBrightness(bool applyImmediately) {
if (!getState().displayBrightness) {
return;
}
- if (auto displayId = PhysicalDisplayId::tryCast(mId)) {
+ if (auto displayId = getDisplayIdVariant().and_then(asPhysicalDisplayId)) {
auto& hwc = getCompositionEngine().getHwComposer();
status_t result = hwc.setDisplayBrightness(*displayId, *getState().displayBrightness,
getState().displayBrightnessNits,
@@ -226,7 +229,7 @@ void Display::beginFrame() {
Output::beginFrame();
// If we don't have a HWC display, then we are done.
- const auto halDisplayId = HalDisplayId::tryCast(mId);
+ const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
if (!halDisplayId) {
return;
}
@@ -244,7 +247,7 @@ bool Display::chooseCompositionStrategy(
}
// If we don't have a HWC display, then we are done.
- const auto halDisplayId = HalDisplayId::tryCast(mId);
+ const auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
if (!halDisplayId) {
return false;
}
@@ -266,9 +269,9 @@ bool Display::chooseCompositionStrategy(
}
if (isPowerHintSessionEnabled()) {
- mPowerAdvisor->setHwcValidateTiming(mId, hwcValidateStartTime, TimePoint::now());
- if (auto halDisplayId = HalDisplayId::tryCast(mId)) {
- mPowerAdvisor->setSkippedValidate(mId, hwc.getValidateSkipped(*halDisplayId));
+ mPowerAdvisor->setHwcValidateTiming(getId(), hwcValidateStartTime, TimePoint::now());
+ if (auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) {
+ mPowerAdvisor->setSkippedValidate(*halDisplayId, hwc.getValidateSkipped(*halDisplayId));
}
}
@@ -292,7 +295,7 @@ void Display::applyCompositionStrategy(const std::optional<DeviceRequestedChange
bool Display::getSkipColorTransform() const {
auto& hwc = getCompositionEngine().getHwComposer();
- if (auto halDisplayId = HalDisplayId::tryCast(mId)) {
+ if (auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) {
return hwc.hasDisplayCapability(*halDisplayId,
DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
}
@@ -383,7 +386,7 @@ void Display::applyLayerLutsToLayers(const LayerLuts& layerLuts) {
}
void Display::executeCommands() {
- const auto halDisplayIdOpt = HalDisplayId::tryCast(mId);
+ const auto halDisplayIdOpt = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
if (mIsDisconnected || !halDisplayIdOpt) {
return;
}
@@ -394,7 +397,7 @@ void Display::executeCommands() {
compositionengine::Output::FrameFences Display::presentFrame() {
auto fences = impl::Output::presentFrame();
- const auto halDisplayIdOpt = HalDisplayId::tryCast(mId);
+ const auto halDisplayIdOpt = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>);
if (mIsDisconnected || !halDisplayIdOpt) {
return fences;
}
@@ -404,13 +407,13 @@ compositionengine::Output::FrameFences Display::presentFrame() {
const TimePoint startTime = TimePoint::now();
if (isPowerHintSessionEnabled() && getState().earliestPresentTime) {
- mPowerAdvisor->setHwcPresentDelayedTime(mId, *getState().earliestPresentTime);
+ mPowerAdvisor->setHwcPresentDelayedTime(*halDisplayIdOpt, *getState().earliestPresentTime);
}
hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime);
if (isPowerHintSessionEnabled()) {
- mPowerAdvisor->setHwcPresentTiming(mId, startTime, TimePoint::now());
+ mPowerAdvisor->setHwcPresentTiming(*halDisplayIdOpt, startTime, TimePoint::now());
}
fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
@@ -433,8 +436,8 @@ compositionengine::Output::FrameFences Display::presentFrame() {
void Display::setExpensiveRenderingExpected(bool enabled) {
Output::setExpensiveRenderingExpected(enabled);
- if (mPowerAdvisor && !GpuVirtualDisplayId::tryCast(mId)) {
- mPowerAdvisor->setExpensiveRenderingExpected(mId, enabled);
+ if (mPowerAdvisor && !isGpuVirtualDisplay()) {
+ mPowerAdvisor->setExpensiveRenderingExpected(getId(), enabled);
}
}
@@ -449,15 +452,15 @@ bool Display::isPowerHintSessionGpuReportingEnabled() {
// For ADPF GPU v0 this is expected to set start time to when the GPU commands are submitted with
// fence returned, i.e. when RenderEngine flushes the commands and returns the draw fence.
void Display::setHintSessionGpuStart(TimePoint startTime) {
- mPowerAdvisor->setGpuStartTime(mId, startTime);
+ mPowerAdvisor->setGpuStartTime(getId(), startTime);
}
void Display::setHintSessionGpuFence(std::unique_ptr<FenceTime>&& gpuFence) {
- mPowerAdvisor->setGpuFenceTime(mId, std::move(gpuFence));
+ mPowerAdvisor->setGpuFenceTime(getId(), std::move(gpuFence));
}
void Display::setHintSessionRequiresRenderEngine(bool requiresRenderEngine) {
- mPowerAdvisor->setRequiresRenderEngine(mId, requiresRenderEngine);
+ mPowerAdvisor->setRequiresRenderEngine(getId(), requiresRenderEngine);
}
const aidl::android::hardware::graphics::composer3::OverlayProperties*
@@ -478,7 +481,7 @@ void Display::finishFrame(GpuCompositionResult&& result) {
// 1) It is being handled by hardware composer, which may need this to
// keep its virtual display state machine in sync, or
// 2) There is work to be done (the dirty region isn't empty)
- if (GpuVirtualDisplayId::tryCast(mId) && !mustRecompose()) {
+ if (isGpuVirtualDisplay() && !mustRecompose()) {
ALOGV("Skipping display composition");
return;
}
@@ -487,7 +490,7 @@ void Display::finishFrame(GpuCompositionResult&& result) {
}
bool Display::supportsOffloadPresent() const {
- if (auto halDisplayId = HalDisplayId::tryCast(mId)) {
+ if (auto halDisplayId = getDisplayIdVariant().and_then(asHalDisplayId<DisplayIdVariant>)) {
auto& hwc = getCompositionEngine().getHwComposer();
return hwc.hasDisplayCapability(*halDisplayId, DisplayCapability::MULTI_THREADED_PRESENT);
}
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index b30cf20121..00a61a5ab6 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -118,6 +118,10 @@ ftl::Optional<DisplayId> Output::getDisplayId() const {
return {};
}
+ftl::Optional<DisplayIdVariant> Output::getDisplayIdVariant() const {
+ return {};
+}
+
const std::string& Output::getName() const {
return mName;
}
@@ -436,8 +440,8 @@ void Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArg
ftl::Future<std::monostate> Output::present(
const compositionengine::CompositionRefreshArgs& refreshArgs) {
const auto stringifyExpectedPresentTime = [this, &refreshArgs]() -> std::string {
- return getDisplayId()
- .and_then(PhysicalDisplayId::tryCast)
+ return getDisplayIdVariant()
+ .and_then(asPhysicalDisplayId)
.and_then([&refreshArgs](PhysicalDisplayId id) {
return refreshArgs.frameTargets.get(id);
})
@@ -890,8 +894,8 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr
return;
}
- if (auto frameTargetPtrOpt = getDisplayId()
- .and_then(PhysicalDisplayId::tryCast)
+ if (auto frameTargetPtrOpt = getDisplayIdVariant()
+ .and_then(asPhysicalDisplayId)
.and_then([&refreshArgs](PhysicalDisplayId id) {
return refreshArgs.frameTargets.get(id);
})) {
@@ -1672,6 +1676,7 @@ void Output::presentFrameAndReleaseLayers(bool flushEvenWhenDisabled) {
Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence);
}
layer->getLayerFE().setReleaseFence(releaseFence);
+ layer->getLayerFE().setReleasedBuffer(layer->getLayerFE().getCompositionState()->buffer);
}
// We've got a list of layers needing fences, that are disjoint with
@@ -1841,7 +1846,7 @@ void Output::applyPictureProfile() {
if (!getDisplayId()) {
return;
}
- if (auto displayId = PhysicalDisplayId::tryCast(*getDisplayId())) {
+ if (auto displayId = getDisplayIdVariant().and_then(asPhysicalDisplayId)) {
auto& hwc = getCompositionEngine().getHwComposer();
const status_t error =
hwc.setDisplayPictureProfileHandle(*displayId, getState().pictureProfileHandle);
diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
index ad65c4422e..34c09db6f8 100644
--- a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
@@ -43,6 +43,10 @@ using ::testing::ReturnRef;
using ::testing::SaveArg;
using ::testing::StrictMock;
+static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(123u);
+static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(234u);
+static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(567u);
+
struct CompositionEngineTest : public testing::Test {
std::shared_ptr<TimeStats> mTimeStats;
@@ -52,6 +56,31 @@ struct CompositionEngineTest : public testing::Test {
std::shared_ptr<mock::Output> mOutput1{std::make_shared<StrictMock<mock::Output>>()};
std::shared_ptr<mock::Output> mOutput2{std::make_shared<StrictMock<mock::Output>>()};
std::shared_ptr<mock::Output> mOutput3{std::make_shared<StrictMock<mock::Output>>()};
+
+ std::array<impl::OutputCompositionState, 3> mOutputStates;
+
+ void SetUp() override {
+ EXPECT_CALL(*mOutput1, getDisplayId)
+ .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId1)));
+ EXPECT_CALL(*mOutput1, getDisplayIdVariant).WillRepeatedly(Return(kDisplayId1));
+
+ EXPECT_CALL(*mOutput2, getDisplayId)
+ .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId2)));
+ EXPECT_CALL(*mOutput2, getDisplayIdVariant).WillRepeatedly(Return(kDisplayId2));
+
+ EXPECT_CALL(*mOutput3, getDisplayId)
+ .WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId3)));
+ EXPECT_CALL(*mOutput3, getDisplayIdVariant).WillRepeatedly(Return(kDisplayId3));
+
+ // Most tests will depend on the outputs being enabled.
+ for (auto& state : mOutputStates) {
+ state.isEnabled = true;
+ }
+
+ EXPECT_CALL(*mOutput1, getState).WillRepeatedly(ReturnRef(mOutputStates[0]));
+ EXPECT_CALL(*mOutput2, getState).WillRepeatedly(ReturnRef(mOutputStates[1]));
+ EXPECT_CALL(*mOutput3, getState).WillRepeatedly(ReturnRef(mOutputStates[2]));
+ }
};
TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
@@ -94,7 +123,7 @@ struct CompositionEnginePresentTest : public CompositionEngineTest {
StrictMock<CompositionEnginePartialMock> mEngine;
};
-TEST_F(CompositionEnginePresentTest, worksWithEmptyRequest) {
+TEST_F(CompositionEnginePresentTest, zeroOutputs) {
// present() always calls preComposition() and postComposition()
EXPECT_CALL(mEngine, preComposition(Ref(mRefreshArgs)));
EXPECT_CALL(mEngine, postComposition(Ref(mRefreshArgs)));
@@ -102,7 +131,7 @@ TEST_F(CompositionEnginePresentTest, worksWithEmptyRequest) {
mEngine.present(mRefreshArgs);
}
-TEST_F(CompositionEnginePresentTest, worksAsExpected) {
+TEST_F(CompositionEnginePresentTest, threeOutputs) {
// Expect calls to in a certain sequence
InSequence seq;
@@ -114,9 +143,7 @@ TEST_F(CompositionEnginePresentTest, worksAsExpected) {
EXPECT_CALL(*mOutput2, prepare(Ref(mRefreshArgs), _));
EXPECT_CALL(*mOutput3, prepare(Ref(mRefreshArgs), _));
- // All of mOutput<i> are StrictMocks. If the flag is true, it will introduce
- // calls to getDisplayId, which are not relevant to this test.
- SET_FLAG_FOR_TEST(flags::multithreaded_present, false);
+ EXPECT_CALL(*mOutput1, supportsOffloadPresent).WillOnce(Return(false));
// The last step is to actually present each output.
EXPECT_CALL(*mOutput1, present(Ref(mRefreshArgs)))
@@ -284,8 +311,6 @@ struct CompositionEngineOffloadTest : public testing::Test {
std::shared_ptr<mock::Output> mVirtualDisplay{std::make_shared<StrictMock<mock::Output>>()};
std::shared_ptr<mock::Output> mHalVirtualDisplay{std::make_shared<StrictMock<mock::Output>>()};
- static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(123u);
- static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(234u);
static constexpr GpuVirtualDisplayId kGpuVirtualDisplayId{789u};
static constexpr HalVirtualDisplayId kHalVirtualDisplayId{456u};
@@ -294,12 +319,23 @@ struct CompositionEngineOffloadTest : public testing::Test {
void SetUp() override {
EXPECT_CALL(*mDisplay1, getDisplayId)
.WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId1)));
+ EXPECT_CALL(*mDisplay1, getDisplayIdVariant).WillRepeatedly(Return(kDisplayId1));
+
EXPECT_CALL(*mDisplay2, getDisplayId)
.WillRepeatedly(Return(std::make_optional<DisplayId>(kDisplayId2)));
+ EXPECT_CALL(*mDisplay2, getDisplayIdVariant).WillRepeatedly(Return(kDisplayId2));
+
EXPECT_CALL(*mVirtualDisplay, getDisplayId)
.WillRepeatedly(Return(std::make_optional<DisplayId>(kGpuVirtualDisplayId)));
+ const DisplayIdVariant gpuVariant =
+ GpuVirtualDisplayId::fromValue(kGpuVirtualDisplayId.value);
+ EXPECT_CALL(*mVirtualDisplay, getDisplayIdVariant).WillRepeatedly(Return(gpuVariant));
+
EXPECT_CALL(*mHalVirtualDisplay, getDisplayId)
.WillRepeatedly(Return(std::make_optional<DisplayId>(kHalVirtualDisplayId)));
+ const DisplayIdVariant halVariant =
+ HalVirtualDisplayId::fromValue(kHalVirtualDisplayId.value);
+ EXPECT_CALL(*mHalVirtualDisplay, getDisplayIdVariant).WillRepeatedly(Return(halVariant));
// Most tests will depend on the outputs being enabled.
for (auto& state : mOutputStates) {
@@ -332,7 +368,6 @@ TEST_F(CompositionEngineOffloadTest, basic) {
EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1);
EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
setOutputs({mDisplay1, mDisplay2});
mEngine.present(mRefreshArgs);
@@ -345,7 +380,6 @@ TEST_F(CompositionEngineOffloadTest, dependsOnSupport) {
EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
setOutputs({mDisplay1, mDisplay2});
mEngine.present(mRefreshArgs);
@@ -358,20 +392,6 @@ TEST_F(CompositionEngineOffloadTest, dependsOnSupport2) {
EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
- setOutputs({mDisplay1, mDisplay2});
-
- mEngine.present(mRefreshArgs);
-}
-
-TEST_F(CompositionEngineOffloadTest, dependsOnFlag) {
- EXPECT_CALL(*mDisplay1, supportsOffloadPresent).Times(0);
- EXPECT_CALL(*mDisplay2, supportsOffloadPresent).Times(0);
-
- EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
- EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
-
- SET_FLAG_FOR_TEST(flags::multithreaded_present, false);
setOutputs({mDisplay1, mDisplay2});
mEngine.present(mRefreshArgs);
@@ -382,7 +402,6 @@ TEST_F(CompositionEngineOffloadTest, oneDisplay) {
EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
setOutputs({mDisplay1});
mEngine.present(mRefreshArgs);
@@ -397,7 +416,6 @@ TEST_F(CompositionEngineOffloadTest, virtualDisplay) {
EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
EXPECT_CALL(*mVirtualDisplay, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
setOutputs({mDisplay1, mDisplay2, mVirtualDisplay});
mEngine.present(mRefreshArgs);
@@ -410,7 +428,6 @@ TEST_F(CompositionEngineOffloadTest, virtualDisplay2) {
EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
EXPECT_CALL(*mVirtualDisplay, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
setOutputs({mDisplay1, mVirtualDisplay});
mEngine.present(mRefreshArgs);
@@ -423,7 +440,6 @@ TEST_F(CompositionEngineOffloadTest, halVirtual) {
EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1);
EXPECT_CALL(*mHalVirtualDisplay, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
setOutputs({mDisplay1, mHalVirtualDisplay});
mEngine.present(mRefreshArgs);
@@ -440,7 +456,6 @@ TEST_F(CompositionEngineOffloadTest, ordering) {
EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(1);
EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
setOutputs({mVirtualDisplay, mHalVirtualDisplay, mDisplay1, mDisplay2});
mEngine.present(mRefreshArgs);
@@ -458,7 +473,6 @@ TEST_F(CompositionEngineOffloadTest, dependsOnEnabled) {
EXPECT_CALL(*mDisplay1, offloadPresentNextFrame).Times(0);
EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
setOutputs({mDisplay1, mDisplay2});
mEngine.present(mRefreshArgs);
@@ -478,7 +492,6 @@ TEST_F(CompositionEngineOffloadTest, disabledDisplaysDoNotPreventOthersFromOfflo
EXPECT_CALL(*mDisplay2, offloadPresentNextFrame).Times(0);
EXPECT_CALL(*mHalVirtualDisplay, offloadPresentNextFrame).Times(0);
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
setOutputs({mDisplay1, mDisplay2, mHalVirtualDisplay});
mEngine.present(mRefreshArgs);
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index c1e59d01de..77fd4466ef 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -278,7 +278,7 @@ TEST_F(DisplayCreationTest, createGpuVirtualDisplay) {
impl::createDisplay(mCompositionEngine, getDisplayCreationArgsForGpuVirtualDisplay());
EXPECT_FALSE(display->isSecure());
EXPECT_TRUE(display->isVirtual());
- EXPECT_TRUE(GpuVirtualDisplayId::tryCast(display->getId()));
+ EXPECT_TRUE(display->getDisplayIdVariant().and_then(asDisplayIdOfType<GpuVirtualDisplayId>));
}
/*
@@ -318,6 +318,7 @@ TEST_F(DisplaySetConfigurationTest, configuresHalVirtualDisplay) {
EXPECT_EQ(HAL_VIRTUAL_DISPLAY_ID, mDisplay->getId());
EXPECT_FALSE(mDisplay->isSecure());
EXPECT_TRUE(mDisplay->isVirtual());
+ EXPECT_TRUE(mDisplay->getDisplayIdVariant().and_then(asDisplayIdOfType<HalVirtualDisplayId>));
EXPECT_FALSE(mDisplay->isValid());
const auto& filter = mDisplay->getState().layerFilter;
@@ -337,6 +338,7 @@ TEST_F(DisplaySetConfigurationTest, configuresGpuVirtualDisplay) {
EXPECT_EQ(GPU_VIRTUAL_DISPLAY_ID, mDisplay->getId());
EXPECT_FALSE(mDisplay->isSecure());
EXPECT_TRUE(mDisplay->isVirtual());
+ EXPECT_TRUE(mDisplay->getDisplayIdVariant().and_then(asDisplayIdOfType<GpuVirtualDisplayId>));
EXPECT_FALSE(mDisplay->isValid());
const auto& filter = mDisplay->getState().layerFilter;
@@ -572,7 +574,7 @@ TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfGpuDisplay) {
auto args = getDisplayCreationArgsForGpuVirtualDisplay();
std::shared_ptr<Display> gpuDisplay =
createPartialMockDisplay<Display>(mCompositionEngine, args);
- EXPECT_TRUE(GpuVirtualDisplayId::tryCast(gpuDisplay->getId()));
+ EXPECT_TRUE(gpuDisplay->getDisplayIdVariant().and_then(asDisplayIdOfType<GpuVirtualDisplayId>));
chooseCompositionStrategy(gpuDisplay.get());
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 09ad9fa497..590626ace5 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -148,20 +148,23 @@ struct OutputTest : public testing::Test {
virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
virtual ftl::Optional<DisplayId> getDisplayId() const override { return mId; }
+ virtual ftl::Optional<DisplayIdVariant> getDisplayIdVariant() const override {
+ return DisplayIdVariant(mId);
+ }
virtual bool hasPictureProcessing() const override { return mHasPictureProcessing; }
virtual int32_t getMaxLayerPictureProfiles() const override {
return mMaxLayerPictureProfiles;
}
- void setDisplayIdForTest(DisplayId value) { mId = value; }
+ void setDisplayIdForTest(PhysicalDisplayId value) { mId = value; }
void setHasPictureProcessingForTest(bool value) { mHasPictureProcessing = value; }
void setMaxLayerPictureProfilesForTest(int32_t value) { mMaxLayerPictureProfiles = value; }
private:
- ftl::Optional<DisplayId> mId;
+ PhysicalDisplayId mId;
bool mHasPictureProcessing;
int32_t mMaxLayerPictureProfiles;
};
@@ -3311,6 +3314,17 @@ TEST_F(OutputPostFramebufferTest, releaseFencesAreSetInLayerFE) {
sp<Fence> layer2Fence = sp<Fence>::make();
sp<Fence> layer3Fence = sp<Fence>::make();
+ // Set up layerfe buffers
+ LayerFECompositionState layer1State;
+ layer1State.buffer = sp<GraphicBuffer>::make();
+ LayerFECompositionState layer2State;
+ layer2State.buffer = sp<GraphicBuffer>::make();
+ LayerFECompositionState layer3State;
+ layer3State.buffer = nullptr;
+ EXPECT_CALL(*mLayer1.layerFE, getCompositionState()).WillOnce(Return(&layer1State));
+ EXPECT_CALL(*mLayer2.layerFE, getCompositionState()).WillOnce(Return(&layer2State));
+ EXPECT_CALL(*mLayer3.layerFE, getCompositionState()).WillOnce(Return(&layer3State));
+
Output::FrameFences frameFences;
frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
@@ -3327,14 +3341,23 @@ TEST_F(OutputPostFramebufferTest, releaseFencesAreSetInLayerFE) {
.WillOnce([&layer1Fence](FenceResult releaseFence) {
EXPECT_EQ(FenceResult(layer1Fence), releaseFence);
});
+ EXPECT_CALL(*mLayer1.layerFE, setReleasedBuffer(_)).WillOnce([&](sp<GraphicBuffer> buffer) {
+ EXPECT_EQ(layer1State.buffer, buffer);
+ });
EXPECT_CALL(*mLayer2.layerFE, setReleaseFence(_))
.WillOnce([&layer2Fence](FenceResult releaseFence) {
EXPECT_EQ(FenceResult(layer2Fence), releaseFence);
});
+ EXPECT_CALL(*mLayer2.layerFE, setReleasedBuffer(_)).WillOnce([&](sp<GraphicBuffer> buffer) {
+ EXPECT_EQ(layer2State.buffer, buffer);
+ });
EXPECT_CALL(*mLayer3.layerFE, setReleaseFence(_))
.WillOnce([&layer3Fence](FenceResult releaseFence) {
EXPECT_EQ(FenceResult(layer3Fence), releaseFence);
});
+ EXPECT_CALL(*mLayer3.layerFE, setReleasedBuffer(_)).WillOnce([&](sp<GraphicBuffer> buffer) {
+ EXPECT_EQ(layer3State.buffer, buffer);
+ });
constexpr bool kFlushEvenWhenDisabled = false;
mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
@@ -3350,6 +3373,17 @@ TEST_F(OutputPostFramebufferTest, setReleaseFencesIncludeClientTargetAcquireFenc
frameFences.layerFences.emplace(&mLayer2.hwc2Layer, sp<Fence>::make());
frameFences.layerFences.emplace(&mLayer3.hwc2Layer, sp<Fence>::make());
+ // Set up layerfe buffers
+ LayerFECompositionState layer1State;
+ layer1State.buffer = sp<GraphicBuffer>::make();
+ LayerFECompositionState layer2State;
+ layer2State.buffer = sp<GraphicBuffer>::make();
+ LayerFECompositionState layer3State;
+ layer3State.buffer = nullptr;
+ EXPECT_CALL(*mLayer1.layerFE, getCompositionState()).WillOnce(Return(&layer1State));
+ EXPECT_CALL(*mLayer2.layerFE, getCompositionState()).WillOnce(Return(&layer2State));
+ EXPECT_CALL(*mLayer3.layerFE, getCompositionState()).WillOnce(Return(&layer3State));
+
EXPECT_CALL(mOutput, presentFrame()).WillOnce(Return(frameFences));
EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
@@ -3359,6 +3393,15 @@ TEST_F(OutputPostFramebufferTest, setReleaseFencesIncludeClientTargetAcquireFenc
EXPECT_CALL(*mLayer1.layerFE, setReleaseFence).WillOnce(Return());
EXPECT_CALL(*mLayer2.layerFE, setReleaseFence).WillOnce(Return());
EXPECT_CALL(*mLayer3.layerFE, setReleaseFence).WillOnce(Return());
+ EXPECT_CALL(*mLayer1.layerFE, setReleasedBuffer(_)).WillOnce([&](sp<GraphicBuffer> buffer) {
+ EXPECT_EQ(layer1State.buffer, buffer);
+ });
+ EXPECT_CALL(*mLayer2.layerFE, setReleasedBuffer(_)).WillOnce([&](sp<GraphicBuffer> buffer) {
+ EXPECT_EQ(layer2State.buffer, buffer);
+ });
+ EXPECT_CALL(*mLayer3.layerFE, setReleasedBuffer(_)).WillOnce([&](sp<GraphicBuffer> buffer) {
+ EXPECT_EQ(layer3State.buffer, buffer);
+ });
constexpr bool kFlushEvenWhenDisabled = false;
mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
}
@@ -3401,7 +3444,6 @@ TEST_F(OutputPostFramebufferTest, setReleasedLayersSentPresentFence) {
.WillOnce([&presentFence](FenceResult fenceResult) {
EXPECT_EQ(FenceResult(presentFence), fenceResult);
});
-
constexpr bool kFlushEvenWhenDisabled = false;
mOutput.presentFrameAndReleaseLayers(kFlushEvenWhenDisabled);
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index b39654437f..de7d455fa4 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -26,7 +26,6 @@
#include <common/trace.h>
#include <compositionengine/CompositionEngine.h>
-#include <compositionengine/Display.h>
#include <compositionengine/DisplayColorProfile.h>
#include <compositionengine/DisplayColorProfileCreationArgs.h>
#include <compositionengine/DisplayCreationArgs.h>
@@ -51,17 +50,6 @@ namespace android {
namespace hal = hardware::graphics::composer::hal;
-namespace gui {
-inline std::string_view to_string(ISurfaceComposer::OptimizationPolicy optimizationPolicy) {
- switch (optimizationPolicy) {
- case ISurfaceComposer::OptimizationPolicy::optimizeForPower:
- return "optimizeForPower";
- case ISurfaceComposer::OptimizationPolicy::optimizeForPerformance:
- return "optimizeForPerformance";
- }
-}
-} // namespace gui
-
DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(
const sp<SurfaceFlinger>& flinger, HWComposer& hwComposer, const wp<IBinder>& displayToken,
std::shared_ptr<compositionengine::Display> compositionDisplay)
@@ -308,6 +296,10 @@ DisplayId DisplayDevice::getId() const {
return mCompositionDisplay->getId();
}
+bool DisplayDevice::isVirtual() const {
+ return mCompositionDisplay->isVirtual();
+}
+
bool DisplayDevice::isSecure() const {
return mCompositionDisplay->isSecure();
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 02522a3deb..1b14145147 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -23,6 +23,8 @@
#include <android-base/thread_annotations.h>
#include <android/native_window.h>
#include <binder/IBinder.h>
+#include <compositionengine/Display.h>
+#include <compositionengine/DisplaySurface.h>
#include <gui/LayerState.h>
#include <math/mat4.h>
#include <renderengine/RenderEngine.h>
@@ -61,15 +63,21 @@ class SurfaceFlinger;
struct CompositionInfo;
struct DisplayDeviceCreationArgs;
-namespace compositionengine {
-class Display;
-class DisplaySurface;
-} // namespace compositionengine
-
namespace display {
class DisplaySnapshot;
} // namespace display
+namespace gui {
+inline const char* to_string(ISurfaceComposer::OptimizationPolicy optimizationPolicy) {
+ switch (optimizationPolicy) {
+ case ISurfaceComposer::OptimizationPolicy::optimizeForPower:
+ return "optimizeForPower";
+ case ISurfaceComposer::OptimizationPolicy::optimizeForPerformance:
+ return "optimizeForPerformance";
+ }
+}
+} // namespace gui
+
class DisplayDevice : public RefBase {
public:
constexpr static float sDefaultMinLumiance = 0.0;
@@ -85,7 +93,7 @@ public:
return mCompositionDisplay;
}
- bool isVirtual() const { return getId().isVirtual(); }
+ bool isVirtual() const;
bool isPrimary() const { return mIsPrimary; }
// isSecure indicates whether this display can be trusted to display
@@ -123,17 +131,30 @@ public:
DisplayId getId() const;
+ DisplayIdVariant getDisplayIdVariant() const {
+ const auto idVariant = mCompositionDisplay->getDisplayIdVariant();
+ LOG_FATAL_IF(!idVariant);
+ return *idVariant;
+ }
+
+ std::optional<VirtualDisplayIdVariant> getVirtualDisplayIdVariant() const {
+ return ftl::match(
+ getDisplayIdVariant(),
+ [](PhysicalDisplayId) { return std::optional<VirtualDisplayIdVariant>(); },
+ [](auto id) { return std::optional<VirtualDisplayIdVariant>(id); });
+ }
+
// Shorthand to upcast the ID of a display whose type is known as a precondition.
PhysicalDisplayId getPhysicalId() const {
- const auto id = PhysicalDisplayId::tryCast(getId());
- LOG_FATAL_IF(!id);
- return *id;
+ const auto physicalDisplayId = asPhysicalDisplayId(getDisplayIdVariant());
+ LOG_FATAL_IF(!physicalDisplayId);
+ return *physicalDisplayId;
}
VirtualDisplayId getVirtualId() const {
- const auto id = VirtualDisplayId::tryCast(getId());
- LOG_FATAL_IF(!id);
- return *id;
+ const auto virtualDisplayId = asVirtualDisplayId(getDisplayIdVariant());
+ LOG_FATAL_IF(!virtualDisplayId);
+ return *virtualDisplayId;
}
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
diff --git a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
index bb6bebed8d..d547af98ea 100644
--- a/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
@@ -1773,7 +1773,6 @@ void AidlComposer::onHotplugDisconnect(Display display) {
}
bool AidlComposer::hasMultiThreadedPresentSupport(Display display) {
- if (!FlagManager::getInstance().multithreaded_present()) return false;
const auto displayId = translate<int64_t>(display);
std::vector<AidlDisplayCapability> capabilities;
const auto status = mAidlComposerClient->getDisplayCapabilities(displayId, &capabilities);
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 384f7b22c7..56ed11f07a 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -47,7 +47,8 @@
namespace android {
-VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, VirtualDisplayId displayId,
+VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc,
+ VirtualDisplayIdVariant virtualIdVariant,
const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer,
@@ -58,7 +59,7 @@ VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, VirtualDisplayId d
: ConsumerBase(bqConsumer),
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
mHwc(hwc),
- mDisplayId(displayId),
+ mVirtualIdVariant(virtualIdVariant),
mDisplayName(name),
mSource{},
mDefaultOutputFormat(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
@@ -119,7 +120,7 @@ VirtualDisplaySurface::~VirtualDisplaySurface() {
}
status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) {
- if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+ if (isBackedByGpu()) {
return NO_ERROR;
}
@@ -133,7 +134,7 @@ status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) {
}
status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
- if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+ if (isBackedByGpu()) {
return NO_ERROR;
}
@@ -181,7 +182,10 @@ status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
}
status_t VirtualDisplaySurface::advanceFrame(float hdrSdrRatio) {
- if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+ const auto halVirtualDisplayId = ftl::match(
+ mVirtualIdVariant, [](HalVirtualDisplayId id) { return ftl::Optional(id); },
+ [](auto) { return ftl::Optional<HalVirtualDisplayId>(); });
+ if (!halVirtualDisplayId) {
return NO_ERROR;
}
@@ -212,11 +216,8 @@ status_t VirtualDisplaySurface::advanceFrame(float hdrSdrRatio) {
VDS_LOGV("%s: fb=%d(%p) out=%d(%p)", __func__, mFbProducerSlot, fbBuffer.get(),
mOutputProducerSlot, outBuffer.get());
- const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
- LOG_FATAL_IF(!halDisplayId);
- // At this point we know the output buffer acquire fence,
- // so update HWC state with it.
- mHwc.setOutputBuffer(*halDisplayId, mOutputFence, outBuffer);
+ // At this point we know the output buffer acquire fence, so update HWC state with it.
+ mHwc.setOutputBuffer(*halVirtualDisplayId, mOutputFence, outBuffer);
status_t result = NO_ERROR;
if (fbBuffer != nullptr) {
@@ -227,7 +228,7 @@ status_t VirtualDisplaySurface::advanceFrame(float hdrSdrRatio) {
hwcBuffer = fbBuffer; // HWC hasn't previously seen this buffer in this slot
}
// TODO: Correctly propagate the dataspace from GL composition
- result = mHwc.setClientTarget(*halDisplayId, mFbProducerSlot, mFbFence, hwcBuffer,
+ result = mHwc.setClientTarget(*halVirtualDisplayId, mFbProducerSlot, mFbFence, hwcBuffer,
ui::Dataspace::UNKNOWN, hdrSdrRatio);
}
@@ -235,8 +236,8 @@ status_t VirtualDisplaySurface::advanceFrame(float hdrSdrRatio) {
}
void VirtualDisplaySurface::onFrameCommitted() {
- const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
- if (!halDisplayId) {
+ const auto halDisplayId = asHalDisplayId(mVirtualIdVariant);
+ if (!halDisplayId.has_value()) {
return;
}
@@ -250,8 +251,7 @@ void VirtualDisplaySurface::onFrameCommitted() {
Mutex::Autolock lock(mMutex);
int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot);
VDS_LOGV("%s: release scratch sslot=%d", __func__, sslot);
- addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot],
- retireFence);
+ addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], retireFence);
releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot]);
}
@@ -299,7 +299,7 @@ const sp<Fence>& VirtualDisplaySurface::getClientTargetAcquireFence() const {
status_t VirtualDisplaySurface::requestBuffer(int pslot,
sp<GraphicBuffer>* outBuf) {
- if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+ if (isBackedByGpu()) {
return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf);
}
@@ -321,7 +321,7 @@ status_t VirtualDisplaySurface::setAsyncMode(bool async) {
status_t VirtualDisplaySurface::dequeueBuffer(Source source,
PixelFormat format, uint64_t usage, int* sslot, sp<Fence>* fence) {
- LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value());
+ LOG_ALWAYS_FATAL_IF(isBackedByGpu());
status_t result =
mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight,
@@ -373,7 +373,7 @@ status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, uint
PixelFormat format, uint64_t usage,
uint64_t* outBufferAge,
FrameEventHistoryDelta* outTimestamps) {
- if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+ if (isBackedByGpu()) {
return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, w, h, format, usage, outBufferAge,
outTimestamps);
}
@@ -459,7 +459,7 @@ status_t VirtualDisplaySurface::attachBuffer(int*, const sp<GraphicBuffer>&) {
status_t VirtualDisplaySurface::queueBuffer(int pslot,
const QueueBufferInput& input, QueueBufferOutput* output) {
- if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+ if (isBackedByGpu()) {
return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output);
}
@@ -517,7 +517,7 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot,
status_t VirtualDisplaySurface::cancelBuffer(int pslot,
const sp<Fence>& fence) {
- if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+ if (isBackedByGpu()) {
return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence);
}
@@ -621,7 +621,10 @@ void VirtualDisplaySurface::resetPerFrameState() {
}
status_t VirtualDisplaySurface::refreshOutputBuffer() {
- LOG_ALWAYS_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId).has_value());
+ const auto halVirtualDisplayId = ftl::match(
+ mVirtualIdVariant, [](HalVirtualDisplayId id) { return ftl::Optional(id); },
+ [](auto) { return ftl::Optional<HalVirtualDisplayId>(); });
+ LOG_ALWAYS_FATAL_IF(!halVirtualDisplayId);
if (mOutputProducerSlot >= 0) {
mSource[SOURCE_SINK]->cancelBuffer(
@@ -640,14 +643,16 @@ status_t VirtualDisplaySurface::refreshOutputBuffer() {
// until after GPU calls queueBuffer(). So here we just set the buffer
// (for use in HWC prepare) but not the fence; we'll call this again with
// the proper fence once we have it.
- const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
- LOG_FATAL_IF(!halDisplayId);
- result = mHwc.setOutputBuffer(*halDisplayId, Fence::NO_FENCE,
+ result = mHwc.setOutputBuffer(*halVirtualDisplayId, Fence::NO_FENCE,
mProducerBuffers[mOutputProducerSlot]);
return result;
}
+bool VirtualDisplaySurface::isBackedByGpu() const {
+ return std::holds_alternative<GpuVirtualDisplayId>(mVirtualIdVariant);
+}
+
// This slot mapping function is its own inverse, so two copies are unnecessary.
// Both are kept to make the intent clear where the function is called, and for
// the (unlikely) chance that we switch to a different mapping function.
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 90426f729a..cb65c79152 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -75,7 +75,8 @@ class VirtualDisplaySurface : public compositionengine::DisplaySurface,
public BnGraphicBufferProducer,
private ConsumerBase {
public:
- VirtualDisplaySurface(HWComposer&, VirtualDisplayId, const sp<IGraphicBufferProducer>& sink,
+ VirtualDisplaySurface(HWComposer&, VirtualDisplayIdVariant,
+ const sp<IGraphicBufferProducer>& sink,
const sp<IGraphicBufferProducer>& bqProducer,
const sp<IGraphicBufferConsumer>& bqConsumer, const std::string& name);
@@ -145,6 +146,7 @@ private:
void updateQueueBufferOutput(QueueBufferOutput&&);
void resetPerFrameState();
status_t refreshOutputBuffer();
+ bool isBackedByGpu() const;
// Both the sink and scratch buffer pools have their own set of slots
// ("source slots", or "sslot"). We have to merge these into the single
@@ -159,7 +161,7 @@ private:
// Immutable after construction
//
HWComposer& mHwc;
- const VirtualDisplayId mDisplayId;
+ const VirtualDisplayIdVariant mVirtualIdVariant;
const std::string mDisplayName;
sp<IGraphicBufferProducer> mSource[2]; // indexed by SOURCE_*
uint32_t mDefaultOutputFormat;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 95a7170fbb..2e312827f2 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -722,6 +722,10 @@ void Layer::callReleaseBufferCallback(const sp<ITransactionCompletedListener>& l
uint32_t currentMaxAcquiredBufferCount =
mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
+ if (FlagManager::getInstance().monitor_buffer_fences()) {
+ buffer->getDependencyMonitor().addEgress(FenceTime::makeValid(fence), "Layer release");
+ }
+
if (listener) {
listener->onReleaseBuffer(callbackId, fence, currentMaxAcquiredBufferCount);
}
@@ -940,6 +944,7 @@ bool Layer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer,
std::max(mDrawingState.frameNumber, mDrawingState.barrierFrameNumber);
mDrawingState.releaseBufferListener = bufferData.releaseBufferListener;
+ mDrawingState.previousBuffer = std::move(mDrawingState.buffer);
mDrawingState.buffer = std::move(buffer);
mDrawingState.acquireFence = bufferData.flags.test(BufferData::BufferDataChange::fenceChanged)
? bufferData.acquireFence
@@ -1122,6 +1127,7 @@ bool Layer::setTransactionCompletedListeners(const std::vector<sp<CallbackHandle
handle->acquireTimeOrFence = mCallbackHandleAcquireTimeOrFence;
handle->frameNumber = mDrawingState.frameNumber;
handle->previousFrameNumber = mDrawingState.previousFrameNumber;
+ handle->previousBuffer = mDrawingState.previousBuffer;
if (mPreviousReleaseBufferEndpoint == handle->listener) {
// Add fence from previous screenshot now so that it can be dispatched to the
// client.
@@ -1433,8 +1439,8 @@ void Layer::onCompositionPresented(const DisplayDevice* display,
presentFence,
FrameTracer::FrameEvent::PRESENT_FENCE);
mDeprecatedFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
- } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId());
- displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
+ } else if (const auto displayId = asPhysicalDisplayId(display->getDisplayIdVariant());
+ displayId.has_value() && mFlinger->getHwComposer().isConnected(*displayId)) {
// The HWC doesn't support present fences, so use the present timestamp instead.
const nsecs_t presentTimestamp =
mFlinger->getHwComposer().getPresentTimestamp(*displayId);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 081bb22246..88754f9fa3 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -117,6 +117,7 @@ public:
uint32_t bufferTransform;
bool transformToDisplayInverse;
Region transparentRegionHint;
+ std::shared_ptr<renderengine::ExternalTexture> previousBuffer;
std::shared_ptr<renderengine::ExternalTexture> buffer;
sp<Fence> acquireFence;
std::shared_ptr<FenceTime> acquireFenceTime;
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
index b6192685ae..5e076bdae4 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -410,6 +410,15 @@ void LayerFE::setReleaseFence(const FenceResult& releaseFence) {
if (mReleaseFencePromiseStatus == ReleaseFencePromiseStatus::FULFILLED) {
return;
}
+
+ if (releaseFence.has_value()) {
+ if (FlagManager::getInstance().monitor_buffer_fences()) {
+ if (auto strongBuffer = mReleasedBuffer.promote()) {
+ strongBuffer->getDependencyMonitor()
+ .addAccessCompletion(FenceTime::makeValid(releaseFence.value()), "HWC");
+ }
+ }
+ }
mReleaseFence.set_value(releaseFence);
mReleaseFencePromiseStatus = ReleaseFencePromiseStatus::FULFILLED;
}
@@ -428,6 +437,10 @@ LayerFE::ReleaseFencePromiseStatus LayerFE::getReleaseFencePromiseStatus() {
return mReleaseFencePromiseStatus;
}
+void LayerFE::setReleasedBuffer(sp<GraphicBuffer> buffer) {
+ mReleasedBuffer = std::move(buffer);
+}
+
void LayerFE::setLastHwcState(const LayerFE::HwcLayerDebugState &state) {
mLastHwcState = state;
}
diff --git a/services/surfaceflinger/LayerFE.h b/services/surfaceflinger/LayerFE.h
index a537456beb..b89b6b4b92 100644
--- a/services/surfaceflinger/LayerFE.h
+++ b/services/surfaceflinger/LayerFE.h
@@ -18,6 +18,7 @@
#include <android/gui/CachingHint.h>
#include <gui/LayerMetadata.h>
+#include <ui/GraphicBuffer.h>
#include <ui/LayerStack.h>
#include <ui/PictureProfileHandle.h>
@@ -58,6 +59,7 @@ public:
ftl::Future<FenceResult> createReleaseFenceFuture() override;
void setReleaseFence(const FenceResult& releaseFence) override;
LayerFE::ReleaseFencePromiseStatus getReleaseFencePromiseStatus() override;
+ void setReleasedBuffer(sp<GraphicBuffer> buffer) override;
void onPictureProfileCommitted() override;
// Used for debugging purposes, e.g. perfetto tracing, dumpsys.
@@ -95,6 +97,7 @@ private:
std::promise<FenceResult> mReleaseFence;
ReleaseFencePromiseStatus mReleaseFencePromiseStatus = ReleaseFencePromiseStatus::UNINITIALIZED;
HwcLayerDebugState mLastHwcState;
+ wp<GraphicBuffer> mReleasedBuffer;
};
} // namespace android
diff --git a/services/surfaceflinger/LayerVector.h b/services/surfaceflinger/LayerVector.h
index 38dc11d3bc..81155fd697 100644
--- a/services/surfaceflinger/LayerVector.h
+++ b/services/surfaceflinger/LayerVector.h
@@ -49,7 +49,8 @@ public:
using Visitor = std::function<void(Layer*)>;
private:
- const StateSet mStateSet;
+ // FIXME: This is set but not used anywhere.
+ [[maybe_unused]] const StateSet mStateSet;
};
}
diff --git a/services/surfaceflinger/PowerAdvisor/SessionManager.h b/services/surfaceflinger/PowerAdvisor/SessionManager.h
index 93a80b55ab..afa52eb260 100644
--- a/services/surfaceflinger/PowerAdvisor/SessionManager.h
+++ b/services/surfaceflinger/PowerAdvisor/SessionManager.h
@@ -68,7 +68,8 @@ private:
bool isLayerRelevant(int32_t layerId);
// The UID of whoever created our ISessionManager connection
- const uid_t mUid;
+ // FIXME: This is set but is not used anywhere.
+ [[maybe_unused]] const uid_t mUid;
// State owned by the main thread
@@ -99,4 +100,4 @@ private:
};
} // namespace adpf
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/QueuedTransactionState.h b/services/surfaceflinger/QueuedTransactionState.h
index 86683da26c..6a17a0d0cb 100644
--- a/services/surfaceflinger/QueuedTransactionState.h
+++ b/services/surfaceflinger/QueuedTransactionState.h
@@ -25,6 +25,7 @@
#include <common/FlagManager.h>
#include <ftl/flags.h>
#include <gui/LayerState.h>
+#include <gui/TransactionState.h>
#include <system/window.h>
namespace android {
@@ -50,33 +51,26 @@ public:
struct QueuedTransactionState {
QueuedTransactionState() = default;
- QueuedTransactionState(const FrameTimelineInfo& frameTimelineInfo,
- std::vector<ResolvedComposerState>& composerStates,
- const Vector<DisplayState>& displayStates, uint32_t transactionFlags,
- const sp<IBinder>& applyToken,
- const InputWindowCommands& inputWindowCommands,
- int64_t desiredPresentTime, bool isAutoTimestamp,
- std::vector<uint64_t> uncacheBufferIds, int64_t postTime,
- bool hasListenerCallbacks,
- std::vector<ListenerCallbacks> listenerCallbacks, int originPid,
- int originUid, uint64_t transactionId,
- std::vector<uint64_t> mergedTransactionIds)
- : frameTimelineInfo(frameTimelineInfo),
- states(std::move(composerStates)),
- displays(displayStates),
- flags(transactionFlags),
- applyToken(applyToken),
- inputWindowCommands(inputWindowCommands),
- desiredPresentTime(desiredPresentTime),
- isAutoTimestamp(isAutoTimestamp),
+ QueuedTransactionState(TransactionState&& transactionState,
+ std::vector<ResolvedComposerState>&& composerStates,
+ std::vector<uint64_t>&& uncacheBufferIds, int64_t postTime,
+ int originPid, int originUid)
+ : frameTimelineInfo(std::move(transactionState.mFrameTimelineInfo)),
+ states(composerStates),
+ displays(std::move(transactionState.mDisplayStates)),
+ flags(transactionState.mFlags),
+ applyToken(transactionState.mApplyToken),
+ inputWindowCommands(std::move(transactionState.mInputWindowCommands)),
+ desiredPresentTime(transactionState.mDesiredPresentTime),
+ isAutoTimestamp(transactionState.mIsAutoTimestamp),
uncacheBufferIds(std::move(uncacheBufferIds)),
postTime(postTime),
- hasListenerCallbacks(hasListenerCallbacks),
- listenerCallbacks(listenerCallbacks),
+ hasListenerCallbacks(transactionState.mHasListenerCallbacks),
+ listenerCallbacks(std::move(transactionState.mListenerCallbacks)),
originPid(originPid),
originUid(originUid),
- id(transactionId),
- mergedTransactionIds(std::move(mergedTransactionIds)) {}
+ id(transactionState.getId()),
+ mergedTransactionIds(std::move(transactionState.mMergedTransactionIds)) {}
// Invokes `void(const layer_state_t&)` visitor for matching layers.
template <typename Visitor>
@@ -135,7 +129,7 @@ struct QueuedTransactionState {
FrameTimelineInfo frameTimelineInfo;
std::vector<ResolvedComposerState> states;
- Vector<DisplayState> displays;
+ std::vector<DisplayState> displays;
uint32_t flags;
sp<IBinder> applyToken;
InputWindowCommands inputWindowCommands;
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 514adac20c..615492a872 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -348,7 +348,7 @@ void RegionSamplingThread::captureSample() {
SurfaceFlinger::ScreenshotArgs screenshotArgs;
screenshotArgs.captureTypeVariant = displayWeak;
- screenshotArgs.displayId = std::nullopt;
+ screenshotArgs.displayIdVariant = std::nullopt;
screenshotArgs.sourceCrop = sampledBounds.isEmpty() ? layerStackSpaceRect : sampledBounds;
screenshotArgs.reqSize = sampledBounds.getSize();
screenshotArgs.dataspace = ui::Dataspace::V0_SRGB;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index e587178ec2..911d4894ce 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -554,8 +554,7 @@ void Scheduler::resyncAllToHardwareVsync(bool allowToEnable) {
ftl::FakeGuard guard(kMainThreadContext);
for (const auto& [id, display] : mDisplays) {
- if (display.powerMode != hal::PowerMode::OFF ||
- !FlagManager::getInstance().multithreaded_present()) {
+ if (display.powerMode != hal::PowerMode::OFF) {
resyncToHardwareVsyncLocked(id, allowToEnable);
}
}
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/interface/CompositionCoverage.h b/services/surfaceflinger/Scheduler/include/scheduler/interface/CompositionCoverage.h
index 767462dfce..70ae940b65 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/interface/CompositionCoverage.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/interface/CompositionCoverage.h
@@ -36,7 +36,7 @@ enum class CompositionCoverage : std::uint8_t {
using CompositionCoverageFlags = ftl::Flags<CompositionCoverage>;
-using CompositionCoveragePerDisplay = ui::DisplayMap<DisplayId, CompositionCoverageFlags>;
+using CompositionCoveragePerDisplay = ui::DisplayMap<DisplayIdVariant, CompositionCoverageFlags>;
inline CompositionCoverageFlags multiDisplayUnion(const CompositionCoveragePerDisplay& displays) {
CompositionCoverageFlags coverage;
diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp
index af6d4d30e4..2906bbd5b8 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.cpp
+++ b/services/surfaceflinger/ScreenCaptureOutput.cpp
@@ -30,11 +30,12 @@ namespace android {
std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutputArgs args) {
std::shared_ptr<ScreenCaptureOutput> output = compositionengine::impl::createOutputTemplated<
ScreenCaptureOutput, compositionengine::CompositionEngine,
- /* sourceCrop */ const Rect, std::optional<DisplayId>,
+ /* sourceCrop */ const Rect, ftl::Optional<DisplayIdVariant>,
const compositionengine::Output::ColorProfile&,
/* layerAlpha */ float,
- /* regionSampling */ bool>(args.compositionEngine, args.sourceCrop, args.displayId,
- args.colorProfile, args.layerAlpha, args.regionSampling,
+ /* regionSampling */ bool>(args.compositionEngine, args.sourceCrop,
+ args.displayIdVariant, args.colorProfile, args.layerAlpha,
+ args.regionSampling,
args.dimInGammaSpaceForEnhancedScreenshots,
args.enableLocalTonemapping);
output->editState().isSecure = args.isSecure;
@@ -59,8 +60,8 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp
{
std::string name = args.regionSampling ? "RegionSampling" : "ScreenCaptureOutput";
- if (args.displayId) {
- base::StringAppendF(&name, " for %" PRIu64, args.displayId.value().value);
+ if (const auto id = args.displayIdVariant.and_then(asDisplayIdOfType<DisplayId>)) {
+ base::StringAppendF(&name, " for %" PRIu64, id->value);
}
output->setName(name);
}
@@ -68,12 +69,12 @@ std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutp
}
ScreenCaptureOutput::ScreenCaptureOutput(
- const Rect sourceCrop, std::optional<DisplayId> displayId,
+ const Rect sourceCrop, ftl::Optional<DisplayIdVariant> displayIdVariant,
const compositionengine::Output::ColorProfile& colorProfile, float layerAlpha,
bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots,
bool enableLocalTonemapping)
: mSourceCrop(sourceCrop),
- mDisplayId(displayId),
+ mDisplayIdVariant(displayIdVariant),
mColorProfile(colorProfile),
mLayerAlpha(layerAlpha),
mRegionSampling(regionSampling),
@@ -137,12 +138,9 @@ ScreenCaptureOutput::generateLuts() {
}
std::vector<aidl::android::hardware::graphics::composer3::Luts> luts;
- if (mDisplayId) {
- const auto id = PhysicalDisplayId::tryCast(mDisplayId.value());
- if (id) {
- auto& hwc = getCompositionEngine().getHwComposer();
- hwc.getLuts(*id, buffers, &luts);
- }
+ if (const auto physicalDisplayId = mDisplayIdVariant.and_then(asPhysicalDisplayId)) {
+ auto& hwc = getCompositionEngine().getHwComposer();
+ hwc.getLuts(*physicalDisplayId, buffers, &luts);
}
if (buffers.size() == luts.size()) {
diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h
index b3e98b1a32..d4e20fc2f3 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.h
+++ b/services/surfaceflinger/ScreenCaptureOutput.h
@@ -30,7 +30,7 @@ struct ScreenCaptureOutputArgs {
ui::LayerStack layerStack;
Rect sourceCrop;
std::shared_ptr<renderengine::ExternalTexture> buffer;
- std::optional<DisplayId> displayId;
+ ftl::Optional<DisplayIdVariant> displayIdVariant;
ui::Size reqBufferSize;
float sdrWhitePointNits;
float displayBrightnessNits;
@@ -51,7 +51,7 @@ struct ScreenCaptureOutputArgs {
// SurfaceFlinger::captureLayers and SurfaceFlinger::captureDisplay.
class ScreenCaptureOutput : public compositionengine::impl::Output {
public:
- ScreenCaptureOutput(const Rect sourceCrop, std::optional<DisplayId> displayId,
+ ScreenCaptureOutput(const Rect sourceCrop, ftl::Optional<DisplayIdVariant> displayIdVariant,
const compositionengine::Output::ColorProfile& colorProfile,
float layerAlpha, bool regionSampling,
bool dimInGammaSpaceForEnhancedScreenshots, bool enableLocalTonemapping);
@@ -70,7 +70,7 @@ protected:
private:
std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> generateLuts();
const Rect mSourceCrop;
- const std::optional<DisplayId> mDisplayId;
+ const ftl::Optional<DisplayIdVariant> mDisplayIdVariant;
const compositionengine::Output::ColorProfile& mColorProfile;
const float mLayerAlpha;
const bool mRegionSampling;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0029bfc63e..aa933ee8a7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -659,12 +659,14 @@ void SurfaceFlinger::enableHalVirtualDisplays(bool enable) {
}
}
-VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution, ui::PixelFormat format,
- const std::string& uniqueId) {
+std::optional<VirtualDisplayIdVariant> SurfaceFlinger::acquireVirtualDisplay(
+ ui::Size resolution, ui::PixelFormat format, const std::string& uniqueId,
+ compositionengine::DisplayCreationArgsBuilder& builder) {
if (auto& generator = mVirtualDisplayIdGenerators.hal) {
if (const auto id = generator->generateId()) {
if (getHwComposer().allocateVirtualDisplay(*id, resolution, &format)) {
acquireVirtualDisplaySnapshot(*id, uniqueId);
+ builder.setId(*id);
return *id;
}
@@ -679,22 +681,23 @@ VirtualDisplayId SurfaceFlinger::acquireVirtualDisplay(ui::Size resolution, ui::
const auto id = mVirtualDisplayIdGenerators.gpu.generateId();
LOG_ALWAYS_FATAL_IF(!id, "Failed to generate ID for GPU virtual display");
acquireVirtualDisplaySnapshot(*id, uniqueId);
+ builder.setId(*id);
return *id;
}
-void SurfaceFlinger::releaseVirtualDisplay(VirtualDisplayId displayId) {
- if (const auto id = HalVirtualDisplayId::tryCast(displayId)) {
- if (auto& generator = mVirtualDisplayIdGenerators.hal) {
- generator->releaseId(*id);
- releaseVirtualDisplaySnapshot(*id);
- }
- return;
- }
-
- const auto id = GpuVirtualDisplayId::tryCast(displayId);
- LOG_ALWAYS_FATAL_IF(!id);
- mVirtualDisplayIdGenerators.gpu.releaseId(*id);
- releaseVirtualDisplaySnapshot(*id);
+void SurfaceFlinger::releaseVirtualDisplay(VirtualDisplayIdVariant displayId) {
+ ftl::match(
+ displayId,
+ [this](HalVirtualDisplayId halVirtualDisplayId) {
+ if (auto& generator = mVirtualDisplayIdGenerators.hal) {
+ generator->releaseId(halVirtualDisplayId);
+ releaseVirtualDisplaySnapshot(halVirtualDisplayId);
+ }
+ },
+ [this](GpuVirtualDisplayId gpuVirtualDisplayId) {
+ mVirtualDisplayIdGenerators.gpu.releaseId(gpuVirtualDisplayId);
+ releaseVirtualDisplaySnapshot(gpuVirtualDisplayId);
+ });
}
void SurfaceFlinger::releaseVirtualDisplaySnapshot(VirtualDisplayId displayId) {
@@ -1182,6 +1185,7 @@ status_t SurfaceFlinger::getStaticDisplayInfo(int64_t displayId, ui::StaticDispl
const auto& snapshot = snapshotRef.get();
info->connectionType = snapshot.connectionType();
+ info->port = snapshot.port();
info->deviceProductInfo = snapshot.deviceProductInfo();
if (mEmulatedDisplayDensity) {
@@ -1265,7 +1269,17 @@ void SurfaceFlinger::getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo*& info
ui::FrameRateCategoryRate frameRateCategoryRate(normal.getValue(), high.getValue());
info->frameRateCategoryRate = frameRateCategoryRate;
- info->supportedRefreshRates = display->refreshRateSelector().getSupportedFrameRates();
+ if (info->hasArrSupport) {
+ info->supportedRefreshRates = display->refreshRateSelector().getSupportedFrameRates();
+ } else {
+ // On non-ARR devices, list the refresh rates same as the supported display modes.
+ std::vector<float> supportedFrameRates;
+ supportedFrameRates.reserve(info->supportedDisplayModes.size());
+ std::transform(info->supportedDisplayModes.begin(), info->supportedDisplayModes.end(),
+ std::back_inserter(supportedFrameRates),
+ [](ui::DisplayMode mode) { return mode.peakRefreshRate; });
+ info->supportedRefreshRates = supportedFrameRates;
+ }
info->activeColorMode = display->getCompositionDisplay()->getState().colorMode;
info->hdrCapabilities = filterOut4k30(display->getHdrCapabilities());
@@ -2863,9 +2877,9 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
// output. Layer stacks are not tracked in Display when we iterate through
// frameTargeters. Cross-referencing layer stacks allows us to filter out displays
// by ID with duplicate layer stacks before adding them to CompositionEngine output.
- ui::DisplayMap<DisplayId, ui::LayerStack> physicalDisplayLayerStacks;
+ ui::DisplayMap<PhysicalDisplayId, ui::LayerStack> physicalDisplayLayerStacks;
for (auto& [_, display] : displays) {
- const auto id = PhysicalDisplayId::tryCast(display->getId());
+ const auto id = asPhysicalDisplayId(display->getDisplayIdVariant());
if (id && frameTargeters.contains(*id)) {
physicalDisplayLayerStacks.try_emplace(*id, display->getLayerStack());
}
@@ -3131,7 +3145,7 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
for (const auto& [_, display] : displays) {
const auto& state = display->getCompositionDisplay()->getState();
CompositionCoverageFlags& flags =
- mCompositionCoverage.try_emplace(display->getId()).first->second;
+ mCompositionCoverage.try_emplace(display->getDisplayIdVariant()).first->second;
if (state.usesDeviceComposition) {
flags |= CompositionCoverage::Hwc;
@@ -3185,8 +3199,8 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
CompositeResultsPerDisplay resultsPerDisplay;
// Filter out virtual displays.
- for (const auto& [id, coverage] : mCompositionCoverage) {
- if (const auto idOpt = PhysicalDisplayId::tryCast(id)) {
+ for (const auto& [idVar, coverage] : mCompositionCoverage) {
+ if (const auto idOpt = asPhysicalDisplayId(idVar)) {
resultsPerDisplay.try_emplace(*idOpt, CompositeResult{coverage});
}
}
@@ -3224,16 +3238,12 @@ bool SurfaceFlinger::isHdrLayer(const frontend::LayerSnapshot& snapshot) const {
return false;
}
-ui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(DisplayId displayId,
+ui::Rotation SurfaceFlinger::getPhysicalDisplayOrientation(PhysicalDisplayId displayId,
bool isPrimary) const {
- const auto id = PhysicalDisplayId::tryCast(displayId);
- if (!id) {
- return ui::ROTATION_0;
- }
if (!mIgnoreHwcPhysicalDisplayOrientation &&
getHwComposer().getComposer()->isSupported(
Hwc2::Composer::OptionalFeature::PhysicalDisplayOrientation)) {
- switch (getHwComposer().getPhysicalDisplayOrientation(*id)) {
+ switch (getHwComposer().getPhysicalDisplayOrientation(displayId)) {
case Hwc2::AidlTransform::ROT_90:
return ui::ROTATION_90;
case Hwc2::AidlTransform::ROT_180:
@@ -3881,13 +3891,17 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
creationArgs.hasWideColorGamut = false;
creationArgs.supportedPerFrameMetadata = 0;
- if (const auto physicalIdOpt = PhysicalDisplayId::tryCast(compositionDisplay->getId())) {
+ if (const auto physicalIdOpt =
+ compositionDisplay->getDisplayIdVariant().and_then(asPhysicalDisplayId)) {
const auto physicalId = *physicalIdOpt;
creationArgs.isPrimary = physicalId == getPrimaryDisplayIdLocked();
creationArgs.refreshRateSelector =
FTL_FAKE_GUARD(kMainThreadContext,
mDisplayModeController.selectorPtrFor(physicalId));
+ creationArgs.physicalOrientation =
+ getPhysicalDisplayOrientation(physicalId, creationArgs.isPrimary);
+ ALOGV("Display Orientation: %s", toCString(creationArgs.physicalOrientation));
mPhysicalDisplays.get(physicalId)
.transform(&PhysicalDisplay::snapshotRef)
@@ -3900,7 +3914,8 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
}));
}
- if (const auto id = HalDisplayId::tryCast(compositionDisplay->getId())) {
+ if (const auto id = compositionDisplay->getDisplayIdVariant().and_then(
+ asHalDisplayId<DisplayIdVariant>)) {
getHwComposer().getHdrCapabilities(*id, &creationArgs.hdrCapabilities);
creationArgs.supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(*id);
}
@@ -3916,10 +3931,6 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
nativeWindow->setSwapInterval(nativeWindow.get(), 0);
}
- creationArgs.physicalOrientation =
- getPhysicalDisplayOrientation(compositionDisplay->getId(), creationArgs.isPrimary);
- ALOGV("Display Orientation: %s", toCString(creationArgs.physicalOrientation));
-
if (FlagManager::getInstance().correct_virtual_display_power_state()) {
creationArgs.initialPowerMode = state.initialPowerMode;
} else {
@@ -3949,7 +3960,8 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
mode.getPeakFps());
}
- display->setLayerFilter(makeLayerFilterForDisplay(display->getId(), state.layerStack));
+ display->setLayerFilter(
+ makeLayerFilterForDisplay(display->getDisplayIdVariant(), state.layerStack));
display->setProjection(state.orientation, state.layerStackSpaceRect,
state.orientedDisplaySpaceRect);
display->setDisplayName(state.displayName);
@@ -4005,10 +4017,12 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
}
compositionengine::DisplayCreationArgsBuilder builder;
+ std::optional<VirtualDisplayIdVariant> virtualDisplayIdVariantOpt;
if (const auto& physical = state.physical) {
builder.setId(physical->id);
} else {
- builder.setId(acquireVirtualDisplay(resolution, pixelFormat, state.uniqueId));
+ virtualDisplayIdVariantOpt =
+ acquireVirtualDisplay(resolution, pixelFormat, state.uniqueId, builder);
}
builder.setPixels(resolution);
@@ -4028,10 +4042,10 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
if (state.isVirtual()) {
- const auto displayId = VirtualDisplayId::tryCast(compositionDisplay->getId());
- LOG_FATAL_IF(!displayId);
- auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *displayId, state.surface,
- bqProducer, bqConsumer, state.displayName);
+ LOG_FATAL_IF(!virtualDisplayIdVariantOpt);
+ auto surface = sp<VirtualDisplaySurface>::make(getHwComposer(), *virtualDisplayIdVariantOpt,
+ state.surface, bqProducer, bqConsumer,
+ state.displayName);
displaySurface = surface;
producer = std::move(surface);
} else {
@@ -4039,18 +4053,17 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
"adding a supported display, but rendering "
"surface is provided (%p), ignoring it",
state.surface.get());
- const auto displayId = PhysicalDisplayId::tryCast(compositionDisplay->getId());
- LOG_FATAL_IF(!displayId);
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
const auto frameBufferSurface =
- sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqProducer, bqConsumer,
+ sp<FramebufferSurface>::make(getHwComposer(), state.physical->id, bqProducer,
+ bqConsumer,
state.physical->activeMode->getResolution(),
ui::Size(maxGraphicsWidth, maxGraphicsHeight));
displaySurface = frameBufferSurface;
producer = frameBufferSurface->getSurface()->getIGraphicBufferProducer();
#else
displaySurface =
- sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqConsumer,
+ sp<FramebufferSurface>::make(getHwComposer(), state.physical->id, bqConsumer,
state.physical->activeMode->getResolution(),
ui::Size(maxGraphicsWidth, maxGraphicsHeight));
producer = bqProducer;
@@ -4107,8 +4120,8 @@ void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
if (display) {
display->disconnect();
- if (display->isVirtual()) {
- releaseVirtualDisplay(display->getVirtualId());
+ if (const auto virtualDisplayIdVariant = display->getVirtualDisplayIdVariant()) {
+ releaseVirtualDisplay(*virtualDisplayIdVariant);
} else {
mScheduler->unregisterDisplay(display->getPhysicalId(), mActiveDisplayId);
}
@@ -4151,8 +4164,8 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
if (currentBinder != drawingBinder || currentState.sequenceId != drawingState.sequenceId) {
if (const auto display = getDisplayDeviceLocked(displayToken)) {
display->disconnect();
- if (display->isVirtual()) {
- releaseVirtualDisplay(display->getVirtualId());
+ if (const auto virtualDisplayIdVariant = display->getVirtualDisplayIdVariant()) {
+ releaseVirtualDisplay(*virtualDisplayIdVariant);
}
if (display->isRefreshable()) {
@@ -4184,8 +4197,8 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
if (const auto display = getDisplayDeviceLocked(displayToken)) {
if (currentState.layerStack != drawingState.layerStack) {
- display->setLayerFilter(
- makeLayerFilterForDisplay(display->getId(), currentState.layerStack));
+ display->setLayerFilter(makeLayerFilterForDisplay(display->getDisplayIdVariant(),
+ currentState.layerStack));
}
if (currentState.flags != drawingState.flags) {
display->setFlags(currentState.flags);
@@ -4427,7 +4440,7 @@ void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos,
void SurfaceFlinger::updateCursorAsync() {
compositionengine::CompositionRefreshArgs refreshArgs;
for (const auto& [_, display] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
- if (HalDisplayId::tryCast(display->getId())) {
+ if (asHalDisplayId(display->getDisplayIdVariant())) {
refreshArgs.outputs.push_back(display->getCompositionDisplay());
}
}
@@ -5015,13 +5028,7 @@ bool SurfaceFlinger::shouldLatchUnsignaled(const layer_state_t& state, size_t nu
return true;
}
-status_t SurfaceFlinger::setTransactionState(
- const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states,
- Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
- InputWindowCommands inputWindowCommands, int64_t desiredPresentTime, bool isAutoTimestamp,
- const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks,
- const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId,
- const std::vector<uint64_t>& mergedTransactionIds) {
+status_t SurfaceFlinger::setTransactionState(TransactionState&& transactionState) {
SFTRACE_CALL();
IPCThreadState* ipc = IPCThreadState::self();
@@ -5029,7 +5036,7 @@ status_t SurfaceFlinger::setTransactionState(
const int originUid = ipc->getCallingUid();
uint32_t permissions = LayerStatePermissions::getTransactionPermissions(originPid, originUid);
ftl::Flags<adpf::Workload> queuedWorkload;
- for (auto& composerState : states) {
+ for (auto& composerState : transactionState.mComposerStates) {
composerState.state.sanitize(permissions);
if (composerState.state.what & layer_state_t::COMPOSITION_EFFECTS) {
queuedWorkload |= adpf::Workload::EFFECTS;
@@ -5039,27 +5046,27 @@ status_t SurfaceFlinger::setTransactionState(
}
}
- for (DisplayState& display : displays) {
+ for (DisplayState& display : transactionState.mDisplayStates) {
display.sanitize(permissions);
}
- if (!inputWindowCommands.empty() &&
+ if (!transactionState.mInputWindowCommands.empty() &&
(permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) {
ALOGE("Only privileged callers are allowed to send input commands.");
- inputWindowCommands.clear();
+ transactionState.mInputWindowCommands.clear();
}
- if (flags & (eEarlyWakeupStart | eEarlyWakeupEnd)) {
+ if (transactionState.mFlags & (eEarlyWakeupStart | eEarlyWakeupEnd)) {
const bool hasPermission =
(permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) ||
callingThreadHasPermission(sWakeupSurfaceFlinger);
if (!hasPermission) {
ALOGE("Caller needs permission android.permission.WAKEUP_SURFACE_FLINGER to use "
"eEarlyWakeup[Start|End] flags");
- flags &= ~(eEarlyWakeupStart | eEarlyWakeupEnd);
+ transactionState.mFlags &= ~(eEarlyWakeupStart | eEarlyWakeupEnd);
}
}
- if (flags & eEarlyWakeupStart) {
+ if (transactionState.mFlags & eEarlyWakeupStart) {
queuedWorkload |= adpf::Workload::WAKEUP;
}
mPowerAdvisor->setQueuedWorkload(queuedWorkload);
@@ -5067,8 +5074,8 @@ status_t SurfaceFlinger::setTransactionState(
const int64_t postTime = systemTime();
std::vector<uint64_t> uncacheBufferIds;
- uncacheBufferIds.reserve(uncacheBuffers.size());
- for (const auto& uncacheBuffer : uncacheBuffers) {
+ uncacheBufferIds.reserve(transactionState.mUncacheBuffers.size());
+ for (const auto& uncacheBuffer : transactionState.mUncacheBuffers) {
sp<GraphicBuffer> buffer = ClientCache::getInstance().erase(uncacheBuffer);
if (buffer != nullptr) {
uncacheBufferIds.push_back(buffer->getId());
@@ -5076,8 +5083,8 @@ status_t SurfaceFlinger::setTransactionState(
}
std::vector<ResolvedComposerState> resolvedStates;
- resolvedStates.reserve(states.size());
- for (auto& state : states) {
+ resolvedStates.reserve(transactionState.mComposerStates.size());
+ for (auto& state : transactionState.mComposerStates) {
resolvedStates.emplace_back(std::move(state));
auto& resolvedState = resolvedStates.back();
resolvedState.layerId = LayerHandle::getLayerId(resolvedState.state.surface);
@@ -5088,9 +5095,15 @@ status_t SurfaceFlinger::setTransactionState(
layer->getDebugName() : std::to_string(resolvedState.state.layerId);
resolvedState.externalTexture =
getExternalTextureFromBufferData(*resolvedState.state.bufferData,
- layerName.c_str(), transactionId);
+ layerName.c_str(), transactionState.getId());
if (resolvedState.externalTexture) {
resolvedState.state.bufferData->buffer = resolvedState.externalTexture->getBuffer();
+ if (FlagManager::getInstance().monitor_buffer_fences()) {
+ resolvedState.state.bufferData->buffer->getDependencyMonitor()
+ .addIngress(FenceTime::makeValid(
+ resolvedState.state.bufferData->acquireFence),
+ "Incoming txn");
+ }
}
mBufferCountTracker.increment(resolvedState.layerId);
}
@@ -5110,22 +5123,12 @@ status_t SurfaceFlinger::setTransactionState(
}
}
- QueuedTransactionState state{frameTimelineInfo,
- resolvedStates,
- displays,
- flags,
- applyToken,
- std::move(inputWindowCommands),
- desiredPresentTime,
- isAutoTimestamp,
+ QueuedTransactionState state{std::move(transactionState),
+ std::move(resolvedStates),
std::move(uncacheBufferIds),
postTime,
- hasListenerCallbacks,
- listenerCallbacks,
originPid,
- originUid,
- transactionId,
- mergedTransactionIds};
+ originUid};
state.workloadHint = queuedWorkload;
if (mTransactionTracing) {
@@ -5148,16 +5151,16 @@ status_t SurfaceFlinger::setTransactionState(
for (const auto& [displayId, data] : mNotifyExpectedPresentMap) {
if (data.hintStatus.load() == NotifyExpectedPresentHintStatus::ScheduleOnTx) {
- scheduleNotifyExpectedPresentHint(displayId, VsyncId{frameTimelineInfo.vsyncId});
+ scheduleNotifyExpectedPresentHint(displayId, VsyncId{state.frameTimelineInfo.vsyncId});
}
}
- setTransactionFlags(eTransactionFlushNeeded, schedule, applyToken, frameHint);
+ setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken, frameHint);
return NO_ERROR;
}
bool SurfaceFlinger::applyTransactionState(
const FrameTimelineInfo& frameTimelineInfo, std::vector<ResolvedComposerState>& states,
- Vector<DisplayState>& displays, uint32_t flags,
+ std::span<DisplayState> displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime,
bool isAutoTimestamp, const std::vector<uint64_t>& uncacheBufferIds, const int64_t postTime,
bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
@@ -5647,7 +5650,8 @@ void SurfaceFlinger::initializeDisplays() {
auto layerStack = ui::DEFAULT_LAYER_STACK.id;
for (const auto& [id, display] : FTL_FAKE_GUARD(mStateLock, mPhysicalDisplays)) {
- state.displays.push(DisplayState(display.token(), ui::LayerStack::fromValue(layerStack++)));
+ state.displays.emplace_back(
+ DisplayState(display.token(), ui::LayerStack::fromValue(layerStack++)));
}
std::vector<QueuedTransactionState> transactions;
@@ -5715,7 +5719,13 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
incRefreshableDisplays();
}
+ if (displayId == mActiveDisplayId &&
+ FlagManager::getInstance().correct_virtual_display_power_state()) {
+ applyOptimizationPolicy(__func__);
+ }
+
const auto activeMode = display->refreshRateSelector().getActiveMode().modePtr;
+ using OptimizationPolicy = gui::ISurfaceComposer::OptimizationPolicy;
if (currentMode == hal::PowerMode::OFF) {
// Turn on the display
@@ -5730,22 +5740,20 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
onActiveDisplayChangedLocked(activeDisplay.get(), *display);
}
- if (displayId == mActiveDisplayId) {
- if (FlagManager::getInstance().correct_virtual_display_power_state()) {
- applyOptimizationPolicy("setPhysicalDisplayPowerMode(ON)");
- } else {
- disablePowerOptimizations("setPhysicalDisplayPowerMode(ON)");
- }
+ if (displayId == mActiveDisplayId &&
+ !FlagManager::getInstance().correct_virtual_display_power_state()) {
+ optimizeThreadScheduling("setPhysicalDisplayPowerMode(ON/DOZE)",
+ OptimizationPolicy::optimizeForPerformance);
}
getHwComposer().setPowerMode(displayId, mode);
- if (mode != hal::PowerMode::DOZE_SUSPEND &&
- (displayId == mActiveDisplayId || FlagManager::getInstance().multithreaded_present())) {
+ if (mode != hal::PowerMode::DOZE_SUSPEND) {
const bool enable =
mScheduler->getVsyncSchedule(displayId)->getPendingHardwareVsyncState();
requestHardwareVsync(displayId, enable);
- if (displayId == mActiveDisplayId) {
+ if (displayId == mActiveDisplayId &&
+ !FlagManager::getInstance().correct_virtual_display_power_state()) {
mScheduler->enableSyntheticVsync(false);
}
@@ -5762,21 +5770,18 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
if (const auto display = getActivatableDisplay()) {
onActiveDisplayChangedLocked(activeDisplay.get(), *display);
} else {
- if (FlagManager::getInstance().correct_virtual_display_power_state()) {
- applyOptimizationPolicy("setPhysicalDisplayPowerMode(OFF)");
- } else {
- enablePowerOptimizations("setPhysicalDisplayPowerMode(OFF)");
+ if (!FlagManager::getInstance().correct_virtual_display_power_state()) {
+ optimizeThreadScheduling("setPhysicalDisplayPowerMode(OFF)",
+ OptimizationPolicy::optimizeForPower);
}
- if (currentModeNotDozeSuspend) {
- if (!FlagManager::getInstance().multithreaded_present()) {
- mScheduler->disableHardwareVsync(displayId, true);
- }
+ if (currentModeNotDozeSuspend &&
+ !FlagManager::getInstance().correct_virtual_display_power_state()) {
mScheduler->enableSyntheticVsync();
}
}
}
- if (currentModeNotDozeSuspend && FlagManager::getInstance().multithreaded_present()) {
+ if (currentModeNotDozeSuspend) {
constexpr bool kDisallow = true;
mScheduler->disableHardwareVsync(displayId, kDisallow);
}
@@ -5794,24 +5799,25 @@ void SurfaceFlinger::setPhysicalDisplayPowerMode(const sp<DisplayDevice>& displa
} else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
// Update display while dozing
getHwComposer().setPowerMode(displayId, mode);
- if (currentMode == hal::PowerMode::DOZE_SUSPEND &&
- (displayId == mActiveDisplayId || FlagManager::getInstance().multithreaded_present())) {
+ if (currentMode == hal::PowerMode::DOZE_SUSPEND) {
if (displayId == mActiveDisplayId) {
ALOGI("Force repainting for DOZE_SUSPEND -> DOZE or ON.");
mVisibleRegionsDirty = true;
scheduleRepaint();
- mScheduler->enableSyntheticVsync(false);
+ if (!FlagManager::getInstance().correct_virtual_display_power_state()) {
+ mScheduler->enableSyntheticVsync(false);
+ }
}
constexpr bool kAllowToEnable = true;
mScheduler->resyncToHardwareVsync(displayId, kAllowToEnable, activeMode.get());
}
} else if (mode == hal::PowerMode::DOZE_SUSPEND) {
// Leave display going to doze
- if (displayId == mActiveDisplayId || FlagManager::getInstance().multithreaded_present()) {
- constexpr bool kDisallow = true;
- mScheduler->disableHardwareVsync(displayId, kDisallow);
- }
- if (displayId == mActiveDisplayId) {
+ constexpr bool kDisallow = true;
+ mScheduler->disableHardwareVsync(displayId, kDisallow);
+
+ if (displayId == mActiveDisplayId &&
+ !FlagManager::getInstance().correct_virtual_display_power_state()) {
mScheduler->enableSyntheticVsync();
}
getHwComposer().setPowerMode(displayId, mode);
@@ -5850,43 +5856,44 @@ void SurfaceFlinger::setVirtualDisplayPowerMode(const sp<DisplayDevice>& display
to_string(displayId).c_str());
}
-bool SurfaceFlinger::shouldOptimizeForPerformance() {
- for (const auto& [_, display] : mDisplays) {
- // Displays that are optimized for power are always powered on and should not influence
- // whether there is an active display for the purpose of power optimization, etc. If these
- // displays are being shown somewhere, a different (physical or virtual) display that is
- // optimized for performance will be powered on in addition. Displays optimized for
- // performance will change power mode, so if they are off then they are not active.
- if (display->isPoweredOn() &&
- display->getOptimizationPolicy() ==
- gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance) {
- return true;
- }
- }
- return false;
-}
-
-void SurfaceFlinger::enablePowerOptimizations(const char* whence) {
- ALOGD("%s: Enabling power optimizations", whence);
-
- setSchedAttr(false, whence);
- setSchedFifo(false, whence);
-}
-
-void SurfaceFlinger::disablePowerOptimizations(const char* whence) {
- ALOGD("%s: Disabling power optimizations", whence);
+void SurfaceFlinger::optimizeThreadScheduling(
+ const char* whence, gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy) {
+ ALOGD("%s: Optimizing thread scheduling: %s", whence, to_string(optimizationPolicy));
+ const bool optimizeForPerformance =
+ optimizationPolicy == gui::ISurfaceComposer::OptimizationPolicy::optimizeForPerformance;
// TODO: b/281692563 - Merge the syscalls. For now, keep uclamp in a separate syscall
// and set it before SCHED_FIFO due to b/190237315.
- setSchedAttr(true, whence);
- setSchedFifo(true, whence);
+ setSchedAttr(optimizeForPerformance, whence);
+ setSchedFifo(optimizeForPerformance, whence);
}
void SurfaceFlinger::applyOptimizationPolicy(const char* whence) {
- if (shouldOptimizeForPerformance()) {
- disablePowerOptimizations(whence);
- } else {
- enablePowerOptimizations(whence);
+ using OptimizationPolicy = gui::ISurfaceComposer::OptimizationPolicy;
+
+ const bool optimizeForPerformance =
+ std::any_of(mDisplays.begin(), mDisplays.end(), [](const auto& pair) {
+ const auto& display = pair.second;
+ return display->isPoweredOn() &&
+ display->getOptimizationPolicy() ==
+ OptimizationPolicy::optimizeForPerformance;
+ });
+
+ optimizeThreadScheduling(whence,
+ optimizeForPerformance ? OptimizationPolicy::optimizeForPerformance
+ : OptimizationPolicy::optimizeForPower);
+
+ if (mScheduler) {
+ const bool disableSyntheticVsync =
+ std::any_of(mDisplays.begin(), mDisplays.end(), [](const auto& pair) {
+ const auto& display = pair.second;
+ const hal::PowerMode powerMode = display->getPowerMode();
+ return powerMode != hal::PowerMode::OFF &&
+ powerMode != hal::PowerMode::DOZE_SUSPEND &&
+ display->getOptimizationPolicy() ==
+ OptimizationPolicy::optimizeForPerformance;
+ });
+ mScheduler->enableSyntheticVsync(!disableSyntheticVsync);
}
}
@@ -6110,17 +6117,15 @@ void SurfaceFlinger::dumpDisplays(std::string& result) const {
for (const auto& [token, display] : mDisplays) {
if (display->isVirtual()) {
- const auto displayId = display->getId();
+ const VirtualDisplayId virtualId = display->getVirtualId();
utils::Dumper::Section section(dumper,
- ftl::Concat("Virtual Display ", displayId.value).str());
+ ftl::Concat("Virtual Display ", virtualId.value).str());
display->dump(dumper);
- if (const auto virtualIdOpt = VirtualDisplayId::tryCast(displayId)) {
- std::lock_guard lock(mVirtualDisplaysMutex);
- const auto virtualSnapshotIt = mVirtualDisplays.find(virtualIdOpt.value());
- if (virtualSnapshotIt != mVirtualDisplays.end()) {
- virtualSnapshotIt->second.dump(dumper);
- }
+ std::lock_guard lock(mVirtualDisplaysMutex);
+ const auto virtualSnapshotIt = mVirtualDisplays.find(virtualId);
+ if (virtualSnapshotIt != mVirtualDisplays.end()) {
+ virtualSnapshotIt->second.dump(dumper);
}
}
}
@@ -6128,7 +6133,7 @@ void SurfaceFlinger::dumpDisplays(std::string& result) const {
void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const {
for (const auto& [token, display] : mDisplays) {
- const auto displayId = PhysicalDisplayId::tryCast(display->getId());
+ const auto displayId = asPhysicalDisplayId(display->getDisplayIdVariant());
if (!displayId) {
continue;
}
@@ -6337,7 +6342,7 @@ perfetto::protos::LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t t
void SurfaceFlinger::dumpHwcLayersMinidump(std::string& result) const {
for (const auto& [token, display] : mDisplays) {
- const auto displayId = HalDisplayId::tryCast(display->getId());
+ const auto displayId = asHalDisplayId(display->getDisplayIdVariant());
if (!displayId) {
continue;
}
@@ -7404,7 +7409,7 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
}
wp<const DisplayDevice> displayWeak;
- DisplayId displayId;
+ ftl::Optional<DisplayIdVariant> displayIdVariantOpt;
ui::LayerStack layerStack;
ui::Size reqSize(args.width, args.height);
std::unordered_set<uint32_t> excludeLayerIds;
@@ -7420,7 +7425,7 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
return;
}
displayWeak = display;
- displayId = display->getId();
+ displayIdVariantOpt = display->getDisplayIdVariant();
layerStack = display->getLayerStack();
displayIsSecure = display->isSecure();
@@ -7448,7 +7453,7 @@ void SurfaceFlinger::captureDisplay(const DisplayCaptureArgs& args,
ScreenshotArgs screenshotArgs;
screenshotArgs.captureTypeVariant = displayWeak;
- screenshotArgs.displayId = displayId;
+ screenshotArgs.displayIdVariant = displayIdVariantOpt;
screenshotArgs.sourceCrop = gui::aidl_utils::fromARect(captureArgs.sourceCrop);
if (screenshotArgs.sourceCrop.isEmpty()) {
screenshotArgs.sourceCrop = layerStackSpaceRect;
@@ -7467,6 +7472,7 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args
const sp<IScreenCaptureListener>& captureListener) {
ui::LayerStack layerStack;
wp<const DisplayDevice> displayWeak;
+ ftl::Optional<DisplayIdVariant> displayIdVariantOpt;
ui::Size size;
Rect layerStackSpaceRect;
bool displayIsSecure;
@@ -7482,6 +7488,7 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args
}
displayWeak = display;
+ displayIdVariantOpt = display->getDisplayIdVariant();
layerStack = display->getLayerStack();
layerStackSpaceRect = display->getLayerStackSpaceRect();
size = display->getLayerStackSpaceRect().getSize();
@@ -7516,7 +7523,7 @@ void SurfaceFlinger::captureDisplay(DisplayId displayId, const CaptureArgs& args
ScreenshotArgs screenshotArgs;
screenshotArgs.captureTypeVariant = displayWeak;
- screenshotArgs.displayId = displayId;
+ screenshotArgs.displayIdVariant = displayIdVariantOpt;
screenshotArgs.sourceCrop = layerStackSpaceRect;
screenshotArgs.reqSize = size;
screenshotArgs.dataspace = static_cast<ui::Dataspace>(args.dataspace);
@@ -8008,7 +8015,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl(
.layerStack = layerStack,
.sourceCrop = args.sourceCrop,
.buffer = std::move(buffer),
- .displayId = args.displayId,
+ .displayIdVariant = args.displayIdVariant,
.reqBufferSize = args.reqSize,
.sdrWhitePointNits = args.sdrWhitePointNits,
.displayBrightnessNits = args.displayBrightnessNits,
@@ -8408,8 +8415,8 @@ sp<DisplayDevice> SurfaceFlinger::getActivatableDisplay() const {
// TODO(b/255635821): Choose the pacesetter display, considering both internal and external
// displays. For now, pick the other internal display, assuming a dual-display foldable.
return findDisplay([this](const DisplayDevice& display) REQUIRES(mStateLock) {
- const auto idOpt = PhysicalDisplayId::tryCast(display.getId());
- return idOpt && *idOpt != mActiveDisplayId && display.isPoweredOn() &&
+ const auto idOpt = asPhysicalDisplayId(display.getDisplayIdVariant());
+ return idOpt.has_value() && *idOpt != mActiveDisplayId && display.isPoweredOn() &&
mPhysicalDisplays.get(*idOpt)
.transform(&PhysicalDisplay::isInternal)
.value_or(false);
@@ -8946,6 +8953,7 @@ binder::Status SurfaceComposerAIDL::getStaticDisplayInfo(int64_t displayId,
if (status == NO_ERROR) {
// convert ui::StaticDisplayInfo to gui::StaticDisplayInfo
outInfo->connectionType = static_cast<gui::DisplayConnectionType>(info.connectionType);
+ outInfo->port = info.port;
outInfo->density = info.density;
outInfo->secure = info.secure;
outInfo->installOrientation = static_cast<gui::Rotation>(info.installOrientation);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 37f362fd21..f61214cc65 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -160,6 +160,7 @@ class DisplaySurface;
class OutputLayer;
struct CompositionRefreshArgs;
+class DisplayCreationArgsBuilder;
} // namespace compositionengine
namespace renderengine {
@@ -544,13 +545,7 @@ private:
}
sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const;
- status_t setTransactionState(
- const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state,
- Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
- InputWindowCommands inputWindowCommands, int64_t desiredPresentTime,
- bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers,
- bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
- uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) override;
+ status_t setTransactionState(TransactionState&&) override;
void bootFinished();
status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const;
sp<IDisplayEventConnection> createDisplayEventConnection(
@@ -738,19 +733,14 @@ private:
void setVirtualDisplayPowerMode(const sp<DisplayDevice>& display, hal::PowerMode mode)
REQUIRES(mStateLock, kMainThreadContext);
- // Returns whether to optimize globally for performance instead of power.
- bool shouldOptimizeForPerformance() REQUIRES(mStateLock);
-
- // Turns on power optimizations, for example when there are no displays to be optimized for
- // performance.
- static void enablePowerOptimizations(const char* whence);
-
- // Turns off power optimizations.
- static void disablePowerOptimizations(const char* whence);
+ // Adjusts thread scheduling according to the optimization policy
+ static void optimizeThreadScheduling(
+ const char* whence, gui::ISurfaceComposer::OptimizationPolicy optimizationPolicy);
// Enables or disables power optimizations depending on whether there are displays that should
// be optimized for performance.
- void applyOptimizationPolicy(const char* whence) REQUIRES(mStateLock);
+ void applyOptimizationPolicy(const char* whence) REQUIRES(kMainThreadContext)
+ REQUIRES(mStateLock);
// Returns the preferred mode for PhysicalDisplayId if the Scheduler has selected one for that
// display. Falls back to the display's defaultModeId otherwise.
@@ -797,7 +787,7 @@ private:
*/
bool applyTransactionState(const FrameTimelineInfo& info,
std::vector<ResolvedComposerState>& state,
- Vector<DisplayState>& displays, uint32_t flags,
+ std::span<DisplayState> displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
const int64_t desiredPresentTime, bool isAutoTimestamp,
const std::vector<uint64_t>& uncacheBufferIds,
@@ -891,7 +881,7 @@ private:
std::variant<int32_t, wp<const DisplayDevice>> captureTypeVariant;
// Display ID of the display the result will be on
- std::optional<DisplayId> displayId{std::nullopt};
+ ftl::Optional<DisplayIdVariant> displayIdVariant{std::nullopt};
// If true, transform is inverted from the parent layer snapshot
bool childrenOnly{false};
@@ -1045,10 +1035,10 @@ private:
// region of all screens presenting this layer stack.
void invalidateLayerStack(const ui::LayerFilter& layerFilter, const Region& dirty);
- ui::LayerFilter makeLayerFilterForDisplay(DisplayId displayId, ui::LayerStack layerStack)
+ ui::LayerFilter makeLayerFilterForDisplay(DisplayIdVariant displayId, ui::LayerStack layerStack)
REQUIRES(mStateLock) {
return {layerStack,
- PhysicalDisplayId::tryCast(displayId)
+ asPhysicalDisplayId(displayId)
.and_then(display::getPhysicalDisplay(mPhysicalDisplays))
.transform(&display::PhysicalDisplay::isInternal)
.value_or(false)};
@@ -1141,8 +1131,10 @@ private:
void enableHalVirtualDisplays(bool);
// Virtual display lifecycle for ID generation and HAL allocation.
- VirtualDisplayId acquireVirtualDisplay(ui::Size, ui::PixelFormat, const std::string& uniqueId)
- REQUIRES(mStateLock);
+ std::optional<VirtualDisplayIdVariant> acquireVirtualDisplay(
+ ui::Size, ui::PixelFormat, const std::string& uniqueId,
+ compositionengine::DisplayCreationArgsBuilder&) REQUIRES(mStateLock);
+
template <typename ID>
void acquireVirtualDisplaySnapshot(ID displayId, const std::string& uniqueId) {
std::lock_guard lock(mVirtualDisplaysMutex);
@@ -1153,7 +1145,7 @@ private:
}
}
- void releaseVirtualDisplay(VirtualDisplayId);
+ void releaseVirtualDisplay(VirtualDisplayIdVariant displayId);
void releaseVirtualDisplaySnapshot(VirtualDisplayId displayId);
// Returns a display other than `mActiveDisplayId` that can be activated, if any.
@@ -1238,7 +1230,7 @@ private:
bool isHdrLayer(const frontend::LayerSnapshot& snapshot) const;
- ui::Rotation getPhysicalDisplayOrientation(DisplayId, bool isPrimary) const
+ ui::Rotation getPhysicalDisplayOrientation(PhysicalDisplayId, bool isPrimary) const
REQUIRES(mStateLock);
void traverseLegacyLayers(const LayerVector::Visitor& visitor) const
REQUIRES(kMainThreadContext);
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
index 3297c16113..6bbc04cf6f 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
@@ -321,7 +321,7 @@ QueuedTransactionState TransactionProtoParser::fromProto(
int32_t displayCount = proto.display_changes_size();
t.displays.reserve(static_cast<size_t>(displayCount));
for (int i = 0; i < displayCount; i++) {
- t.displays.add(fromProto(proto.display_changes(i)));
+ t.displays.emplace_back(fromProto(proto.display_changes(i)));
}
return t;
}
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index b22ec66819..2e8c8c1111 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -18,7 +18,7 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
#undef LOG_TAG
#define LOG_TAG "TransactionCallbackInvoker"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
@@ -28,6 +28,7 @@
#include "Utils/FenceUtils.h"
#include <binder/IInterface.h>
+#include <common/FlagManager.h>
#include <common/trace.h>
#include <utils/RefBase.h>
@@ -142,8 +143,17 @@ status_t TransactionCallbackInvoker::addCallbackHandle(const sp<CallbackHandle>&
handle->transformHint,
handle->currentMaxAcquiredBufferCount,
eventStats, handle->previousReleaseCallbackId);
+
if (handle->bufferReleaseChannel &&
handle->previousReleaseCallbackId != ReleaseCallbackId::INVALID_ID) {
+ if (FlagManager::getInstance().monitor_buffer_fences()) {
+ if (auto previousBuffer = handle->previousBuffer.lock()) {
+ previousBuffer->getBuffer()
+ ->getDependencyMonitor()
+ .addEgress(FenceTime::makeValid(handle->previousReleaseFence),
+ "Txn release");
+ }
+ }
mBufferReleases.emplace_back(handle->name, handle->bufferReleaseChannel,
handle->previousReleaseCallbackId,
handle->previousReleaseFence,
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.h b/services/surfaceflinger/TransactionCallbackInvoker.h
index 178ddbbe79..34f6ffc5da 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.h
+++ b/services/surfaceflinger/TransactionCallbackInvoker.h
@@ -25,6 +25,7 @@
#include <ftl/future.h>
#include <gui/BufferReleaseChannel.h>
#include <gui/ITransactionCompletedListener.h>
+#include <renderengine/ExternalTexture.h>
#include <ui/Fence.h>
#include <ui/FenceResult.h>
@@ -55,6 +56,7 @@ public:
uint64_t previousFrameNumber = 0;
ReleaseCallbackId previousReleaseCallbackId = ReleaseCallbackId::INVALID_ID;
std::shared_ptr<gui::BufferReleaseChannel::ProducerEndpoint> bufferReleaseChannel;
+ std::weak_ptr<renderengine::ExternalTexture> previousBuffer;
};
class TransactionCallbackInvoker {
diff --git a/services/surfaceflinger/common/FlagManager.cpp b/services/surfaceflinger/common/FlagManager.cpp
index 42fa436975..bf1035149b 100644
--- a/services/surfaceflinger/common/FlagManager.cpp
+++ b/services/surfaceflinger/common/FlagManager.cpp
@@ -129,6 +129,7 @@ void FlagManager::dump(std::string& result) const {
DUMP_ACONFIG_FLAG(correct_virtual_display_power_state);
DUMP_ACONFIG_FLAG(graphite_renderengine_preview_rollout);
DUMP_ACONFIG_FLAG(increase_missed_frame_jank_threshold);
+ DUMP_ACONFIG_FLAG(monitor_buffer_fences);
DUMP_ACONFIG_FLAG(refresh_rate_overlay_on_external_display);
DUMP_ACONFIG_FLAG(vsync_predictor_recovery);
@@ -164,7 +165,6 @@ void FlagManager::dump(std::string& result) const {
DUMP_ACONFIG_FLAG(latch_unsignaled_with_auto_refresh_changed);
DUMP_ACONFIG_FLAG(local_tonemap_screenshots);
DUMP_ACONFIG_FLAG(misc1);
- DUMP_ACONFIG_FLAG(multithreaded_present);
DUMP_ACONFIG_FLAG(no_vsyncs_on_screen_off);
DUMP_ACONFIG_FLAG(override_trusted_overlay);
DUMP_ACONFIG_FLAG(protected_if_client);
@@ -259,7 +259,6 @@ FLAG_MANAGER_ACONFIG_FLAG(frame_rate_category_mrr, "debug.sf.frame_rate_category
FLAG_MANAGER_ACONFIG_FLAG(misc1, "")
FLAG_MANAGER_ACONFIG_FLAG(vrr_config, "debug.sf.enable_vrr_config")
FLAG_MANAGER_ACONFIG_FLAG(hdcp_level_hal, "")
-FLAG_MANAGER_ACONFIG_FLAG(multithreaded_present, "debug.sf.multithreaded_present")
FLAG_MANAGER_ACONFIG_FLAG(add_sf_skipped_frames_to_trace, "")
FLAG_MANAGER_ACONFIG_FLAG(use_known_refresh_rate_for_fps_consistency, "")
FLAG_MANAGER_ACONFIG_FLAG(cache_when_source_crop_layer_only_moved,
@@ -305,6 +304,7 @@ FLAG_MANAGER_ACONFIG_FLAG(adpf_gpu_sf, "")
FLAG_MANAGER_ACONFIG_FLAG(adpf_native_session_manager, "");
FLAG_MANAGER_ACONFIG_FLAG(graphite_renderengine_preview_rollout, "");
FLAG_MANAGER_ACONFIG_FLAG(increase_missed_frame_jank_threshold, "");
+FLAG_MANAGER_ACONFIG_FLAG(monitor_buffer_fences, "");
FLAG_MANAGER_ACONFIG_FLAG(vsync_predictor_recovery, "");
/// Trunk stable server (R/W) flags from outside SurfaceFlinger ///
diff --git a/services/surfaceflinger/common/include/common/FlagManager.h b/services/surfaceflinger/common/include/common/FlagManager.h
index dd7042d8cb..8f361ac610 100644
--- a/services/surfaceflinger/common/include/common/FlagManager.h
+++ b/services/surfaceflinger/common/include/common/FlagManager.h
@@ -63,6 +63,7 @@ public:
bool correct_virtual_display_power_state() const;
bool graphite_renderengine_preview_rollout() const;
bool increase_missed_frame_jank_threshold() const;
+ bool monitor_buffer_fences() const;
bool refresh_rate_overlay_on_external_display() const;
bool vsync_predictor_recovery() const;
@@ -99,7 +100,6 @@ public:
bool local_tonemap_screenshots() const;
bool luts_api() const;
bool misc1() const;
- bool multithreaded_present() const;
bool no_vsyncs_on_screen_off() const;
bool override_trusted_overlay() const;
bool protected_if_client() const;
diff --git a/services/surfaceflinger/surfaceflinger_flags_new.aconfig b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
index d8f51fe7e4..d412a19f3c 100644
--- a/services/surfaceflinger/surfaceflinger_flags_new.aconfig
+++ b/services/surfaceflinger/surfaceflinger_flags_new.aconfig
@@ -216,6 +216,13 @@ flag {
} # local_tonemap_screenshots
flag {
+ name: "monitor_buffer_fences"
+ namespace: "core_graphics"
+ description: "Monitors fences for each buffer"
+ bug: "360932099"
+} # monitor_buffer_fences
+
+flag {
name: "no_vsyncs_on_screen_off"
namespace: "core_graphics"
description: "Stop vsync / Choreographer callbacks to apps when the screen is off"
diff --git a/services/surfaceflinger/tests/DereferenceSurfaceControl_test.cpp b/services/surfaceflinger/tests/DereferenceSurfaceControl_test.cpp
index 46b98f9193..192602d7d2 100644
--- a/services/surfaceflinger/tests/DereferenceSurfaceControl_test.cpp
+++ b/services/surfaceflinger/tests/DereferenceSurfaceControl_test.cpp
@@ -52,6 +52,8 @@ protected:
};
TEST_F(DereferenceSurfaceControlTest, LayerNotInTransaction) {
+ // Last strong pointer is removed, the layer is destroyed and is removed
+ // from compostion.
fgLayer = nullptr;
{
SCOPED_TRACE("after setting null");
@@ -61,7 +63,9 @@ TEST_F(DereferenceSurfaceControlTest, LayerNotInTransaction) {
}
TEST_F(DereferenceSurfaceControlTest, LayerInTransaction) {
- auto transaction = Transaction().show(fgLayer);
+ Transaction transaction;
+ transaction.show(fgLayer);
+ // |transaction| retains a strong pointer, so layer is retained.
fgLayer = nullptr;
{
SCOPED_TRACE("after setting null");
diff --git a/services/surfaceflinger/tests/IPC_test.cpp b/services/surfaceflinger/tests/IPC_test.cpp
index 18bd3b92d2..94cb878311 100644
--- a/services/surfaceflinger/tests/IPC_test.cpp
+++ b/services/surfaceflinger/tests/IPC_test.cpp
@@ -42,14 +42,22 @@ using CallbackInfo = SurfaceComposerClient::CallbackInfo;
using TCLHash = SurfaceComposerClient::TCLHash;
using android::hardware::graphics::common::V1_1::BufferUsage;
-class TransactionHelper : public Transaction {
+class TransactionHelper : public Transaction, public Parcelable {
public:
+ TransactionHelper() : Transaction() {}
size_t getNumListeners() { return mListenerCallbacks.size(); }
std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash>
getListenerCallbacks() {
return mListenerCallbacks;
}
+ status_t writeToParcel(Parcel* parcel) const override {
+ return Transaction::writeToParcel(parcel);
+ }
+
+ status_t readFromParcel(const Parcel* parcel) override {
+ return Transaction::readFromParcel(parcel);
+ }
};
class IPCTestUtils {
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
index 4322af7cef..75182e5fbb 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -183,7 +183,7 @@ struct DisplayIdGetter;
template <typename PhysicalDisplay>
struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
- static PhysicalDisplayId get() {
+ static DisplayIdVariant get() {
if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY)
? LEGACY_DISPLAY_TYPE_PRIMARY
@@ -199,12 +199,12 @@ struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
template <VirtualDisplayId::BaseId displayId>
struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
- static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
+ static DisplayIdVariant get() { return HalVirtualDisplayId(displayId); }
};
template <>
struct DisplayIdGetter<GpuVirtualDisplayIdType> {
- static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); }
+ static DisplayIdVariant get() { return GpuVirtualDisplayId(0); }
};
template <typename>
@@ -374,9 +374,8 @@ struct HwcDisplayVariant {
// Called by tests to inject a HWC display setup
template <hal::PowerMode kPowerMode = hal::PowerMode::ON>
static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
- const auto displayId = DisplayVariant::DISPLAY_ID::get();
- ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
- TestableSurfaceFlinger::FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
+ TestableSurfaceFlinger::FakeHwcDisplayInjector(DisplayVariant::DISPLAY_ID::get(),
+ HWC_DISPLAY_TYPE,
static_cast<bool>(DisplayVariant::PRIMARY))
.setHwcDisplayId(HWC_DISPLAY_ID)
.setResolution(DisplayVariant::RESOLUTION)
@@ -663,9 +662,8 @@ struct HwcVirtualDisplayVariant
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
- const auto displayId = Base::DISPLAY_ID::get();
auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
- .setId(displayId)
+ .setId(Base::DISPLAY_ID::get())
.setPixels(Base::RESOLUTION)
.setIsSecure(static_cast<bool>(Base::SECURE))
.setPowerAdvisor(&test->mPowerAdvisor)
@@ -678,7 +676,12 @@ struct HwcVirtualDisplayVariant
ceDisplayArgs);
// Insert display data so that the HWC thinks it created the virtual display.
- test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
+ const auto ceDisplayIdVar = compositionDisplay->getDisplayIdVariant();
+ LOG_ALWAYS_FATAL_IF(!ceDisplayIdVar);
+ EXPECT_EQ(*ceDisplayIdVar, Base::DISPLAY_ID::get());
+ const auto displayId = asHalDisplayId(*ceDisplayIdVar);
+ LOG_ALWAYS_FATAL_IF(!displayId);
+ test->mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
return compositionDisplay;
}
@@ -816,8 +819,9 @@ using HwcVirtualDisplayCase =
inline DisplayModePtr createDisplayMode(DisplayModeId modeId, Fps refreshRate, int32_t group = 0,
ui::Size resolution = ui::Size(1920, 1080)) {
- return mock::createDisplayMode(modeId, refreshRate, group, resolution,
- PrimaryDisplayVariant::DISPLAY_ID::get());
+ const auto physicalDisplayId = asPhysicalDisplayId(PrimaryDisplayVariant::DISPLAY_ID::get());
+ LOG_ALWAYS_FATAL_IF(!physicalDisplayId);
+ return mock::createDisplayMode(modeId, refreshRate, group, resolution, *physicalDisplayId);
}
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/DualDisplayTransactionTest.h b/services/surfaceflinger/tests/unittests/DualDisplayTransactionTest.h
index 90e716ff1f..edcb639f82 100644
--- a/services/surfaceflinger/tests/unittests/DualDisplayTransactionTest.h
+++ b/services/surfaceflinger/tests/unittests/DualDisplayTransactionTest.h
@@ -48,8 +48,10 @@ struct DualDisplayTransactionTest : DisplayTransactionTest {
}
}
- static inline PhysicalDisplayId kInnerDisplayId = InnerDisplayVariant::DISPLAY_ID::get();
- static inline PhysicalDisplayId kOuterDisplayId = OuterDisplayVariant::DISPLAY_ID::get();
+ static inline PhysicalDisplayId kInnerDisplayId =
+ asPhysicalDisplayId(InnerDisplayVariant::DISPLAY_ID::get()).value();
+ static inline PhysicalDisplayId kOuterDisplayId =
+ asPhysicalDisplayId(OuterDisplayVariant::DISPLAY_ID::get()).value();
sp<DisplayDevice> mInnerDisplay, mOuterDisplay;
};
diff --git a/services/surfaceflinger/tests/unittests/FlagManagerTest.cpp b/services/surfaceflinger/tests/unittests/FlagManagerTest.cpp
index a5b347a43c..c6da1a1a79 100644
--- a/services/surfaceflinger/tests/unittests/FlagManagerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FlagManagerTest.cpp
@@ -125,13 +125,13 @@ TEST_F(FlagManagerTest, DISABLED_returnsOverrideFalse) {
TEST_F(FlagManagerTest, ignoresOverrideInUnitTestMode) {
mFlagManager.setUnitTestMode();
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
+ SET_FLAG_FOR_TEST(flags::no_vsyncs_on_screen_off, true);
// If this has not been called in this process, it will be called.
// Regardless, the result is ignored.
EXPECT_CALL(mFlagManager, getBoolProperty).WillRepeatedly(Return(false));
- EXPECT_EQ(true, mFlagManager.multithreaded_present());
+ EXPECT_EQ(true, mFlagManager.no_vsyncs_on_screen_off());
}
TEST_F(FlagManagerTest, returnsValue) {
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 49c35e2ca7..116fcd9f6d 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -741,8 +741,6 @@ TEST_F(SchedulerTest, resyncAllDoNotAllow) FTL_FAKE_GUARD(kMainThreadContext) {
}
TEST_F(SchedulerTest, resyncAllSkipsOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
-
// resyncAllToHardwareVsync will result in requesting hardware VSYNC on display 1, which is on,
// but not on display 2, which is off.
EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
@@ -763,28 +761,6 @@ TEST_F(SchedulerTest, resyncAllSkipsOffDisplays) FTL_FAKE_GUARD(kMainThreadConte
mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
}
-TEST_F(SchedulerTest, resyncAllLegacyAppliesToOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
- SET_FLAG_FOR_TEST(flags::multithreaded_present, false);
-
- // In the legacy code, prior to the flag, resync applied to OFF displays.
- EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
- EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
-
- mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
-
- mScheduler->registerDisplay(kDisplayId2,
- std::make_shared<RefreshRateSelector>(kDisplay2Modes,
- kDisplay2Mode60->getId()));
- ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
-
- static constexpr bool kDisallow = true;
- mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
- mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
-
- static constexpr bool kAllowToEnable = true;
- mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
-}
-
class AttachedChoreographerTest : public SchedulerTest {
protected:
void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
index aa5b7863a9..aa48c1b26a 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
@@ -50,9 +50,9 @@ public:
EXPECT_EQ(display.requestedRefreshRate, Fps::fromValue(requestedRefreshRate));
EXPECT_EQ(name.c_str(), display.displayName);
- const VirtualDisplayId vid = GpuVirtualDisplayId(baseId);
sp<DisplayDevice> device =
- mFlinger.createVirtualDisplayDevice(displayToken, vid, requestedRefreshRate);
+ mFlinger.createVirtualDisplayDevice(displayToken, GpuVirtualDisplayId(baseId),
+ requestedRefreshRate);
EXPECT_TRUE(device->isVirtual());
device->adjustRefreshRate(Fps::fromValue(pacesetterDisplayRefreshRate));
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
index 1335640342..eac5a8e9c5 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayTransactionCommitTest.cpp
@@ -68,13 +68,9 @@ void DisplayTransactionCommitTest::setupCommonPreconditions() {
template <typename Case, bool connected>
void DisplayTransactionCommitTest::expectHotplugReceived(mock::EventThread* eventThread) {
- const auto convert = [](auto physicalDisplayId) {
- return std::make_optional(DisplayId{physicalDisplayId});
- };
-
- EXPECT_CALL(*eventThread,
- onHotplugReceived(ResultOf(convert, Case::Display::DISPLAY_ID::get()), connected))
- .Times(1);
+ const auto physicalDisplayId = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get());
+ ASSERT_TRUE(physicalDisplayId);
+ EXPECT_CALL(*eventThread, onHotplugReceived(*physicalDisplayId, connected)).Times(1);
}
template <typename Case>
@@ -111,7 +107,7 @@ void DisplayTransactionCommitTest::verifyDisplayIsConnected(const sp<IBinder>& d
std::optional<DisplayDeviceState::Physical> expectedPhysical;
if (Case::Display::CONNECTION_TYPE::value) {
- const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
+ const auto displayId = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get());
ASSERT_TRUE(displayId);
const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
ASSERT_TRUE(hwcDisplayId);
@@ -137,10 +133,10 @@ void DisplayTransactionCommitTest::verifyPhysicalDisplayIsConnected() {
EXPECT_TRUE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
// SF should have a display token.
- const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ const auto displayIdOpt = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get());
+ ASSERT_TRUE(displayIdOpt);
- const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(displayId);
+ const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(*displayIdOpt);
ASSERT_TRUE(displayOpt);
const auto& display = displayOpt->get();
@@ -246,9 +242,9 @@ void DisplayTransactionCommitTest::processesHotplugDisconnectCommon() {
EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
// SF should not have a PhysicalDisplay.
- const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
- ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(displayId));
+ const auto physicalDisplayIdOpt = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get());
+ ASSERT_TRUE(physicalDisplayIdOpt);
+ ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(*physicalDisplayIdOpt));
// The existing token should have been removed.
verifyDisplayIsNotConnected(existing.token());
@@ -356,9 +352,10 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugConnectThenDisconnectPrimar
EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
// SF should not have a PhysicalDisplay.
- const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
- ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(displayId));
+ const auto physicalDisplayIdOpt =
+ asPhysicalDisplayId(Case::Display::DISPLAY_ID::get());
+ ASSERT_TRUE(physicalDisplayIdOpt);
+ ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(*physicalDisplayIdOpt));
}(),
testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected.");
}
@@ -400,10 +397,12 @@ TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectThenConnectPrimar
// The existing token should have been removed.
verifyDisplayIsNotConnected(existing.token());
- const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
+ const auto physicalDisplayIdOpt =
+ asPhysicalDisplayId(Case::Display::DISPLAY_ID::get());
+ ASSERT_TRUE(physicalDisplayIdOpt);
- const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(displayId);
+ const auto displayOpt =
+ mFlinger.mutablePhysicalDisplays().get(*physicalDisplayIdOpt);
ASSERT_TRUE(displayOpt);
EXPECT_NE(existing.token(), displayOpt->get().token());
@@ -540,9 +539,9 @@ TEST_F(DisplayTransactionCommitTest, processesVirtualDisplayRemoval) {
// Preconditions
// A virtual display is set up but is removed from the current state.
- const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId));
- mFlinger.mutableHwcDisplayData().try_emplace(displayId);
+ const auto displayId = asHalDisplayId(Case::Display::DISPLAY_ID::get());
+ ASSERT_TRUE(displayId);
+ mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
Case::Display::injectHwcDisplay(this);
auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
existing.inject();
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp
index fde2749438..8972840c8a 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_FoldableTest.cpp
@@ -167,7 +167,6 @@ TEST_F(FoldableTest, requestsHardwareVsyncForBothDisplays) {
}
TEST_F(FoldableTest, requestVsyncOnPowerOn) {
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
EXPECT_CALL(mFlinger.scheduler()->mockRequestHardwareVsync, Call(kInnerDisplayId, true))
.Times(1);
EXPECT_CALL(mFlinger.scheduler()->mockRequestHardwareVsync, Call(kOuterDisplayId, true))
@@ -178,7 +177,6 @@ TEST_F(FoldableTest, requestVsyncOnPowerOn) {
}
TEST_F(FoldableTest, disableVsyncOnPowerOffPacesetter) {
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
// When the device boots, the inner display should be the pacesetter.
ASSERT_EQ(mFlinger.scheduler()->pacesetterDisplayId(), kInnerDisplayId);
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp
index 49972b03f6..b8b1b9527c 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_HotplugTest.cpp
@@ -90,7 +90,9 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) {
mFlinger.configure();
EXPECT_TRUE(hasPhysicalHwcDisplay(PrimaryDisplay::HWC_DISPLAY_ID));
- EXPECT_TRUE(mFlinger.getHwComposer().isConnected(PrimaryDisplay::DISPLAY_ID::get()));
+ const auto primaryDisplayId = asPhysicalDisplayId(PrimaryDisplay::DISPLAY_ID::get());
+ ASSERT_TRUE(primaryDisplayId);
+ EXPECT_TRUE(mFlinger.getHwComposer().isConnected(*primaryDisplayId));
const auto primaryDisplayIdOpt =
mFlinger.getHwComposer().toPhysicalDisplayId(PrimaryDisplay::HWC_DISPLAY_ID);
ASSERT_TRUE(primaryDisplayIdOpt.has_value());
@@ -98,13 +100,15 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) {
mFlinger.physicalDisplays().get(primaryDisplayIdOpt.value());
ASSERT_TRUE(primaryPhysicalDisplayOpt.has_value());
const auto primaryDisplaySnapshotRef = primaryPhysicalDisplayOpt->get().snapshotRef();
- EXPECT_EQ(PrimaryDisplay::DISPLAY_ID::get(), primaryDisplaySnapshotRef.get().displayId());
+ EXPECT_EQ(*primaryDisplayId, primaryDisplaySnapshotRef.get().displayId());
EXPECT_EQ(PrimaryDisplay::PORT::value, primaryDisplaySnapshotRef.get().port());
EXPECT_EQ(PrimaryDisplay::CONNECTION_TYPE::value,
primaryDisplaySnapshotRef.get().connectionType());
EXPECT_TRUE(hasPhysicalHwcDisplay(ExternalDisplay::HWC_DISPLAY_ID));
- EXPECT_TRUE(mFlinger.getHwComposer().isConnected(ExternalDisplay::DISPLAY_ID::get()));
+ const auto externalDisplayId = asPhysicalDisplayId(ExternalDisplay::DISPLAY_ID::get());
+ ASSERT_TRUE(externalDisplayId);
+ EXPECT_TRUE(mFlinger.getHwComposer().isConnected(*externalDisplayId));
const auto externalDisplayIdOpt =
mFlinger.getHwComposer().toPhysicalDisplayId(ExternalDisplay::HWC_DISPLAY_ID);
ASSERT_TRUE(externalDisplayIdOpt.has_value());
@@ -112,7 +116,7 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) {
mFlinger.physicalDisplays().get(externalDisplayIdOpt.value());
ASSERT_TRUE(externalPhysicalDisplayOpt.has_value());
const auto externalDisplaySnapshotRef = externalPhysicalDisplayOpt->get().snapshotRef();
- EXPECT_EQ(ExternalDisplay::DISPLAY_ID::get(), externalDisplaySnapshotRef.get().displayId());
+ EXPECT_EQ(*externalDisplayId, externalDisplaySnapshotRef.get().displayId());
EXPECT_EQ(ExternalDisplay::PORT::value, externalDisplaySnapshotRef.get().port());
EXPECT_EQ(ExternalDisplay::CONNECTION_TYPE::value,
externalDisplaySnapshotRef.get().connectionType());
@@ -154,8 +158,8 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithoutIdentificationData)
constexpr PhysicalDisplayId primaryInternalDisplayId =
PhysicalDisplayId::fromPort(primaryInternalDisplayPort);
EXPECT_TRUE(hasPhysicalHwcDisplay(PrimaryDisplay::HWC_DISPLAY_ID));
- ASSERT_EQ(primaryInternalDisplayId, PrimaryDisplay::DISPLAY_ID::get());
- EXPECT_TRUE(mFlinger.getHwComposer().isConnected(PrimaryDisplay::DISPLAY_ID::get()));
+ ASSERT_EQ(primaryInternalDisplayId, asPhysicalDisplayId(PrimaryDisplay::DISPLAY_ID::get()));
+ EXPECT_TRUE(mFlinger.getHwComposer().isConnected(primaryInternalDisplayId));
const auto primaryDisplayIdOpt =
mFlinger.getHwComposer().toPhysicalDisplayId(PrimaryDisplay::HWC_DISPLAY_ID);
ASSERT_TRUE(primaryDisplayIdOpt.has_value());
@@ -220,7 +224,9 @@ TEST_F(HotplugTest, ignoresDuplicateDisconnection) {
// The display should be scheduled for removal during the next commit. At this point, it should
// still exist but be marked as disconnected.
EXPECT_TRUE(hasPhysicalHwcDisplay(ExternalDisplay::HWC_DISPLAY_ID));
- EXPECT_FALSE(mFlinger.getHwComposer().isConnected(ExternalDisplay::DISPLAY_ID::get()));
+ const auto externalDisplayId = asPhysicalDisplayId(ExternalDisplay::DISPLAY_ID::get());
+ ASSERT_TRUE(externalDisplayId);
+ EXPECT_FALSE(mFlinger.getHwComposer().isConnected(*externalDisplayId));
}
TEST_F(HotplugTest, rejectsHotplugIfFailedToLoadDisplayModes) {
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp
index 6cc6322bfc..9c143fdd41 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_NotifyExpectedPresentTest.cpp
@@ -45,28 +45,15 @@ protected:
void setTransactionState() {
ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
TransactionInfo transaction;
- mFlinger.setTransactionState(FrameTimelineInfo{}, transaction.states, transaction.displays,
- transaction.flags, transaction.applyToken,
- transaction.inputWindowCommands,
- TimePoint::now().ns() + s2ns(1), transaction.isAutoTimestamp,
- transaction.unCachedBuffers,
- /*HasListenerCallbacks=*/false, transaction.callbacks,
- transaction.id, transaction.mergedTransactionIds);
+ mFlinger.setTransactionState(std::move(transaction));
}
- struct TransactionInfo {
- Vector<ComposerState> states;
- Vector<DisplayState> displays;
- uint32_t flags = 0;
- sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
- InputWindowCommands inputWindowCommands;
- int64_t desiredPresentTime = 0;
- bool isAutoTimestamp = false;
- FrameTimelineInfo frameTimelineInfo{};
- std::vector<client_cache_t> unCachedBuffers;
- uint64_t id = static_cast<uint64_t>(-1);
- std::vector<uint64_t> mergedTransactionIds;
- std::vector<ListenerCallbacks> callbacks;
+ struct TransactionInfo : public TransactionState {
+ TransactionInfo() {
+ mApplyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
+ mIsAutoTimestamp = false;
+ mId = static_cast<uint64_t>(-1);
+ }
};
struct Compositor final : ICompositor {
@@ -383,4 +370,4 @@ TEST_F(NotifyExpectedPresentTest, notifyExpectedPresentRenderRateChanged) {
}
}
}
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPhysicalDisplayPowerModeTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPhysicalDisplayPowerModeTest.cpp
index f2fbbdda72..2332bf62da 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPhysicalDisplayPowerModeTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPhysicalDisplayPowerModeTest.cpp
@@ -17,6 +17,7 @@
#undef LOG_TAG
#define LOG_TAG "LibSurfaceFlingerUnittests"
+#include <android_companion_virtualdevice_flags.h>
#include <com_android_graphics_surfaceflinger_flags.h>
#include <common/test/FlagUtils.h>
#include "DisplayTransactionTestHelpers.h"
@@ -78,11 +79,19 @@ struct EventThreadBaseSupportedVariant {
struct EventThreadNotSupportedVariant : public EventThreadBaseSupportedVariant {
static void setupEnableVsyncCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, true)).Times(1);
+ setupDisableSyntheticVsyncCallExpectations(test);
+ }
+
+ static void setupDisableSyntheticVsyncCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(_)).Times(0);
}
static void setupDisableVsyncCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, false)).Times(1);
+ setupEnableSyntheticVsyncCallExpectations(test);
+ }
+
+ static void setupEnableSyntheticVsyncCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(_)).Times(0);
}
};
@@ -91,12 +100,20 @@ struct EventThreadIsSupportedVariant : public EventThreadBaseSupportedVariant {
static void setupEnableVsyncCallExpectations(DisplayTransactionTest* test) {
// Expect to enable hardware VSYNC and disable synthetic VSYNC.
EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, true)).Times(1);
+ setupDisableSyntheticVsyncCallExpectations(test);
+ }
+
+ static void setupDisableSyntheticVsyncCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(false)).Times(1);
}
static void setupDisableVsyncCallExpectations(DisplayTransactionTest* test) {
// Expect to disable hardware VSYNC and enable synthetic VSYNC.
EXPECT_CALL(test->mFlinger.scheduler()->mockRequestHardwareVsync, Call(_, false)).Times(1);
+ setupEnableSyntheticVsyncCallExpectations(test);
+ }
+
+ static void setupEnableSyntheticVsyncCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mEventThread, enableSyntheticVsync(true)).Times(1);
}
};
@@ -151,7 +168,7 @@ struct TransitionOffToDozeSuspendVariant
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
- Case::EventThread::setupVsyncNoCallExpectations(test);
+ Case::EventThread::setupEnableSyntheticVsyncCallExpectations(test);
Case::setupRepaintEverythingCallExpectations(test);
}
@@ -176,7 +193,7 @@ struct TransitionDozeSuspendToOffVariant
: public TransitionVariantCommon<PowerMode::DOZE_SUSPEND, PowerMode::OFF> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
- Case::EventThread::setupVsyncNoCallExpectations(test);
+ Case::EventThread::setupEnableSyntheticVsyncCallExpectations(test);
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::OFF);
}
@@ -188,7 +205,7 @@ struct TransitionDozeSuspendToOffVariant
struct TransitionOnToDozeVariant : public TransitionVariantCommon<PowerMode::ON, PowerMode::DOZE> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
- Case::EventThread::setupVsyncNoCallExpectations(test);
+ Case::EventThread::setupDisableSyntheticVsyncCallExpectations(test);
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE);
}
};
@@ -206,7 +223,7 @@ struct TransitionDozeSuspendToDozeVariant
struct TransitionDozeToOnVariant : public TransitionVariantCommon<PowerMode::DOZE, PowerMode::ON> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
- Case::EventThread::setupVsyncNoCallExpectations(test);
+ Case::EventThread::setupDisableSyntheticVsyncCallExpectations(test);
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
}
};
@@ -234,7 +251,7 @@ struct TransitionOnToUnknownVariant
: public TransitionVariantCommon<PowerMode::ON, static_cast<PowerMode>(POWER_MODE_LEET)> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
- Case::EventThread::setupVsyncNoCallExpectations(test);
+ Case::EventThread::setupDisableSyntheticVsyncCallExpectations(test);
Case::setupNoComposerPowerModeCallExpectations(test);
}
};
@@ -335,11 +352,13 @@ void SetPhysicalDisplayPowerModeTest::transitionDisplayCommon() {
// --------------------------------------------------------------------
// Preconditions
+ SET_FLAG_FOR_TEST(android::companion::virtualdevice::flags::correct_virtual_display_power_state,
+ true);
+
Case::Doze::setupComposerCallExpectations(this);
auto display =
Case::injectDisplayWithInitialPowerMode(this, Case::Transition::INITIAL_POWER_MODE);
- auto displayId = display->getId();
- if (auto physicalDisplayId = PhysicalDisplayId::tryCast(displayId)) {
+ if (auto physicalDisplayId = asPhysicalDisplayId(display->getDisplayIdVariant())) {
Case::setInitialHwVsyncEnabled(this, *physicalDisplayId,
PowerModeInitialVSyncEnabled<
Case::Transition::INITIAL_POWER_MODE>::value);
@@ -393,9 +412,9 @@ TEST_F(SetPhysicalDisplayPowerModeTest, setPhysicalDisplayPowerModeDoesNothingIf
// Preconditions
// Insert display data so that the HWC thinks it created the virtual display.
- const auto displayId = Case::Display::DISPLAY_ID::get();
- ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId));
- mFlinger.mutableHwcDisplayData().try_emplace(displayId);
+ const auto displayId = asHalDisplayId(Case::Display::DISPLAY_ID::get());
+ ASSERT_TRUE(displayId);
+ ASSERT_TRUE(mFlinger.mutableHwcDisplayData().try_emplace(*displayId).second);
// A virtual display device is set up
Case::Display::injectHwcDisplay(this);
@@ -457,7 +476,6 @@ TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToUnknownPrimary
}
TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOffToOnExternalDisplay) {
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOffToOnVariant>>();
}
@@ -466,7 +484,6 @@ TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOffToDozeSuspendEx
}
TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToOffExternalDisplay) {
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToOffVariant>>();
}
@@ -479,7 +496,6 @@ TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToDozeExternalDi
}
TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeSuspendToDozeExternalDisplay) {
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToDozeVariant>>();
}
@@ -488,12 +504,10 @@ TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeToOnExternalDi
}
TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromDozeSuspendToOnExternalDisplay) {
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
transitionDisplayCommon<ExternalDisplayPowerCase<TransitionDozeSuspendToOnVariant>>();
}
TEST_F(SetPhysicalDisplayPowerModeTest, transitionsDisplayFromOnToDozeSuspendExternalDisplay) {
- SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
transitionDisplayCommon<ExternalDisplayPowerCase<TransitionOnToDozeSuspendVariant>>();
}
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
index cd554ea1ec..23e73de660 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
@@ -235,7 +235,7 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
constexpr auto kConnectionTypeOpt = Case::Display::CONNECTION_TYPE::value;
if constexpr (kConnectionTypeOpt) {
- const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
+ const auto displayId = asPhysicalDisplayId(Case::Display::DISPLAY_ID::get());
ASSERT_TRUE(displayId);
const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
ASSERT_TRUE(hwcDisplayId);
@@ -282,7 +282,7 @@ void SetupNewDisplayDeviceInternalTest::setupNewDisplayDeviceInternalTest() {
// Postconditions
ASSERT_NE(nullptr, device);
- EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getId());
+ EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getDisplayIdVariant());
EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), device->isVirtual());
EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), device->isPrimary());
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index a3ee08f6b7..13c32bdf08 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -481,7 +481,7 @@ public:
SurfaceFlinger::ScreenshotArgs screenshotArgs;
screenshotArgs.captureTypeVariant = display;
- screenshotArgs.displayId = std::nullopt;
+ screenshotArgs.displayIdVariant = std::nullopt;
screenshotArgs.sourceCrop = sourceCrop;
screenshotArgs.reqSize = sourceCrop.getSize();
screenshotArgs.dataspace = dataspace;
@@ -519,18 +519,8 @@ public:
return mFlinger->mTransactionHandler.mPendingTransactionCount.load();
}
- auto setTransactionState(
- const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& states,
- Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
- const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
- bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffers,
- bool hasListenerCallbacks, std::vector<ListenerCallbacks>& listenerCallbacks,
- uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) {
- return mFlinger->setTransactionState(frameTimelineInfo, states, displays, flags, applyToken,
- inputWindowCommands, desiredPresentTime,
- isAutoTimestamp, uncacheBuffers, hasListenerCallbacks,
- listenerCallbacks, transactionId,
- mergedTransactionIds);
+ auto setTransactionState(TransactionState&& state) {
+ return mFlinger->setTransactionState(std::move(state));
}
auto setTransactionStateInternal(QueuedTransactionState& transaction) {
@@ -583,7 +573,7 @@ public:
}
sp<DisplayDevice> createVirtualDisplayDevice(const sp<IBinder> displayToken,
- VirtualDisplayId displayId,
+ GpuVirtualDisplayId displayId,
float requestedRefreshRate) {
constexpr ui::Size kResolution = {1080, 1920};
auto compositionDisplay = compositionengine::impl::
@@ -827,9 +817,11 @@ public:
static constexpr int32_t DEFAULT_DPI = 320;
static constexpr hal::HWConfigId DEFAULT_ACTIVE_CONFIG = 0;
- FakeHwcDisplayInjector(HalDisplayId displayId, hal::DisplayType hwcDisplayType,
+ FakeHwcDisplayInjector(DisplayIdVariant displayIdVariant, hal::DisplayType hwcDisplayType,
bool isPrimary)
- : mDisplayId(displayId), mHwcDisplayType(hwcDisplayType), mIsPrimary(isPrimary) {}
+ : mDisplayIdVariant(displayIdVariant),
+ mHwcDisplayType(hwcDisplayType),
+ mIsPrimary(isPrimary) {}
auto& setHwcDisplayId(hal::HWDisplayId displayId) {
mHwcDisplayId = displayId;
@@ -894,7 +886,9 @@ public:
display->setPowerMode(mPowerMode);
- flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = std::move(display);
+ const auto halDisplayId = asHalDisplayId(mDisplayIdVariant);
+ ASSERT_TRUE(halDisplayId);
+ flinger->mutableHwcDisplayData()[*halDisplayId].hwcDisplay = std::move(display);
EXPECT_CALL(*composer, getDisplayConfigs(mHwcDisplayId, _))
.WillRepeatedly(
@@ -932,9 +926,10 @@ public:
DoAll(SetArgPointee<3>(mConfigGroup), Return(hal::Error::NONE)));
if (mHwcDisplayType == hal::DisplayType::PHYSICAL) {
- const auto physicalId = PhysicalDisplayId::tryCast(mDisplayId);
- LOG_ALWAYS_FATAL_IF(!physicalId);
- flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, *physicalId);
+ const auto physicalDisplayId = asPhysicalDisplayId(mDisplayIdVariant);
+ ASSERT_TRUE(physicalDisplayId);
+ flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId,
+ *physicalDisplayId);
if (mIsPrimary) {
flinger->mutablePrimaryHwcDisplayId() = mHwcDisplayId;
} else {
@@ -947,7 +942,7 @@ public:
}
private:
- const HalDisplayId mDisplayId;
+ const DisplayIdVariant mDisplayIdVariant;
const hal::DisplayType mHwcDisplayType;
const bool mIsPrimary;
@@ -983,8 +978,8 @@ public:
sp<IBinder> token() const { return mDisplayToken; }
auto physicalDisplay() const {
- return ftl::Optional(mCreationArgs.compositionDisplay->getDisplayId())
- .and_then(&PhysicalDisplayId::tryCast)
+ return mCreationArgs.compositionDisplay->getDisplayIdVariant()
+ .and_then(asPhysicalDisplayId)
.and_then(display::getPhysicalDisplay(mFlinger.physicalDisplays()));
}
@@ -1082,7 +1077,9 @@ public:
DisplayDeviceState state;
state.isSecure = mCreationArgs.isSecure;
- if (const auto physicalId = PhysicalDisplayId::tryCast(*displayId)) {
+ if (const auto physicalId =
+ mCreationArgs.compositionDisplay->getDisplayIdVariant().and_then(
+ asPhysicalDisplayId)) {
LOG_ALWAYS_FATAL_IF(!mConnectionType);
LOG_ALWAYS_FATAL_IF(!mHwcDisplayId);
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 69dfcc4a8f..1395fb6af3 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -17,6 +17,8 @@
#undef LOG_TAG
#define LOG_TAG "TransactionApplicationTest"
+#include <cstdint>
+
#include <binder/Binder.h>
#include <common/test/FlagUtils.h>
#include <compositionengine/Display.h>
@@ -69,38 +71,32 @@ public:
TestableSurfaceFlinger mFlinger;
renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
- struct TransactionInfo {
- Vector<ComposerState> states;
- Vector<DisplayState> displays;
- uint32_t flags = 0;
- sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
- InputWindowCommands inputWindowCommands;
- int64_t desiredPresentTime = 0;
- bool isAutoTimestamp = true;
- FrameTimelineInfo frameTimelineInfo;
- std::vector<client_cache_t> uncacheBuffers;
- uint64_t id = static_cast<uint64_t>(-1);
- std::vector<uint64_t> mergedTransactionIds;
- static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
+ struct TransactionInfo : public TransactionState {
+ TransactionInfo() {
+ mApplyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
+ mId = static_cast<uint64_t>(-1);
+ }
};
- void checkEqual(TransactionInfo info, QueuedTransactionState state) {
- EXPECT_EQ(0u, info.states.size());
+ void checkEqual(const TransactionInfo& info, const QueuedTransactionState& state) {
+ EXPECT_EQ(0u, info.mComposerStates.size());
EXPECT_EQ(0u, state.states.size());
- EXPECT_EQ(0u, info.displays.size());
+ EXPECT_EQ(0u, info.mDisplayStates.size());
EXPECT_EQ(0u, state.displays.size());
- EXPECT_EQ(info.flags, state.flags);
- EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
+ EXPECT_EQ(info.mFlags, state.flags);
+ EXPECT_EQ(info.mDesiredPresentTime, state.desiredPresentTime);
}
void setupSingle(TransactionInfo& transaction, uint32_t flags, int64_t desiredPresentTime,
bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo) {
mTransactionNumber++;
- transaction.flags |= flags;
- transaction.desiredPresentTime = desiredPresentTime;
- transaction.isAutoTimestamp = isAutoTimestamp;
- transaction.frameTimelineInfo = frameTimelineInfo;
+ transaction.mFlags |= flags;
+ transaction.mDesiredPresentTime = desiredPresentTime;
+ transaction.mIsAutoTimestamp = isAutoTimestamp;
+ transaction.mFrameTimelineInfo = frameTimelineInfo;
+ transaction.mHasListenerCallbacks = mHasListenerCallbacks;
+ transaction.mListenerCallbacks = mCallbacks;
}
void NotPlacedOnTransactionQueue(uint32_t flags) {
@@ -111,12 +107,7 @@ public:
/*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
FrameTimelineInfo{});
nsecs_t applicationTime = systemTime();
- mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
- transaction.displays, transaction.flags,
- transaction.applyToken, transaction.inputWindowCommands,
- transaction.desiredPresentTime, transaction.isAutoTimestamp,
- transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
- transaction.id, transaction.mergedTransactionIds);
+ mFlinger.setTransactionState(std::move(transaction));
// If transaction is synchronous, SF applyTransactionState should time out (5s) wating for
// SF to commit the transaction. If this is animation, it should not time out waiting.
@@ -138,12 +129,7 @@ public:
setupSingle(transaction, flags, /*desiredPresentTime*/ time + s2ns(1), false,
FrameTimelineInfo{});
nsecs_t applicationSentTime = systemTime();
- mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
- transaction.displays, transaction.flags,
- transaction.applyToken, transaction.inputWindowCommands,
- transaction.desiredPresentTime, transaction.isAutoTimestamp,
- transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
- transaction.id, transaction.mergedTransactionIds);
+ mFlinger.setTransactionState(std::move(transaction));
nsecs_t returnedTime = systemTime();
EXPECT_LE(returnedTime, applicationSentTime + TRANSACTION_TIMEOUT);
@@ -169,12 +155,7 @@ public:
/*isAutoTimestamp*/ true, FrameTimelineInfo{});
nsecs_t applicationSentTime = systemTime();
- mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
- transactionA.displays, transactionA.flags,
- transactionA.applyToken, transactionA.inputWindowCommands,
- transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
- transactionA.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
- transactionA.id, transactionA.mergedTransactionIds);
+ mFlinger.setTransactionState(std::move(transactionA));
// This thread should not have been blocked by the above transaction
// (5s is the timeout period that applyTransactionState waits for SF to
@@ -184,12 +165,7 @@ public:
mFlinger.flushTransactionQueues();
applicationSentTime = systemTime();
- mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
- transactionB.displays, transactionB.flags,
- transactionB.applyToken, transactionB.inputWindowCommands,
- transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
- transactionB.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
- transactionB.id, transactionB.mergedTransactionIds);
+ mFlinger.setTransactionState(std::move(transactionB));
// this thread should have been blocked by the above transaction
// if this is an animation, this thread should be blocked for 5s
@@ -222,12 +198,7 @@ TEST_F(TransactionApplicationTest, AddToPendingQueue) {
TransactionInfo transactionA; // transaction to go on pending queue
setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
FrameTimelineInfo{});
- mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
- transactionA.displays, transactionA.flags, transactionA.applyToken,
- transactionA.inputWindowCommands, transactionA.desiredPresentTime,
- transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
- mHasListenerCallbacks, mCallbacks, transactionA.id,
- transactionA.mergedTransactionIds);
+ mFlinger.setTransactionState(std::move(transactionA));
auto& transactionQueue = mFlinger.getTransactionQueue();
ASSERT_FALSE(transactionQueue.isEmpty());
@@ -243,12 +214,7 @@ TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
TransactionInfo transactionA; // transaction to go on pending queue
setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
FrameTimelineInfo{});
- mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
- transactionA.displays, transactionA.flags, transactionA.applyToken,
- transactionA.inputWindowCommands, transactionA.desiredPresentTime,
- transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
- mHasListenerCallbacks, mCallbacks, transactionA.id,
- transactionA.mergedTransactionIds);
+ mFlinger.setTransactionState(std::move(transactionA));
auto& transactionQueue = mFlinger.getTransactionQueue();
ASSERT_FALSE(transactionQueue.isEmpty());
@@ -257,12 +223,10 @@ TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
// transaction here (sending a null applyToken to fake it as from a
// different process) to re-query and reset the cached expected present time
TransactionInfo empty;
- empty.applyToken = sp<IBinder>();
- mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
- empty.applyToken, empty.inputWindowCommands,
- empty.desiredPresentTime, empty.isAutoTimestamp,
- empty.uncacheBuffers, mHasListenerCallbacks, mCallbacks, empty.id,
- empty.mergedTransactionIds);
+ empty.mApplyToken = sp<IBinder>();
+ empty.mHasListenerCallbacks = mHasListenerCallbacks;
+ empty.mListenerCallbacks = mCallbacks;
+ mFlinger.setTransactionState(std::move(empty));
// flush transaction queue should flush as desiredPresentTime has
// passed
@@ -406,9 +370,9 @@ public:
const auto kFrameTimelineInfo = FrameTimelineInfo{};
setupSingle(transaction, kFlags, kDesiredPresentTime, kIsAutoTimestamp, kFrameTimelineInfo);
- transaction.applyToken = applyToken;
+ transaction.mApplyToken = applyToken;
for (const auto& state : states) {
- transaction.states.push_back(state);
+ transaction.mComposerStates.push_back(state);
}
return transaction;
@@ -419,8 +383,8 @@ public:
EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
std::unordered_set<uint32_t> createdLayers;
- for (auto transaction : transactions) {
- for (auto& state : transaction.states) {
+ for (auto& transaction : transactions) {
+ for (auto& state : transaction.mComposerStates) {
auto layerId = static_cast<uint32_t>(state.state.layerId);
if (createdLayers.find(layerId) == createdLayers.end()) {
mFlinger.addLayer(layerId);
@@ -434,8 +398,8 @@ public:
for (auto transaction : transactions) {
std::vector<ResolvedComposerState> resolvedStates;
- resolvedStates.reserve(transaction.states.size());
- for (auto& state : transaction.states) {
+ resolvedStates.reserve(transaction.mComposerStates.size());
+ for (auto& state : transaction.mComposerStates) {
ResolvedComposerState resolvedState;
resolvedState.state = std::move(state.state);
resolvedState.externalTexture =
@@ -446,15 +410,9 @@ public:
resolvedStates.emplace_back(resolvedState);
}
- QueuedTransactionState transactionState(transaction.frameTimelineInfo, resolvedStates,
- transaction.displays, transaction.flags,
- transaction.applyToken,
- transaction.inputWindowCommands,
- transaction.desiredPresentTime,
- transaction.isAutoTimestamp, {}, systemTime(),
- mHasListenerCallbacks, mCallbacks, getpid(),
- static_cast<int>(getuid()), transaction.id,
- transaction.mergedTransactionIds);
+ QueuedTransactionState transactionState(std::move(transaction),
+ std::move(resolvedStates), {}, systemTime(),
+ getpid(), static_cast<int>(getuid()));
mFlinger.setTransactionStateInternal(transactionState);
}
mFlinger.flushTransactionQueues();
diff --git a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
index d3eec5c6f3..b36ad213c8 100644
--- a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
@@ -66,7 +66,7 @@ TEST(TransactionProtoParserTest, parse) {
display.token = nullptr;
}
display.width = 85;
- t1.displays.add(display);
+ t1.displays.push_back(display);
}
class TestMapper : public TransactionProtoParser::FlingerDataMapper {
diff --git a/vulkan/vkjson/vkjson.cc b/vulkan/vkjson/vkjson.cc
index 18fef2bf58..531a623e90 100644
--- a/vulkan/vkjson/vkjson.cc
+++ b/vulkan/vkjson/vkjson.cc
@@ -56,13 +56,15 @@ inline bool IsIntegral(double value) {
// Floating point fields of Vulkan structure use single precision. The string
// output of max double value in c++ will be larger than Java double's infinity
// value. Below fake double max/min values are only to serve the safe json text
-// parsing in between C++ and Java, becasue Java json library simply cannot
+// parsing in between C++ and Java, because Java json library simply cannot
// handle infinity.
static const double SAFE_DOUBLE_MAX = 0.99 * std::numeric_limits<double>::max();
static const double SAFE_DOUBLE_MIN = -SAFE_DOUBLE_MAX;
-template <typename T> struct EnumTraits;
-template <> struct EnumTraits<VkPhysicalDeviceType> {
+template <typename T>
+struct EnumTraits;
+template <>
+struct EnumTraits<VkPhysicalDeviceType> {
static bool exist(uint32_t e) {
switch (e) {
case VK_PHYSICAL_DEVICE_TYPE_OTHER:
@@ -76,7 +78,8 @@ template <> struct EnumTraits<VkPhysicalDeviceType> {
}
};
-template <> struct EnumTraits<VkFormat> {
+template <>
+struct EnumTraits<VkFormat> {
static bool exist(uint32_t e) {
switch (e) {
case VK_FORMAT_UNDEFINED:
@@ -482,708 +485,1447 @@ struct EnumTraits<VkImageLayout> {
template <typename Visitor>
inline bool Iterate(Visitor* visitor, VkExtent3D* extents) {
+ return visitor->Visit("width", &extents->width) &&
+ visitor->Visit("height", &extents->height) &&
+ visitor->Visit("depth", &extents->depth);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkConformanceVersionKHR* version) {
+ return visitor->Visit("major", &version->major) &&
+ visitor->Visit("minor", &version->minor) &&
+ visitor->Visit("subminor", &version->subminor) &&
+ visitor->Visit("patch", &version->patch);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkMemoryType* type) {
+ return visitor->Visit("propertyFlags", &type->propertyFlags) &&
+ visitor->Visit("heapIndex", &type->heapIndex);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkMemoryHeap* heap) {
+ return visitor->Visit("size", &heap->size) &&
+ visitor->Visit("flags", &heap->flags);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonCore11* core) {
+ return visitor->Visit("properties", &core->properties) &&
+ visitor->Visit("features", &core->features);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonCore12* core) {
+ return visitor->Visit("properties", &core->properties) &&
+ visitor->Visit("features", &core->features);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonCore13* core) {
+ return visitor->Visit("properties", &core->properties) &&
+ visitor->Visit("features", &core->features);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonCore14* core) {
+ return visitor->Visit("properties", &core->properties) &&
+ visitor->Visit("features", &core->features);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonKHRVariablePointers* structs) {
+ return visitor->Visit("variablePointerFeaturesKHR",
+ &structs->variable_pointer_features_khr) &&
+ visitor->Visit("variablePointersFeaturesKHR",
+ &structs->variable_pointers_features_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonKHRShaderFloat16Int8* structs) {
+ return visitor->Visit("shaderFloat16Int8FeaturesKHR",
+ &structs->shader_float16_int8_features_khr) &&
+ visitor->Visit("float16Int8FeaturesKHR",
+ &structs->float16_int8_features_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonExtImage2dViewOf3d* structs) {
+ return visitor->Visit("image2DViewOf3DFeaturesEXT",
+ &structs->image_2d_view_of_3d_features_ext);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonExtCustomBorderColor* structs) {
+ return visitor->Visit("customBorderColorFeaturesEXT",
+ &structs->custom_border_color_features_ext);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkJsonExtPrimitiveTopologyListRestart* structs) {
+ return visitor->Visit("primitiveTopologyListRestartFeaturesEXT",
+ &structs->primitive_topology_list_restart_features_ext);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonExtProvokingVertex* structs) {
+ return visitor->Visit("provokingVertexFeaturesEXT",
+ &structs->provoking_vertex_features_ext);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonKHRIndexTypeUint8* structs) {
+ return visitor->Visit("indexTypeUint8FeaturesKHR",
+ &structs->index_type_uint8_features_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonExtIndexTypeUint8* structs) {
+ return visitor->Visit("indexTypeUint8FeaturesEXT",
+ &structs->index_type_uint8_features_ext);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkJsonKHRVertexAttributeDivisor* structs) {
+ return visitor->Visit("vertexAttributeDivisorFeaturesKHR",
+ &structs->vertex_attribute_divisor_features_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkJsonExtVertexAttributeDivisor* structs) {
+ return visitor->Visit("vertexAttributeDivisorFeaturesEXT",
+ &structs->vertex_attribute_divisor_features_ext);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonExtTransformFeedback* structs) {
+ return visitor->Visit("transformFeedbackFeaturesEXT",
+ &structs->transform_feedback_features_ext);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkJsonKHRShaderSubgroupUniformControlFlow* structs) {
+ return visitor->Visit(
+ "shaderSubgroupUniformControlFlowFeaturesKHR",
+ &structs->shader_subgroup_uniform_control_flow_features_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkJsonKHRShaderSubgroupExtendedTypes* structs) {
+ return visitor->Visit("shaderSubgroupExtendedTypesFeaturesKHR",
+ &structs->shader_subgroup_extended_types_features_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonKHR8bitStorage* structs) {
+ return visitor->Visit("bit8StorageFeaturesKHR",
+ &structs->bit8_storage_features_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkJsonKHRShaderIntegerDotProduct* structs) {
+ return visitor->Visit("shaderIntegerDotProductFeaturesKHR",
+ &structs->shader_integer_dot_product_features_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkJsonIMGRelaxedLineRasterization* structs) {
+ return visitor->Visit("relaxedLineRasterizationFeaturesIMG",
+ &structs->relaxed_line_rasterization_features_img);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonKHRLineRasterization* structs) {
+ return visitor->Visit("lineRasterizationFeaturesKHR",
+ &structs->line_rasterization_features_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonExtLineRasterization* structs) {
+ return visitor->Visit("lineRasterizationFeaturesEXT",
+ &structs->line_rasterization_features_ext);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkJsonExtPrimitivesGeneratedQuery* structs) {
+ return visitor->Visit("primitivesGeneratedQueryFeaturesEXT",
+ &structs->primitives_generated_query_features_ext);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonKHRShaderFloatControls* structs) {
+ return visitor->Visit("floatControlsPropertiesKHR",
+ &structs->float_controls_properties_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkJsonKHRDriverProperties* structs) {
+ return visitor->Visit("driverPropertiesKHR", &structs->driver_properties_khr);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceFloatControlsProperties* properties) {
return
- visitor->Visit("width", &extents->width) &&
- visitor->Visit("height", &extents->height) &&
- visitor->Visit("depth", &extents->depth);
+
+ visitor->Visit("denormBehaviorIndependence",
+ &properties->denormBehaviorIndependence) &&
+ visitor->Visit("roundingModeIndependence",
+ &properties->roundingModeIndependence) &&
+ visitor->Visit("shaderSignedZeroInfNanPreserveFloat16",
+ &properties->shaderSignedZeroInfNanPreserveFloat16) &&
+ visitor->Visit("shaderSignedZeroInfNanPreserveFloat32",
+ &properties->shaderSignedZeroInfNanPreserveFloat32) &&
+ visitor->Visit("shaderSignedZeroInfNanPreserveFloat64",
+ &properties->shaderSignedZeroInfNanPreserveFloat64) &&
+ visitor->Visit("shaderDenormPreserveFloat16",
+ &properties->shaderDenormPreserveFloat16) &&
+ visitor->Visit("shaderDenormPreserveFloat32",
+ &properties->shaderDenormPreserveFloat32) &&
+ visitor->Visit("shaderDenormPreserveFloat64",
+ &properties->shaderDenormPreserveFloat64) &&
+ visitor->Visit("shaderDenormFlushToZeroFloat16",
+ &properties->shaderDenormFlushToZeroFloat16) &&
+ visitor->Visit("shaderDenormFlushToZeroFloat32",
+ &properties->shaderDenormFlushToZeroFloat32) &&
+ visitor->Visit("shaderDenormFlushToZeroFloat64",
+ &properties->shaderDenormFlushToZeroFloat64) &&
+ visitor->Visit("shaderRoundingModeRTEFloat16",
+ &properties->shaderRoundingModeRTEFloat16) &&
+ visitor->Visit("shaderRoundingModeRTEFloat32",
+ &properties->shaderRoundingModeRTEFloat32) &&
+ visitor->Visit("shaderRoundingModeRTEFloat64",
+ &properties->shaderRoundingModeRTEFloat64) &&
+ visitor->Visit("shaderRoundingModeRTZFloat16",
+ &properties->shaderRoundingModeRTZFloat16) &&
+ visitor->Visit("shaderRoundingModeRTZFloat32",
+ &properties->shaderRoundingModeRTZFloat32) &&
+ visitor->Visit("shaderRoundingModeRTZFloat64",
+ &properties->shaderRoundingModeRTZFloat64);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkImageFormatProperties* properties) {
+inline bool Iterate(Visitor* visitor, VkPhysicalDeviceProperties* properties) {
return
- visitor->Visit("maxExtent", &properties->maxExtent) &&
- visitor->Visit("maxMipLevels", &properties->maxMipLevels) &&
- visitor->Visit("maxArrayLayers", &properties->maxArrayLayers) &&
- visitor->Visit("sampleCounts", &properties->sampleCounts) &&
- visitor->Visit("maxResourceSize", &properties->maxResourceSize);
+
+ visitor->Visit("apiVersion", &properties->apiVersion) &&
+ visitor->Visit("driverVersion", &properties->driverVersion) &&
+ visitor->Visit("vendorID", &properties->vendorID) &&
+ visitor->Visit("deviceID", &properties->deviceID) &&
+ visitor->Visit("deviceType", &properties->deviceType) &&
+ visitor->Visit("deviceName", &properties->deviceName) &&
+ visitor->Visit("pipelineCacheUUID", &properties->pipelineCacheUUID) &&
+ visitor->Visit("limits", &properties->limits) &&
+ visitor->Visit("sparseProperties", &properties->sparseProperties);
}
-// clang-format off
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkPhysicalDeviceLimits* limits) {
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceMemoryProperties* properties) {
return
- visitor->Visit("maxImageDimension1D", &limits->maxImageDimension1D) &&
- visitor->Visit("maxImageDimension2D", &limits->maxImageDimension2D) &&
- visitor->Visit("maxImageDimension3D", &limits->maxImageDimension3D) &&
- visitor->Visit("maxImageDimensionCube", &limits->maxImageDimensionCube) &&
- visitor->Visit("maxImageArrayLayers", &limits->maxImageArrayLayers) &&
- visitor->Visit("maxTexelBufferElements", &limits->maxTexelBufferElements) &&
- visitor->Visit("maxUniformBufferRange", &limits->maxUniformBufferRange) &&
- visitor->Visit("maxStorageBufferRange", &limits->maxStorageBufferRange) &&
- visitor->Visit("maxPushConstantsSize", &limits->maxPushConstantsSize) &&
- visitor->Visit("maxMemoryAllocationCount", &limits->maxMemoryAllocationCount) &&
- visitor->Visit("maxSamplerAllocationCount", &limits->maxSamplerAllocationCount) &&
- visitor->Visit("bufferImageGranularity", &limits->bufferImageGranularity) &&
- visitor->Visit("sparseAddressSpaceSize", &limits->sparseAddressSpaceSize) &&
- visitor->Visit("maxBoundDescriptorSets", &limits->maxBoundDescriptorSets) &&
- visitor->Visit("maxPerStageDescriptorSamplers", &limits->maxPerStageDescriptorSamplers) &&
- visitor->Visit("maxPerStageDescriptorUniformBuffers", &limits->maxPerStageDescriptorUniformBuffers) &&
- visitor->Visit("maxPerStageDescriptorStorageBuffers", &limits->maxPerStageDescriptorStorageBuffers) &&
- visitor->Visit("maxPerStageDescriptorSampledImages", &limits->maxPerStageDescriptorSampledImages) &&
- visitor->Visit("maxPerStageDescriptorStorageImages", &limits->maxPerStageDescriptorStorageImages) &&
- visitor->Visit("maxPerStageDescriptorInputAttachments", &limits->maxPerStageDescriptorInputAttachments) &&
- visitor->Visit("maxPerStageResources", &limits->maxPerStageResources) &&
- visitor->Visit("maxDescriptorSetSamplers", &limits->maxDescriptorSetSamplers) &&
- visitor->Visit("maxDescriptorSetUniformBuffers", &limits->maxDescriptorSetUniformBuffers) &&
- visitor->Visit("maxDescriptorSetUniformBuffersDynamic", &limits->maxDescriptorSetUniformBuffersDynamic) &&
- visitor->Visit("maxDescriptorSetStorageBuffers", &limits->maxDescriptorSetStorageBuffers) &&
- visitor->Visit("maxDescriptorSetStorageBuffersDynamic", &limits->maxDescriptorSetStorageBuffersDynamic) &&
- visitor->Visit("maxDescriptorSetSampledImages", &limits->maxDescriptorSetSampledImages) &&
- visitor->Visit("maxDescriptorSetStorageImages", &limits->maxDescriptorSetStorageImages) &&
- visitor->Visit("maxDescriptorSetInputAttachments", &limits->maxDescriptorSetInputAttachments) &&
- visitor->Visit("maxVertexInputAttributes", &limits->maxVertexInputAttributes) &&
- visitor->Visit("maxVertexInputBindings", &limits->maxVertexInputBindings) &&
- visitor->Visit("maxVertexInputAttributeOffset", &limits->maxVertexInputAttributeOffset) &&
- visitor->Visit("maxVertexInputBindingStride", &limits->maxVertexInputBindingStride) &&
- visitor->Visit("maxVertexOutputComponents", &limits->maxVertexOutputComponents) &&
- visitor->Visit("maxTessellationGenerationLevel", &limits->maxTessellationGenerationLevel) &&
- visitor->Visit("maxTessellationPatchSize", &limits->maxTessellationPatchSize) &&
- visitor->Visit("maxTessellationControlPerVertexInputComponents", &limits->maxTessellationControlPerVertexInputComponents) &&
- visitor->Visit("maxTessellationControlPerVertexOutputComponents", &limits->maxTessellationControlPerVertexOutputComponents) &&
- visitor->Visit("maxTessellationControlPerPatchOutputComponents", &limits->maxTessellationControlPerPatchOutputComponents) &&
- visitor->Visit("maxTessellationControlTotalOutputComponents", &limits->maxTessellationControlTotalOutputComponents) &&
- visitor->Visit("maxTessellationEvaluationInputComponents", &limits->maxTessellationEvaluationInputComponents) &&
- visitor->Visit("maxTessellationEvaluationOutputComponents", &limits->maxTessellationEvaluationOutputComponents) &&
- visitor->Visit("maxGeometryShaderInvocations", &limits->maxGeometryShaderInvocations) &&
- visitor->Visit("maxGeometryInputComponents", &limits->maxGeometryInputComponents) &&
- visitor->Visit("maxGeometryOutputComponents", &limits->maxGeometryOutputComponents) &&
- visitor->Visit("maxGeometryOutputVertices", &limits->maxGeometryOutputVertices) &&
- visitor->Visit("maxGeometryTotalOutputComponents", &limits->maxGeometryTotalOutputComponents) &&
- visitor->Visit("maxFragmentInputComponents", &limits->maxFragmentInputComponents) &&
- visitor->Visit("maxFragmentOutputAttachments", &limits->maxFragmentOutputAttachments) &&
- visitor->Visit("maxFragmentDualSrcAttachments", &limits->maxFragmentDualSrcAttachments) &&
- visitor->Visit("maxFragmentCombinedOutputResources", &limits->maxFragmentCombinedOutputResources) &&
- visitor->Visit("maxComputeSharedMemorySize", &limits->maxComputeSharedMemorySize) &&
- visitor->Visit("maxComputeWorkGroupCount", &limits->maxComputeWorkGroupCount) &&
- visitor->Visit("maxComputeWorkGroupInvocations", &limits->maxComputeWorkGroupInvocations) &&
- visitor->Visit("maxComputeWorkGroupSize", &limits->maxComputeWorkGroupSize) &&
- visitor->Visit("subPixelPrecisionBits", &limits->subPixelPrecisionBits) &&
- visitor->Visit("subTexelPrecisionBits", &limits->subTexelPrecisionBits) &&
- visitor->Visit("mipmapPrecisionBits", &limits->mipmapPrecisionBits) &&
- visitor->Visit("maxDrawIndexedIndexValue", &limits->maxDrawIndexedIndexValue) &&
- visitor->Visit("maxDrawIndirectCount", &limits->maxDrawIndirectCount) &&
- visitor->Visit("maxSamplerLodBias", &limits->maxSamplerLodBias) &&
- visitor->Visit("maxSamplerAnisotropy", &limits->maxSamplerAnisotropy) &&
- visitor->Visit("maxViewports", &limits->maxViewports) &&
- visitor->Visit("maxViewportDimensions", &limits->maxViewportDimensions) &&
- visitor->Visit("viewportBoundsRange", &limits->viewportBoundsRange) &&
- visitor->Visit("viewportSubPixelBits", &limits->viewportSubPixelBits) &&
- visitor->Visit("minMemoryMapAlignment", &limits->minMemoryMapAlignment) &&
- visitor->Visit("minTexelBufferOffsetAlignment", &limits->minTexelBufferOffsetAlignment) &&
- visitor->Visit("minUniformBufferOffsetAlignment", &limits->minUniformBufferOffsetAlignment) &&
- visitor->Visit("minStorageBufferOffsetAlignment", &limits->minStorageBufferOffsetAlignment) &&
- visitor->Visit("minTexelOffset", &limits->minTexelOffset) &&
- visitor->Visit("maxTexelOffset", &limits->maxTexelOffset) &&
- visitor->Visit("minTexelGatherOffset", &limits->minTexelGatherOffset) &&
- visitor->Visit("maxTexelGatherOffset", &limits->maxTexelGatherOffset) &&
- visitor->Visit("minInterpolationOffset", &limits->minInterpolationOffset) &&
- visitor->Visit("maxInterpolationOffset", &limits->maxInterpolationOffset) &&
- visitor->Visit("subPixelInterpolationOffsetBits", &limits->subPixelInterpolationOffsetBits) &&
- visitor->Visit("maxFramebufferWidth", &limits->maxFramebufferWidth) &&
- visitor->Visit("maxFramebufferHeight", &limits->maxFramebufferHeight) &&
- visitor->Visit("maxFramebufferLayers", &limits->maxFramebufferLayers) &&
- visitor->Visit("framebufferColorSampleCounts", &limits->framebufferColorSampleCounts) &&
- visitor->Visit("framebufferDepthSampleCounts", &limits->framebufferDepthSampleCounts) &&
- visitor->Visit("framebufferStencilSampleCounts", &limits->framebufferStencilSampleCounts) &&
- visitor->Visit("framebufferNoAttachmentsSampleCounts", &limits->framebufferNoAttachmentsSampleCounts) &&
- visitor->Visit("maxColorAttachments", &limits->maxColorAttachments) &&
- visitor->Visit("sampledImageColorSampleCounts", &limits->sampledImageColorSampleCounts) &&
- visitor->Visit("sampledImageIntegerSampleCounts", &limits->sampledImageIntegerSampleCounts) &&
- visitor->Visit("sampledImageDepthSampleCounts", &limits->sampledImageDepthSampleCounts) &&
- visitor->Visit("sampledImageStencilSampleCounts", &limits->sampledImageStencilSampleCounts) &&
- visitor->Visit("storageImageSampleCounts", &limits->storageImageSampleCounts) &&
- visitor->Visit("maxSampleMaskWords", &limits->maxSampleMaskWords) &&
- visitor->Visit("timestampComputeAndGraphics", &limits->timestampComputeAndGraphics) &&
- visitor->Visit("timestampPeriod", &limits->timestampPeriod) &&
- visitor->Visit("maxClipDistances", &limits->maxClipDistances) &&
- visitor->Visit("maxCullDistances", &limits->maxCullDistances) &&
- visitor->Visit("maxCombinedClipAndCullDistances", &limits->maxCombinedClipAndCullDistances) &&
- visitor->Visit("discreteQueuePriorities", &limits->discreteQueuePriorities) &&
- visitor->Visit("pointSizeRange", &limits->pointSizeRange) &&
- visitor->Visit("lineWidthRange", &limits->lineWidthRange) &&
- visitor->Visit("pointSizeGranularity", &limits->pointSizeGranularity) &&
- visitor->Visit("lineWidthGranularity", &limits->lineWidthGranularity) &&
- visitor->Visit("strictLines", &limits->strictLines) &&
- visitor->Visit("standardSampleLocations", &limits->standardSampleLocations) &&
- visitor->Visit("optimalBufferCopyOffsetAlignment", &limits->optimalBufferCopyOffsetAlignment) &&
- visitor->Visit("optimalBufferCopyRowPitchAlignment", &limits->optimalBufferCopyRowPitchAlignment) &&
- visitor->Visit("nonCoherentAtomSize", &limits->nonCoherentAtomSize);
+
+ visitor->Visit("memoryTypeCount", &properties->memoryTypeCount) &&
+ visitor->VisitArray("memoryTypes", properties->memoryTypeCount,
+ &properties->memoryTypes) &&
+ visitor->Visit("memoryHeapCount", &properties->memoryHeapCount) &&
+ visitor->VisitArray("memoryHeaps", properties->memoryHeapCount,
+ &properties->memoryHeaps);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceSparseProperties* properties) {
+ VkPhysicalDeviceSubgroupProperties* properties) {
return
- visitor->Visit("residencyStandard2DBlockShape", &properties->residencyStandard2DBlockShape) &&
- visitor->Visit("residencyStandard2DMultisampleBlockShape", &properties->residencyStandard2DMultisampleBlockShape) &&
- visitor->Visit("residencyStandard3DBlockShape", &properties->residencyStandard3DBlockShape) &&
- visitor->Visit("residencyAlignedMipSize", &properties->residencyAlignedMipSize) &&
- visitor->Visit("residencyNonResidentStrict", &properties->residencyNonResidentStrict);
+
+ visitor->Visit("subgroupSize", &properties->subgroupSize) &&
+ visitor->Visit("supportedStages", &properties->supportedStages) &&
+ visitor->Visit("supportedOperations", &properties->supportedOperations) &&
+ visitor->Visit("quadOperationsInAllStages",
+ &properties->quadOperationsInAllStages);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceProperties* properties) {
+ VkPhysicalDevicePointClippingProperties* properties) {
return
- visitor->Visit("apiVersion", &properties->apiVersion) &&
- visitor->Visit("driverVersion", &properties->driverVersion) &&
- visitor->Visit("vendorID", &properties->vendorID) &&
- visitor->Visit("deviceID", &properties->deviceID) &&
- visitor->Visit("deviceType", &properties->deviceType) &&
- visitor->Visit("deviceName", &properties->deviceName) &&
- visitor->Visit("pipelineCacheUUID", &properties->pipelineCacheUUID) &&
- visitor->Visit("limits", &properties->limits) &&
- visitor->Visit("sparseProperties", &properties->sparseProperties);
+
+ visitor->Visit("pointClippingBehavior",
+ &properties->pointClippingBehavior);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkPhysicalDeviceFeatures* features) {
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceMultiviewProperties* properties) {
return
- visitor->Visit("robustBufferAccess", &features->robustBufferAccess) &&
- visitor->Visit("fullDrawIndexUint32", &features->fullDrawIndexUint32) &&
- visitor->Visit("imageCubeArray", &features->imageCubeArray) &&
- visitor->Visit("independentBlend", &features->independentBlend) &&
- visitor->Visit("geometryShader", &features->geometryShader) &&
- visitor->Visit("tessellationShader", &features->tessellationShader) &&
- visitor->Visit("sampleRateShading", &features->sampleRateShading) &&
- visitor->Visit("dualSrcBlend", &features->dualSrcBlend) &&
- visitor->Visit("logicOp", &features->logicOp) &&
- visitor->Visit("multiDrawIndirect", &features->multiDrawIndirect) &&
- visitor->Visit("drawIndirectFirstInstance", &features->drawIndirectFirstInstance) &&
- visitor->Visit("depthClamp", &features->depthClamp) &&
- visitor->Visit("depthBiasClamp", &features->depthBiasClamp) &&
- visitor->Visit("fillModeNonSolid", &features->fillModeNonSolid) &&
- visitor->Visit("depthBounds", &features->depthBounds) &&
- visitor->Visit("wideLines", &features->wideLines) &&
- visitor->Visit("largePoints", &features->largePoints) &&
- visitor->Visit("alphaToOne", &features->alphaToOne) &&
- visitor->Visit("multiViewport", &features->multiViewport) &&
- visitor->Visit("samplerAnisotropy", &features->samplerAnisotropy) &&
- visitor->Visit("textureCompressionETC2", &features->textureCompressionETC2) &&
- visitor->Visit("textureCompressionASTC_LDR", &features->textureCompressionASTC_LDR) &&
- visitor->Visit("textureCompressionBC", &features->textureCompressionBC) &&
- visitor->Visit("occlusionQueryPrecise", &features->occlusionQueryPrecise) &&
- visitor->Visit("pipelineStatisticsQuery", &features->pipelineStatisticsQuery) &&
- visitor->Visit("vertexPipelineStoresAndAtomics", &features->vertexPipelineStoresAndAtomics) &&
- visitor->Visit("fragmentStoresAndAtomics", &features->fragmentStoresAndAtomics) &&
- visitor->Visit("shaderTessellationAndGeometryPointSize", &features->shaderTessellationAndGeometryPointSize) &&
- visitor->Visit("shaderImageGatherExtended", &features->shaderImageGatherExtended) &&
- visitor->Visit("shaderStorageImageExtendedFormats", &features->shaderStorageImageExtendedFormats) &&
- visitor->Visit("shaderStorageImageMultisample", &features->shaderStorageImageMultisample) &&
- visitor->Visit("shaderStorageImageReadWithoutFormat", &features->shaderStorageImageReadWithoutFormat) &&
- visitor->Visit("shaderStorageImageWriteWithoutFormat", &features->shaderStorageImageWriteWithoutFormat) &&
- visitor->Visit("shaderUniformBufferArrayDynamicIndexing", &features->shaderUniformBufferArrayDynamicIndexing) &&
- visitor->Visit("shaderSampledImageArrayDynamicIndexing", &features->shaderSampledImageArrayDynamicIndexing) &&
- visitor->Visit("shaderStorageBufferArrayDynamicIndexing", &features->shaderStorageBufferArrayDynamicIndexing) &&
- visitor->Visit("shaderStorageImageArrayDynamicIndexing", &features->shaderStorageImageArrayDynamicIndexing) &&
- visitor->Visit("shaderClipDistance", &features->shaderClipDistance) &&
- visitor->Visit("shaderCullDistance", &features->shaderCullDistance) &&
- visitor->Visit("shaderFloat64", &features->shaderFloat64) &&
- visitor->Visit("shaderInt64", &features->shaderInt64) &&
- visitor->Visit("shaderInt16", &features->shaderInt16) &&
- visitor->Visit("shaderResourceResidency", &features->shaderResourceResidency) &&
- visitor->Visit("shaderResourceMinLod", &features->shaderResourceMinLod) &&
- visitor->Visit("sparseBinding", &features->sparseBinding) &&
- visitor->Visit("sparseResidencyBuffer", &features->sparseResidencyBuffer) &&
- visitor->Visit("sparseResidencyImage2D", &features->sparseResidencyImage2D) &&
- visitor->Visit("sparseResidencyImage3D", &features->sparseResidencyImage3D) &&
- visitor->Visit("sparseResidency2Samples", &features->sparseResidency2Samples) &&
- visitor->Visit("sparseResidency4Samples", &features->sparseResidency4Samples) &&
- visitor->Visit("sparseResidency8Samples", &features->sparseResidency8Samples) &&
- visitor->Visit("sparseResidency16Samples", &features->sparseResidency16Samples) &&
- visitor->Visit("sparseResidencyAliased", &features->sparseResidencyAliased) &&
- visitor->Visit("variableMultisampleRate", &features->variableMultisampleRate) &&
- visitor->Visit("inheritedQueries", &features->inheritedQueries);
+
+ visitor->Visit("maxMultiviewViewCount",
+ &properties->maxMultiviewViewCount) &&
+ visitor->Visit("maxMultiviewInstanceIndex",
+ &properties->maxMultiviewInstanceIndex);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkJsonCore12* core) {
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceIDProperties* properties) {
return
- visitor->Visit("features", &core->features) &&
- visitor->Visit("properties", &core->properties);
+
+ visitor->Visit("deviceUUID", &properties->deviceUUID) &&
+ visitor->Visit("driverUUID", &properties->driverUUID) &&
+ visitor->Visit("deviceLUID", &properties->deviceLUID) &&
+ visitor->Visit("deviceNodeMask", &properties->deviceNodeMask) &&
+ visitor->Visit("deviceLUIDValid", &properties->deviceLUIDValid);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan12Properties* properties) {
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceMaintenance3Properties* properties) {
return
- visitor->Visit("driverID", &properties->driverID) &&
- visitor->Visit("driverName", &properties->driverName) &&
- visitor->Visit("driverInfo", &properties->driverInfo) &&
- visitor->Visit("conformanceVersion", &properties->conformanceVersion) &&
- visitor->Visit("denormBehaviorIndependence", &properties->denormBehaviorIndependence) &&
- visitor->Visit("roundingModeIndependence", &properties->roundingModeIndependence) &&
- visitor->Visit("shaderSignedZeroInfNanPreserveFloat16", &properties->shaderSignedZeroInfNanPreserveFloat16) &&
- visitor->Visit("shaderSignedZeroInfNanPreserveFloat32", &properties->shaderSignedZeroInfNanPreserveFloat32) &&
- visitor->Visit("shaderSignedZeroInfNanPreserveFloat64", &properties->shaderSignedZeroInfNanPreserveFloat64) &&
- visitor->Visit("shaderDenormPreserveFloat16", &properties->shaderDenormPreserveFloat16) &&
- visitor->Visit("shaderDenormPreserveFloat32", &properties->shaderDenormPreserveFloat32) &&
- visitor->Visit("shaderDenormPreserveFloat64", &properties->shaderDenormPreserveFloat64) &&
- visitor->Visit("shaderDenormFlushToZeroFloat16", &properties->shaderDenormFlushToZeroFloat16) &&
- visitor->Visit("shaderDenormFlushToZeroFloat32", &properties->shaderDenormFlushToZeroFloat32) &&
- visitor->Visit("shaderDenormFlushToZeroFloat64", &properties->shaderDenormFlushToZeroFloat64) &&
- visitor->Visit("shaderRoundingModeRTEFloat16", &properties->shaderRoundingModeRTEFloat16) &&
- visitor->Visit("shaderRoundingModeRTEFloat32", &properties->shaderRoundingModeRTEFloat32) &&
- visitor->Visit("shaderRoundingModeRTEFloat64", &properties->shaderRoundingModeRTEFloat64) &&
- visitor->Visit("shaderRoundingModeRTZFloat16", &properties->shaderRoundingModeRTZFloat16) &&
- visitor->Visit("shaderRoundingModeRTZFloat32", &properties->shaderRoundingModeRTZFloat32) &&
- visitor->Visit("shaderRoundingModeRTZFloat64", &properties->shaderRoundingModeRTZFloat64) &&
- visitor->Visit("maxUpdateAfterBindDescriptorsInAllPools", &properties->maxUpdateAfterBindDescriptorsInAllPools) &&
- visitor->Visit("shaderUniformBufferArrayNonUniformIndexingNative", &properties->shaderUniformBufferArrayNonUniformIndexingNative) &&
- visitor->Visit("shaderSampledImageArrayNonUniformIndexingNative", &properties->shaderSampledImageArrayNonUniformIndexingNative) &&
- visitor->Visit("shaderStorageBufferArrayNonUniformIndexingNative", &properties->shaderStorageBufferArrayNonUniformIndexingNative) &&
- visitor->Visit("shaderStorageImageArrayNonUniformIndexingNative", &properties->shaderStorageImageArrayNonUniformIndexingNative) &&
- visitor->Visit("shaderInputAttachmentArrayNonUniformIndexingNative", &properties->shaderInputAttachmentArrayNonUniformIndexingNative) &&
- visitor->Visit("robustBufferAccessUpdateAfterBind", &properties->robustBufferAccessUpdateAfterBind) &&
- visitor->Visit("quadDivergentImplicitLod", &properties->quadDivergentImplicitLod) &&
- visitor->Visit("maxPerStageDescriptorUpdateAfterBindSamplers", &properties->maxPerStageDescriptorUpdateAfterBindSamplers) &&
- visitor->Visit("maxPerStageDescriptorUpdateAfterBindUniformBuffers", &properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers) &&
- visitor->Visit("maxPerStageDescriptorUpdateAfterBindStorageBuffers", &properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers) &&
- visitor->Visit("maxPerStageDescriptorUpdateAfterBindSampledImages", &properties->maxPerStageDescriptorUpdateAfterBindSampledImages) &&
- visitor->Visit("maxPerStageDescriptorUpdateAfterBindStorageImages", &properties->maxPerStageDescriptorUpdateAfterBindStorageImages) &&
- visitor->Visit("maxPerStageDescriptorUpdateAfterBindInputAttachments", &properties->maxPerStageDescriptorUpdateAfterBindInputAttachments) &&
- visitor->Visit("maxPerStageUpdateAfterBindResources", &properties->maxPerStageUpdateAfterBindResources) &&
- visitor->Visit("maxDescriptorSetUpdateAfterBindSamplers", &properties->maxDescriptorSetUpdateAfterBindSamplers) &&
- visitor->Visit("maxDescriptorSetUpdateAfterBindUniformBuffers", &properties->maxDescriptorSetUpdateAfterBindUniformBuffers) &&
- visitor->Visit("maxDescriptorSetUpdateAfterBindUniformBuffersDynamic", &properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic) &&
- visitor->Visit("maxDescriptorSetUpdateAfterBindStorageBuffers", &properties->maxDescriptorSetUpdateAfterBindStorageBuffers) &&
- visitor->Visit("maxDescriptorSetUpdateAfterBindStorageBuffersDynamic", &properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic) &&
- visitor->Visit("maxDescriptorSetUpdateAfterBindSampledImages", &properties->maxDescriptorSetUpdateAfterBindSampledImages) &&
- visitor->Visit("maxDescriptorSetUpdateAfterBindStorageImages", &properties->maxDescriptorSetUpdateAfterBindStorageImages) &&
- visitor->Visit("maxDescriptorSetUpdateAfterBindInputAttachments", &properties->maxDescriptorSetUpdateAfterBindInputAttachments) &&
- visitor->Visit("supportedDepthResolveModes", &properties->supportedDepthResolveModes) &&
- visitor->Visit("supportedStencilResolveModes", &properties->supportedStencilResolveModes) &&
- visitor->Visit("independentResolveNone", &properties->independentResolveNone) &&
- visitor->Visit("independentResolve", &properties->independentResolve) &&
- visitor->Visit("filterMinmaxSingleComponentFormats", &properties->filterMinmaxSingleComponentFormats) &&
- visitor->Visit("filterMinmaxImageComponentMapping", &properties->filterMinmaxImageComponentMapping) &&
- visitor->Visit("maxTimelineSemaphoreValueDifference", &properties->maxTimelineSemaphoreValueDifference) &&
- visitor->Visit("framebufferIntegerColorSampleCounts", &properties->framebufferIntegerColorSampleCounts);
-}
-
-template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan12Features* features) {
+
+ visitor->Visit("maxPerSetDescriptors",
+ &properties->maxPerSetDescriptors) &&
+ visitor->Visit("maxMemoryAllocationSize",
+ &properties->maxMemoryAllocationSize);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceSparseProperties* properties) {
return
- visitor->Visit("samplerMirrorClampToEdge", &features->samplerMirrorClampToEdge) &&
- visitor->Visit("drawIndirectCount", &features->drawIndirectCount) &&
- visitor->Visit("storageBuffer8BitAccess", &features->storageBuffer8BitAccess) &&
- visitor->Visit("uniformAndStorageBuffer8BitAccess", &features->uniformAndStorageBuffer8BitAccess) &&
- visitor->Visit("storagePushConstant8", &features->storagePushConstant8) &&
- visitor->Visit("shaderBufferInt64Atomics", &features->shaderBufferInt64Atomics) &&
- visitor->Visit("shaderSharedInt64Atomics", &features->shaderSharedInt64Atomics) &&
- visitor->Visit("shaderFloat16", &features->shaderFloat16) &&
- visitor->Visit("shaderInt8", &features->shaderInt8) &&
- visitor->Visit("descriptorIndexing", &features->descriptorIndexing) &&
- visitor->Visit("shaderInputAttachmentArrayDynamicIndexing", &features->shaderInputAttachmentArrayDynamicIndexing) &&
- visitor->Visit("shaderUniformTexelBufferArrayDynamicIndexing", &features->shaderUniformTexelBufferArrayDynamicIndexing) &&
- visitor->Visit("shaderStorageTexelBufferArrayDynamicIndexing", &features->shaderStorageTexelBufferArrayDynamicIndexing) &&
- visitor->Visit("shaderUniformBufferArrayNonUniformIndexing", &features->shaderUniformBufferArrayNonUniformIndexing) &&
- visitor->Visit("shaderSampledImageArrayNonUniformIndexing", &features->shaderSampledImageArrayNonUniformIndexing) &&
- visitor->Visit("shaderStorageBufferArrayNonUniformIndexing", &features->shaderStorageBufferArrayNonUniformIndexing) &&
- visitor->Visit("shaderStorageImageArrayNonUniformIndexing", &features->shaderStorageImageArrayNonUniformIndexing) &&
- visitor->Visit("shaderInputAttachmentArrayNonUniformIndexing", &features->shaderInputAttachmentArrayNonUniformIndexing) &&
- visitor->Visit("shaderUniformTexelBufferArrayNonUniformIndexing", &features->shaderUniformTexelBufferArrayNonUniformIndexing) &&
- visitor->Visit("shaderStorageTexelBufferArrayNonUniformIndexing", &features->shaderStorageTexelBufferArrayNonUniformIndexing) &&
- visitor->Visit("descriptorBindingUniformBufferUpdateAfterBind", &features->descriptorBindingUniformBufferUpdateAfterBind) &&
- visitor->Visit("descriptorBindingSampledImageUpdateAfterBind", &features->descriptorBindingSampledImageUpdateAfterBind) &&
- visitor->Visit("descriptorBindingStorageImageUpdateAfterBind", &features->descriptorBindingStorageImageUpdateAfterBind) &&
- visitor->Visit("descriptorBindingStorageBufferUpdateAfterBind", &features->descriptorBindingStorageBufferUpdateAfterBind) &&
- visitor->Visit("descriptorBindingUniformTexelBufferUpdateAfterBind", &features->descriptorBindingUniformTexelBufferUpdateAfterBind) &&
- visitor->Visit("descriptorBindingStorageTexelBufferUpdateAfterBind", &features->descriptorBindingStorageTexelBufferUpdateAfterBind) &&
- visitor->Visit("descriptorBindingUpdateUnusedWhilePending", &features->descriptorBindingUpdateUnusedWhilePending) &&
- visitor->Visit("descriptorBindingPartiallyBound", &features->descriptorBindingPartiallyBound) &&
- visitor->Visit("descriptorBindingVariableDescriptorCount", &features->descriptorBindingVariableDescriptorCount) &&
- visitor->Visit("runtimeDescriptorArray", &features->runtimeDescriptorArray) &&
- visitor->Visit("samplerFilterMinmax", &features->samplerFilterMinmax) &&
- visitor->Visit("scalarBlockLayout", &features->scalarBlockLayout) &&
- visitor->Visit("imagelessFramebuffer", &features->imagelessFramebuffer) &&
- visitor->Visit("uniformBufferStandardLayout", &features->uniformBufferStandardLayout) &&
- visitor->Visit("shaderSubgroupExtendedTypes", &features->shaderSubgroupExtendedTypes) &&
- visitor->Visit("separateDepthStencilLayouts", &features->separateDepthStencilLayouts) &&
- visitor->Visit("hostQueryReset", &features->hostQueryReset) &&
- visitor->Visit("timelineSemaphore", &features->timelineSemaphore) &&
- visitor->Visit("bufferDeviceAddress", &features->bufferDeviceAddress) &&
- visitor->Visit("bufferDeviceAddressCaptureReplay", &features->bufferDeviceAddressCaptureReplay) &&
- visitor->Visit("bufferDeviceAddressMultiDevice", &features->bufferDeviceAddressMultiDevice) &&
- visitor->Visit("vulkanMemoryModel", &features->vulkanMemoryModel) &&
- visitor->Visit("vulkanMemoryModelDeviceScope", &features->vulkanMemoryModelDeviceScope) &&
- visitor->Visit("vulkanMemoryModelAvailabilityVisibilityChains", &features->vulkanMemoryModelAvailabilityVisibilityChains) &&
- visitor->Visit("shaderOutputViewportIndex", &features->shaderOutputViewportIndex) &&
- visitor->Visit("shaderOutputLayer", &features->shaderOutputLayer) &&
- visitor->Visit("subgroupBroadcastDynamicId", &features->subgroupBroadcastDynamicId);
+
+ visitor->Visit("residencyStandard2DBlockShape",
+ &properties->residencyStandard2DBlockShape) &&
+ visitor->Visit("residencyStandard2DMultisampleBlockShape",
+ &properties->residencyStandard2DMultisampleBlockShape) &&
+ visitor->Visit("residencyStandard3DBlockShape",
+ &properties->residencyStandard3DBlockShape) &&
+ visitor->Visit("residencyAlignedMipSize",
+ &properties->residencyAlignedMipSize) &&
+ visitor->Visit("residencyNonResidentStrict",
+ &properties->residencyNonResidentStrict);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkJsonCore13* core) {
+inline bool Iterate(Visitor* visitor, VkImageFormatProperties* properties) {
return
- visitor->Visit("features", &core->features) &&
- visitor->Visit("properties", &core->properties);
+
+ visitor->Visit("maxExtent", &properties->maxExtent) &&
+ visitor->Visit("maxMipLevels", &properties->maxMipLevels) &&
+ visitor->Visit("maxArrayLayers", &properties->maxArrayLayers) &&
+ visitor->Visit("sampleCounts", &properties->sampleCounts) &&
+ visitor->Visit("maxResourceSize", &properties->maxResourceSize);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan13Properties* properties) {
+inline bool Iterate(Visitor* visitor, VkQueueFamilyProperties* properties) {
return
- visitor->Visit("minSubgroupSize", &properties->minSubgroupSize) &&
- visitor->Visit("maxSubgroupSize", &properties->maxSubgroupSize) &&
- visitor->Visit("maxComputeWorkgroupSubgroups", &properties->maxComputeWorkgroupSubgroups) &&
- visitor->Visit("requiredSubgroupSizeStages", &properties->requiredSubgroupSizeStages) &&
- visitor->Visit("maxInlineUniformBlockSize", &properties->maxInlineUniformBlockSize) &&
- visitor->Visit("maxPerStageDescriptorInlineUniformBlocks", &properties->maxPerStageDescriptorInlineUniformBlocks) &&
- visitor->Visit("maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks", &properties->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks) &&
- visitor->Visit("maxDescriptorSetInlineUniformBlocks", &properties->maxDescriptorSetInlineUniformBlocks) &&
- visitor->Visit("maxDescriptorSetUpdateAfterBindInlineUniformBlocks", &properties->maxDescriptorSetUpdateAfterBindInlineUniformBlocks) &&
- visitor->Visit("maxInlineUniformTotalSize", &properties->maxInlineUniformTotalSize) &&
- visitor->Visit("integerDotProduct8BitUnsignedAccelerated", &properties->integerDotProduct8BitUnsignedAccelerated) &&
- visitor->Visit("integerDotProduct8BitSignedAccelerated", &properties->integerDotProduct8BitSignedAccelerated) &&
- visitor->Visit("integerDotProduct8BitMixedSignednessAccelerated", &properties->integerDotProduct8BitMixedSignednessAccelerated) &&
- visitor->Visit("integerDotProduct4x8BitPackedUnsignedAccelerated", &properties->integerDotProduct4x8BitPackedUnsignedAccelerated) &&
- visitor->Visit("integerDotProduct4x8BitPackedSignedAccelerated", &properties->integerDotProduct4x8BitPackedSignedAccelerated) &&
- visitor->Visit("integerDotProduct4x8BitPackedMixedSignednessAccelerated", &properties->integerDotProduct4x8BitPackedMixedSignednessAccelerated) &&
- visitor->Visit("integerDotProduct16BitUnsignedAccelerated", &properties->integerDotProduct16BitUnsignedAccelerated) &&
- visitor->Visit("integerDotProduct16BitSignedAccelerated", &properties->integerDotProduct16BitSignedAccelerated) &&
- visitor->Visit("integerDotProduct16BitMixedSignednessAccelerated", &properties->integerDotProduct16BitMixedSignednessAccelerated) &&
- visitor->Visit("integerDotProduct32BitUnsignedAccelerated", &properties->integerDotProduct32BitUnsignedAccelerated) &&
- visitor->Visit("integerDotProduct32BitSignedAccelerated", &properties->integerDotProduct32BitSignedAccelerated) &&
- visitor->Visit("integerDotProduct32BitMixedSignednessAccelerated", &properties->integerDotProduct32BitMixedSignednessAccelerated) &&
- visitor->Visit("integerDotProduct64BitUnsignedAccelerated", &properties->integerDotProduct64BitUnsignedAccelerated) &&
- visitor->Visit("integerDotProduct64BitSignedAccelerated", &properties->integerDotProduct64BitSignedAccelerated) &&
- visitor->Visit("integerDotProduct64BitMixedSignednessAccelerated", &properties->integerDotProduct64BitMixedSignednessAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating8BitUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating8BitUnsignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating8BitSignedAccelerated", &properties->integerDotProductAccumulatingSaturating8BitSignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated", &properties->integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating16BitUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating16BitUnsignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating16BitSignedAccelerated", &properties->integerDotProductAccumulatingSaturating16BitSignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating32BitUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating32BitUnsignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating32BitSignedAccelerated", &properties->integerDotProductAccumulatingSaturating32BitSignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating64BitUnsignedAccelerated", &properties->integerDotProductAccumulatingSaturating64BitUnsignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating64BitSignedAccelerated", &properties->integerDotProductAccumulatingSaturating64BitSignedAccelerated) &&
- visitor->Visit("integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated", &properties->integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated) &&
- visitor->Visit("storageTexelBufferOffsetAlignmentBytes", &properties->storageTexelBufferOffsetAlignmentBytes) &&
- visitor->Visit("storageTexelBufferOffsetSingleTexelAlignment", &properties->storageTexelBufferOffsetSingleTexelAlignment) &&
- visitor->Visit("uniformTexelBufferOffsetAlignmentBytes", &properties->uniformTexelBufferOffsetAlignmentBytes) &&
- visitor->Visit("uniformTexelBufferOffsetSingleTexelAlignment", &properties->uniformTexelBufferOffsetSingleTexelAlignment) &&
- visitor->Visit("maxBufferSize", &properties->maxBufferSize);
-}
-
-template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan13Features* features) {
+
+ visitor->Visit("queueFlags", &properties->queueFlags) &&
+ visitor->Visit("queueCount", &properties->queueCount) &&
+ visitor->Visit("timestampValidBits", &properties->timestampValidBits) &&
+ visitor->Visit("minImageTransferGranularity",
+ &properties->minImageTransferGranularity);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkExtensionProperties* properties) {
return
- visitor->Visit("robustImageAccess", &features->robustImageAccess) &&
- visitor->Visit("inlineUniformBlock", &features->inlineUniformBlock) &&
- visitor->Visit("descriptorBindingInlineUniformBlockUpdateAfterBind", &features->descriptorBindingInlineUniformBlockUpdateAfterBind) &&
- visitor->Visit("pipelineCreationCacheControl", &features->pipelineCreationCacheControl) &&
- visitor->Visit("privateData", &features->privateData) &&
- visitor->Visit("shaderDemoteToHelperInvocation", &features->shaderDemoteToHelperInvocation) &&
- visitor->Visit("shaderTerminateInvocation", &features->shaderTerminateInvocation) &&
- visitor->Visit("subgroupSizeControl", &features->subgroupSizeControl) &&
- visitor->Visit("computeFullSubgroups", &features->computeFullSubgroups) &&
- visitor->Visit("synchronization2", &features->synchronization2) &&
- visitor->Visit("textureCompressionASTC_HDR", &features->textureCompressionASTC_HDR) &&
- visitor->Visit("shaderZeroInitializeWorkgroupMemory", &features->shaderZeroInitializeWorkgroupMemory) &&
- visitor->Visit("dynamicRendering", &features->dynamicRendering) &&
- visitor->Visit("shaderIntegerDotProduct", &features->shaderIntegerDotProduct) &&
- visitor->Visit("maintenance4", &features->maintenance4);
+
+ visitor->Visit("extensionName", &properties->extensionName) &&
+ visitor->Visit("specVersion", &properties->specVersion);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkJsonCore14* core) {
+inline bool Iterate(Visitor* visitor, VkLayerProperties* properties) {
return
- visitor->Visit("features", &core->features) &&
- visitor->Visit("properties", &core->properties);
+
+ visitor->Visit("layerName", &properties->layerName) &&
+ visitor->Visit("specVersion", &properties->specVersion) &&
+ visitor->Visit("implementationVersion",
+ &properties->implementationVersion) &&
+ visitor->Visit("description", &properties->description);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan14Properties* properties) {
+inline bool Iterate(Visitor* visitor, VkFormatProperties* properties) {
return
- visitor->Visit("lineSubPixelPrecisionBits", &properties->lineSubPixelPrecisionBits) &&
- visitor->Visit("maxVertexAttribDivisor", &properties->maxVertexAttribDivisor) &&
- visitor->Visit("supportsNonZeroFirstInstance", &properties->supportsNonZeroFirstInstance) &&
- visitor->Visit("maxPushDescriptors", &properties->maxPushDescriptors) &&
- visitor->Visit("dynamicRenderingLocalReadDepthStencilAttachments", &properties->dynamicRenderingLocalReadDepthStencilAttachments) &&
- visitor->Visit("dynamicRenderingLocalReadMultisampledAttachments", &properties->dynamicRenderingLocalReadMultisampledAttachments) &&
- visitor->Visit("earlyFragmentMultisampleCoverageAfterSampleCounting", &properties->earlyFragmentMultisampleCoverageAfterSampleCounting) &&
- visitor->Visit("earlyFragmentSampleMaskTestBeforeSampleCounting", &properties->earlyFragmentSampleMaskTestBeforeSampleCounting) &&
- visitor->Visit("depthStencilSwizzleOneSupport", &properties->depthStencilSwizzleOneSupport) &&
- visitor->Visit("polygonModePointSize", &properties->polygonModePointSize) &&
- visitor->Visit("nonStrictSinglePixelWideLinesUseParallelogram", &properties->nonStrictSinglePixelWideLinesUseParallelogram) &&
- visitor->Visit("nonStrictWideLinesUseParallelogram", &properties->nonStrictWideLinesUseParallelogram) &&
- visitor->Visit("blockTexelViewCompatibleMultipleLayers", &properties->blockTexelViewCompatibleMultipleLayers) &&
- visitor->Visit("maxCombinedImageSamplerDescriptorCount", &properties->maxCombinedImageSamplerDescriptorCount) &&
- visitor->Visit("fragmentShadingRateClampCombinerInputs", &properties->fragmentShadingRateClampCombinerInputs) &&
- visitor->Visit("defaultRobustnessStorageBuffers", &properties->defaultRobustnessStorageBuffers) &&
- visitor->Visit("defaultRobustnessUniformBuffers", &properties->defaultRobustnessUniformBuffers) &&
- visitor->Visit("defaultRobustnessVertexInputs", &properties->defaultRobustnessVertexInputs) &&
- visitor->Visit("defaultRobustnessImages", &properties->defaultRobustnessImages) &&
- visitor->Visit("copySrcLayoutCount", &properties->copySrcLayoutCount) &&
- visitor->VisitArray("pCopySrcLayouts", properties->copySrcLayoutCount, &properties->pCopySrcLayouts) &&
- visitor->Visit("copyDstLayoutCount", &properties->copyDstLayoutCount) &&
- visitor->VisitArray("pCopyDstLayouts", properties->copyDstLayoutCount, &properties->pCopyDstLayouts) &&
- visitor->Visit("optimalTilingLayoutUUID", &properties->optimalTilingLayoutUUID) &&
- visitor->Visit("identicalMemoryTypeRequirements", &properties->identicalMemoryTypeRequirements);
-}
-
-template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkPhysicalDeviceVulkan14Features* features) {
+
+ visitor->Visit("linearTilingFeatures",
+ &properties->linearTilingFeatures) &&
+ visitor->Visit("optimalTilingFeatures",
+ &properties->optimalTilingFeatures) &&
+ visitor->Visit("bufferFeatures", &properties->bufferFeatures);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceVariablePointersFeatures* features) {
return
- visitor->Visit("globalPriorityQuery", &features->globalPriorityQuery) &&
- visitor->Visit("shaderSubgroupRotate", &features->shaderSubgroupRotate) &&
- visitor->Visit("shaderSubgroupRotateClustered", &features->shaderSubgroupRotateClustered) &&
- visitor->Visit("shaderFloatControls2", &features->shaderFloatControls2) &&
- visitor->Visit("shaderExpectAssume", &features->shaderExpectAssume) &&
- visitor->Visit("rectangularLines", &features->rectangularLines) &&
- visitor->Visit("bresenhamLines", &features->bresenhamLines) &&
- visitor->Visit("smoothLines", &features->smoothLines) &&
- visitor->Visit("stippledRectangularLines", &features->stippledRectangularLines) &&
- visitor->Visit("stippledBresenhamLines", &features->stippledBresenhamLines) &&
- visitor->Visit("stippledSmoothLines", &features->stippledSmoothLines) &&
- visitor->Visit("vertexAttributeInstanceRateDivisor", &features->vertexAttributeInstanceRateDivisor) &&
- visitor->Visit("vertexAttributeInstanceRateZeroDivisor", &features->vertexAttributeInstanceRateZeroDivisor) &&
- visitor->Visit("indexTypeUint8", &features->indexTypeUint8) &&
- visitor->Visit("dynamicRenderingLocalRead", &features->dynamicRenderingLocalRead) &&
- visitor->Visit("maintenance5", &features->maintenance5) &&
- visitor->Visit("maintenance6", &features->maintenance6) &&
- visitor->Visit("pipelineProtectedAccess", &features->pipelineProtectedAccess) &&
- visitor->Visit("pipelineRobustness", &features->pipelineRobustness) &&
- visitor->Visit("hostImageCopy", &features->hostImageCopy);
-}
-// clang-format on
+
+ visitor->Visit("variablePointersStorageBuffer",
+ &features->variablePointersStorageBuffer) &&
+ visitor->Visit("variablePointers", &features->variablePointers);
+}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkJsonExtDriverProperties* properties) {
- return visitor->Visit("driverPropertiesKHR",
- &properties->driver_properties_khr);
+ VkPhysicalDeviceShaderFloat16Int8Features* features) {
+ return
+
+ visitor->Visit("shaderFloat16", &features->shaderFloat16) &&
+ visitor->Visit("shaderInt8", &features->shaderInt8);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceDriverPropertiesKHR* properties) {
- return visitor->Visit("driverID", &properties->driverID) &&
- visitor->Visit("driverName", &properties->driverName) &&
- visitor->Visit("driverInfo", &properties->driverInfo) &&
- visitor->Visit("conformanceVersion", &properties->conformanceVersion);
+ VkPhysicalDeviceImage2DViewOf3DFeaturesEXT* features) {
+ return
+
+ visitor->Visit("image2DViewOf3D", &features->image2DViewOf3D) &&
+ visitor->Visit("sampler2DViewOf3D", &features->sampler2DViewOf3D);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkConformanceVersionKHR* version) {
- return visitor->Visit("major", &version->major) &&
- visitor->Visit("minor", &version->minor) &&
- visitor->Visit("subminor", &version->subminor) &&
- visitor->Visit("patch", &version->patch);
+ VkPhysicalDeviceCustomBorderColorFeaturesEXT* features) {
+ return
+
+ visitor->Visit("customBorderColors", &features->customBorderColors) &&
+ visitor->Visit("customBorderColorWithoutFormat",
+ &features->customBorderColorWithoutFormat);
+}
+
+template <typename Visitor>
+inline bool Iterate(
+ Visitor* visitor,
+ VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT* features) {
+ return
+
+ visitor->Visit("primitiveTopologyListRestart",
+ &features->primitiveTopologyListRestart) &&
+ visitor->Visit("primitiveTopologyPatchListRestart",
+ &features->primitiveTopologyPatchListRestart);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkJsonExtVariablePointerFeatures* features) {
- return visitor->Visit("variablePointerFeaturesKHR",
- &features->variable_pointer_features_khr);
+ VkPhysicalDeviceProvokingVertexFeaturesEXT* features) {
+ return
+
+ visitor->Visit("provokingVertexLast", &features->provokingVertexLast) &&
+ visitor->Visit("transformFeedbackPreservesProvokingVertex",
+ &features->transformFeedbackPreservesProvokingVertex);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkJsonExtImage2DViewOf3DFeatures* features) {
- return visitor->Visit("image2DViewOf3DFeaturesEXT",
- &features->image_2D_view_of_3D_features_EXT);
+ VkPhysicalDeviceIndexTypeUint8Features* features) {
+ return
+
+ visitor->Visit("indexTypeUint8", &features->indexTypeUint8);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkJsonExtShaderFloat16Int8Features* features) {
- return visitor->Visit("shaderFloat16Int8FeaturesKHR",
- &features->shader_float16_int8_features_khr);
+ VkPhysicalDeviceVertexAttributeDivisorFeatures* features) {
+ return
+
+ visitor->Visit("vertexAttributeInstanceRateDivisor",
+ &features->vertexAttributeInstanceRateDivisor) &&
+ visitor->Visit("vertexAttributeInstanceRateZeroDivisor",
+ &features->vertexAttributeInstanceRateZeroDivisor);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkMemoryType* type) {
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceTransformFeedbackFeaturesEXT* features) {
return
- visitor->Visit("propertyFlags", &type->propertyFlags) &&
- visitor->Visit("heapIndex", &type->heapIndex);
+
+ visitor->Visit("transformFeedback", &features->transformFeedback) &&
+ visitor->Visit("geometryStreams", &features->geometryStreams);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkMemoryHeap* heap) {
+inline bool Iterate(
+ Visitor* visitor,
+ VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR* features) {
return
- visitor->Visit("size", &heap->size) &&
- visitor->Visit("flags", &heap->flags);
+
+ visitor->Visit("shaderSubgroupUniformControlFlow",
+ &features->shaderSubgroupUniformControlFlow);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkPhysicalDeviceMemoryProperties* properties) {
+inline bool Iterate(
+ Visitor* visitor,
+ VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures* features) {
return
- visitor->Visit("memoryTypeCount", &properties->memoryTypeCount) &&
- visitor->VisitArray("memoryTypes", properties->memoryTypeCount, &properties->memoryTypes) &&
- visitor->Visit("memoryHeapCount", &properties->memoryHeapCount) &&
- visitor->VisitArray("memoryHeaps", properties->memoryHeapCount, &properties->memoryHeaps);
+
+ visitor->Visit("shaderSubgroupExtendedTypes",
+ &features->shaderSubgroupExtendedTypes);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceSubgroupProperties* properties) {
- return visitor->Visit("subgroupSize", &properties->subgroupSize) &&
- visitor->Visit("supportedStages", &properties->supportedStages) &&
- visitor->Visit("supportedOperations",
- &properties->supportedOperations) &&
- visitor->Visit("quadOperationsInAllStages",
- &properties->quadOperationsInAllStages);
+ VkPhysicalDevice8BitStorageFeatures* features) {
+ return
+
+ visitor->Visit("storageBuffer8BitAccess",
+ &features->storageBuffer8BitAccess) &&
+ visitor->Visit("uniformAndStorageBuffer8BitAccess",
+ &features->uniformAndStorageBuffer8BitAccess) &&
+ visitor->Visit("storagePushConstant8", &features->storagePushConstant8);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDevicePointClippingProperties* properties) {
- return visitor->Visit("pointClippingBehavior",
- &properties->pointClippingBehavior);
+ VkPhysicalDeviceShaderIntegerDotProductFeatures* features) {
+ return
+
+ visitor->Visit("shaderIntegerDotProduct",
+ &features->shaderIntegerDotProduct);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceMultiviewProperties* properties) {
- return visitor->Visit("maxMultiviewViewCount",
- &properties->maxMultiviewViewCount) &&
- visitor->Visit("maxMultiviewInstanceIndex",
- &properties->maxMultiviewInstanceIndex);
+inline bool Iterate(
+ Visitor* visitor,
+ VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG* features) {
+ return
+
+ visitor->Visit("relaxedLineRasterization",
+ &features->relaxedLineRasterization);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceIDProperties* properties) {
- return visitor->Visit("deviceUUID", &properties->deviceUUID) &&
- visitor->Visit("driverUUID", &properties->driverUUID) &&
- visitor->Visit("deviceLUID", &properties->deviceLUID) &&
- visitor->Visit("deviceNodeMask", &properties->deviceNodeMask) &&
- visitor->Visit("deviceLUIDValid", &properties->deviceLUIDValid);
+ VkPhysicalDeviceLineRasterizationFeatures* features) {
+ return
+
+ visitor->Visit("rectangularLines", &features->rectangularLines) &&
+ visitor->Visit("bresenhamLines", &features->bresenhamLines) &&
+ visitor->Visit("smoothLines", &features->smoothLines) &&
+ visitor->Visit("stippledRectangularLines",
+ &features->stippledRectangularLines) &&
+ visitor->Visit("stippledBresenhamLines",
+ &features->stippledBresenhamLines) &&
+ visitor->Visit("stippledSmoothLines", &features->stippledSmoothLines);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceMaintenance3Properties* properties) {
- return visitor->Visit("maxPerSetDescriptors",
- &properties->maxPerSetDescriptors) &&
- visitor->Visit("maxMemoryAllocationSize",
- &properties->maxMemoryAllocationSize);
+inline bool Iterate(
+ Visitor* visitor,
+ VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT* features) {
+ return
+
+ visitor->Visit("primitivesGeneratedQuery",
+ &features->primitivesGeneratedQuery) &&
+ visitor->Visit(
+ "primitivesGeneratedQueryWithRasterizerDiscard",
+ &features->primitivesGeneratedQueryWithRasterizerDiscard) &&
+ visitor->Visit("primitivesGeneratedQueryWithNonZeroStreams",
+ &features->primitivesGeneratedQueryWithNonZeroStreams);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
VkPhysicalDevice16BitStorageFeatures* features) {
- return visitor->Visit("storageBuffer16BitAccess",
- &features->storageBuffer16BitAccess) &&
- visitor->Visit("uniformAndStorageBuffer16BitAccess",
- &features->uniformAndStorageBuffer16BitAccess) &&
- visitor->Visit("storagePushConstant16",
- &features->storagePushConstant16) &&
- visitor->Visit("storageInputOutput16",
- &features->storageInputOutput16);
+ return
+
+ visitor->Visit("storageBuffer16BitAccess",
+ &features->storageBuffer16BitAccess) &&
+ visitor->Visit("uniformAndStorageBuffer16BitAccess",
+ &features->uniformAndStorageBuffer16BitAccess) &&
+ visitor->Visit("storagePushConstant16",
+ &features->storagePushConstant16) &&
+ visitor->Visit("storageInputOutput16", &features->storageInputOutput16);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
VkPhysicalDeviceMultiviewFeatures* features) {
- return visitor->Visit("multiview", &features->multiview) &&
- visitor->Visit("multiviewGeometryShader",
- &features->multiviewGeometryShader) &&
- visitor->Visit("multiviewTessellationShader",
- &features->multiviewTessellationShader);
+ return
+
+ visitor->Visit("multiview", &features->multiview) &&
+ visitor->Visit("multiviewGeometryShader",
+ &features->multiviewGeometryShader) &&
+ visitor->Visit("multiviewTessellationShader",
+ &features->multiviewTessellationShader);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceVariablePointerFeatures* features) {
- return visitor->Visit("variablePointersStorageBuffer",
- &features->variablePointersStorageBuffer) &&
- visitor->Visit("variablePointers", &features->variablePointers);
+ VkPhysicalDeviceProtectedMemoryFeatures* features) {
+ return
+
+ visitor->Visit("protectedMemory", &features->protectedMemory);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceImage2DViewOf3DFeaturesEXT* features) {
- return visitor->Visit("image2DViewOf3D", &features->image2DViewOf3D) &&
- visitor->Visit("sampler2DViewOf3D", &features->sampler2DViewOf3D);
+ VkPhysicalDeviceSamplerYcbcrConversionFeatures* features) {
+ return
+
+ visitor->Visit("samplerYcbcrConversion",
+ &features->samplerYcbcrConversion);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceShaderFloat16Int8FeaturesKHR* features) {
- return visitor->Visit("shaderFloat16", &features->shaderFloat16) &&
- visitor->Visit("shaderInt8", &features->shaderInt8);
+ VkPhysicalDeviceShaderDrawParameterFeatures* features) {
+ return
+
+ visitor->Visit("shaderDrawParameters", &features->shaderDrawParameters);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkPhysicalDeviceLimits* limits) {
+ return
+
+ visitor->Visit("maxImageDimension1D", &limits->maxImageDimension1D) &&
+ visitor->Visit("maxImageDimension2D", &limits->maxImageDimension2D) &&
+ visitor->Visit("maxImageDimension3D", &limits->maxImageDimension3D) &&
+ visitor->Visit("maxImageDimensionCube", &limits->maxImageDimensionCube) &&
+ visitor->Visit("maxImageArrayLayers", &limits->maxImageArrayLayers) &&
+ visitor->Visit("maxTexelBufferElements",
+ &limits->maxTexelBufferElements) &&
+ visitor->Visit("maxUniformBufferRange", &limits->maxUniformBufferRange) &&
+ visitor->Visit("maxStorageBufferRange", &limits->maxStorageBufferRange) &&
+ visitor->Visit("maxPushConstantsSize", &limits->maxPushConstantsSize) &&
+ visitor->Visit("maxMemoryAllocationCount",
+ &limits->maxMemoryAllocationCount) &&
+ visitor->Visit("maxSamplerAllocationCount",
+ &limits->maxSamplerAllocationCount) &&
+ visitor->Visit("bufferImageGranularity",
+ &limits->bufferImageGranularity) &&
+ visitor->Visit("sparseAddressSpaceSize",
+ &limits->sparseAddressSpaceSize) &&
+ visitor->Visit("maxBoundDescriptorSets",
+ &limits->maxBoundDescriptorSets) &&
+ visitor->Visit("maxPerStageDescriptorSamplers",
+ &limits->maxPerStageDescriptorSamplers) &&
+ visitor->Visit("maxPerStageDescriptorUniformBuffers",
+ &limits->maxPerStageDescriptorUniformBuffers) &&
+ visitor->Visit("maxPerStageDescriptorStorageBuffers",
+ &limits->maxPerStageDescriptorStorageBuffers) &&
+ visitor->Visit("maxPerStageDescriptorSampledImages",
+ &limits->maxPerStageDescriptorSampledImages) &&
+ visitor->Visit("maxPerStageDescriptorStorageImages",
+ &limits->maxPerStageDescriptorStorageImages) &&
+ visitor->Visit("maxPerStageDescriptorInputAttachments",
+ &limits->maxPerStageDescriptorInputAttachments) &&
+ visitor->Visit("maxPerStageResources", &limits->maxPerStageResources) &&
+ visitor->Visit("maxDescriptorSetSamplers",
+ &limits->maxDescriptorSetSamplers) &&
+ visitor->Visit("maxDescriptorSetUniformBuffers",
+ &limits->maxDescriptorSetUniformBuffers) &&
+ visitor->Visit("maxDescriptorSetUniformBuffersDynamic",
+ &limits->maxDescriptorSetUniformBuffersDynamic) &&
+ visitor->Visit("maxDescriptorSetStorageBuffers",
+ &limits->maxDescriptorSetStorageBuffers) &&
+ visitor->Visit("maxDescriptorSetStorageBuffersDynamic",
+ &limits->maxDescriptorSetStorageBuffersDynamic) &&
+ visitor->Visit("maxDescriptorSetSampledImages",
+ &limits->maxDescriptorSetSampledImages) &&
+ visitor->Visit("maxDescriptorSetStorageImages",
+ &limits->maxDescriptorSetStorageImages) &&
+ visitor->Visit("maxDescriptorSetInputAttachments",
+ &limits->maxDescriptorSetInputAttachments) &&
+ visitor->Visit("maxVertexInputAttributes",
+ &limits->maxVertexInputAttributes) &&
+ visitor->Visit("maxVertexInputBindings",
+ &limits->maxVertexInputBindings) &&
+ visitor->Visit("maxVertexInputAttributeOffset",
+ &limits->maxVertexInputAttributeOffset) &&
+ visitor->Visit("maxVertexInputBindingStride",
+ &limits->maxVertexInputBindingStride) &&
+ visitor->Visit("maxVertexOutputComponents",
+ &limits->maxVertexOutputComponents) &&
+ visitor->Visit("maxTessellationGenerationLevel",
+ &limits->maxTessellationGenerationLevel) &&
+ visitor->Visit("maxTessellationPatchSize",
+ &limits->maxTessellationPatchSize) &&
+ visitor->Visit("maxTessellationControlPerVertexInputComponents",
+ &limits->maxTessellationControlPerVertexInputComponents) &&
+ visitor->Visit(
+ "maxTessellationControlPerVertexOutputComponents",
+ &limits->maxTessellationControlPerVertexOutputComponents) &&
+ visitor->Visit("maxTessellationControlPerPatchOutputComponents",
+ &limits->maxTessellationControlPerPatchOutputComponents) &&
+ visitor->Visit("maxTessellationControlTotalOutputComponents",
+ &limits->maxTessellationControlTotalOutputComponents) &&
+ visitor->Visit("maxTessellationEvaluationInputComponents",
+ &limits->maxTessellationEvaluationInputComponents) &&
+ visitor->Visit("maxTessellationEvaluationOutputComponents",
+ &limits->maxTessellationEvaluationOutputComponents) &&
+ visitor->Visit("maxGeometryShaderInvocations",
+ &limits->maxGeometryShaderInvocations) &&
+ visitor->Visit("maxGeometryInputComponents",
+ &limits->maxGeometryInputComponents) &&
+ visitor->Visit("maxGeometryOutputComponents",
+ &limits->maxGeometryOutputComponents) &&
+ visitor->Visit("maxGeometryOutputVertices",
+ &limits->maxGeometryOutputVertices) &&
+ visitor->Visit("maxGeometryTotalOutputComponents",
+ &limits->maxGeometryTotalOutputComponents) &&
+ visitor->Visit("maxFragmentInputComponents",
+ &limits->maxFragmentInputComponents) &&
+ visitor->Visit("maxFragmentOutputAttachments",
+ &limits->maxFragmentOutputAttachments) &&
+ visitor->Visit("maxFragmentDualSrcAttachments",
+ &limits->maxFragmentDualSrcAttachments) &&
+ visitor->Visit("maxFragmentCombinedOutputResources",
+ &limits->maxFragmentCombinedOutputResources) &&
+ visitor->Visit("maxComputeSharedMemorySize",
+ &limits->maxComputeSharedMemorySize) &&
+ visitor->Visit("maxComputeWorkGroupCount",
+ &limits->maxComputeWorkGroupCount) &&
+ visitor->Visit("maxComputeWorkGroupInvocations",
+ &limits->maxComputeWorkGroupInvocations) &&
+ visitor->Visit("maxComputeWorkGroupSize",
+ &limits->maxComputeWorkGroupSize) &&
+ visitor->Visit("subPixelPrecisionBits", &limits->subPixelPrecisionBits) &&
+ visitor->Visit("subTexelPrecisionBits", &limits->subTexelPrecisionBits) &&
+ visitor->Visit("mipmapPrecisionBits", &limits->mipmapPrecisionBits) &&
+ visitor->Visit("maxDrawIndexedIndexValue",
+ &limits->maxDrawIndexedIndexValue) &&
+ visitor->Visit("maxDrawIndirectCount", &limits->maxDrawIndirectCount) &&
+ visitor->Visit("maxSamplerLodBias", &limits->maxSamplerLodBias) &&
+ visitor->Visit("maxSamplerAnisotropy", &limits->maxSamplerAnisotropy) &&
+ visitor->Visit("maxViewports", &limits->maxViewports) &&
+ visitor->Visit("maxViewportDimensions", &limits->maxViewportDimensions) &&
+ visitor->Visit("viewportBoundsRange", &limits->viewportBoundsRange) &&
+ visitor->Visit("viewportSubPixelBits", &limits->viewportSubPixelBits) &&
+ visitor->Visit("minMemoryMapAlignment", &limits->minMemoryMapAlignment) &&
+ visitor->Visit("minTexelBufferOffsetAlignment",
+ &limits->minTexelBufferOffsetAlignment) &&
+ visitor->Visit("minUniformBufferOffsetAlignment",
+ &limits->minUniformBufferOffsetAlignment) &&
+ visitor->Visit("minStorageBufferOffsetAlignment",
+ &limits->minStorageBufferOffsetAlignment) &&
+ visitor->Visit("minTexelOffset", &limits->minTexelOffset) &&
+ visitor->Visit("maxTexelOffset", &limits->maxTexelOffset) &&
+ visitor->Visit("minTexelGatherOffset", &limits->minTexelGatherOffset) &&
+ visitor->Visit("maxTexelGatherOffset", &limits->maxTexelGatherOffset) &&
+ visitor->Visit("minInterpolationOffset",
+ &limits->minInterpolationOffset) &&
+ visitor->Visit("maxInterpolationOffset",
+ &limits->maxInterpolationOffset) &&
+ visitor->Visit("subPixelInterpolationOffsetBits",
+ &limits->subPixelInterpolationOffsetBits) &&
+ visitor->Visit("maxFramebufferWidth", &limits->maxFramebufferWidth) &&
+ visitor->Visit("maxFramebufferHeight", &limits->maxFramebufferHeight) &&
+ visitor->Visit("maxFramebufferLayers", &limits->maxFramebufferLayers) &&
+ visitor->Visit("framebufferColorSampleCounts",
+ &limits->framebufferColorSampleCounts) &&
+ visitor->Visit("framebufferDepthSampleCounts",
+ &limits->framebufferDepthSampleCounts) &&
+ visitor->Visit("framebufferStencilSampleCounts",
+ &limits->framebufferStencilSampleCounts) &&
+ visitor->Visit("framebufferNoAttachmentsSampleCounts",
+ &limits->framebufferNoAttachmentsSampleCounts) &&
+ visitor->Visit("maxColorAttachments", &limits->maxColorAttachments) &&
+ visitor->Visit("sampledImageColorSampleCounts",
+ &limits->sampledImageColorSampleCounts) &&
+ visitor->Visit("sampledImageIntegerSampleCounts",
+ &limits->sampledImageIntegerSampleCounts) &&
+ visitor->Visit("sampledImageDepthSampleCounts",
+ &limits->sampledImageDepthSampleCounts) &&
+ visitor->Visit("sampledImageStencilSampleCounts",
+ &limits->sampledImageStencilSampleCounts) &&
+ visitor->Visit("storageImageSampleCounts",
+ &limits->storageImageSampleCounts) &&
+ visitor->Visit("maxSampleMaskWords", &limits->maxSampleMaskWords) &&
+ visitor->Visit("timestampComputeAndGraphics",
+ &limits->timestampComputeAndGraphics) &&
+ visitor->Visit("timestampPeriod", &limits->timestampPeriod) &&
+ visitor->Visit("maxClipDistances", &limits->maxClipDistances) &&
+ visitor->Visit("maxCullDistances", &limits->maxCullDistances) &&
+ visitor->Visit("maxCombinedClipAndCullDistances",
+ &limits->maxCombinedClipAndCullDistances) &&
+ visitor->Visit("discreteQueuePriorities",
+ &limits->discreteQueuePriorities) &&
+ visitor->Visit("pointSizeRange", &limits->pointSizeRange) &&
+ visitor->Visit("lineWidthRange", &limits->lineWidthRange) &&
+ visitor->Visit("pointSizeGranularity", &limits->pointSizeGranularity) &&
+ visitor->Visit("lineWidthGranularity", &limits->lineWidthGranularity) &&
+ visitor->Visit("strictLines", &limits->strictLines) &&
+ visitor->Visit("standardSampleLocations",
+ &limits->standardSampleLocations) &&
+ visitor->Visit("optimalBufferCopyOffsetAlignment",
+ &limits->optimalBufferCopyOffsetAlignment) &&
+ visitor->Visit("optimalBufferCopyRowPitchAlignment",
+ &limits->optimalBufferCopyRowPitchAlignment) &&
+ visitor->Visit("nonCoherentAtomSize", &limits->nonCoherentAtomSize);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkPhysicalDeviceFeatures* features) {
+ return
+
+ visitor->Visit("robustBufferAccess", &features->robustBufferAccess) &&
+ visitor->Visit("fullDrawIndexUint32", &features->fullDrawIndexUint32) &&
+ visitor->Visit("imageCubeArray", &features->imageCubeArray) &&
+ visitor->Visit("independentBlend", &features->independentBlend) &&
+ visitor->Visit("geometryShader", &features->geometryShader) &&
+ visitor->Visit("tessellationShader", &features->tessellationShader) &&
+ visitor->Visit("sampleRateShading", &features->sampleRateShading) &&
+ visitor->Visit("dualSrcBlend", &features->dualSrcBlend) &&
+ visitor->Visit("logicOp", &features->logicOp) &&
+ visitor->Visit("multiDrawIndirect", &features->multiDrawIndirect) &&
+ visitor->Visit("drawIndirectFirstInstance",
+ &features->drawIndirectFirstInstance) &&
+ visitor->Visit("depthClamp", &features->depthClamp) &&
+ visitor->Visit("depthBiasClamp", &features->depthBiasClamp) &&
+ visitor->Visit("fillModeNonSolid", &features->fillModeNonSolid) &&
+ visitor->Visit("depthBounds", &features->depthBounds) &&
+ visitor->Visit("wideLines", &features->wideLines) &&
+ visitor->Visit("largePoints", &features->largePoints) &&
+ visitor->Visit("alphaToOne", &features->alphaToOne) &&
+ visitor->Visit("multiViewport", &features->multiViewport) &&
+ visitor->Visit("samplerAnisotropy", &features->samplerAnisotropy) &&
+ visitor->Visit("textureCompressionETC2",
+ &features->textureCompressionETC2) &&
+ visitor->Visit("textureCompressionASTC_LDR",
+ &features->textureCompressionASTC_LDR) &&
+ visitor->Visit("textureCompressionBC", &features->textureCompressionBC) &&
+ visitor->Visit("occlusionQueryPrecise",
+ &features->occlusionQueryPrecise) &&
+ visitor->Visit("pipelineStatisticsQuery",
+ &features->pipelineStatisticsQuery) &&
+ visitor->Visit("vertexPipelineStoresAndAtomics",
+ &features->vertexPipelineStoresAndAtomics) &&
+ visitor->Visit("fragmentStoresAndAtomics",
+ &features->fragmentStoresAndAtomics) &&
+ visitor->Visit("shaderTessellationAndGeometryPointSize",
+ &features->shaderTessellationAndGeometryPointSize) &&
+ visitor->Visit("shaderImageGatherExtended",
+ &features->shaderImageGatherExtended) &&
+ visitor->Visit("shaderStorageImageExtendedFormats",
+ &features->shaderStorageImageExtendedFormats) &&
+ visitor->Visit("shaderStorageImageMultisample",
+ &features->shaderStorageImageMultisample) &&
+ visitor->Visit("shaderStorageImageReadWithoutFormat",
+ &features->shaderStorageImageReadWithoutFormat) &&
+ visitor->Visit("shaderStorageImageWriteWithoutFormat",
+ &features->shaderStorageImageWriteWithoutFormat) &&
+ visitor->Visit("shaderUniformBufferArrayDynamicIndexing",
+ &features->shaderUniformBufferArrayDynamicIndexing) &&
+ visitor->Visit("shaderSampledImageArrayDynamicIndexing",
+ &features->shaderSampledImageArrayDynamicIndexing) &&
+ visitor->Visit("shaderStorageBufferArrayDynamicIndexing",
+ &features->shaderStorageBufferArrayDynamicIndexing) &&
+ visitor->Visit("shaderStorageImageArrayDynamicIndexing",
+ &features->shaderStorageImageArrayDynamicIndexing) &&
+ visitor->Visit("shaderClipDistance", &features->shaderClipDistance) &&
+ visitor->Visit("shaderCullDistance", &features->shaderCullDistance) &&
+ visitor->Visit("shaderFloat64", &features->shaderFloat64) &&
+ visitor->Visit("shaderInt64", &features->shaderInt64) &&
+ visitor->Visit("shaderInt16", &features->shaderInt16) &&
+ visitor->Visit("shaderResourceResidency",
+ &features->shaderResourceResidency) &&
+ visitor->Visit("shaderResourceMinLod", &features->shaderResourceMinLod) &&
+ visitor->Visit("sparseBinding", &features->sparseBinding) &&
+ visitor->Visit("sparseResidencyBuffer",
+ &features->sparseResidencyBuffer) &&
+ visitor->Visit("sparseResidencyImage2D",
+ &features->sparseResidencyImage2D) &&
+ visitor->Visit("sparseResidencyImage3D",
+ &features->sparseResidencyImage3D) &&
+ visitor->Visit("sparseResidency2Samples",
+ &features->sparseResidency2Samples) &&
+ visitor->Visit("sparseResidency4Samples",
+ &features->sparseResidency4Samples) &&
+ visitor->Visit("sparseResidency8Samples",
+ &features->sparseResidency8Samples) &&
+ visitor->Visit("sparseResidency16Samples",
+ &features->sparseResidency16Samples) &&
+ visitor->Visit("sparseResidencyAliased",
+ &features->sparseResidencyAliased) &&
+ visitor->Visit("variableMultisampleRate",
+ &features->variableMultisampleRate) &&
+ visitor->Visit("inheritedQueries", &features->inheritedQueries);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceProtectedMemoryFeatures* features) {
- return visitor->Visit("protectedMemory", &features->protectedMemory);
+ VkPhysicalDeviceVulkan11Properties* properties) {
+ return
+
+ visitor->Visit("deviceUUID", &properties->deviceUUID) &&
+ visitor->Visit("driverUUID", &properties->driverUUID) &&
+ visitor->Visit("deviceLUID", &properties->deviceLUID) &&
+ visitor->Visit("deviceNodeMask", &properties->deviceNodeMask) &&
+ visitor->Visit("deviceLUIDValid", &properties->deviceLUIDValid) &&
+ visitor->Visit("subgroupSize", &properties->subgroupSize) &&
+ visitor->Visit("subgroupSupportedStages",
+ &properties->subgroupSupportedStages) &&
+ visitor->Visit("subgroupSupportedOperations",
+ &properties->subgroupSupportedOperations) &&
+ visitor->Visit("subgroupQuadOperationsInAllStages",
+ &properties->subgroupQuadOperationsInAllStages) &&
+ visitor->Visit("pointClippingBehavior",
+ &properties->pointClippingBehavior) &&
+ visitor->Visit("maxMultiviewViewCount",
+ &properties->maxMultiviewViewCount) &&
+ visitor->Visit("maxMultiviewInstanceIndex",
+ &properties->maxMultiviewInstanceIndex) &&
+ visitor->Visit("protectedNoFault", &properties->protectedNoFault) &&
+ visitor->Visit("maxPerSetDescriptors",
+ &properties->maxPerSetDescriptors) &&
+ visitor->Visit("maxMemoryAllocationSize",
+ &properties->maxMemoryAllocationSize);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceSamplerYcbcrConversionFeatures* features) {
- return visitor->Visit("samplerYcbcrConversion",
- &features->samplerYcbcrConversion);
+ VkPhysicalDeviceVulkan11Features* features) {
+ return
+
+ visitor->Visit("storageBuffer16BitAccess",
+ &features->storageBuffer16BitAccess) &&
+ visitor->Visit("uniformAndStorageBuffer16BitAccess",
+ &features->uniformAndStorageBuffer16BitAccess) &&
+ visitor->Visit("storagePushConstant16",
+ &features->storagePushConstant16) &&
+ visitor->Visit("storageInputOutput16", &features->storageInputOutput16) &&
+ visitor->Visit("multiview", &features->multiview) &&
+ visitor->Visit("multiviewGeometryShader",
+ &features->multiviewGeometryShader) &&
+ visitor->Visit("multiviewTessellationShader",
+ &features->multiviewTessellationShader) &&
+ visitor->Visit("variablePointersStorageBuffer",
+ &features->variablePointersStorageBuffer) &&
+ visitor->Visit("variablePointers", &features->variablePointers) &&
+ visitor->Visit("protectedMemory", &features->protectedMemory) &&
+ visitor->Visit("samplerYcbcrConversion",
+ &features->samplerYcbcrConversion) &&
+ visitor->Visit("shaderDrawParameters", &features->shaderDrawParameters);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkPhysicalDeviceShaderDrawParameterFeatures* features) {
- return visitor->Visit("shaderDrawParameters",
- &features->shaderDrawParameters);
+ VkPhysicalDeviceVulkan12Properties* properties) {
+ return
+
+ visitor->Visit("driverID", &properties->driverID) &&
+ visitor->Visit("driverName", &properties->driverName) &&
+ visitor->Visit("driverInfo", &properties->driverInfo) &&
+ visitor->Visit("conformanceVersion", &properties->conformanceVersion) &&
+ visitor->Visit("denormBehaviorIndependence",
+ &properties->denormBehaviorIndependence) &&
+ visitor->Visit("roundingModeIndependence",
+ &properties->roundingModeIndependence) &&
+ visitor->Visit("shaderSignedZeroInfNanPreserveFloat16",
+ &properties->shaderSignedZeroInfNanPreserveFloat16) &&
+ visitor->Visit("shaderSignedZeroInfNanPreserveFloat32",
+ &properties->shaderSignedZeroInfNanPreserveFloat32) &&
+ visitor->Visit("shaderSignedZeroInfNanPreserveFloat64",
+ &properties->shaderSignedZeroInfNanPreserveFloat64) &&
+ visitor->Visit("shaderDenormPreserveFloat16",
+ &properties->shaderDenormPreserveFloat16) &&
+ visitor->Visit("shaderDenormPreserveFloat32",
+ &properties->shaderDenormPreserveFloat32) &&
+ visitor->Visit("shaderDenormPreserveFloat64",
+ &properties->shaderDenormPreserveFloat64) &&
+ visitor->Visit("shaderDenormFlushToZeroFloat16",
+ &properties->shaderDenormFlushToZeroFloat16) &&
+ visitor->Visit("shaderDenormFlushToZeroFloat32",
+ &properties->shaderDenormFlushToZeroFloat32) &&
+ visitor->Visit("shaderDenormFlushToZeroFloat64",
+ &properties->shaderDenormFlushToZeroFloat64) &&
+ visitor->Visit("shaderRoundingModeRTEFloat16",
+ &properties->shaderRoundingModeRTEFloat16) &&
+ visitor->Visit("shaderRoundingModeRTEFloat32",
+ &properties->shaderRoundingModeRTEFloat32) &&
+ visitor->Visit("shaderRoundingModeRTEFloat64",
+ &properties->shaderRoundingModeRTEFloat64) &&
+ visitor->Visit("shaderRoundingModeRTZFloat16",
+ &properties->shaderRoundingModeRTZFloat16) &&
+ visitor->Visit("shaderRoundingModeRTZFloat32",
+ &properties->shaderRoundingModeRTZFloat32) &&
+ visitor->Visit("shaderRoundingModeRTZFloat64",
+ &properties->shaderRoundingModeRTZFloat64) &&
+ visitor->Visit("maxUpdateAfterBindDescriptorsInAllPools",
+ &properties->maxUpdateAfterBindDescriptorsInAllPools) &&
+ visitor->Visit(
+ "shaderUniformBufferArrayNonUniformIndexingNative",
+ &properties->shaderUniformBufferArrayNonUniformIndexingNative) &&
+ visitor->Visit(
+ "shaderSampledImageArrayNonUniformIndexingNative",
+ &properties->shaderSampledImageArrayNonUniformIndexingNative) &&
+ visitor->Visit(
+ "shaderStorageBufferArrayNonUniformIndexingNative",
+ &properties->shaderStorageBufferArrayNonUniformIndexingNative) &&
+ visitor->Visit(
+ "shaderStorageImageArrayNonUniformIndexingNative",
+ &properties->shaderStorageImageArrayNonUniformIndexingNative) &&
+ visitor->Visit(
+ "shaderInputAttachmentArrayNonUniformIndexingNative",
+ &properties->shaderInputAttachmentArrayNonUniformIndexingNative) &&
+ visitor->Visit("robustBufferAccessUpdateAfterBind",
+ &properties->robustBufferAccessUpdateAfterBind) &&
+ visitor->Visit("quadDivergentImplicitLod",
+ &properties->quadDivergentImplicitLod) &&
+ visitor->Visit(
+ "maxPerStageDescriptorUpdateAfterBindSamplers",
+ &properties->maxPerStageDescriptorUpdateAfterBindSamplers) &&
+ visitor->Visit(
+ "maxPerStageDescriptorUpdateAfterBindUniformBuffers",
+ &properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers) &&
+ visitor->Visit(
+ "maxPerStageDescriptorUpdateAfterBindStorageBuffers",
+ &properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers) &&
+ visitor->Visit(
+ "maxPerStageDescriptorUpdateAfterBindSampledImages",
+ &properties->maxPerStageDescriptorUpdateAfterBindSampledImages) &&
+ visitor->Visit(
+ "maxPerStageDescriptorUpdateAfterBindStorageImages",
+ &properties->maxPerStageDescriptorUpdateAfterBindStorageImages) &&
+ visitor->Visit(
+ "maxPerStageDescriptorUpdateAfterBindInputAttachments",
+ &properties->maxPerStageDescriptorUpdateAfterBindInputAttachments) &&
+ visitor->Visit("maxPerStageUpdateAfterBindResources",
+ &properties->maxPerStageUpdateAfterBindResources) &&
+ visitor->Visit("maxDescriptorSetUpdateAfterBindSamplers",
+ &properties->maxDescriptorSetUpdateAfterBindSamplers) &&
+ visitor->Visit(
+ "maxDescriptorSetUpdateAfterBindUniformBuffers",
+ &properties->maxDescriptorSetUpdateAfterBindUniformBuffers) &&
+ visitor->Visit(
+ "maxDescriptorSetUpdateAfterBindUniformBuffersDynamic",
+ &properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic) &&
+ visitor->Visit(
+ "maxDescriptorSetUpdateAfterBindStorageBuffers",
+ &properties->maxDescriptorSetUpdateAfterBindStorageBuffers) &&
+ visitor->Visit(
+ "maxDescriptorSetUpdateAfterBindStorageBuffersDynamic",
+ &properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic) &&
+ visitor->Visit(
+ "maxDescriptorSetUpdateAfterBindSampledImages",
+ &properties->maxDescriptorSetUpdateAfterBindSampledImages) &&
+ visitor->Visit(
+ "maxDescriptorSetUpdateAfterBindStorageImages",
+ &properties->maxDescriptorSetUpdateAfterBindStorageImages) &&
+ visitor->Visit(
+ "maxDescriptorSetUpdateAfterBindInputAttachments",
+ &properties->maxDescriptorSetUpdateAfterBindInputAttachments) &&
+ visitor->Visit("supportedDepthResolveModes",
+ &properties->supportedDepthResolveModes) &&
+ visitor->Visit("supportedStencilResolveModes",
+ &properties->supportedStencilResolveModes) &&
+ visitor->Visit("independentResolveNone",
+ &properties->independentResolveNone) &&
+ visitor->Visit("independentResolve", &properties->independentResolve) &&
+ visitor->Visit("filterMinmaxSingleComponentFormats",
+ &properties->filterMinmaxSingleComponentFormats) &&
+ visitor->Visit("filterMinmaxImageComponentMapping",
+ &properties->filterMinmaxImageComponentMapping) &&
+ visitor->Visit("maxTimelineSemaphoreValueDifference",
+ &properties->maxTimelineSemaphoreValueDifference) &&
+ visitor->Visit("framebufferIntegerColorSampleCounts",
+ &properties->framebufferIntegerColorSampleCounts);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkExternalFenceProperties* properties) {
- return visitor->Visit("exportFromImportedHandleTypes",
- &properties->exportFromImportedHandleTypes) &&
- visitor->Visit("compatibleHandleTypes",
- &properties->compatibleHandleTypes) &&
- visitor->Visit("externalFenceFeatures",
- &properties->externalFenceFeatures);
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceVulkan12Features* features) {
+ return
+
+ visitor->Visit("samplerMirrorClampToEdge",
+ &features->samplerMirrorClampToEdge) &&
+ visitor->Visit("drawIndirectCount", &features->drawIndirectCount) &&
+ visitor->Visit("storageBuffer8BitAccess",
+ &features->storageBuffer8BitAccess) &&
+ visitor->Visit("uniformAndStorageBuffer8BitAccess",
+ &features->uniformAndStorageBuffer8BitAccess) &&
+ visitor->Visit("storagePushConstant8", &features->storagePushConstant8) &&
+ visitor->Visit("shaderBufferInt64Atomics",
+ &features->shaderBufferInt64Atomics) &&
+ visitor->Visit("shaderSharedInt64Atomics",
+ &features->shaderSharedInt64Atomics) &&
+ visitor->Visit("shaderFloat16", &features->shaderFloat16) &&
+ visitor->Visit("shaderInt8", &features->shaderInt8) &&
+ visitor->Visit("descriptorIndexing", &features->descriptorIndexing) &&
+ visitor->Visit("shaderInputAttachmentArrayDynamicIndexing",
+ &features->shaderInputAttachmentArrayDynamicIndexing) &&
+ visitor->Visit("shaderUniformTexelBufferArrayDynamicIndexing",
+ &features->shaderUniformTexelBufferArrayDynamicIndexing) &&
+ visitor->Visit("shaderStorageTexelBufferArrayDynamicIndexing",
+ &features->shaderStorageTexelBufferArrayDynamicIndexing) &&
+ visitor->Visit("shaderUniformBufferArrayNonUniformIndexing",
+ &features->shaderUniformBufferArrayNonUniformIndexing) &&
+ visitor->Visit("shaderSampledImageArrayNonUniformIndexing",
+ &features->shaderSampledImageArrayNonUniformIndexing) &&
+ visitor->Visit("shaderStorageBufferArrayNonUniformIndexing",
+ &features->shaderStorageBufferArrayNonUniformIndexing) &&
+ visitor->Visit("shaderStorageImageArrayNonUniformIndexing",
+ &features->shaderStorageImageArrayNonUniformIndexing) &&
+ visitor->Visit("shaderInputAttachmentArrayNonUniformIndexing",
+ &features->shaderInputAttachmentArrayNonUniformIndexing) &&
+ visitor->Visit(
+ "shaderUniformTexelBufferArrayNonUniformIndexing",
+ &features->shaderUniformTexelBufferArrayNonUniformIndexing) &&
+ visitor->Visit(
+ "shaderStorageTexelBufferArrayNonUniformIndexing",
+ &features->shaderStorageTexelBufferArrayNonUniformIndexing) &&
+ visitor->Visit(
+ "descriptorBindingUniformBufferUpdateAfterBind",
+ &features->descriptorBindingUniformBufferUpdateAfterBind) &&
+ visitor->Visit("descriptorBindingSampledImageUpdateAfterBind",
+ &features->descriptorBindingSampledImageUpdateAfterBind) &&
+ visitor->Visit("descriptorBindingStorageImageUpdateAfterBind",
+ &features->descriptorBindingStorageImageUpdateAfterBind) &&
+ visitor->Visit(
+ "descriptorBindingStorageBufferUpdateAfterBind",
+ &features->descriptorBindingStorageBufferUpdateAfterBind) &&
+ visitor->Visit(
+ "descriptorBindingUniformTexelBufferUpdateAfterBind",
+ &features->descriptorBindingUniformTexelBufferUpdateAfterBind) &&
+ visitor->Visit(
+ "descriptorBindingStorageTexelBufferUpdateAfterBind",
+ &features->descriptorBindingStorageTexelBufferUpdateAfterBind) &&
+ visitor->Visit("descriptorBindingUpdateUnusedWhilePending",
+ &features->descriptorBindingUpdateUnusedWhilePending) &&
+ visitor->Visit("descriptorBindingPartiallyBound",
+ &features->descriptorBindingPartiallyBound) &&
+ visitor->Visit("descriptorBindingVariableDescriptorCount",
+ &features->descriptorBindingVariableDescriptorCount) &&
+ visitor->Visit("runtimeDescriptorArray",
+ &features->runtimeDescriptorArray) &&
+ visitor->Visit("samplerFilterMinmax", &features->samplerFilterMinmax) &&
+ visitor->Visit("scalarBlockLayout", &features->scalarBlockLayout) &&
+ visitor->Visit("imagelessFramebuffer", &features->imagelessFramebuffer) &&
+ visitor->Visit("uniformBufferStandardLayout",
+ &features->uniformBufferStandardLayout) &&
+ visitor->Visit("shaderSubgroupExtendedTypes",
+ &features->shaderSubgroupExtendedTypes) &&
+ visitor->Visit("separateDepthStencilLayouts",
+ &features->separateDepthStencilLayouts) &&
+ visitor->Visit("hostQueryReset", &features->hostQueryReset) &&
+ visitor->Visit("timelineSemaphore", &features->timelineSemaphore) &&
+ visitor->Visit("bufferDeviceAddress", &features->bufferDeviceAddress) &&
+ visitor->Visit("bufferDeviceAddressCaptureReplay",
+ &features->bufferDeviceAddressCaptureReplay) &&
+ visitor->Visit("bufferDeviceAddressMultiDevice",
+ &features->bufferDeviceAddressMultiDevice) &&
+ visitor->Visit("vulkanMemoryModel", &features->vulkanMemoryModel) &&
+ visitor->Visit("vulkanMemoryModelDeviceScope",
+ &features->vulkanMemoryModelDeviceScope) &&
+ visitor->Visit(
+ "vulkanMemoryModelAvailabilityVisibilityChains",
+ &features->vulkanMemoryModelAvailabilityVisibilityChains) &&
+ visitor->Visit("shaderOutputViewportIndex",
+ &features->shaderOutputViewportIndex) &&
+ visitor->Visit("shaderOutputLayer", &features->shaderOutputLayer) &&
+ visitor->Visit("subgroupBroadcastDynamicId",
+ &features->subgroupBroadcastDynamicId);
}
template <typename Visitor>
inline bool Iterate(Visitor* visitor,
- VkExternalSemaphoreProperties* properties) {
- return visitor->Visit("exportFromImportedHandleTypes",
- &properties->exportFromImportedHandleTypes) &&
- visitor->Visit("compatibleHandleTypes",
- &properties->compatibleHandleTypes) &&
- visitor->Visit("externalSemaphoreFeatures",
- &properties->externalSemaphoreFeatures);
+ VkPhysicalDeviceVulkan13Properties* properties) {
+ return
+
+ visitor->Visit("minSubgroupSize", &properties->minSubgroupSize) &&
+ visitor->Visit("maxSubgroupSize", &properties->maxSubgroupSize) &&
+ visitor->Visit("maxComputeWorkgroupSubgroups",
+ &properties->maxComputeWorkgroupSubgroups) &&
+ visitor->Visit("requiredSubgroupSizeStages",
+ &properties->requiredSubgroupSizeStages) &&
+ visitor->Visit("maxInlineUniformBlockSize",
+ &properties->maxInlineUniformBlockSize) &&
+ visitor->Visit("maxPerStageDescriptorInlineUniformBlocks",
+ &properties->maxPerStageDescriptorInlineUniformBlocks) &&
+ visitor->Visit(
+ "maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks",
+ &properties
+ ->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks) &&
+ visitor->Visit("maxDescriptorSetInlineUniformBlocks",
+ &properties->maxDescriptorSetInlineUniformBlocks) &&
+ visitor->Visit(
+ "maxDescriptorSetUpdateAfterBindInlineUniformBlocks",
+ &properties->maxDescriptorSetUpdateAfterBindInlineUniformBlocks) &&
+ visitor->Visit("maxInlineUniformTotalSize",
+ &properties->maxInlineUniformTotalSize) &&
+ visitor->Visit("integerDotProduct8BitUnsignedAccelerated",
+ &properties->integerDotProduct8BitUnsignedAccelerated) &&
+ visitor->Visit("integerDotProduct8BitSignedAccelerated",
+ &properties->integerDotProduct8BitSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProduct8BitMixedSignednessAccelerated",
+ &properties->integerDotProduct8BitMixedSignednessAccelerated) &&
+ visitor->Visit(
+ "integerDotProduct4x8BitPackedUnsignedAccelerated",
+ &properties->integerDotProduct4x8BitPackedUnsignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProduct4x8BitPackedSignedAccelerated",
+ &properties->integerDotProduct4x8BitPackedSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProduct4x8BitPackedMixedSignednessAccelerated",
+ &properties
+ ->integerDotProduct4x8BitPackedMixedSignednessAccelerated) &&
+ visitor->Visit("integerDotProduct16BitUnsignedAccelerated",
+ &properties->integerDotProduct16BitUnsignedAccelerated) &&
+ visitor->Visit("integerDotProduct16BitSignedAccelerated",
+ &properties->integerDotProduct16BitSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProduct16BitMixedSignednessAccelerated",
+ &properties->integerDotProduct16BitMixedSignednessAccelerated) &&
+ visitor->Visit("integerDotProduct32BitUnsignedAccelerated",
+ &properties->integerDotProduct32BitUnsignedAccelerated) &&
+ visitor->Visit("integerDotProduct32BitSignedAccelerated",
+ &properties->integerDotProduct32BitSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProduct32BitMixedSignednessAccelerated",
+ &properties->integerDotProduct32BitMixedSignednessAccelerated) &&
+ visitor->Visit("integerDotProduct64BitUnsignedAccelerated",
+ &properties->integerDotProduct64BitUnsignedAccelerated) &&
+ visitor->Visit("integerDotProduct64BitSignedAccelerated",
+ &properties->integerDotProduct64BitSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProduct64BitMixedSignednessAccelerated",
+ &properties->integerDotProduct64BitMixedSignednessAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating8BitUnsignedAccelerated",
+ &properties
+ ->integerDotProductAccumulatingSaturating8BitUnsignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating8BitSignedAccelerated",
+ &properties
+ ->integerDotProductAccumulatingSaturating8BitSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerate"
+ "d",
+ &properties
+ ->integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerat"
+ "ed",
+ &properties
+ ->integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerate"
+ "d",
+ &properties
+ ->integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAc"
+ "celerated",
+ &properties
+ ->integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating16BitUnsignedAccelerated",
+ &properties
+ ->integerDotProductAccumulatingSaturating16BitUnsignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating16BitSignedAccelerated",
+ &properties
+ ->integerDotProductAccumulatingSaturating16BitSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerat"
+ "ed",
+ &properties
+ ->integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating32BitUnsignedAccelerated",
+ &properties
+ ->integerDotProductAccumulatingSaturating32BitUnsignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating32BitSignedAccelerated",
+ &properties
+ ->integerDotProductAccumulatingSaturating32BitSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerat"
+ "ed",
+ &properties
+ ->integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating64BitUnsignedAccelerated",
+ &properties
+ ->integerDotProductAccumulatingSaturating64BitUnsignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating64BitSignedAccelerated",
+ &properties
+ ->integerDotProductAccumulatingSaturating64BitSignedAccelerated) &&
+ visitor->Visit(
+ "integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerat"
+ "ed",
+ &properties
+ ->integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated) &&
+ visitor->Visit("storageTexelBufferOffsetAlignmentBytes",
+ &properties->storageTexelBufferOffsetAlignmentBytes) &&
+ visitor->Visit(
+ "storageTexelBufferOffsetSingleTexelAlignment",
+ &properties->storageTexelBufferOffsetSingleTexelAlignment) &&
+ visitor->Visit("uniformTexelBufferOffsetAlignmentBytes",
+ &properties->uniformTexelBufferOffsetAlignmentBytes) &&
+ visitor->Visit(
+ "uniformTexelBufferOffsetSingleTexelAlignment",
+ &properties->uniformTexelBufferOffsetSingleTexelAlignment) &&
+ visitor->Visit("maxBufferSize", &properties->maxBufferSize);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkQueueFamilyProperties* properties) {
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceVulkan13Features* features) {
return
- visitor->Visit("queueFlags", &properties->queueFlags) &&
- visitor->Visit("queueCount", &properties->queueCount) &&
- visitor->Visit("timestampValidBits", &properties->timestampValidBits) &&
- visitor->Visit("minImageTransferGranularity", &properties->minImageTransferGranularity);
+
+ visitor->Visit("robustImageAccess", &features->robustImageAccess) &&
+ visitor->Visit("inlineUniformBlock", &features->inlineUniformBlock) &&
+ visitor->Visit(
+ "descriptorBindingInlineUniformBlockUpdateAfterBind",
+ &features->descriptorBindingInlineUniformBlockUpdateAfterBind) &&
+ visitor->Visit("pipelineCreationCacheControl",
+ &features->pipelineCreationCacheControl) &&
+ visitor->Visit("privateData", &features->privateData) &&
+ visitor->Visit("shaderDemoteToHelperInvocation",
+ &features->shaderDemoteToHelperInvocation) &&
+ visitor->Visit("shaderTerminateInvocation",
+ &features->shaderTerminateInvocation) &&
+ visitor->Visit("subgroupSizeControl", &features->subgroupSizeControl) &&
+ visitor->Visit("computeFullSubgroups", &features->computeFullSubgroups) &&
+ visitor->Visit("synchronization2", &features->synchronization2) &&
+ visitor->Visit("textureCompressionASTC_HDR",
+ &features->textureCompressionASTC_HDR) &&
+ visitor->Visit("shaderZeroInitializeWorkgroupMemory",
+ &features->shaderZeroInitializeWorkgroupMemory) &&
+ visitor->Visit("dynamicRendering", &features->dynamicRendering) &&
+ visitor->Visit("shaderIntegerDotProduct",
+ &features->shaderIntegerDotProduct) &&
+ visitor->Visit("maintenance4", &features->maintenance4);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkExtensionProperties* properties) {
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceVulkan14Properties* properties) {
return
- visitor->Visit("extensionName", &properties->extensionName) &&
- visitor->Visit("specVersion", &properties->specVersion);
+
+ visitor->Visit("lineSubPixelPrecisionBits",
+ &properties->lineSubPixelPrecisionBits) &&
+ visitor->Visit("maxVertexAttribDivisor",
+ &properties->maxVertexAttribDivisor) &&
+ visitor->Visit("supportsNonZeroFirstInstance",
+ &properties->supportsNonZeroFirstInstance) &&
+ visitor->Visit("maxPushDescriptors", &properties->maxPushDescriptors) &&
+ visitor->Visit(
+ "dynamicRenderingLocalReadDepthStencilAttachments",
+ &properties->dynamicRenderingLocalReadDepthStencilAttachments) &&
+ visitor->Visit(
+ "dynamicRenderingLocalReadMultisampledAttachments",
+ &properties->dynamicRenderingLocalReadMultisampledAttachments) &&
+ visitor->Visit(
+ "earlyFragmentMultisampleCoverageAfterSampleCounting",
+ &properties->earlyFragmentMultisampleCoverageAfterSampleCounting) &&
+ visitor->Visit(
+ "earlyFragmentSampleMaskTestBeforeSampleCounting",
+ &properties->earlyFragmentSampleMaskTestBeforeSampleCounting) &&
+ visitor->Visit("depthStencilSwizzleOneSupport",
+ &properties->depthStencilSwizzleOneSupport) &&
+ visitor->Visit("polygonModePointSize",
+ &properties->polygonModePointSize) &&
+ visitor->Visit(
+ "nonStrictSinglePixelWideLinesUseParallelogram",
+ &properties->nonStrictSinglePixelWideLinesUseParallelogram) &&
+ visitor->Visit("nonStrictWideLinesUseParallelogram",
+ &properties->nonStrictWideLinesUseParallelogram) &&
+ visitor->Visit("blockTexelViewCompatibleMultipleLayers",
+ &properties->blockTexelViewCompatibleMultipleLayers) &&
+ visitor->Visit("maxCombinedImageSamplerDescriptorCount",
+ &properties->maxCombinedImageSamplerDescriptorCount) &&
+ visitor->Visit("fragmentShadingRateClampCombinerInputs",
+ &properties->fragmentShadingRateClampCombinerInputs) &&
+ visitor->Visit("defaultRobustnessStorageBuffers",
+ &properties->defaultRobustnessStorageBuffers) &&
+ visitor->Visit("defaultRobustnessUniformBuffers",
+ &properties->defaultRobustnessUniformBuffers) &&
+ visitor->Visit("defaultRobustnessVertexInputs",
+ &properties->defaultRobustnessVertexInputs) &&
+ visitor->Visit("defaultRobustnessImages",
+ &properties->defaultRobustnessImages) &&
+ visitor->Visit("copySrcLayoutCount", &properties->copySrcLayoutCount) &&
+ visitor->VisitArray("pCopySrcLayouts", properties->copySrcLayoutCount,
+ &properties->pCopySrcLayouts) &&
+ visitor->Visit("copyDstLayoutCount", &properties->copyDstLayoutCount) &&
+ visitor->VisitArray("pCopyDstLayouts", properties->copyDstLayoutCount,
+ &properties->pCopyDstLayouts) &&
+ visitor->Visit("optimalTilingLayoutUUID",
+ &properties->optimalTilingLayoutUUID) &&
+ visitor->Visit("identicalMemoryTypeRequirements",
+ &properties->identicalMemoryTypeRequirements);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkLayerProperties* properties) {
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceVulkan14Features* features) {
return
- visitor->Visit("layerName", &properties->layerName) &&
- visitor->Visit("specVersion", &properties->specVersion) &&
- visitor->Visit("implementationVersion", &properties->implementationVersion) &&
- visitor->Visit("description", &properties->description);
+
+ visitor->Visit("globalPriorityQuery", &features->globalPriorityQuery) &&
+ visitor->Visit("shaderSubgroupRotate", &features->shaderSubgroupRotate) &&
+ visitor->Visit("shaderSubgroupRotateClustered",
+ &features->shaderSubgroupRotateClustered) &&
+ visitor->Visit("shaderFloatControls2", &features->shaderFloatControls2) &&
+ visitor->Visit("shaderExpectAssume", &features->shaderExpectAssume) &&
+ visitor->Visit("rectangularLines", &features->rectangularLines) &&
+ visitor->Visit("bresenhamLines", &features->bresenhamLines) &&
+ visitor->Visit("smoothLines", &features->smoothLines) &&
+ visitor->Visit("stippledRectangularLines",
+ &features->stippledRectangularLines) &&
+ visitor->Visit("stippledBresenhamLines",
+ &features->stippledBresenhamLines) &&
+ visitor->Visit("stippledSmoothLines", &features->stippledSmoothLines) &&
+ visitor->Visit("vertexAttributeInstanceRateDivisor",
+ &features->vertexAttributeInstanceRateDivisor) &&
+ visitor->Visit("vertexAttributeInstanceRateZeroDivisor",
+ &features->vertexAttributeInstanceRateZeroDivisor) &&
+ visitor->Visit("indexTypeUint8", &features->indexTypeUint8) &&
+ visitor->Visit("dynamicRenderingLocalRead",
+ &features->dynamicRenderingLocalRead) &&
+ visitor->Visit("maintenance5", &features->maintenance5) &&
+ visitor->Visit("maintenance6", &features->maintenance6) &&
+ visitor->Visit("pipelineProtectedAccess",
+ &features->pipelineProtectedAccess) &&
+ visitor->Visit("pipelineRobustness", &features->pipelineRobustness) &&
+ visitor->Visit("hostImageCopy", &features->hostImageCopy);
}
template <typename Visitor>
-inline bool Iterate(Visitor* visitor, VkFormatProperties* properties) {
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceDriverProperties* properties) {
return
- visitor->Visit("linearTilingFeatures", &properties->linearTilingFeatures) &&
- visitor->Visit("optimalTilingFeatures", &properties->optimalTilingFeatures) &&
- visitor->Visit("bufferFeatures", &properties->bufferFeatures);
+
+ visitor->Visit("driverID", &properties->driverID) &&
+ visitor->Visit("driverName", &properties->driverName) &&
+ visitor->Visit("driverInfo", &properties->driverInfo) &&
+ visitor->Visit("conformanceVersion", &properties->conformanceVersion);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor, VkExternalFenceProperties* properties) {
+ return visitor->Visit("exportFromImportedHandleTypes",
+ &properties->exportFromImportedHandleTypes) &&
+ visitor->Visit("compatibleHandleTypes",
+ &properties->compatibleHandleTypes) &&
+ visitor->Visit("externalFenceFeatures",
+ &properties->externalFenceFeatures);
+}
+
+template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkExternalSemaphoreProperties* properties) {
+ return visitor->Visit("exportFromImportedHandleTypes",
+ &properties->exportFromImportedHandleTypes) &&
+ visitor->Visit("compatibleHandleTypes",
+ &properties->compatibleHandleTypes) &&
+ visitor->Visit("externalSemaphoreFeatures",
+ &properties->externalSemaphoreFeatures);
}
template <typename Visitor>
@@ -1211,6 +1953,7 @@ inline bool Iterate(Visitor* visitor, VkJsonDevice* device) {
ret &= visitor->Visit("core13", &device->core13);
FALLTHROUGH_INTENDED;
case VK_API_VERSION_1_2:
+ ret &= visitor->Visit("core11", &device->core11);
ret &= visitor->Visit("core12", &device->core12);
FALLTHROUGH_INTENDED;
case VK_API_VERSION_1_1:
@@ -1223,17 +1966,17 @@ inline bool Iterate(Visitor* visitor, VkJsonDevice* device) {
visitor->Visit("idProperties", &device->id_properties) &&
visitor->Visit("maintenance3Properties",
&device->maintenance3_properties) &&
- visitor->Visit("16bitStorageFeatures",
- &device->bit16_storage_features) &&
visitor->Visit("multiviewFeatures", &device->multiview_features) &&
- visitor->Visit("variablePointerFeatures",
- &device->variable_pointer_features) &&
+ visitor->Visit("variablePointersFeatures",
+ &device->variable_pointers_features) &&
visitor->Visit("protectedMemoryFeatures",
&device->protected_memory_features) &&
visitor->Visit("samplerYcbcrConversionFeatures",
&device->sampler_ycbcr_conversion_features) &&
visitor->Visit("shaderDrawParameterFeatures",
&device->shader_draw_parameter_features) &&
+ visitor->Visit("bit16StorageFeatures",
+ &device->bit16_storage_features) &&
visitor->Visit("externalFenceProperties",
&device->external_fence_properties) &&
visitor->Visit("externalSemaphoreProperties",
@@ -1247,21 +1990,90 @@ inline bool Iterate(Visitor* visitor, VkJsonDevice* device) {
visitor->Visit("extensions", &device->extensions) &&
visitor->Visit("layers", &device->layers) &&
visitor->Visit("formats", &device->formats);
- if (device->ext_driver_properties.reported) {
- ret &= visitor->Visit("VK_KHR_driver_properties",
- &device->ext_driver_properties);
- }
- if (device->ext_variable_pointer_features.reported) {
+
+ if (device->khr_variable_pointers.reported) {
ret &= visitor->Visit("VK_KHR_variable_pointers",
- &device->ext_variable_pointer_features);
+ &device->khr_variable_pointers);
}
- if (device->ext_image_2d_view_of_3d_features.reported) {
+ if (device->khr_shader_float16_int8.reported) {
+ ret &= visitor->Visit("VK_KHR_shader_float16_int8",
+ &device->khr_shader_float16_int8);
+ }
+ if (device->ext_image_2d_view_of_3d.reported) {
ret &= visitor->Visit("VK_EXT_image_2d_view_of_3d",
- &device->ext_image_2d_view_of_3d_features);
+ &device->ext_image_2d_view_of_3d);
}
- if (device->ext_shader_float16_int8_features.reported) {
- ret &= visitor->Visit("VK_KHR_shader_float16_int8",
- &device->ext_shader_float16_int8_features);
+ if (device->ext_custom_border_color.reported) {
+ ret &= visitor->Visit("VK_EXT_custom_border_color",
+ &device->ext_custom_border_color);
+ }
+ if (device->ext_primitive_topology_list_restart.reported) {
+ ret &= visitor->Visit("VK_EXT_primitive_topology_list_restart",
+ &device->ext_primitive_topology_list_restart);
+ }
+ if (device->ext_provoking_vertex.reported) {
+ ret &= visitor->Visit("VK_EXT_provoking_vertex",
+ &device->ext_provoking_vertex);
+ }
+ if (device->khr_index_type_uint8.reported) {
+ ret &= visitor->Visit("VK_KHR_index_type_uint8",
+ &device->khr_index_type_uint8);
+ }
+ if (device->ext_index_type_uint8.reported) {
+ ret &= visitor->Visit("VK_EXT_index_type_uint8",
+ &device->ext_index_type_uint8);
+ }
+ if (device->khr_vertex_attribute_divisor.reported) {
+ ret &= visitor->Visit("VK_KHR_vertex_attribute_divisor",
+ &device->khr_vertex_attribute_divisor);
+ }
+ if (device->ext_vertex_attribute_divisor.reported) {
+ ret &= visitor->Visit("VK_EXT_vertex_attribute_divisor",
+ &device->ext_vertex_attribute_divisor);
+ }
+ if (device->ext_transform_feedback.reported) {
+ ret &= visitor->Visit("VK_EXT_transform_feedback",
+ &device->ext_transform_feedback);
+ }
+ if (device->khr_shader_subgroup_uniform_control_flow.reported) {
+ ret &=
+ visitor->Visit("VK_KHR_shader_subgroup_uniform_control_flow",
+ &device->khr_shader_subgroup_uniform_control_flow);
+ }
+ if (device->khr_shader_subgroup_extended_types.reported) {
+ ret &= visitor->Visit("VK_KHR_shader_subgroup_extended_types",
+ &device->khr_shader_subgroup_extended_types);
+ }
+ if (device->khr_8bit_storage.reported) {
+ ret &= visitor->Visit("VK_KHR_8bit_storage", &device->khr_8bit_storage);
+ }
+ if (device->khr_shader_integer_dot_product.reported) {
+ ret &= visitor->Visit("VK_KHR_shader_integer_dot_product",
+ &device->khr_shader_integer_dot_product);
+ }
+ if (device->img_relaxed_line_rasterization.reported) {
+ ret &= visitor->Visit("VK_IMG_relaxed_line_rasterization",
+ &device->img_relaxed_line_rasterization);
+ }
+ if (device->khr_line_rasterization.reported) {
+ ret &= visitor->Visit("VK_KHR_line_rasterization",
+ &device->khr_line_rasterization);
+ }
+ if (device->ext_line_rasterization.reported) {
+ ret &= visitor->Visit("VK_EXT_line_rasterization",
+ &device->ext_line_rasterization);
+ }
+ if (device->ext_primitives_generated_query.reported) {
+ ret &= visitor->Visit("VK_EXT_primitives_generated_query",
+ &device->ext_primitives_generated_query);
+ }
+ if (device->khr_shader_float_controls.reported) {
+ ret &= visitor->Visit("VK_KHR_shader_float_controls",
+ &device->khr_shader_float_controls);
+ }
+ if (device->khr_driver_properties.reported) {
+ ret &= visitor->Visit("VK_KHR_driver_properties",
+ &device->khr_driver_properties);
}
}
return ret;
@@ -1319,7 +2131,9 @@ inline Json::Value ToJsonValue(const uint64_t& value) {
return Json::Value(string);
}
-template <typename T, typename = EnableForEnum<T>, typename = void,
+template <typename T,
+ typename = EnableForEnum<T>,
+ typename = void,
typename = void>
inline Json::Value ToJsonValue(const T& value) {
return Json::Value(static_cast<double>(value));
@@ -1328,7 +2142,8 @@ inline Json::Value ToJsonValue(const T& value) {
template <typename T>
inline Json::Value ArrayToJsonValue(uint32_t count, const T* values) {
Json::Value array(Json::arrayValue);
- for (unsigned int i = 0; i < count; ++i) array.append(ToJsonValue(values[i]));
+ for (unsigned int i = 0; i < count; ++i)
+ array.append(ToJsonValue(values[i]));
return array;
}
@@ -1360,7 +2175,8 @@ inline Json::Value ToJsonValue(const std::pair<F, S>& value) {
template <typename F, typename S>
inline Json::Value ToJsonValue(const std::map<F, S>& value) {
Json::Value array(Json::arrayValue);
- for (auto& kv : value) array.append(ToJsonValue(kv));
+ for (auto& kv : value)
+ array.append(ToJsonValue(kv));
return array;
}
@@ -1370,7 +2186,8 @@ class JsonWriterVisitor {
~JsonWriterVisitor() {}
- template <typename T> bool Visit(const char* key, const T* value) {
+ template <typename T>
+ bool Visit(const char* key, const T* value) {
object_[key] = ToJsonValue(*value);
return true;
}
@@ -1383,7 +2200,7 @@ class JsonWriterVisitor {
}
template <typename T>
- bool VisitArray(const char* key, uint32_t count, const T *value) {
+ bool VisitArray(const char* key, uint32_t count, const T* value) {
object_[key] = ArrayToJsonValue(count, *value);
return true;
}
@@ -1410,7 +2227,8 @@ template <typename T, typename = EnableForStruct<T>>
bool AsValue(Json::Value* json_value, T* t);
inline bool AsValue(Json::Value* json_value, int32_t* value) {
- if (json_value->type() != Json::realValue) return false;
+ if (json_value->type() != Json::realValue)
+ return false;
double d = json_value->asDouble();
if (!IsIntegral(d) ||
d < static_cast<double>(std::numeric_limits<int32_t>::min()) ||
@@ -1421,14 +2239,16 @@ inline bool AsValue(Json::Value* json_value, int32_t* value) {
}
inline bool AsValue(Json::Value* json_value, uint64_t* value) {
- if (json_value->type() != Json::stringValue) return false;
+ if (json_value->type() != Json::stringValue)
+ return false;
int result =
std::sscanf(json_value->asString().c_str(), "0x%016" PRIx64, value);
return result == 1;
}
inline bool AsValue(Json::Value* json_value, uint32_t* value) {
- if (json_value->type() != Json::realValue) return false;
+ if (json_value->type() != Json::realValue)
+ return false;
double d = json_value->asDouble();
if (!IsIntegral(d) || d < 0.0 ||
d > static_cast<double>(std::numeric_limits<uint32_t>::max()))
@@ -1447,7 +2267,8 @@ inline bool AsValue(Json::Value* json_value, uint8_t* value) {
}
inline bool AsValue(Json::Value* json_value, float* value) {
- if (json_value->type() != Json::realValue) return false;
+ if (json_value->type() != Json::realValue)
+ return false;
*value = static_cast<float>(json_value->asDouble());
return true;
}
@@ -1456,7 +2277,8 @@ inline bool AsValue(Json::Value* json_value, VkImageLayout* t) {
uint32_t value = 0;
if (!AsValue(json_value, &value))
return false;
- if (!EnumTraits<VkImageLayout>::exist(value)) return false;
+ if (!EnumTraits<VkImageLayout>::exist(value))
+ return false;
*t = static_cast<VkImageLayout>(value);
return true;
}
@@ -1466,7 +2288,8 @@ inline bool AsArray(Json::Value* json_value, uint32_t count, T* values) {
if (json_value->type() != Json::arrayValue || json_value->size() != count)
return false;
for (uint32_t i = 0; i < count; ++i) {
- if (!AsValue(&(*json_value)[i], values + i)) return false;
+ if (!AsValue(&(*json_value)[i], values + i))
+ return false;
}
return true;
}
@@ -1478,12 +2301,13 @@ inline bool AsValue(Json::Value* json_value, T (*value)[N]) {
template <size_t N>
inline bool AsValue(Json::Value* json_value, char (*value)[N]) {
- if (json_value->type() != Json::stringValue) return false;
+ if (json_value->type() != Json::stringValue)
+ return false;
size_t len = json_value->asString().length();
if (len >= N)
return false;
memcpy(*value, json_value->asString().c_str(), len);
- memset(*value + len, 0, N-len);
+ memset(*value + len, 0, N - len);
return true;
}
@@ -1491,15 +2315,17 @@ template <typename T, typename = EnableForEnum<T>, typename = void>
inline bool AsValue(Json::Value* json_value, T* t) {
uint32_t value = 0;
if (!AsValue(json_value, &value))
- return false;
- if (!EnumTraits<T>::exist(value)) return false;
+ return false;
+ if (!EnumTraits<T>::exist(value))
+ return false;
*t = static_cast<T>(value);
return true;
}
template <typename T>
inline bool AsValue(Json::Value* json_value, std::vector<T>* value) {
- if (json_value->type() != Json::arrayValue) return false;
+ if (json_value->type() != Json::arrayValue)
+ return false;
int size = json_value->size();
value->resize(size);
return AsArray(json_value, size, value->data());
@@ -1515,11 +2341,13 @@ inline bool AsValue(Json::Value* json_value, std::pair<F, S>* value) {
template <typename F, typename S>
inline bool AsValue(Json::Value* json_value, std::map<F, S>* value) {
- if (json_value->type() != Json::arrayValue) return false;
+ if (json_value->type() != Json::arrayValue)
+ return false;
int size = json_value->size();
for (int i = 0; i < size; ++i) {
std::pair<F, S> elem;
- if (!AsValue(&(*json_value)[i], &elem)) return false;
+ if (!AsValue(&(*json_value)[i], &elem))
+ return false;
if (!value->insert(elem).second)
return false;
}
@@ -1527,7 +2355,9 @@ inline bool AsValue(Json::Value* json_value, std::map<F, S>* value) {
}
template <typename T>
-bool ReadValue(Json::Value* object, const char* key, T* value,
+bool ReadValue(Json::Value* object,
+ const char* key,
+ T* value,
std::string* errors) {
Json::Value json_value = (*object)[key];
if (!json_value) {
@@ -1535,7 +2365,8 @@ bool ReadValue(Json::Value* object, const char* key, T* value,
*errors = std::string(key) + " missing.";
return false;
}
- if (AsValue(&json_value, value)) return true;
+ if (AsValue(&json_value, value))
+ return true;
if (errors)
*errors = std::string("Wrong type for ") + std::string(key) + ".";
return false;
@@ -1551,7 +2382,8 @@ class JsonReaderVisitor {
JsonReaderVisitor(Json::Value* object, std::string* errors)
: object_(object), errors_(errors) {}
- template <typename T> bool Visit(const char* key, T* value) const {
+ template <typename T>
+ bool Visit(const char* key, T* value) const {
return ReadValue(object_, key, value, errors_);
}
@@ -1565,27 +2397,28 @@ class JsonReaderVisitor {
*errors_ = std::string(key) + " missing.";
return false;
}
- if (AsArray(&json_value, count, *value)) return true;
+ if (AsArray(&json_value, count, *value))
+ return true;
if (errors_)
*errors_ = std::string("Wrong type for ") + std::string(key) + ".";
return false;
}
template <typename T>
- bool VisitArray(const char* key, uint32_t count, T *value) {
+ bool VisitArray(const char* key, uint32_t count, T* value) {
Json::Value json_value = (*object_)[key];
if (!json_value) {
if (errors_)
*errors_ = std::string(key) + " missing.";
return false;
}
- if (AsArray(&json_value, count, *value)) return true;
+ if (AsArray(&json_value, count, *value))
+ return true;
if (errors_)
*errors_ = std::string("Wrong type for ") + std::string(key) + ".";
return false;
}
-
private:
Json::Value* object_;
std::string* errors_;
@@ -1593,21 +2426,21 @@ class JsonReaderVisitor {
template <typename T, typename /*= EnableForStruct<T>*/>
bool AsValue(Json::Value* json_value, T* t) {
- if (json_value->type() != Json::objectValue) return false;
+ if (json_value->type() != Json::objectValue)
+ return false;
JsonReaderVisitor visitor(json_value, nullptr);
return VisitForRead(&visitor, t);
}
-
-template <typename T> std::string VkTypeToJson(const T& t) {
+template <typename T>
+std::string VkTypeToJson(const T& t) {
JsonWriterVisitor visitor;
VisitForWrite(&visitor, t);
return visitor.get_object().toStyledString();
}
-template <typename T> bool VkTypeFromJson(const std::string& json,
- T* t,
- std::string* errors) {
+template <typename T>
+bool VkTypeFromJson(const std::string& json, T* t, std::string* errors) {
*t = T();
Json::Value object(Json::objectValue);
Json::CharReaderBuilder builder;
diff --git a/vulkan/vkjson/vkjson.h b/vulkan/vkjson/vkjson.h
index 87a76c1ac9..d74644ca8e 100644
--- a/vulkan/vkjson/vkjson.h
+++ b/vulkan/vkjson/vkjson.h
@@ -21,8 +21,8 @@
#ifndef VKJSON_H_
#define VKJSON_H_
-#include <vulkan/vulkan.h>
#include <string.h>
+#include <vulkan/vulkan.h>
#include <map>
#include <string>
@@ -38,44 +38,233 @@ struct VkJsonLayer {
std::vector<VkExtensionProperties> extensions;
};
-struct VkJsonExtDriverProperties {
- VkJsonExtDriverProperties() {
+struct VkJsonKHRVariablePointers {
+ VkJsonKHRVariablePointers() {
reported = false;
- memset(&driver_properties_khr, 0,
- sizeof(VkPhysicalDeviceDriverPropertiesKHR));
+ memset(&variable_pointer_features_khr, 0,
+ sizeof(VkPhysicalDeviceVariablePointerFeaturesKHR));
+ memset(&variable_pointers_features_khr, 0,
+ sizeof(VkPhysicalDeviceVariablePointersFeaturesKHR));
}
bool reported;
- VkPhysicalDeviceDriverPropertiesKHR driver_properties_khr;
+ VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointer_features_khr;
+ VkPhysicalDeviceVariablePointersFeaturesKHR variable_pointers_features_khr;
};
-struct VkJsonExtVariablePointerFeatures {
- VkJsonExtVariablePointerFeatures() {
+struct VkJsonKHRShaderFloat16Int8 {
+ VkJsonKHRShaderFloat16Int8() {
reported = false;
- memset(&variable_pointer_features_khr, 0,
- sizeof(VkPhysicalDeviceVariablePointerFeaturesKHR));
+ memset(&shader_float16_int8_features_khr, 0,
+ sizeof(VkPhysicalDeviceShaderFloat16Int8FeaturesKHR));
+ memset(&float16_int8_features_khr, 0,
+ sizeof(VkPhysicalDeviceFloat16Int8FeaturesKHR));
}
bool reported;
- VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointer_features_khr;
+ VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_float16_int8_features_khr;
+ VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8_features_khr;
};
-struct VkJsonExtImage2DViewOf3DFeatures {
- VkJsonExtImage2DViewOf3DFeatures() {
+struct VkJsonExtImage2dViewOf3d {
+ VkJsonExtImage2dViewOf3d() {
reported = false;
- memset(&image_2D_view_of_3D_features_EXT, 0,
+ memset(&image_2d_view_of_3d_features_ext, 0,
sizeof(VkPhysicalDeviceImage2DViewOf3DFeaturesEXT));
}
bool reported;
- VkPhysicalDeviceImage2DViewOf3DFeaturesEXT image_2D_view_of_3D_features_EXT;
+ VkPhysicalDeviceImage2DViewOf3DFeaturesEXT image_2d_view_of_3d_features_ext;
};
-struct VkJsonExtShaderFloat16Int8Features {
- VkJsonExtShaderFloat16Int8Features() {
+struct VkJsonExtCustomBorderColor {
+ VkJsonExtCustomBorderColor() {
reported = false;
- memset(&shader_float16_int8_features_khr, 0,
- sizeof(VkPhysicalDeviceShaderFloat16Int8FeaturesKHR));
+ memset(&custom_border_color_features_ext, 0,
+ sizeof(VkPhysicalDeviceCustomBorderColorFeaturesEXT));
}
bool reported;
- VkPhysicalDeviceShaderFloat16Int8FeaturesKHR shader_float16_int8_features_khr;
+ VkPhysicalDeviceCustomBorderColorFeaturesEXT custom_border_color_features_ext;
+};
+
+struct VkJsonExtPrimitiveTopologyListRestart {
+ VkJsonExtPrimitiveTopologyListRestart() {
+ reported = false;
+ memset(&primitive_topology_list_restart_features_ext, 0,
+ sizeof(VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT));
+ }
+ bool reported;
+ VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT
+ primitive_topology_list_restart_features_ext;
+};
+
+struct VkJsonExtProvokingVertex {
+ VkJsonExtProvokingVertex() {
+ reported = false;
+ memset(&provoking_vertex_features_ext, 0,
+ sizeof(VkPhysicalDeviceProvokingVertexFeaturesEXT));
+ }
+ bool reported;
+ VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex_features_ext;
+};
+
+struct VkJsonKHRIndexTypeUint8 {
+ VkJsonKHRIndexTypeUint8() {
+ reported = false;
+ memset(&index_type_uint8_features_khr, 0,
+ sizeof(VkPhysicalDeviceIndexTypeUint8FeaturesKHR));
+ }
+ bool reported;
+ VkPhysicalDeviceIndexTypeUint8FeaturesKHR index_type_uint8_features_khr;
+};
+
+struct VkJsonExtIndexTypeUint8 {
+ VkJsonExtIndexTypeUint8() {
+ reported = false;
+ memset(&index_type_uint8_features_ext, 0,
+ sizeof(VkPhysicalDeviceIndexTypeUint8FeaturesEXT));
+ }
+ bool reported;
+ VkPhysicalDeviceIndexTypeUint8FeaturesEXT index_type_uint8_features_ext;
+};
+
+struct VkJsonKHRVertexAttributeDivisor {
+ VkJsonKHRVertexAttributeDivisor() {
+ reported = false;
+ memset(&vertex_attribute_divisor_features_khr, 0,
+ sizeof(VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR));
+ }
+ bool reported;
+ VkPhysicalDeviceVertexAttributeDivisorFeaturesKHR
+ vertex_attribute_divisor_features_khr;
+};
+
+struct VkJsonExtVertexAttributeDivisor {
+ VkJsonExtVertexAttributeDivisor() {
+ reported = false;
+ memset(&vertex_attribute_divisor_features_ext, 0,
+ sizeof(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT));
+ }
+ bool reported;
+ VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT
+ vertex_attribute_divisor_features_ext;
+};
+
+struct VkJsonExtTransformFeedback {
+ VkJsonExtTransformFeedback() {
+ reported = false;
+ memset(&transform_feedback_features_ext, 0,
+ sizeof(VkPhysicalDeviceTransformFeedbackFeaturesEXT));
+ }
+ bool reported;
+ VkPhysicalDeviceTransformFeedbackFeaturesEXT transform_feedback_features_ext;
+};
+
+struct VkJsonKHRShaderSubgroupUniformControlFlow {
+ VkJsonKHRShaderSubgroupUniformControlFlow() {
+ reported = false;
+ memset(&shader_subgroup_uniform_control_flow_features_khr, 0,
+ sizeof(VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR));
+ }
+ bool reported;
+ VkPhysicalDeviceShaderSubgroupUniformControlFlowFeaturesKHR
+ shader_subgroup_uniform_control_flow_features_khr;
+};
+
+struct VkJsonKHRShaderSubgroupExtendedTypes {
+ VkJsonKHRShaderSubgroupExtendedTypes() {
+ reported = false;
+ memset(&shader_subgroup_extended_types_features_khr, 0,
+ sizeof(VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR));
+ }
+ bool reported;
+ VkPhysicalDeviceShaderSubgroupExtendedTypesFeaturesKHR
+ shader_subgroup_extended_types_features_khr;
+};
+
+struct VkJsonKHR8bitStorage {
+ VkJsonKHR8bitStorage() {
+ reported = false;
+ memset(&bit8_storage_features_khr, 0,
+ sizeof(VkPhysicalDevice8BitStorageFeaturesKHR));
+ }
+ bool reported;
+ VkPhysicalDevice8BitStorageFeaturesKHR bit8_storage_features_khr;
+};
+
+struct VkJsonKHRShaderIntegerDotProduct {
+ VkJsonKHRShaderIntegerDotProduct() {
+ reported = false;
+ memset(&shader_integer_dot_product_features_khr, 0,
+ sizeof(VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR));
+ }
+ bool reported;
+ VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR
+ shader_integer_dot_product_features_khr;
+};
+
+struct VkJsonIMGRelaxedLineRasterization {
+ VkJsonIMGRelaxedLineRasterization() {
+ reported = false;
+ memset(&relaxed_line_rasterization_features_img, 0,
+ sizeof(VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG));
+ }
+ bool reported;
+ VkPhysicalDeviceRelaxedLineRasterizationFeaturesIMG
+ relaxed_line_rasterization_features_img;
+};
+
+struct VkJsonKHRLineRasterization {
+ VkJsonKHRLineRasterization() {
+ reported = false;
+ memset(&line_rasterization_features_khr, 0,
+ sizeof(VkPhysicalDeviceLineRasterizationFeaturesKHR));
+ }
+ bool reported;
+ VkPhysicalDeviceLineRasterizationFeaturesKHR line_rasterization_features_khr;
+};
+
+struct VkJsonExtLineRasterization {
+ VkJsonExtLineRasterization() {
+ reported = false;
+ memset(&line_rasterization_features_ext, 0,
+ sizeof(VkPhysicalDeviceLineRasterizationFeaturesEXT));
+ }
+ bool reported;
+ VkPhysicalDeviceLineRasterizationFeaturesEXT line_rasterization_features_ext;
+};
+
+struct VkJsonExtPrimitivesGeneratedQuery {
+ VkJsonExtPrimitivesGeneratedQuery() {
+ reported = false;
+ memset(&primitives_generated_query_features_ext, 0,
+ sizeof(VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT));
+ }
+ bool reported;
+ VkPhysicalDevicePrimitivesGeneratedQueryFeaturesEXT
+ primitives_generated_query_features_ext;
+};
+
+struct VkJsonKHRShaderFloatControls {
+ VkJsonKHRShaderFloatControls() {
+ reported = false;
+ memset(&float_controls_properties_khr, 0,
+ sizeof(VkPhysicalDeviceFloatControlsPropertiesKHR));
+ }
+ bool reported;
+ VkPhysicalDeviceFloatControlsPropertiesKHR float_controls_properties_khr;
+};
+
+struct VkJsonKHRDriverProperties {
+ VkJsonKHRDriverProperties() {
+ reported = false;
+ memset(&driver_properties_khr, 0,
+ sizeof(VkPhysicalDeviceDriverPropertiesKHR));
+ }
+ bool reported;
+ VkPhysicalDeviceDriverPropertiesKHR driver_properties_khr;
+};
+
+struct VkJsonCore11 {
+ VkPhysicalDeviceVulkan11Properties properties;
+ VkPhysicalDeviceVulkan11Features features;
};
struct VkJsonCore12 {
@@ -109,29 +298,48 @@ struct VkJsonDevice {
memset(&bit16_storage_features, 0,
sizeof(VkPhysicalDevice16BitStorageFeatures));
memset(&multiview_features, 0, sizeof(VkPhysicalDeviceMultiviewFeatures));
- memset(&variable_pointer_features, 0,
- sizeof(VkPhysicalDeviceVariablePointerFeatures));
+ memset(&variable_pointers_features, 0,
+ sizeof(VkPhysicalDeviceVariablePointersFeatures));
memset(&protected_memory_features, 0,
sizeof(VkPhysicalDeviceProtectedMemoryFeatures));
memset(&sampler_ycbcr_conversion_features, 0,
sizeof(VkPhysicalDeviceSamplerYcbcrConversionFeatures));
memset(&shader_draw_parameter_features, 0,
sizeof(VkPhysicalDeviceShaderDrawParameterFeatures));
+ memset(&core11, 0, sizeof(VkJsonCore11));
memset(&core12, 0, sizeof(VkJsonCore12));
memset(&core13, 0, sizeof(VkJsonCore13));
memset(&core14, 0, sizeof(VkJsonCore14));
}
+ VkJsonKHRVariablePointers khr_variable_pointers;
+ VkJsonKHRShaderFloat16Int8 khr_shader_float16_int8;
+ VkJsonExtImage2dViewOf3d ext_image_2d_view_of_3d;
+ VkJsonExtCustomBorderColor ext_custom_border_color;
+ VkJsonExtPrimitiveTopologyListRestart ext_primitive_topology_list_restart;
+ VkJsonExtProvokingVertex ext_provoking_vertex;
+ VkJsonKHRIndexTypeUint8 khr_index_type_uint8;
+ VkJsonExtIndexTypeUint8 ext_index_type_uint8;
+ VkJsonKHRVertexAttributeDivisor khr_vertex_attribute_divisor;
+ VkJsonExtVertexAttributeDivisor ext_vertex_attribute_divisor;
+ VkJsonExtTransformFeedback ext_transform_feedback;
+ VkJsonKHRShaderSubgroupUniformControlFlow
+ khr_shader_subgroup_uniform_control_flow;
+ VkJsonKHRShaderSubgroupExtendedTypes khr_shader_subgroup_extended_types;
+ VkJsonKHR8bitStorage khr_8bit_storage;
+ VkJsonKHRShaderIntegerDotProduct khr_shader_integer_dot_product;
+ VkJsonIMGRelaxedLineRasterization img_relaxed_line_rasterization;
+ VkJsonKHRLineRasterization khr_line_rasterization;
+ VkJsonExtLineRasterization ext_line_rasterization;
+ VkJsonExtPrimitivesGeneratedQuery ext_primitives_generated_query;
+ VkJsonKHRShaderFloatControls khr_shader_float_controls;
+ VkJsonKHRDriverProperties khr_driver_properties;
+ VkJsonCore11 core11;
+ VkJsonCore12 core12;
+ VkJsonCore13 core13;
+ VkJsonCore14 core14;
VkPhysicalDeviceProperties properties;
VkPhysicalDeviceFeatures features;
- VkJsonExtDriverProperties ext_driver_properties;
- VkJsonExtVariablePointerFeatures ext_variable_pointer_features;
- VkJsonExtImage2DViewOf3DFeatures ext_image_2d_view_of_3d_features;
- VkJsonExtShaderFloat16Int8Features ext_shader_float16_int8_features;
VkPhysicalDeviceMemoryProperties memory;
- std::vector<VkQueueFamilyProperties> queues;
- std::vector<VkExtensionProperties> extensions;
- std::vector<VkLayerProperties> layers;
- std::map<VkFormat, VkFormatProperties> formats;
VkPhysicalDeviceSubgroupProperties subgroup_properties;
VkPhysicalDevicePointClippingProperties point_clipping_properties;
VkPhysicalDeviceMultiviewProperties multiview_properties;
@@ -139,18 +347,19 @@ struct VkJsonDevice {
VkPhysicalDeviceMaintenance3Properties maintenance3_properties;
VkPhysicalDevice16BitStorageFeatures bit16_storage_features;
VkPhysicalDeviceMultiviewFeatures multiview_features;
- VkPhysicalDeviceVariablePointerFeatures variable_pointer_features;
+ VkPhysicalDeviceVariablePointersFeatures variable_pointers_features;
VkPhysicalDeviceProtectedMemoryFeatures protected_memory_features;
VkPhysicalDeviceSamplerYcbcrConversionFeatures
sampler_ycbcr_conversion_features;
VkPhysicalDeviceShaderDrawParameterFeatures shader_draw_parameter_features;
+ std::vector<VkQueueFamilyProperties> queues;
+ std::vector<VkExtensionProperties> extensions;
+ std::vector<VkLayerProperties> layers;
+ std::map<VkFormat, VkFormatProperties> formats;
std::map<VkExternalFenceHandleTypeFlagBits, VkExternalFenceProperties>
external_fence_properties;
std::map<VkExternalSemaphoreHandleTypeFlagBits, VkExternalSemaphoreProperties>
external_semaphore_properties;
- VkJsonCore12 core12;
- VkJsonCore13 core13;
- VkJsonCore14 core14;
};
struct VkJsonDeviceGroup {
@@ -204,4 +413,4 @@ inline bool VkJsonAllPropertiesFromJson(const std::string& json,
return VkJsonDeviceFromJson(json, properties, errors);
}
-#endif // VKJSON_H_
+#endif // VKJSON_H_ \ No newline at end of file
diff --git a/vulkan/vkjson/vkjson_instance.cc b/vulkan/vkjson/vkjson_instance.cc
index 04bb446e40..22b3204e61 100644
--- a/vulkan/vkjson/vkjson_instance.cc
+++ b/vulkan/vkjson/vkjson_instance.cc
@@ -79,13 +79,25 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
nullptr,
{},
};
+
+ if (HasExtension("VK_KHR_shader_float_controls", device.extensions)) {
+ device.khr_shader_float_controls.reported = true;
+ device.khr_shader_float_controls.float_controls_properties_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;
+ device.khr_shader_float_controls.float_controls_properties_khr.pNext =
+ properties.pNext;
+ properties.pNext =
+ &device.khr_shader_float_controls.float_controls_properties_khr;
+ }
+
if (HasExtension("VK_KHR_driver_properties", device.extensions)) {
- device.ext_driver_properties.reported = true;
- device.ext_driver_properties.driver_properties_khr.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
- device.ext_driver_properties.driver_properties_khr.pNext = properties.pNext;
- properties.pNext = &device.ext_driver_properties.driver_properties_khr;
+ device.khr_driver_properties.reported = true;
+ device.khr_driver_properties.driver_properties_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
+ device.khr_driver_properties.driver_properties_khr.pNext = properties.pNext;
+ properties.pNext = &device.khr_driver_properties.driver_properties_khr;
}
+
vkGetPhysicalDeviceProperties2(physical_device, &properties);
device.properties = properties.properties;
@@ -94,35 +106,215 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
nullptr,
{},
};
+
if (HasExtension("VK_KHR_variable_pointers", device.extensions)) {
- device.ext_variable_pointer_features.reported = true;
- device.ext_variable_pointer_features.variable_pointer_features_khr.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR;
- device.ext_variable_pointer_features.variable_pointer_features_khr.pNext =
+ device.khr_variable_pointers.reported = true;
+ device.khr_variable_pointers.variable_pointer_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
+ device.khr_variable_pointers.variable_pointer_features_khr.pNext =
+ features.pNext;
+ features.pNext =
+ &device.khr_variable_pointers.variable_pointer_features_khr;
+ device.khr_variable_pointers.variable_pointers_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
+ device.khr_variable_pointers.variable_pointers_features_khr.pNext =
+ features.pNext;
+ features.pNext =
+ &device.khr_variable_pointers.variable_pointers_features_khr;
+ }
+
+ if (HasExtension("VK_KHR_shader_float16_int8", device.extensions)) {
+ device.khr_shader_float16_int8.reported = true;
+ device.khr_shader_float16_int8.shader_float16_int8_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;
+ device.khr_shader_float16_int8.shader_float16_int8_features_khr.pNext =
features.pNext;
features.pNext =
- &device.ext_variable_pointer_features.variable_pointer_features_khr;
+ &device.khr_shader_float16_int8.shader_float16_int8_features_khr;
+ device.khr_shader_float16_int8.float16_int8_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES;
+ device.khr_shader_float16_int8.float16_int8_features_khr.pNext =
+ features.pNext;
+ features.pNext = &device.khr_shader_float16_int8.float16_int8_features_khr;
}
+
if (HasExtension("VK_EXT_image_2d_view_of_3d", device.extensions)) {
- device.ext_image_2d_view_of_3d_features.reported = true;
- device.ext_image_2d_view_of_3d_features.image_2D_view_of_3D_features_EXT
- .sType =
+ device.ext_image_2d_view_of_3d.reported = true;
+ device.ext_image_2d_view_of_3d.image_2d_view_of_3d_features_ext.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_2D_VIEW_OF_3D_FEATURES_EXT;
- device.ext_image_2d_view_of_3d_features.image_2D_view_of_3D_features_EXT
+ device.ext_image_2d_view_of_3d.image_2d_view_of_3d_features_ext.pNext =
+ features.pNext;
+ features.pNext =
+ &device.ext_image_2d_view_of_3d.image_2d_view_of_3d_features_ext;
+ }
+
+ if (HasExtension("VK_EXT_custom_border_color", device.extensions)) {
+ device.ext_custom_border_color.reported = true;
+ device.ext_custom_border_color.custom_border_color_features_ext.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT;
+ device.ext_custom_border_color.custom_border_color_features_ext.pNext =
+ features.pNext;
+ features.pNext =
+ &device.ext_custom_border_color.custom_border_color_features_ext;
+ }
+
+ if (HasExtension("VK_EXT_primitive_topology_list_restart",
+ device.extensions)) {
+ device.ext_primitive_topology_list_restart.reported = true;
+ device.ext_primitive_topology_list_restart
+ .primitive_topology_list_restart_features_ext.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT;
+ device.ext_primitive_topology_list_restart
+ .primitive_topology_list_restart_features_ext.pNext = features.pNext;
+ features.pNext = &device.ext_primitive_topology_list_restart
+ .primitive_topology_list_restart_features_ext;
+ }
+
+ if (HasExtension("VK_EXT_provoking_vertex", device.extensions)) {
+ device.ext_provoking_vertex.reported = true;
+ device.ext_provoking_vertex.provoking_vertex_features_ext.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT;
+ device.ext_provoking_vertex.provoking_vertex_features_ext.pNext =
+ features.pNext;
+ features.pNext = &device.ext_provoking_vertex.provoking_vertex_features_ext;
+ }
+
+ if (HasExtension("VK_KHR_index_type_uint8", device.extensions)) {
+ device.khr_index_type_uint8.reported = true;
+ device.khr_index_type_uint8.index_type_uint8_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES;
+ device.khr_index_type_uint8.index_type_uint8_features_khr.pNext =
+ features.pNext;
+ features.pNext = &device.khr_index_type_uint8.index_type_uint8_features_khr;
+ }
+
+ if (HasExtension("VK_EXT_index_type_uint8", device.extensions)) {
+ device.ext_index_type_uint8.reported = true;
+ device.ext_index_type_uint8.index_type_uint8_features_ext.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES;
+ device.ext_index_type_uint8.index_type_uint8_features_ext.pNext =
+ features.pNext;
+ features.pNext = &device.ext_index_type_uint8.index_type_uint8_features_ext;
+ }
+
+ if (HasExtension("VK_KHR_vertex_attribute_divisor", device.extensions)) {
+ device.khr_vertex_attribute_divisor.reported = true;
+ device.khr_vertex_attribute_divisor.vertex_attribute_divisor_features_khr
+ .sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES;
+ device.khr_vertex_attribute_divisor.vertex_attribute_divisor_features_khr
.pNext = features.pNext;
- features.pNext = &device.ext_image_2d_view_of_3d_features
- .image_2D_view_of_3D_features_EXT;
+ features.pNext = &device.khr_vertex_attribute_divisor
+ .vertex_attribute_divisor_features_khr;
}
- if (HasExtension("VK_KHR_shader_float16_int8", device.extensions)) {
- device.ext_shader_float16_int8_features.reported = true;
- device.ext_shader_float16_int8_features.shader_float16_int8_features_khr
+
+ if (HasExtension("VK_EXT_vertex_attribute_divisor", device.extensions)) {
+ device.ext_vertex_attribute_divisor.reported = true;
+ device.ext_vertex_attribute_divisor.vertex_attribute_divisor_features_ext
.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR;
- device.ext_shader_float16_int8_features.shader_float16_int8_features_khr
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES;
+ device.ext_vertex_attribute_divisor.vertex_attribute_divisor_features_ext
.pNext = features.pNext;
- features.pNext = &device.ext_shader_float16_int8_features
- .shader_float16_int8_features_khr;
+ features.pNext = &device.ext_vertex_attribute_divisor
+ .vertex_attribute_divisor_features_ext;
}
+
+ if (HasExtension("VK_EXT_transform_feedback", device.extensions)) {
+ device.ext_transform_feedback.reported = true;
+ device.ext_transform_feedback.transform_feedback_features_ext.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
+ device.ext_transform_feedback.transform_feedback_features_ext.pNext =
+ features.pNext;
+ features.pNext =
+ &device.ext_transform_feedback.transform_feedback_features_ext;
+ }
+
+ if (HasExtension("VK_KHR_shader_subgroup_uniform_control_flow",
+ device.extensions)) {
+ device.khr_shader_subgroup_uniform_control_flow.reported = true;
+ device.khr_shader_subgroup_uniform_control_flow
+ .shader_subgroup_uniform_control_flow_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_UNIFORM_CONTROL_FLOW_FEATURES_KHR;
+ device.khr_shader_subgroup_uniform_control_flow
+ .shader_subgroup_uniform_control_flow_features_khr.pNext =
+ features.pNext;
+ features.pNext = &device.khr_shader_subgroup_uniform_control_flow
+ .shader_subgroup_uniform_control_flow_features_khr;
+ }
+
+ if (HasExtension("VK_KHR_shader_subgroup_extended_types",
+ device.extensions)) {
+ device.khr_shader_subgroup_extended_types.reported = true;
+ device.khr_shader_subgroup_extended_types
+ .shader_subgroup_extended_types_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES;
+ device.khr_shader_subgroup_extended_types
+ .shader_subgroup_extended_types_features_khr.pNext = features.pNext;
+ features.pNext = &device.khr_shader_subgroup_extended_types
+ .shader_subgroup_extended_types_features_khr;
+ }
+
+ if (HasExtension("VK_KHR_8bit_storage", device.extensions)) {
+ device.khr_8bit_storage.reported = true;
+ device.khr_8bit_storage.bit8_storage_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES;
+ device.khr_8bit_storage.bit8_storage_features_khr.pNext = features.pNext;
+ features.pNext = &device.khr_8bit_storage.bit8_storage_features_khr;
+ }
+
+ if (HasExtension("VK_KHR_shader_integer_dot_product", device.extensions)) {
+ device.khr_shader_integer_dot_product.reported = true;
+ device.khr_shader_integer_dot_product
+ .shader_integer_dot_product_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES;
+ device.khr_shader_integer_dot_product
+ .shader_integer_dot_product_features_khr.pNext = features.pNext;
+ features.pNext = &device.khr_shader_integer_dot_product
+ .shader_integer_dot_product_features_khr;
+ }
+
+ if (HasExtension("VK_IMG_relaxed_line_rasterization", device.extensions)) {
+ device.img_relaxed_line_rasterization.reported = true;
+ device.img_relaxed_line_rasterization
+ .relaxed_line_rasterization_features_img.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RELAXED_LINE_RASTERIZATION_FEATURES_IMG;
+ device.img_relaxed_line_rasterization
+ .relaxed_line_rasterization_features_img.pNext = features.pNext;
+ features.pNext = &device.img_relaxed_line_rasterization
+ .relaxed_line_rasterization_features_img;
+ }
+
+ if (HasExtension("VK_KHR_line_rasterization", device.extensions)) {
+ device.khr_line_rasterization.reported = true;
+ device.khr_line_rasterization.line_rasterization_features_khr.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES;
+ device.khr_line_rasterization.line_rasterization_features_khr.pNext =
+ features.pNext;
+ features.pNext =
+ &device.khr_line_rasterization.line_rasterization_features_khr;
+ }
+
+ if (HasExtension("VK_EXT_line_rasterization", device.extensions)) {
+ device.ext_line_rasterization.reported = true;
+ device.ext_line_rasterization.line_rasterization_features_ext.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES;
+ device.ext_line_rasterization.line_rasterization_features_ext.pNext =
+ features.pNext;
+ features.pNext =
+ &device.ext_line_rasterization.line_rasterization_features_ext;
+ }
+
+ if (HasExtension("VK_EXT_primitives_generated_query", device.extensions)) {
+ device.ext_primitives_generated_query.reported = true;
+ device.ext_primitives_generated_query
+ .primitives_generated_query_features_ext.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVES_GENERATED_QUERY_FEATURES_EXT;
+ device.ext_primitives_generated_query
+ .primitives_generated_query_features_ext.pNext = features.pNext;
+ features.pNext = &device.ext_primitives_generated_query
+ .primitives_generated_query_features_ext;
+ }
+
vkGetPhysicalDeviceFeatures2(physical_device, &features);
device.features = features.features;
@@ -194,20 +386,15 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
vkGetPhysicalDeviceProperties2(physical_device, &properties);
- device.bit16_storage_features.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
- device.bit16_storage_features.pNext = features.pNext;
- features.pNext = &device.bit16_storage_features;
-
device.multiview_features.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES;
device.multiview_features.pNext = features.pNext;
features.pNext = &device.multiview_features;
- device.variable_pointer_features.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES;
- device.variable_pointer_features.pNext = features.pNext;
- features.pNext = &device.variable_pointer_features;
+ device.variable_pointers_features.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES;
+ device.variable_pointers_features.pNext = features.pNext;
+ features.pNext = &device.variable_pointers_features;
device.protected_memory_features.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES;
@@ -220,10 +407,15 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
features.pNext = &device.sampler_ycbcr_conversion_features;
device.shader_draw_parameter_features.sType =
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES;
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES;
device.shader_draw_parameter_features.pNext = features.pNext;
features.pNext = &device.shader_draw_parameter_features;
+ device.bit16_storage_features.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
+ device.bit16_storage_features.pNext = features.pNext;
+ features.pNext = &device.bit16_storage_features;
+
vkGetPhysicalDeviceFeatures2(physical_device, &features);
VkPhysicalDeviceExternalFenceInfo external_fence_info = {
@@ -271,6 +463,11 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
}
if (device.properties.apiVersion >= VK_API_VERSION_1_2) {
+ device.core11.properties.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES;
+ device.core11.properties.pNext = properties.pNext;
+ properties.pNext = &device.core11.properties;
+
device.core12.properties.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
device.core12.properties.pNext = properties.pNext;
@@ -278,6 +475,11 @@ VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
vkGetPhysicalDeviceProperties2(physical_device, &properties);
+ device.core11.features.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
+ device.core11.features.pNext = features.pNext;
+ features.pNext = &device.core11.features;
+
device.core12.features.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
device.core12.features.pNext = features.pNext;
@@ -337,7 +539,8 @@ VkJsonInstance VkJsonGetInstance() {
return VkJsonInstance();
instance.layers.reserve(count);
for (auto& layer : layers) {
- instance.layers.push_back(VkJsonLayer{layer, std::vector<VkExtensionProperties>()});
+ instance.layers.push_back(
+ VkJsonLayer{layer, std::vector<VkExtensionProperties>()});
if (!EnumerateExtensions(layer.layerName,
&instance.layers.back().extensions))
return VkJsonInstance();